Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b1d97c7 authored by Jon Spivack's avatar Jon Spivack Committed by Gerrit Code Review
Browse files

Merge "Dynamically stop services with multiple interfaces"

parents 6d24b1eb 5de798e9
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -423,11 +423,12 @@ ssize_t ServiceManager::Service::getNodeStrongRefCount() {

void ServiceManager::handleClientCallbacks() {
    for (const auto& [name, service] : mNameToService) {
        handleServiceClientCallback(name);
        handleServiceClientCallback(name, true);
    }
}

ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName) {
ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName,
                                                    bool isCalledOnInterval) {
    auto serviceIt = mNameToService.find(serviceName);
    if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) {
        return -1;
@@ -451,6 +452,8 @@ ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceNa
        service.guaranteeClient = false;
    }

    // only send notifications if this was called via the interval checking workflow
    if (isCalledOnInterval) {
        if (hasClients && !service.hasClients) {
            // client was retrieved in some other way
            sendClientCallbackNotifications(serviceName, true);
@@ -460,6 +463,7 @@ ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceNa
        if (!hasClients && service.hasClients) {
            sendClientCallbackNotifications(serviceName, false);
        }
    }

    return count;
}
@@ -518,7 +522,7 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB
        return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
    }

    int clients = handleServiceClientCallback(name);
    int clients = handleServiceClientCallback(name, false);

    // clients < 0: feature not implemented or other error. Assume clients.
    // Otherwise:
@@ -527,7 +531,7 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB
    // So, if clients > 2, then at least one other service on the system must hold a refcount.
    if (clients < 0 || clients > 2) {
        // client callbacks are either disabled or there are other clients
        LOG(INFO) << "Tried to unregister " << name << " but there are clients: " << clients;
        LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients;
        return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
    }

+1 −1
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ private:
    void removeRegistrationCallback(const wp<IBinder>& who,
                        ServiceCallbackMap::iterator* it,
                        bool* found);
    ssize_t handleServiceClientCallback(const std::string& serviceName);
    ssize_t handleServiceClientCallback(const std::string& serviceName, bool isCalledOnInterval);
     // Also updates mHasClients (of what the last callback was)
    void sendClientCallbackNotifications(const std::string& serviceName, bool hasClients);
    // removes a callback from mNameToClientCallback, deleting the entry if the vector is empty
+17 −12
Original line number Diff line number Diff line
@@ -53,14 +53,13 @@ private:

    struct Service {
        sp<IBinder> service;
        std::string name;
        bool allowIsolated;
        int dumpFlags;
    };
    /**
     * Number of services that have been registered.
     * Map of registered names and services
     */
    std::vector<Service> mRegisteredServices;
    std::map<std::string, Service> mRegisteredServices;
};

bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name,
@@ -68,20 +67,24 @@ bool ClientCounterCallback::registerService(const sp<IBinder>& service, const st
    auto manager = interface_cast<AidlServiceManager>(
                    ProcessState::self()->getContextObject(nullptr));

    ALOGI("Registering service %s", name.c_str());
    bool reRegister = mRegisteredServices.count(name) > 0;
    std::string regStr = (reRegister) ? "Re-registering" : "Registering";
    ALOGI("%s service %s", regStr.c_str(), name.c_str());

    if (!manager->addService(name.c_str(), service, allowIsolated, dumpFlags).isOk()) {
        ALOGE("Failed to register service %s", name.c_str());
        return false;
    }

    if (!manager->registerClientCallback(name, service, this).isOk())
    {
    if (!manager->registerClientCallback(name, service, this).isOk()) {
        ALOGE("Failed to add client callback for service %s", name.c_str());
        return false;
    }

    mRegisteredServices.push_back({service, name, allowIsolated, dumpFlags});
    if (!reRegister) {
        // Only add this when a service is added for the first time, as it is not removed
        mRegisteredServices[name] = {service, allowIsolated, dumpFlags};
    }

    return true;
}
@@ -119,10 +122,11 @@ void ClientCounterCallback::tryShutdown() {
    for (; unRegisterIt != mRegisteredServices.end(); ++unRegisterIt) {
        auto& entry = (*unRegisterIt);

        bool success = manager->tryUnregisterService(entry.name, entry.service).isOk();
        bool success = manager->tryUnregisterService(entry.first, entry.second.service).isOk();


        if (!success) {
            ALOGI("Failed to unregister service %s", entry.name.c_str());
            ALOGI("Failed to unregister service %s", entry.first.c_str());
            break;
        }
    }
@@ -137,7 +141,8 @@ void ClientCounterCallback::tryShutdown() {
        auto& entry = (*reRegisterIt);

        // re-register entry
        if (!registerService(entry.service, entry.name, entry.allowIsolated, entry.dumpFlags)) {
        if (!registerService(entry.second.service, entry.first, entry.second.allowIsolated,
                             entry.second.dumpFlags)) {
            // Must restart. Otherwise, clients will never be able to get a hold of this service.
            ALOGE("Bad state: could not re-register services");
        }