diff options
author | 2024-05-03 09:01:56 +0000 | |
---|---|---|
committer | 2024-07-19 16:49:07 +0000 | |
commit | 8578f13447d10824b9c29b0130f2096bb9401575 (patch) | |
tree | 5ed7ad2ec0f211c4a46e9be8b5d6250715caa4ae | |
parent | 454e2fef1f5756553128a2c573d34eac9a1815e7 (diff) |
Support IAccessor in libbinder for RPC services
This cl sets up preconnected RPC binder for services launched with
IAccessor as a proxy.
Bug: 338541373
Test: m
Test: atest vm_accessor_test
Change-Id: Ic54732980778bc9ba8fec3395a0e98d336fea440
-rw-r--r-- | cmds/servicemanager/ServiceManager.cpp | 97 | ||||
-rw-r--r-- | cmds/servicemanager/ServiceManager.h | 9 | ||||
-rw-r--r-- | cmds/servicemanager/test_sm.cpp | 29 | ||||
-rw-r--r-- | libs/binder/Android.bp | 30 | ||||
-rw-r--r-- | libs/binder/BackendUnifiedServiceManager.cpp | 56 | ||||
-rw-r--r-- | libs/binder/BackendUnifiedServiceManager.h | 5 | ||||
-rw-r--r-- | libs/binder/IServiceManager.cpp | 12 | ||||
-rw-r--r-- | libs/binder/RpcSession.cpp | 4 | ||||
-rw-r--r-- | libs/binder/aidl/android/os/IAccessor.aidl | 39 | ||||
-rw-r--r-- | libs/binder/aidl/android/os/IServiceManager.aidl | 5 | ||||
-rw-r--r-- | libs/binder/aidl/android/os/Service.aidl | 28 | ||||
-rw-r--r-- | libs/binder/include/binder/RpcSession.h | 6 | ||||
-rw-r--r-- | libs/binder/servicedispatcher.cpp | 6 |
13 files changed, 277 insertions, 49 deletions
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp index 1333599bf2..0f251d2b2a 100644 --- a/cmds/servicemanager/ServiceManager.cpp +++ b/cmds/servicemanager/ServiceManager.cpp @@ -249,6 +249,25 @@ static std::vector<std::string> getVintfUpdatableNames(const std::string& apexNa return names; } +static std::optional<std::string> getVintfAccessorName(const std::string& name) { + AidlName aname; + if (!AidlName::fill(name, &aname)) return std::nullopt; + + std::optional<std::string> accessor; + forEachManifest([&](const ManifestWithDescription& mwd) { + mwd.manifest->forEachInstance([&](const auto& manifestInstance) { + if (manifestInstance.format() != vintf::HalFormat::AIDL) return true; + if (manifestInstance.package() != aname.package) return true; + if (manifestInstance.interface() != aname.iface) return true; + if (manifestInstance.instance() != aname.instance) return true; + accessor = manifestInstance.accessor(); + return false; // break (libvintf uses opposite convention) + }); + return false; // continue + }); + return accessor; +} + static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) { AidlName aname; if (!AidlName::fill(name, &aname)) return std::nullopt; @@ -364,23 +383,40 @@ ServiceManager::~ServiceManager() { } } -Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) { +Status ServiceManager::getService(const std::string& name, os::Service* outService) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str())); - *outBinder = tryGetService(name, true); + *outService = tryGetService(name, true); // returns ok regardless of result for legacy reasons return Status::ok(); } -Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) { +Status ServiceManager::checkService(const std::string& name, os::Service* outService) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str())); - *outBinder = tryGetService(name, false); + *outService = tryGetService(name, false); // returns ok regardless of result for legacy reasons return Status::ok(); } -sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) { +os::Service ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) { + std::optional<std::string> accessorName; +#ifndef VENDORSERVICEMANAGER + accessorName = getVintfAccessorName(name); +#endif + if (accessorName.has_value()) { + auto ctx = mAccess->getCallingContext(); + if (!mAccess->canFind(ctx, name)) { + return os::Service::make<os::Service::Tag::accessor>(nullptr); + } + return os::Service::make<os::Service::Tag::accessor>( + tryGetBinder(*accessorName, startIfNotFound)); + } else { + return os::Service::make<os::Service::Tag::binder>(tryGetBinder(name, startIfNotFound)); + } +} + +sp<IBinder> ServiceManager::tryGetBinder(const std::string& name, bool startIfNotFound) { SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str())); auto ctx = mAccess->getCallingContext(); @@ -565,8 +601,11 @@ Status ServiceManager::registerForNotifications( auto ctx = mAccess->getCallingContext(); - if (!mAccess->canFind(ctx, name)) { - return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux"); + // TODO(b/338541373): Implement the notification mechanism for services accessed via + // IAccessor. + std::optional<std::string> accessorName; + if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) { + return status; } // note - we could allow isolated apps to get notifications if we @@ -613,8 +652,9 @@ Status ServiceManager::unregisterForNotifications( auto ctx = mAccess->getCallingContext(); - if (!mAccess->canFind(ctx, name)) { - return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); + std::optional<std::string> accessorName; + if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) { + return status; } bool found = false; @@ -638,8 +678,9 @@ Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) { auto ctx = mAccess->getCallingContext(); - if (!mAccess->canFind(ctx, name)) { - return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); + std::optional<std::string> accessorName; + if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) { + return status; } *outReturn = false; @@ -662,8 +703,10 @@ binder::Status ServiceManager::getDeclaredInstances(const std::string& interface outReturn->clear(); + std::optional<std::string> _accessorName; for (const std::string& instance : allInstances) { - if (mAccess->canFind(ctx, interface + "/" + instance)) { + if (auto status = canFindService(ctx, interface + "/" + instance, &_accessorName); + status.isOk()) { outReturn->push_back(instance); } } @@ -681,8 +724,9 @@ Status ServiceManager::updatableViaApex(const std::string& name, auto ctx = mAccess->getCallingContext(); - if (!mAccess->canFind(ctx, name)) { - return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); + std::optional<std::string> _accessorName; + if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) { + return status; } *outReturn = std::nullopt; @@ -706,8 +750,9 @@ Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& ape outReturn->clear(); + std::optional<std::string> _accessorName; for (const std::string& name : apexUpdatableNames) { - if (mAccess->canFind(ctx, name)) { + if (auto status = canFindService(ctx, name, &_accessorName); status.isOk()) { outReturn->push_back(name); } } @@ -724,8 +769,9 @@ Status ServiceManager::getConnectionInfo(const std::string& name, auto ctx = mAccess->getCallingContext(); - if (!mAccess->canFind(ctx, name)) { - return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied."); + std::optional<std::string> _accessorName; + if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) { + return status; } *outReturn = std::nullopt; @@ -1032,6 +1078,23 @@ Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IB return Status::ok(); } +Status ServiceManager::canFindService(const Access::CallingContext& ctx, const std::string& name, + std::optional<std::string>* accessor) { + if (!mAccess->canFind(ctx, name)) { + return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied for service."); + } +#ifndef VENDORSERVICEMANAGER + *accessor = getVintfAccessorName(name); +#endif + if (accessor->has_value()) { + if (!mAccess->canFind(ctx, accessor->value())) { + return Status::fromExceptionCode(Status::EX_SECURITY, + "SELinux denied for the accessor of the service."); + } + } + return Status::ok(); +} + Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) { SM_PERFETTO_TRACE_FUNC(); if (!mAccess->canList(mAccess->getCallingContext())) { diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h index 1536014f0a..18bae68332 100644 --- a/cmds/servicemanager/ServiceManager.h +++ b/cmds/servicemanager/ServiceManager.h @@ -44,8 +44,8 @@ public: ~ServiceManager(); // getService will try to start any services it cannot find - binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override; - binder::Status checkService(const std::string& name, sp<IBinder>* outBinder) override; + binder::Status getService(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; binder::Status listServices(int32_t dumpPriority, std::vector<std::string>* outList) override; @@ -112,7 +112,10 @@ private: // this updates the iterator to the next location void removeClientCallback(const wp<IBinder>& who, ClientCallbackMap::iterator* it); - sp<IBinder> tryGetService(const std::string& name, bool startIfNotFound); + os::Service tryGetService(const std::string& name, bool startIfNotFound); + sp<IBinder> tryGetBinder(const std::string& name, bool startIfNotFound); + binder::Status canFindService(const Access::CallingContext& ctx, const std::string& name, + std::optional<std::string>* accessor); ServiceMap mNameToService; ServiceCallbackMap mNameToRegistrationCallback; diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp index b57505302c..9d22641ac5 100644 --- a/cmds/servicemanager/test_sm.cpp +++ b/cmds/servicemanager/test_sm.cpp @@ -38,6 +38,7 @@ using android::base::StartsWith; using android::binder::Status; using android::os::BnServiceCallback; using android::os::IServiceManager; +using android::os::Service; using testing::_; using testing::ElementsAre; using testing::NiceMock; @@ -153,18 +154,18 @@ TEST(AddService, OverwriteExistingService) { EXPECT_TRUE(sm->addService("foo", serviceA, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); - sp<IBinder> outA; + Service outA; EXPECT_TRUE(sm->getService("foo", &outA).isOk()); - EXPECT_EQ(serviceA, outA); + EXPECT_EQ(serviceA, outA.get<Service::Tag::binder>()); // serviceA should be overwritten by serviceB sp<IBinder> serviceB = getBinder(); EXPECT_TRUE(sm->addService("foo", serviceB, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); - sp<IBinder> outB; + Service outB; EXPECT_TRUE(sm->getService("foo", &outB).isOk()); - EXPECT_EQ(serviceB, outB); + EXPECT_EQ(serviceB, outB.get<Service::Tag::binder>()); } TEST(AddService, NoPermissions) { @@ -186,17 +187,17 @@ TEST(GetService, HappyHappy) { EXPECT_TRUE(sm->addService("foo", service, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); - sp<IBinder> out; + Service out; EXPECT_TRUE(sm->getService("foo", &out).isOk()); - EXPECT_EQ(service, out); + EXPECT_EQ(service, out.get<Service::Tag::binder>()); } TEST(GetService, NonExistant) { auto sm = getPermissiveServiceManager(); - sp<IBinder> out; + Service out; EXPECT_TRUE(sm->getService("foo", &out).isOk()); - EXPECT_EQ(nullptr, out.get()); + EXPECT_EQ(nullptr, out.get<Service::Tag::binder>()); } TEST(GetService, NoPermissionsForGettingService) { @@ -211,10 +212,10 @@ TEST(GetService, NoPermissionsForGettingService) { EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); - sp<IBinder> out; + Service out; // returns nullptr but has OK status for legacy compatibility EXPECT_TRUE(sm->getService("foo", &out).isOk()); - EXPECT_EQ(nullptr, out.get()); + EXPECT_EQ(nullptr, out.get<Service::Tag::binder>()); } TEST(GetService, AllowedFromIsolated) { @@ -236,9 +237,9 @@ TEST(GetService, AllowedFromIsolated) { EXPECT_TRUE(sm->addService("foo", service, true /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); - sp<IBinder> out; + Service out; EXPECT_TRUE(sm->getService("foo", &out).isOk()); - EXPECT_EQ(service, out.get()); + EXPECT_EQ(service, out.get<Service::Tag::binder>()); } TEST(GetService, NotAllowedFromIsolated) { @@ -261,10 +262,10 @@ TEST(GetService, NotAllowedFromIsolated) { EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); - sp<IBinder> out; + Service out; // returns nullptr but has OK status for legacy compatibility EXPECT_TRUE(sm->getService("foo", &out).isOk()); - EXPECT_EQ(nullptr, out.get()); + EXPECT_EQ(nullptr, out.get<Service::Tag::binder>()); } TEST(ListServices, NoPermissions) { diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index cdc7166f65..02c0fa6e31 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -771,11 +771,41 @@ filegroup { "aidl/android/os/IClientCallback.aidl", "aidl/android/os/IServiceCallback.aidl", "aidl/android/os/IServiceManager.aidl", + "aidl/android/os/Service.aidl", "aidl/android/os/ServiceDebugInfo.aidl", + ":libbinder_accessor_aidl", ], path: "aidl", } +filegroup { + name: "libbinder_accessor_aidl", + srcs: [ + "aidl/android/os/IAccessor.aidl", + ], + path: "aidl", +} + +// TODO(b/353492849): Make this interface private to libbinder. +aidl_interface { + name: "android.os.accessor", + srcs: [":libbinder_accessor_aidl"], + unstable: true, + backend: { + rust: { + enabled: true, + apex_available: [ + "com.android.virt", + ], + }, + }, + visibility: [ + ":__subpackages__", + "//system/tools/aidl:__subpackages__", + "//packages/modules/Virtualization:__subpackages__", + ], +} + aidl_interface { name: "packagemanager_aidl", unstable: true, diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp index b0d3048c37..0bf3cadd35 100644 --- a/libs/binder/BackendUnifiedServiceManager.cpp +++ b/libs/binder/BackendUnifiedServiceManager.cpp @@ -15,6 +15,9 @@ */ #include "BackendUnifiedServiceManager.h" +#include <android/os/IAccessor.h> +#include <binder/RpcSession.h> + #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) #include <android-base/properties.h> #endif @@ -22,6 +25,7 @@ namespace android { using AidlServiceManager = android::os::IServiceManager; +using IAccessor = android::os::IAccessor; BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl) : mTheRealServiceManager(impl) {} @@ -30,13 +34,57 @@ sp<AidlServiceManager> BackendUnifiedServiceManager::getImpl() { return mTheRealServiceManager; } binder::Status BackendUnifiedServiceManager::getService(const ::std::string& name, - sp<IBinder>* _aidl_return) { - return mTheRealServiceManager->getService(name, _aidl_return); + os::Service* _out) { + os::Service service; + binder::Status status = mTheRealServiceManager->getService(name, &service); + toBinderService(service, _out); + return status; } + binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& name, - sp<IBinder>* _aidl_return) { - return mTheRealServiceManager->checkService(name, _aidl_return); + os::Service* _out) { + os::Service service; + binder::Status status = mTheRealServiceManager->checkService(name, &service); + toBinderService(service, _out); + return status; } + +void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Service* _out) { + switch (in.getTag()) { + case os::Service::Tag::binder: { + *_out = in; + break; + } + case os::Service::Tag::accessor: { + sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>(); + sp<IAccessor> accessor = interface_cast<IAccessor>(accessorBinder); + if (accessor == nullptr) { + ALOGE("Service#accessor doesn't have accessor. VM is maybe starting..."); + *_out = os::Service::make<os::Service::Tag::binder>(nullptr); + break; + } + auto request = [=] { + os::ParcelFileDescriptor fd; + binder::Status ret = accessor->addConnection(&fd); + if (ret.isOk()) { + return base::unique_fd(fd.release()); + } else { + ALOGE("Failed to connect to RpcSession: %s", ret.toString8().c_str()); + return base::unique_fd(-1); + } + }; + auto session = RpcSession::make(); + session->setupPreconnectedClient(base::unique_fd{}, request); + session->setSessionSpecificRoot(accessorBinder); + *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject()); + break; + } + default: { + LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag()); + } + } +} + binder::Status BackendUnifiedServiceManager::addService(const ::std::string& name, const sp<IBinder>& service, bool allowIsolated, int32_t dumpPriority) { diff --git a/libs/binder/BackendUnifiedServiceManager.h b/libs/binder/BackendUnifiedServiceManager.h index d72b5bb94f..4715be4580 100644 --- a/libs/binder/BackendUnifiedServiceManager.h +++ b/libs/binder/BackendUnifiedServiceManager.h @@ -26,8 +26,8 @@ public: explicit BackendUnifiedServiceManager(const sp<os::IServiceManager>& impl); sp<os::IServiceManager> getImpl(); - binder::Status getService(const ::std::string& name, sp<IBinder>* _aidl_return) override; - binder::Status checkService(const ::std::string& name, sp<IBinder>* _aidl_return) override; + binder::Status getService(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; binder::Status listServices(int32_t dumpPriority, @@ -60,6 +60,7 @@ public: private: sp<os::IServiceManager> mTheRealServiceManager; + void toBinderService(const os::Service& in, os::Service* _out); }; sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager(); diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 17e522d921..12a18f2a69 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -26,6 +26,7 @@ #include <android-base/properties.h> #include <android/os/BnServiceCallback.h> +#include <android/os/IAccessor.h> #include <android/os/IServiceManager.h> #include <binder/IPCThreadState.h> #include <binder/Parcel.h> @@ -57,6 +58,8 @@ using AidlRegistrationCallback = IServiceManager::LocalRegistrationCallback; using AidlServiceManager = android::os::IServiceManager; using android::binder::Status; +using android::os::IAccessor; +using android::os::Service; // libbinder's IServiceManager.h can't rely on the values generated by AIDL // because many places use its headers via include_dirs (meaning, without @@ -139,7 +142,10 @@ protected: // When implementing ServiceManagerShim, use realGetService instead of // mUnifiedServiceManager->getService so that it can be overridden in ServiceManagerHostShim. virtual Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) { - return mUnifiedServiceManager->getService(name, _aidl_return); + Service service; + Status status = mUnifiedServiceManager->getService(name, &service); + *_aidl_return = service.get<Service::Tag::binder>(); + return status; } }; @@ -327,11 +333,11 @@ sp<IBinder> ServiceManagerShim::getService(const String16& name) const sp<IBinder> ServiceManagerShim::checkService(const String16& name) const { - sp<IBinder> ret; + Service ret; if (!mUnifiedServiceManager->checkService(String8(name).c_str(), &ret).isOk()) { return nullptr; } - return ret; + return ret.get<Service::Tag::binder>(); } status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service, diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp index 16a7f9fd48..21dc5c1db1 100644 --- a/libs/binder/RpcSession.cpp +++ b/libs/binder/RpcSession.cpp @@ -801,6 +801,10 @@ bool RpcSession::setForServer(const wp<RpcServer>& server, const wp<EventListene return true; } +void RpcSession::setSessionSpecificRoot(const sp<IBinder>& sessionSpecificRoot) { + mSessionSpecificRootObject = sessionSpecificRoot; +} + sp<RpcSession::RpcConnection> RpcSession::assignIncomingConnectionToThisThread( std::unique_ptr<RpcTransport> rpcTransport) { RpcMutexLockGuard _l(mMutex); diff --git a/libs/binder/aidl/android/os/IAccessor.aidl b/libs/binder/aidl/android/os/IAccessor.aidl new file mode 100644 index 0000000000..a3134a3f7c --- /dev/null +++ b/libs/binder/aidl/android/os/IAccessor.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.os.ParcelFileDescriptor; + +/** + * Interface for accessing the RPC server of a service. + * + * @hide + */ +interface IAccessor { + /** + * Adds a connection to the RPC server of the service managed by the IAccessor. + * + * This method can be called multiple times to establish multiple distinct + * connections to the same RPC server. + * + * @return A file descriptor connected to the RPC session of the service managed + * by IAccessor. + */ + ParcelFileDescriptor addConnection(); + + // TODO(b/350941051): Add API for debugging. +} diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl index 0fb1615391..ac95188470 100644 --- a/libs/binder/aidl/android/os/IServiceManager.aidl +++ b/libs/binder/aidl/android/os/IServiceManager.aidl @@ -18,6 +18,7 @@ package android.os; import android.os.IClientCallback; import android.os.IServiceCallback; +import android.os.Service; import android.os.ServiceDebugInfo; import android.os.ConnectionInfo; @@ -61,7 +62,7 @@ interface IServiceManager { * Returns null if the service does not exist. */ @UnsupportedAppUsage - @nullable IBinder getService(@utf8InCpp String name); + Service getService(@utf8InCpp String name); /** * Retrieve an existing service called @a name from the service @@ -69,7 +70,7 @@ interface IServiceManager { * exist. */ @UnsupportedAppUsage - @nullable IBinder checkService(@utf8InCpp String name); + Service checkService(@utf8InCpp String name); /** * Place a new @a service called @a name into the service diff --git a/libs/binder/aidl/android/os/Service.aidl b/libs/binder/aidl/android/os/Service.aidl new file mode 100644 index 0000000000..4c5210911c --- /dev/null +++ b/libs/binder/aidl/android/os/Service.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +/** + * Service is a union of different service types that can be returned + * by the internal {@link ServiceManager#getService(name)} API. + * + * @hide + */ +union Service { + @nullable IBinder binder; + @nullable IBinder accessor; +}
\ No newline at end of file diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h index 40102bb9f0..af37bf29a4 100644 --- a/libs/binder/include/binder/RpcSession.h +++ b/libs/binder/include/binder/RpcSession.h @@ -220,6 +220,12 @@ public: // internal only LIBBINDER_EXPORTED const std::unique_ptr<RpcState>& state() { return mRpcBinderState; } + /** + * Sets the session-specific root object. This is the object that will be used to attach + * the IAccessor binder to the RpcSession when a binder is set up via accessor. + */ + LIBBINDER_EXPORTED void setSessionSpecificRoot(const sp<IBinder>& sessionSpecificRoot); + private: friend sp<RpcSession>; friend RpcServer; diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp index 18b178b9b1..201dfbc400 100644 --- a/libs/binder/servicedispatcher.cpp +++ b/libs/binder/servicedispatcher.cpp @@ -118,13 +118,11 @@ int Dispatch(const char* name, const ServiceRetriever& serviceRetriever, class ServiceManagerProxyToNative : public android::os::BnServiceManager { public: ServiceManagerProxyToNative(const sp<android::os::IServiceManager>& impl) : mImpl(impl) {} - android::binder::Status getService(const std::string&, - android::sp<android::IBinder>*) override { + android::binder::Status getService(const std::string&, android::os::Service*) override { // We can't send BpBinder for regular binder over RPC. return android::binder::Status::fromStatusT(android::INVALID_OPERATION); } - android::binder::Status checkService(const std::string&, - android::sp<android::IBinder>*) override { + android::binder::Status checkService(const std::string&, android::os::Service*) override { // We can't send BpBinder for regular binder over RPC. return android::binder::Status::fromStatusT(android::INVALID_OPERATION); } |