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

Commit 11da1503 authored by Alice Wang's avatar Alice Wang
Browse files

[native] Restore ServiceManager#getService() to return IBinder

This fixes a crash in 3p libraries.
A new API ServiceManager#getService2() has been introduced to
work with the Service enum type.

Bug: 354674329
Bug: 355187769
Test: atest servicemanager_test
Test: atest vm_accessor_test
Test: Run the demo app in b/354674329 and check it works
Change-Id: If1e0e9bee6dcd3cfceea69bea58ed5fbe431e81d
parent 725f8280
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -392,7 +392,16 @@ ServiceManager::~ServiceManager() {
    }
}

Status ServiceManager::getService(const std::string& name, os::Service* outService) {
Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
            PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));

    *outBinder = tryGetBinder(name, true);
    // returns ok regardless of result for legacy reasons
    return Status::ok();
}

Status ServiceManager::getService2(const std::string& name, os::Service* outService) {
    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
            PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));

+2 −1
Original line number Diff line number Diff line
@@ -44,7 +44,8 @@ public:
    ~ServiceManager();

    // getService will try to start any services it cannot find
    binder::Status getService(const std::string& name, os::Service* outService) override;
    binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override;
    binder::Status getService2(const std::string& name, os::Service* outService) override;
    binder::Status checkService(const std::string& name, os::Service* outService) override;
    binder::Status addService(const std::string& name, const sp<IBinder>& binder,
                              bool allowIsolated, int32_t dumpPriority) override;
+48 −21
Original line number Diff line number Diff line
@@ -155,8 +155,11 @@ TEST(AddService, OverwriteExistingService) {
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());

    Service outA;
    EXPECT_TRUE(sm->getService("foo", &outA).isOk());
    EXPECT_TRUE(sm->getService2("foo", &outA).isOk());
    EXPECT_EQ(serviceA, outA.get<Service::Tag::binder>());
    sp<IBinder> outBinderA;
    EXPECT_TRUE(sm->getService("foo", &outBinderA).isOk());
    EXPECT_EQ(serviceA, outBinderA);

    // serviceA should be overwritten by serviceB
    sp<IBinder> serviceB = getBinder();
@@ -164,8 +167,11 @@ TEST(AddService, OverwriteExistingService) {
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());

    Service outB;
    EXPECT_TRUE(sm->getService("foo", &outB).isOk());
    EXPECT_TRUE(sm->getService2("foo", &outB).isOk());
    EXPECT_EQ(serviceB, outB.get<Service::Tag::binder>());
    sp<IBinder> outBinderB;
    EXPECT_TRUE(sm->getService("foo", &outBinderB).isOk());
    EXPECT_EQ(serviceB, outBinderB);
}

TEST(AddService, NoPermissions) {
@@ -188,16 +194,22 @@ TEST(GetService, HappyHappy) {
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());

    Service out;
    EXPECT_TRUE(sm->getService("foo", &out).isOk());
    EXPECT_TRUE(sm->getService2("foo", &out).isOk());
    EXPECT_EQ(service, out.get<Service::Tag::binder>());
    sp<IBinder> outBinder;
    EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
    EXPECT_EQ(service, outBinder);
}

TEST(GetService, NonExistant) {
    auto sm = getPermissiveServiceManager();

    Service out;
    EXPECT_TRUE(sm->getService("foo", &out).isOk());
    EXPECT_TRUE(sm->getService2("foo", &out).isOk());
    EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
    sp<IBinder> outBinder;
    EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
    EXPECT_EQ(nullptr, outBinder);
}

TEST(GetService, NoPermissionsForGettingService) {
@@ -205,7 +217,7 @@ TEST(GetService, NoPermissionsForGettingService) {

    EXPECT_CALL(*access, getCallingContext()).WillRepeatedly(Return(Access::CallingContext{}));
    EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true));
    EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(false));
    EXPECT_CALL(*access, canFind(_, _)).WillRepeatedly(Return(false));

    sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));

@@ -214,8 +226,11 @@ TEST(GetService, NoPermissionsForGettingService) {

    Service out;
    // returns nullptr but has OK status for legacy compatibility
    EXPECT_TRUE(sm->getService("foo", &out).isOk());
    EXPECT_TRUE(sm->getService2("foo", &out).isOk());
    EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
    sp<IBinder> outBinder;
    EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
    EXPECT_EQ(nullptr, outBinder);
}

TEST(GetService, AllowedFromIsolated) {
@@ -224,12 +239,15 @@ TEST(GetService, AllowedFromIsolated) {
    EXPECT_CALL(*access, getCallingContext())
            // something adds it
            .WillOnce(Return(Access::CallingContext{}))
        // next call is from isolated app
            // next calls is from isolated app
            .WillOnce(Return(Access::CallingContext{
                    .uid = AID_ISOLATED_START,
            }))
            .WillOnce(Return(Access::CallingContext{
                    .uid = AID_ISOLATED_START,
            }));
    EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true));
    EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true));
    EXPECT_CALL(*access, canFind(_, _)).WillRepeatedly(Return(true));

    sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));

@@ -238,8 +256,11 @@ TEST(GetService, AllowedFromIsolated) {
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());

    Service out;
    EXPECT_TRUE(sm->getService("foo", &out).isOk());
    EXPECT_TRUE(sm->getService2("foo", &out).isOk());
    EXPECT_EQ(service, out.get<Service::Tag::binder>());
    sp<IBinder> outBinder;
    EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
    EXPECT_EQ(service, outBinder);
}

TEST(GetService, NotAllowedFromIsolated) {
@@ -248,7 +269,10 @@ TEST(GetService, NotAllowedFromIsolated) {
    EXPECT_CALL(*access, getCallingContext())
            // something adds it
            .WillOnce(Return(Access::CallingContext{}))
        // next call is from isolated app
            // next calls is from isolated app
            .WillOnce(Return(Access::CallingContext{
                    .uid = AID_ISOLATED_START,
            }))
            .WillOnce(Return(Access::CallingContext{
                    .uid = AID_ISOLATED_START,
            }));
@@ -264,8 +288,11 @@ TEST(GetService, NotAllowedFromIsolated) {

    Service out;
    // returns nullptr but has OK status for legacy compatibility
    EXPECT_TRUE(sm->getService("foo", &out).isOk());
    EXPECT_TRUE(sm->getService2("foo", &out).isOk());
    EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
    sp<IBinder> outBinder;
    EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
    EXPECT_EQ(nullptr, outBinder);
}

TEST(ListServices, NoPermissions) {
+11 −2
Original line number Diff line number Diff line
@@ -33,10 +33,19 @@ BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceM
sp<AidlServiceManager> BackendUnifiedServiceManager::getImpl() {
    return mTheRealServiceManager;
}

binder::Status BackendUnifiedServiceManager::getService(const ::std::string& name,
                                                        sp<IBinder>* _aidl_return) {
    os::Service service;
    binder::Status status = getService2(name, &service);
    *_aidl_return = service.get<os::Service::Tag::binder>();
    return status;
}

binder::Status BackendUnifiedServiceManager::getService2(const ::std::string& name,
                                                         os::Service* _out) {
    os::Service service;
    binder::Status status = mTheRealServiceManager->getService(name, &service);
    binder::Status status = mTheRealServiceManager->getService2(name, &service);
    toBinderService(service, _out);
    return status;
}
+2 −1
Original line number Diff line number Diff line
@@ -26,7 +26,8 @@ public:
    explicit BackendUnifiedServiceManager(const sp<os::IServiceManager>& impl);

    sp<os::IServiceManager> getImpl();
    binder::Status getService(const ::std::string& name, os::Service* out) override;
    binder::Status getService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
    binder::Status getService2(const ::std::string& name, os::Service* out) override;
    binder::Status checkService(const ::std::string& name, os::Service* out) override;
    binder::Status addService(const ::std::string& name, const sp<IBinder>& service,
                              bool allowIsolated, int32_t dumpPriority) override;
Loading