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

Commit 3c93111c authored by Devin Moore's avatar Devin Moore
Browse files

Enable ServiceManager APIs without servicemanager process

In some devices, like Microdroid, there is no servicemanager process.
These ServiceManager APIs may still be used with the new Accessor
pattern for communication over sockets with binder RPC.

This CL adds support for all of the getService APIs whithout relying on
the servicemanager process.

Future API support will be added separately.

Test: atest vm_accessor_test binderLibTest
Bug: 358427181
Change-Id: Ibef52415bf1509cdcd6c9cb65dbb8e20ec08d007
parent b53ef230
Loading
Loading
Loading
Loading
+92 −21
Original line number Original line Diff line number Diff line
@@ -47,6 +47,9 @@ using AidlServiceManager = android::os::IServiceManager;
using android::os::IAccessor;
using android::os::IAccessor;
using binder::Status;
using binder::Status;


static const char* kUnsupportedOpNoServiceManager =
        "Unsupported operation without a kernel binder servicemanager process";

static const char* kStaticCachableList[] = {
static const char* kStaticCachableList[] = {
        // go/keep-sorted start
        // go/keep-sorted start
        "accessibility",
        "accessibility",
@@ -220,7 +223,10 @@ Status BackendUnifiedServiceManager::getService2(const ::std::string& name, os::
        return Status::ok();
        return Status::ok();
    }
    }
    os::Service service;
    os::Service service;
    Status status = mTheRealServiceManager->getService2(name, &service);
    Status status = Status::ok();
    if (mTheRealServiceManager) {
        status = mTheRealServiceManager->getService2(name, &service);
    }


    if (status.isOk()) {
    if (status.isOk()) {
        status = toBinderService(name, service, _out);
        status = toBinderService(name, service, _out);
@@ -237,7 +243,10 @@ Status BackendUnifiedServiceManager::checkService(const ::std::string& name, os:
        return Status::ok();
        return Status::ok();
    }
    }


    Status status = mTheRealServiceManager->checkService(name, &service);
    Status status = Status::ok();
    if (mTheRealServiceManager) {
        status = mTheRealServiceManager->checkService(name, &service);
    }
    if (status.isOk()) {
    if (status.isOk()) {
        status = toBinderService(name, service, _out);
        status = toBinderService(name, service, _out);
        if (status.isOk()) {
        if (status.isOk()) {
@@ -315,7 +324,9 @@ Status BackendUnifiedServiceManager::toBinderService(const ::std::string& name,
Status BackendUnifiedServiceManager::addService(const ::std::string& name,
Status BackendUnifiedServiceManager::addService(const ::std::string& name,
                                                const sp<IBinder>& service, bool allowIsolated,
                                                const sp<IBinder>& service, bool allowIsolated,
                                                int32_t dumpPriority) {
                                                int32_t dumpPriority) {
    Status status = mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);
    if (mTheRealServiceManager) {
        Status status =
                mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);
        // mEnableAddServiceCache is true by default.
        // mEnableAddServiceCache is true by default.
        if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) {
        if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) {
            return updateCache(name, service,
            return updateCache(name, service,
@@ -323,58 +334,118 @@ Status BackendUnifiedServiceManager::addService(const ::std::string& name,
        }
        }
        return status;
        return status;
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::listServices(int32_t dumpPriority,
Status BackendUnifiedServiceManager::listServices(int32_t dumpPriority,
                                                  ::std::vector<::std::string>* _aidl_return) {
                                                  ::std::vector<::std::string>* _aidl_return) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
        return mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::registerForNotifications(
Status BackendUnifiedServiceManager::registerForNotifications(
        const ::std::string& name, const sp<os::IServiceCallback>& callback) {
        const ::std::string& name, const sp<os::IServiceCallback>& callback) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->registerForNotifications(name, callback);
        return mTheRealServiceManager->registerForNotifications(name, callback);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::unregisterForNotifications(
Status BackendUnifiedServiceManager::unregisterForNotifications(
        const ::std::string& name, const sp<os::IServiceCallback>& callback) {
        const ::std::string& name, const sp<os::IServiceCallback>& callback) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->unregisterForNotifications(name, callback);
        return mTheRealServiceManager->unregisterForNotifications(name, callback);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name, bool* _aidl_return) {
Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name, bool* _aidl_return) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->isDeclared(name, _aidl_return);
        return mTheRealServiceManager->isDeclared(name, _aidl_return);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::getDeclaredInstances(
Status BackendUnifiedServiceManager::getDeclaredInstances(
        const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) {
        const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
        return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::updatableViaApex(
Status BackendUnifiedServiceManager::updatableViaApex(
        const ::std::string& name, ::std::optional<::std::string>* _aidl_return) {
        const ::std::string& name, ::std::optional<::std::string>* _aidl_return) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->updatableViaApex(name, _aidl_return);
        return mTheRealServiceManager->updatableViaApex(name, _aidl_return);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::getUpdatableNames(const ::std::string& apexName,
Status BackendUnifiedServiceManager::getUpdatableNames(const ::std::string& apexName,
                                                       ::std::vector<::std::string>* _aidl_return) {
                                                       ::std::vector<::std::string>* _aidl_return) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return);
        return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::getConnectionInfo(
Status BackendUnifiedServiceManager::getConnectionInfo(
        const ::std::string& name, ::std::optional<os::ConnectionInfo>* _aidl_return) {
        const ::std::string& name, ::std::optional<os::ConnectionInfo>* _aidl_return) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->getConnectionInfo(name, _aidl_return);
        return mTheRealServiceManager->getConnectionInfo(name, _aidl_return);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::registerClientCallback(
Status BackendUnifiedServiceManager::registerClientCallback(
        const ::std::string& name, const sp<IBinder>& service,
        const ::std::string& name, const sp<IBinder>& service,
        const sp<os::IClientCallback>& callback) {
        const sp<os::IClientCallback>& callback) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->registerClientCallback(name, service, callback);
        return mTheRealServiceManager->registerClientCallback(name, service, callback);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::tryUnregisterService(const ::std::string& name,
Status BackendUnifiedServiceManager::tryUnregisterService(const ::std::string& name,
                                                          const sp<IBinder>& service) {
                                                          const sp<IBinder>& service) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->tryUnregisterService(name, service);
        return mTheRealServiceManager->tryUnregisterService(name, service);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}
Status BackendUnifiedServiceManager::getServiceDebugInfo(
Status BackendUnifiedServiceManager::getServiceDebugInfo(
        ::std::vector<os::ServiceDebugInfo>* _aidl_return) {
        ::std::vector<os::ServiceDebugInfo>* _aidl_return) {
    if (mTheRealServiceManager) {
        return mTheRealServiceManager->getServiceDebugInfo(_aidl_return);
        return mTheRealServiceManager->getServiceDebugInfo(_aidl_return);
    }
    }
    return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
                                     kUnsupportedOpNoServiceManager);
}


[[clang::no_destroy]] static std::once_flag gUSmOnce;
[[clang::no_destroy]] static std::once_flag gUSmOnce;
[[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager;
[[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager;


static bool hasOutOfProcessServiceManager() {
#ifndef BINDER_WITH_KERNEL_IPC
    return false;
#else
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
    return android::base::GetBoolProperty("servicemanager.installed", true);
#else
    return true;
#endif
#endif // BINDER_WITH_KERNEL_IPC
}

sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
    std::call_once(gUSmOnce, []() {
    std::call_once(gUSmOnce, []() {
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
        /* wait for service manager */ {
        /* wait for service manager */
        if (hasOutOfProcessServiceManager()) {
            using std::literals::chrono_literals::operator""s;
            using std::literals::chrono_literals::operator""s;
            using android::base::WaitForProperty;
            using android::base::WaitForProperty;
            while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
            while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
@@ -384,7 +455,7 @@ sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
#endif
#endif


        sp<AidlServiceManager> sm = nullptr;
        sp<AidlServiceManager> sm = nullptr;
        while (sm == nullptr) {
        while (hasOutOfProcessServiceManager() && sm == nullptr) {
            sm = interface_cast<AidlServiceManager>(
            sm = interface_cast<AidlServiceManager>(
                    ProcessState::self()->getContextObject(nullptr));
                    ProcessState::self()->getContextObject(nullptr));
            if (sm == nullptr) {
            if (sm == nullptr) {
+8 −0
Original line number Original line Diff line number Diff line
@@ -80,6 +80,14 @@ public:


    /**
    /**
     * Register a service.
     * Register a service.
     *
     * Note:
     * This status_t return value may be an exception code from an underlying
     * Status type that doesn't have a representive error code in
     * utils/Errors.h.
     * One example of this is a return value of -7
     * (Status::Exception::EX_UNSUPPORTED_OPERATION) when the service manager
     * process is not installed on the device when addService is called.
     */
     */
    // NOLINTNEXTLINE(google-default-arguments)
    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t addService(const String16& name, const sp<IBinder>& service,
    virtual status_t addService(const String16& name, const sp<IBinder>& service,
+45 −12
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@
#include <processgroup/processgroup.h>
#include <processgroup/processgroup.h>
#include <utils/Flattenable.h>
#include <utils/Flattenable.h>
#include <utils/SystemClock.h>
#include <utils/SystemClock.h>
#include "binder/IServiceManagerUnitTestHelper.h"


#include <linux/sched.h>
#include <linux/sched.h>
#include <sys/epoll.h>
#include <sys/epoll.h>
@@ -558,14 +559,14 @@ TEST_F(BinderLibTest, AddManagerToManager) {
    EXPECT_EQ(NO_ERROR, sm->addService(String16("binderLibTest-manager"), binder));
    EXPECT_EQ(NO_ERROR, sm->addService(String16("binderLibTest-manager"), binder));
}
}


TEST_F(BinderLibTest, RegisterForNotificationsFailure) {
class LocalRegistrationCallbackImpl : public virtual IServiceManager::LocalRegistrationCallback {
    auto sm = defaultServiceManager();
    using LocalRegistrationCallback = IServiceManager::LocalRegistrationCallback;
    class LocalRegistrationCallbackImpl : public virtual LocalRegistrationCallback {
    void onServiceRegistration(const String16&, const sp<IBinder>&) override {}
    void onServiceRegistration(const String16&, const sp<IBinder>&) override {}
    virtual ~LocalRegistrationCallbackImpl() {}
    virtual ~LocalRegistrationCallbackImpl() {}
};
};
    sp<LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make();

TEST_F(BinderLibTest, RegisterForNotificationsFailure) {
    auto sm = defaultServiceManager();
    sp<IServiceManager::LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make();


    EXPECT_EQ(BAD_VALUE, sm->registerForNotifications(String16("ValidName"), nullptr));
    EXPECT_EQ(BAD_VALUE, sm->registerForNotifications(String16("ValidName"), nullptr));
    EXPECT_EQ(UNKNOWN_ERROR, sm->registerForNotifications(String16("InvalidName!$"), cb));
    EXPECT_EQ(UNKNOWN_ERROR, sm->registerForNotifications(String16("InvalidName!$"), cb));
@@ -573,12 +574,7 @@ TEST_F(BinderLibTest, RegisterForNotificationsFailure) {


TEST_F(BinderLibTest, UnregisterForNotificationsFailure) {
TEST_F(BinderLibTest, UnregisterForNotificationsFailure) {
    auto sm = defaultServiceManager();
    auto sm = defaultServiceManager();
    using LocalRegistrationCallback = IServiceManager::LocalRegistrationCallback;
    sp<IServiceManager::LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make();
    class LocalRegistrationCallbackImpl : public virtual LocalRegistrationCallback {
        void onServiceRegistration(const String16&, const sp<IBinder>&) override {}
        virtual ~LocalRegistrationCallbackImpl() {}
    };
    sp<LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make();


    EXPECT_EQ(OK, sm->registerForNotifications(String16("ValidName"), cb));
    EXPECT_EQ(OK, sm->registerForNotifications(String16("ValidName"), cb));


@@ -1667,6 +1663,43 @@ TEST(ServiceNotifications, Unregister) {
    EXPECT_EQ(sm->unregisterForNotifications(String16("RogerRafa"), cb), OK);
    EXPECT_EQ(sm->unregisterForNotifications(String16("RogerRafa"), cb), OK);
}
}


// Make sure all IServiceManager APIs will function without an AIDL service
// manager registered on the device.
TEST(ServiceManagerNoAidlServer, SanityCheck) {
    String16 kServiceName("no_services_exist");
    // This is what clients will see when there is no servicemanager process
    // that registers itself as context object 0.
    // Can't use setDefaultServiceManager() here because these test cases run in
    // the same process and will abort when called twice or before/after
    // defaultServiceManager().
    sp<IServiceManager> sm = getServiceManagerShimFromAidlServiceManagerForTests(nullptr);
    auto status = sm->addService(kServiceName, sp<BBinder>::make());
    // CppBackendShim returns Status::exceptionCode as the status_t
    EXPECT_EQ(status, Status::Exception::EX_UNSUPPORTED_OPERATION) << statusToString(status);
    auto service = sm->checkService(String16("no_services_exist"));
    EXPECT_TRUE(service == nullptr);
    auto list = sm->listServices(android::IServiceManager::DUMP_FLAG_PRIORITY_ALL);
    EXPECT_TRUE(list.isEmpty());
    bool declared = sm->isDeclared(kServiceName);
    EXPECT_FALSE(declared);
    list = sm->getDeclaredInstances(kServiceName);
    EXPECT_TRUE(list.isEmpty());
    auto updatable = sm->updatableViaApex(kServiceName);
    EXPECT_EQ(updatable, std::nullopt);
    list = sm->getUpdatableNames(kServiceName);
    EXPECT_TRUE(list.isEmpty());
    auto conInfo = sm->getConnectionInfo(kServiceName);
    EXPECT_EQ(conInfo, std::nullopt);
    auto cb = sp<LocalRegistrationCallbackImpl>::make();
    status = sm->registerForNotifications(kServiceName, cb);
    EXPECT_EQ(status, UNKNOWN_ERROR) << statusToString(status);
    status = sm->unregisterForNotifications(kServiceName, cb);
    EXPECT_EQ(status, BAD_VALUE) << statusToString(status);
    auto dbgInfos = sm->getServiceDebugInfo();
    EXPECT_TRUE(dbgInfos.empty());
    sm->enableAddServiceCache(true);
}

TEST_F(BinderLibTest, ThreadPoolAvailableThreads) {
TEST_F(BinderLibTest, ThreadPoolAvailableThreads) {
    Parcel data, reply;
    Parcel data, reply;
    sp<IBinder> server = addServer();
    sp<IBinder> server = addServer();