diff options
-rw-r--r-- | libs/binder/IServiceManager.cpp | 18 | ||||
-rw-r--r-- | libs/binder/ServiceManagerHost.cpp | 7 | ||||
-rw-r--r-- | libs/binder/ServiceManagerHost.h | 5 | ||||
-rw-r--r-- | libs/binder/include/binder/IServiceManager.h | 11 | ||||
-rw-r--r-- | libs/binder/tests/binderHostDeviceTest.cpp | 4 |
5 files changed, 35 insertions, 10 deletions
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index aff9e0d48d..81e61daae1 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -448,21 +448,27 @@ std::optional<IServiceManager::ConnectionInfo> ServiceManagerShim::getConnection // on-device service manager. class ServiceManagerHostShim : public ServiceManagerShim { public: - using ServiceManagerShim::ServiceManagerShim; + ServiceManagerHostShim(const sp<AidlServiceManager>& impl, + const RpcDelegateServiceManagerOptions& options) + : ServiceManagerShim(impl), mOptions(options) {} // ServiceManagerShim::getService is based on checkService, so no need to override it. sp<IBinder> checkService(const String16& name) const override { - return getDeviceService({String8(name).c_str()}); + return getDeviceService({String8(name).c_str()}, mOptions); } protected: // Override realGetService for ServiceManagerShim::waitForService. Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) { - *_aidl_return = getDeviceService({"-g", name}); + *_aidl_return = getDeviceService({"-g", name}, mOptions); return Status::ok(); } + +private: + RpcDelegateServiceManagerOptions mOptions; }; -sp<IServiceManager> createRpcDelegateServiceManager() { - auto binder = getDeviceService({"manager"}); +sp<IServiceManager> createRpcDelegateServiceManager( + const RpcDelegateServiceManagerOptions& options) { + auto binder = getDeviceService({"manager"}, options); if (binder == nullptr) { ALOGE("getDeviceService(\"manager\") returns null"); return nullptr; @@ -472,7 +478,7 @@ sp<IServiceManager> createRpcDelegateServiceManager() { ALOGE("getDeviceService(\"manager\") returns non service manager"); return nullptr; } - return sp<ServiceManagerHostShim>::make(interface); + return sp<ServiceManagerHostShim>::make(interface, options); } #endif diff --git a/libs/binder/ServiceManagerHost.cpp b/libs/binder/ServiceManagerHost.cpp index 27cc563adc..194254ac69 100644 --- a/libs/binder/ServiceManagerHost.cpp +++ b/libs/binder/ServiceManagerHost.cpp @@ -124,7 +124,8 @@ void cleanupCommandResult(const void* id, void* obj, void* /* cookie */) { } // namespace -sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs) { +sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs, + const RpcDelegateServiceManagerOptions& options) { std::vector<std::string> prefix{"adb", "shell", "servicedispatcher"}; serviceDispatcherArgs.insert(serviceDispatcherArgs.begin(), prefix.begin(), prefix.end()); @@ -158,6 +159,10 @@ sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs) { LOG_ALWAYS_FATAL_IF(!forwardResult->hostPort().has_value()); auto rpcSession = RpcSession::make(); + if (options.maxOutgoingThreads.has_value()) { + rpcSession->setMaxOutgoingThreads(*options.maxOutgoingThreads); + } + if (status_t status = rpcSession->setupInetClient("127.0.0.1", *forwardResult->hostPort()); status != OK) { ALOGE("Unable to set up inet client on host port %u: %s", *forwardResult->hostPort(), diff --git a/libs/binder/ServiceManagerHost.h b/libs/binder/ServiceManagerHost.h index e59724c391..c5310dac20 100644 --- a/libs/binder/ServiceManagerHost.h +++ b/libs/binder/ServiceManagerHost.h @@ -21,11 +21,14 @@ namespace android { +struct RpcDelegateServiceManagerOptions; + // Get a service on device by running servicedispatcher with the given args, e.g. // getDeviceService({"foo"}); // Return nullptr on any error. // When the returned binder object is destroyed, remove adb forwarding and kills // the long-running servicedispatcher process. -sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs); +sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs, + const RpcDelegateServiceManagerOptions& options); } // namespace android diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h index a48075dad1..240e3c2b26 100644 --- a/libs/binder/include/binder/IServiceManager.h +++ b/libs/binder/include/binder/IServiceManager.h @@ -188,7 +188,16 @@ bool checkPermission(const String16& permission, pid_t pid, uid_t uid, // // ... // } // Resources are cleaned up when the object is destroyed. -sp<IServiceManager> createRpcDelegateServiceManager(); +// +// For each returned binder object, at most |maxOutgoingThreads| outgoing threads are instantiated. +// Hence, only |maxOutgoingThreads| calls can be made simultaneously. Additional calls are blocked +// if there are |maxOutgoingThreads| ongoing calls. See RpcSession::setMaxOutgoingThreads. +// If |maxOutgoingThreads| is not set, default is |RpcSession::kDefaultMaxOutgoingThreads|. +struct RpcDelegateServiceManagerOptions { + std::optional<size_t> maxOutgoingThreads; +}; +sp<IServiceManager> createRpcDelegateServiceManager( + const RpcDelegateServiceManagerOptions& options); #endif } // namespace android diff --git a/libs/binder/tests/binderHostDeviceTest.cpp b/libs/binder/tests/binderHostDeviceTest.cpp index eec3b447de..464da60dde 100644 --- a/libs/binder/tests/binderHostDeviceTest.cpp +++ b/libs/binder/tests/binderHostDeviceTest.cpp @@ -65,7 +65,9 @@ MATCHER_P(StatusEq, expected, (negation ? "not " : "") + statusToString(expected void initHostRpcServiceManagerOnce() { static std::once_flag gSmOnce; - std::call_once(gSmOnce, [] { setDefaultServiceManager(createRpcDelegateServiceManager()); }); + std::call_once(gSmOnce, [] { + setDefaultServiceManager(createRpcDelegateServiceManager({.maxOutgoingThreads = 1})); + }); } // Test for host service manager. |