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

Commit 14f95536 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Dynamically stop services with multiple interfaces" am: 8b1d97c7

Change-Id: If1d069e8215eec3dec5b5b0cb826b7b2b2c41105
parents 9b3b0e04 8b1d97c7
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");
        }