Loading cmds/servicemanager/rpc_servicemanager/Android.bp 0 → 100644 +26 −0 Original line number Diff line number Diff line package { // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "frameworks_native_license" // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], } rust_library { name: "librpc_servicemanager", crate_name: "rpc_servicemanager", srcs: ["rpc_servicemanager.rs"], rustlibs: [ "android.system.virtualmachineservice-rust", "libanyhow", "libbinder_rs", "liblibc", "liblog_rust", "librpcbinder_rs", "librustutils", "libvsock", "rpc_servicemanager_aidl-rust", "servicemanager_aidl-rust", ], } cmds/servicemanager/rpc_servicemanager/rpc_servicemanager.rs 0 → 100644 +195 −0 Original line number Diff line number Diff line // Copyright 2025, 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. //! Implementation of the AIDL interface `IServiceManager`. use anyhow::Result; use binder::{Accessor, BinderFeatures, Interface, Strong}; use libc::{sa_family_t, sockaddr_vm, AF_VSOCK}; use log::{error, info}; use rpc_servicemanager_aidl::aidl::android::os::IRpcProvider::{ IRpcProvider, ServiceConnectionInfo::ServiceConnectionInfo, }; use rpcbinder::{FileDescriptorTransportMode, RpcServer}; use rustutils::sockets::{android_get_control_socket, SocketError}; use servicemanager_aidl::aidl::android::os::IServiceManager::{ BnServiceManager, CallerContext::CallerContext, IServiceManager, }; use servicemanager_aidl::aidl::android::os::{ ConnectionInfo::ConnectionInfo, IClientCallback::IClientCallback, IServiceCallback::IServiceCallback, Service::Service, ServiceDebugInfo::ServiceDebugInfo, }; use std::os::unix::io::OwnedFd; use vsock::VMADDR_CID_HOST; // Name of the socket that libbinder is expecting IServiceManager to be served from const RPC_SERVICEMANAGER_UDS_NAME: &str = "rpc_servicemanager"; /// Implementation of `IServiceManager`. pub struct RpcServiceManager { provider_service: Strong<dyn IRpcProvider>, } impl IServiceManager for RpcServiceManager { fn getService(&self, _name: &str) -> binder::Result<Option<binder::SpIBinder>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getService2(&self, name: &str) -> binder::Result<Service> { let provider_service = self.provider_service.clone(); let get_connection_info = move |inst: &str| { let connection_info = provider_service.getServiceConnectionInfo(inst).unwrap(); match connection_info { ServiceConnectionInfo::Vsock(info) => { let addr = sockaddr_vm { svm_family: AF_VSOCK as sa_family_t, svm_reserved1: 0, svm_port: info.port as u32, svm_cid: VMADDR_CID_HOST, svm_zero: [0u8; 4], }; Some(binder::ConnectionInfo::Vsock(addr)) } #[allow(unreachable_patterns)] _ => { error!("Unexpected ServiceConnectionInfo type!"); None } } }; let accessor = Accessor::new(name, get_connection_info); Ok(Service::Accessor(accessor.as_binder())) } fn checkService(&self, _name: &str) -> binder::Result<Option<binder::SpIBinder>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn checkService2(&self, _name: &str) -> binder::Result<Service> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn addService( &self, _name: &str, _service: &binder::SpIBinder, _allow_isolated: bool, _dump_priority: i32, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn listServices(&self, _dump_priority: i32) -> binder::Result<Vec<String>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn registerForNotifications( &self, _name: &str, _callback: &binder::Strong<dyn IServiceCallback>, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn unregisterForNotifications( &self, _name: &str, _callback: &binder::Strong<dyn IServiceCallback>, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn isDeclared(&self, _name: &str) -> binder::Result<bool> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getDeclaredInstances(&self, _iface: &str) -> binder::Result<Vec<String>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn updatableViaApex(&self, _name: &str) -> binder::Result<Option<String>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getUpdatableNames(&self, _apex_name: &str) -> binder::Result<Vec<String>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getConnectionInfo(&self, _name: &str) -> binder::Result<Option<ConnectionInfo>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn registerClientCallback( &self, _name: &str, _service: &binder::SpIBinder, _callback: &binder::Strong<dyn IClientCallback>, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn tryUnregisterService( &self, _name: &str, _service: &binder::SpIBinder, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getServiceDebugInfo(&self) -> binder::Result<Vec<ServiceDebugInfo>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn checkServiceAccess(&self, _: &CallerContext, _: &str, _: &str) -> binder::Result<bool> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } } impl Interface for RpcServiceManager {} impl RpcServiceManager { /// Creates a new `RpcServiceManager` instance from the `IServiceManager` reference. fn new(provider_service: Strong<dyn IRpcProvider>) -> RpcServiceManager { Self { provider_service } } } /// Get the Unix Domain Socket file descriptor for RPC_SERVICEMANAGER_UDS_NAME /// /// A client might need to do this in order to get an FD with the FD_CLOEXEC flag set before /// it forks any other processes. pub fn get_default_rpc_servicemanager_uds_fd() -> Result<OwnedFd, SocketError> { android_get_control_socket(RPC_SERVICEMANAGER_UDS_NAME) } /// Registers the `IServiceManager` service. /// /// servicemanager_fd is an optional argument to provide the Unix Domain Socked file /// descriptor to use for the server. If None is provided, then it will use the default /// of RPC_SERVICEMANAGER_UDS_NAME to get the FD. pub fn register_rpc_servicemanager( provider_service: Strong<dyn IRpcProvider>, servicemanager_fd: Option<OwnedFd>, ) -> Result<()> { let rpc_servicemanager_binder = BnServiceManager::new_binder( RpcServiceManager::new(provider_service), BinderFeatures::default(), ); let servicemanager_fd = match servicemanager_fd { Some(fd) => fd, None => android_get_control_socket(RPC_SERVICEMANAGER_UDS_NAME)?, }; let server = RpcServer::new_bound_socket(rpc_servicemanager_binder.as_binder(), servicemanager_fd)?; // Required for the FD being passed through libbinder's accessor binder server.set_supported_file_descriptor_transport_modes(&[FileDescriptorTransportMode::Unix]); info!("The RPC server '{}' is running.", RPC_SERVICEMANAGER_UDS_NAME); if let Err(e) = rustutils::system_properties::write("servicemanager.ready", "true") { error!("failed to set ro.servicemanager.ready {:?}", e); } // Move server reference into a background thread and run it forever. std::thread::spawn(move || { server.join(); }); Ok(()) } libs/binder/Android.bp +45 −2 Original line number Diff line number Diff line Loading @@ -857,7 +857,7 @@ cc_library_static { ], } // AIDL interface between libbinder and framework.jar // ServiceManager AIDL interface between libbinder and framework.jar filegroup { name: "libbinder_aidl", srcs: [ Loading @@ -881,6 +881,15 @@ filegroup { visibility: [":__subpackages__"], } filegroup { name: "libbinder_rpc_aidl", srcs: [ "aidl/android/os/IRpcProvider.aidl", ], path: "aidl", visibility: [":__subpackages__"], } aidl_interface { name: "packagemanager_aidl", unstable: true, Loading @@ -904,12 +913,44 @@ aidl_interface { } aidl_interface { name: "libbinder_aidl_test_stub", name: "servicemanager_aidl", unstable: true, local_include_dir: "aidl", srcs: [":libbinder_aidl"], vendor_available: true, backend: { cpp: { // libbinder exports this type itself so use that enabled: false, }, rust: { enabled: true, }, java: { enabled: false, }, }, visibility: [ ":__subpackages__", "//system/tools/aidl:__subpackages__", "//frameworks/native/cmds/servicemanager/rpc_servicemanager", ], } aidl_interface { name: "rpc_servicemanager_aidl", unstable: true, local_include_dir: "aidl", srcs: [":libbinder_rpc_aidl"], vendor_available: true, backend: { rust: { enabled: true, apex_available: [ "com.android.virt", "com.android.compos", ], }, java: { enabled: false, }, Loading @@ -917,6 +958,8 @@ aidl_interface { visibility: [ ":__subpackages__", "//system/tools/aidl:__subpackages__", "//frameworks/native/cmds/servicemanager/rpc_servicemanager", "//packages/modules/Virtualization:__subpackages__", ], } Loading libs/binder/BackendUnifiedServiceManager.cpp +41 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ #include <android/os/IAccessor.h> #include <android/os/IServiceManager.h> #include <binder/RpcSession.h> #include <cutils/sockets.h> #include <sys/socket.h> #include <sys/un.h> #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) #include <android-base/properties.h> Loading @@ -26,6 +29,10 @@ namespace android { // This is similar to the kernel binder servicemanager's context 0. It's the // known socket that we expect the Unix Domain Socket servicemanager to be listening on. const char kUdsServiceManagerName[] = ANDROID_SOCKET_DIR "/rpc_servicemanager"; #ifdef LIBBINDER_CLIENT_CACHE constexpr bool kUseCache = true; #else Loading Loading @@ -488,15 +495,29 @@ Status BackendUnifiedServiceManager::checkServiceAccess( [[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager; static bool hasOutOfProcessServiceManager() { #ifndef BINDER_WITH_KERNEL_IPC // We don't currently support kernel binder service management or UDS // service management on host or when libbinder is compiled without any // kernel binder suport. Please use setDefaultServiceManager for host // processes that want to use service manager APIs. #if !defined(BINDER_WITH_KERNEL_IPC) || !defined(__BIONIC__) return false; #else #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) return android::base::GetBoolProperty("servicemanager.installed", true); #else #ifdef __ANDROID_VNDK__ return true; #else return android::base::GetBoolProperty("servicemanager.installed", true); #endif #endif #endif // BINDER_WITH_KERNEL_IPC } static sp<AidlServiceManager> getUdsServiceManager() { auto session = RpcSession::make(); session->setFileDescriptorTransportMode(RpcSession::FileDescriptorTransportMode::UNIX); auto status = session->setupUnixDomainClient(kUdsServiceManagerName); if (status == OK) { return interface_cast<AidlServiceManager>(session->getRootObject()); } return nullptr; } sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() { Loading @@ -514,11 +535,22 @@ sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() { sp<AidlServiceManager> sm = nullptr; while (hasOutOfProcessServiceManager() && sm == nullptr) { sm = interface_cast<AidlServiceManager>( ProcessState::self()->getContextObject(nullptr)); // There is either a kernel binder service manager, or an RPC binder // service manager sp<ProcessState> ps = ProcessState::selfIfKernelBinderEnabled(); if (ps) { // Service management over kernel binder sm = interface_cast<AidlServiceManager>(ps->getContextObject(nullptr)); } else { // Check for service management over Unix Domain Sockets sm = getUdsServiceManager(); } if (sm == nullptr) { ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str()); std::string contextObjectName = ps ? ps->getDriverName() + ", " + kUdsServiceManagerName : kUdsServiceManagerName; ALOGE("Waiting 1s on context object(s) on %s.", contextObjectName.c_str()); sleep(1); } } Loading libs/binder/ProcessState.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,11 @@ sp<ProcessState> ProcessState::selfOrNull() return init(nullptr, false /*requireDefault*/); } sp<ProcessState> ProcessState::selfIfKernelBinderEnabled() { if (access(kDefaultDriver, R_OK) == -1) return nullptr; return init(kDefaultDriver, false /*requireDefault*/); } [[clang::no_destroy]] static sp<ProcessState> gProcess; [[clang::no_destroy]] static std::mutex gProcessMutex; Loading Loading
cmds/servicemanager/rpc_servicemanager/Android.bp 0 → 100644 +26 −0 Original line number Diff line number Diff line package { // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "frameworks_native_license" // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], } rust_library { name: "librpc_servicemanager", crate_name: "rpc_servicemanager", srcs: ["rpc_servicemanager.rs"], rustlibs: [ "android.system.virtualmachineservice-rust", "libanyhow", "libbinder_rs", "liblibc", "liblog_rust", "librpcbinder_rs", "librustutils", "libvsock", "rpc_servicemanager_aidl-rust", "servicemanager_aidl-rust", ], }
cmds/servicemanager/rpc_servicemanager/rpc_servicemanager.rs 0 → 100644 +195 −0 Original line number Diff line number Diff line // Copyright 2025, 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. //! Implementation of the AIDL interface `IServiceManager`. use anyhow::Result; use binder::{Accessor, BinderFeatures, Interface, Strong}; use libc::{sa_family_t, sockaddr_vm, AF_VSOCK}; use log::{error, info}; use rpc_servicemanager_aidl::aidl::android::os::IRpcProvider::{ IRpcProvider, ServiceConnectionInfo::ServiceConnectionInfo, }; use rpcbinder::{FileDescriptorTransportMode, RpcServer}; use rustutils::sockets::{android_get_control_socket, SocketError}; use servicemanager_aidl::aidl::android::os::IServiceManager::{ BnServiceManager, CallerContext::CallerContext, IServiceManager, }; use servicemanager_aidl::aidl::android::os::{ ConnectionInfo::ConnectionInfo, IClientCallback::IClientCallback, IServiceCallback::IServiceCallback, Service::Service, ServiceDebugInfo::ServiceDebugInfo, }; use std::os::unix::io::OwnedFd; use vsock::VMADDR_CID_HOST; // Name of the socket that libbinder is expecting IServiceManager to be served from const RPC_SERVICEMANAGER_UDS_NAME: &str = "rpc_servicemanager"; /// Implementation of `IServiceManager`. pub struct RpcServiceManager { provider_service: Strong<dyn IRpcProvider>, } impl IServiceManager for RpcServiceManager { fn getService(&self, _name: &str) -> binder::Result<Option<binder::SpIBinder>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getService2(&self, name: &str) -> binder::Result<Service> { let provider_service = self.provider_service.clone(); let get_connection_info = move |inst: &str| { let connection_info = provider_service.getServiceConnectionInfo(inst).unwrap(); match connection_info { ServiceConnectionInfo::Vsock(info) => { let addr = sockaddr_vm { svm_family: AF_VSOCK as sa_family_t, svm_reserved1: 0, svm_port: info.port as u32, svm_cid: VMADDR_CID_HOST, svm_zero: [0u8; 4], }; Some(binder::ConnectionInfo::Vsock(addr)) } #[allow(unreachable_patterns)] _ => { error!("Unexpected ServiceConnectionInfo type!"); None } } }; let accessor = Accessor::new(name, get_connection_info); Ok(Service::Accessor(accessor.as_binder())) } fn checkService(&self, _name: &str) -> binder::Result<Option<binder::SpIBinder>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn checkService2(&self, _name: &str) -> binder::Result<Service> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn addService( &self, _name: &str, _service: &binder::SpIBinder, _allow_isolated: bool, _dump_priority: i32, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn listServices(&self, _dump_priority: i32) -> binder::Result<Vec<String>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn registerForNotifications( &self, _name: &str, _callback: &binder::Strong<dyn IServiceCallback>, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn unregisterForNotifications( &self, _name: &str, _callback: &binder::Strong<dyn IServiceCallback>, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn isDeclared(&self, _name: &str) -> binder::Result<bool> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getDeclaredInstances(&self, _iface: &str) -> binder::Result<Vec<String>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn updatableViaApex(&self, _name: &str) -> binder::Result<Option<String>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getUpdatableNames(&self, _apex_name: &str) -> binder::Result<Vec<String>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getConnectionInfo(&self, _name: &str) -> binder::Result<Option<ConnectionInfo>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn registerClientCallback( &self, _name: &str, _service: &binder::SpIBinder, _callback: &binder::Strong<dyn IClientCallback>, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn tryUnregisterService( &self, _name: &str, _service: &binder::SpIBinder, ) -> binder::Result<()> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn getServiceDebugInfo(&self) -> binder::Result<Vec<ServiceDebugInfo>> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } fn checkServiceAccess(&self, _: &CallerContext, _: &str, _: &str) -> binder::Result<bool> { Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into()) } } impl Interface for RpcServiceManager {} impl RpcServiceManager { /// Creates a new `RpcServiceManager` instance from the `IServiceManager` reference. fn new(provider_service: Strong<dyn IRpcProvider>) -> RpcServiceManager { Self { provider_service } } } /// Get the Unix Domain Socket file descriptor for RPC_SERVICEMANAGER_UDS_NAME /// /// A client might need to do this in order to get an FD with the FD_CLOEXEC flag set before /// it forks any other processes. pub fn get_default_rpc_servicemanager_uds_fd() -> Result<OwnedFd, SocketError> { android_get_control_socket(RPC_SERVICEMANAGER_UDS_NAME) } /// Registers the `IServiceManager` service. /// /// servicemanager_fd is an optional argument to provide the Unix Domain Socked file /// descriptor to use for the server. If None is provided, then it will use the default /// of RPC_SERVICEMANAGER_UDS_NAME to get the FD. pub fn register_rpc_servicemanager( provider_service: Strong<dyn IRpcProvider>, servicemanager_fd: Option<OwnedFd>, ) -> Result<()> { let rpc_servicemanager_binder = BnServiceManager::new_binder( RpcServiceManager::new(provider_service), BinderFeatures::default(), ); let servicemanager_fd = match servicemanager_fd { Some(fd) => fd, None => android_get_control_socket(RPC_SERVICEMANAGER_UDS_NAME)?, }; let server = RpcServer::new_bound_socket(rpc_servicemanager_binder.as_binder(), servicemanager_fd)?; // Required for the FD being passed through libbinder's accessor binder server.set_supported_file_descriptor_transport_modes(&[FileDescriptorTransportMode::Unix]); info!("The RPC server '{}' is running.", RPC_SERVICEMANAGER_UDS_NAME); if let Err(e) = rustutils::system_properties::write("servicemanager.ready", "true") { error!("failed to set ro.servicemanager.ready {:?}", e); } // Move server reference into a background thread and run it forever. std::thread::spawn(move || { server.join(); }); Ok(()) }
libs/binder/Android.bp +45 −2 Original line number Diff line number Diff line Loading @@ -857,7 +857,7 @@ cc_library_static { ], } // AIDL interface between libbinder and framework.jar // ServiceManager AIDL interface between libbinder and framework.jar filegroup { name: "libbinder_aidl", srcs: [ Loading @@ -881,6 +881,15 @@ filegroup { visibility: [":__subpackages__"], } filegroup { name: "libbinder_rpc_aidl", srcs: [ "aidl/android/os/IRpcProvider.aidl", ], path: "aidl", visibility: [":__subpackages__"], } aidl_interface { name: "packagemanager_aidl", unstable: true, Loading @@ -904,12 +913,44 @@ aidl_interface { } aidl_interface { name: "libbinder_aidl_test_stub", name: "servicemanager_aidl", unstable: true, local_include_dir: "aidl", srcs: [":libbinder_aidl"], vendor_available: true, backend: { cpp: { // libbinder exports this type itself so use that enabled: false, }, rust: { enabled: true, }, java: { enabled: false, }, }, visibility: [ ":__subpackages__", "//system/tools/aidl:__subpackages__", "//frameworks/native/cmds/servicemanager/rpc_servicemanager", ], } aidl_interface { name: "rpc_servicemanager_aidl", unstable: true, local_include_dir: "aidl", srcs: [":libbinder_rpc_aidl"], vendor_available: true, backend: { rust: { enabled: true, apex_available: [ "com.android.virt", "com.android.compos", ], }, java: { enabled: false, }, Loading @@ -917,6 +958,8 @@ aidl_interface { visibility: [ ":__subpackages__", "//system/tools/aidl:__subpackages__", "//frameworks/native/cmds/servicemanager/rpc_servicemanager", "//packages/modules/Virtualization:__subpackages__", ], } Loading
libs/binder/BackendUnifiedServiceManager.cpp +41 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ #include <android/os/IAccessor.h> #include <android/os/IServiceManager.h> #include <binder/RpcSession.h> #include <cutils/sockets.h> #include <sys/socket.h> #include <sys/un.h> #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) #include <android-base/properties.h> Loading @@ -26,6 +29,10 @@ namespace android { // This is similar to the kernel binder servicemanager's context 0. It's the // known socket that we expect the Unix Domain Socket servicemanager to be listening on. const char kUdsServiceManagerName[] = ANDROID_SOCKET_DIR "/rpc_servicemanager"; #ifdef LIBBINDER_CLIENT_CACHE constexpr bool kUseCache = true; #else Loading Loading @@ -488,15 +495,29 @@ Status BackendUnifiedServiceManager::checkServiceAccess( [[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager; static bool hasOutOfProcessServiceManager() { #ifndef BINDER_WITH_KERNEL_IPC // We don't currently support kernel binder service management or UDS // service management on host or when libbinder is compiled without any // kernel binder suport. Please use setDefaultServiceManager for host // processes that want to use service manager APIs. #if !defined(BINDER_WITH_KERNEL_IPC) || !defined(__BIONIC__) return false; #else #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) return android::base::GetBoolProperty("servicemanager.installed", true); #else #ifdef __ANDROID_VNDK__ return true; #else return android::base::GetBoolProperty("servicemanager.installed", true); #endif #endif #endif // BINDER_WITH_KERNEL_IPC } static sp<AidlServiceManager> getUdsServiceManager() { auto session = RpcSession::make(); session->setFileDescriptorTransportMode(RpcSession::FileDescriptorTransportMode::UNIX); auto status = session->setupUnixDomainClient(kUdsServiceManagerName); if (status == OK) { return interface_cast<AidlServiceManager>(session->getRootObject()); } return nullptr; } sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() { Loading @@ -514,11 +535,22 @@ sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() { sp<AidlServiceManager> sm = nullptr; while (hasOutOfProcessServiceManager() && sm == nullptr) { sm = interface_cast<AidlServiceManager>( ProcessState::self()->getContextObject(nullptr)); // There is either a kernel binder service manager, or an RPC binder // service manager sp<ProcessState> ps = ProcessState::selfIfKernelBinderEnabled(); if (ps) { // Service management over kernel binder sm = interface_cast<AidlServiceManager>(ps->getContextObject(nullptr)); } else { // Check for service management over Unix Domain Sockets sm = getUdsServiceManager(); } if (sm == nullptr) { ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str()); std::string contextObjectName = ps ? ps->getDriverName() + ", " + kUdsServiceManagerName : kUdsServiceManagerName; ALOGE("Waiting 1s on context object(s) on %s.", contextObjectName.c_str()); sleep(1); } } Loading
libs/binder/ProcessState.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,11 @@ sp<ProcessState> ProcessState::selfOrNull() return init(nullptr, false /*requireDefault*/); } sp<ProcessState> ProcessState::selfIfKernelBinderEnabled() { if (access(kDefaultDriver, R_OK) == -1) return nullptr; return init(kDefaultDriver, false /*requireDefault*/); } [[clang::no_destroy]] static sp<ProcessState> gProcess; [[clang::no_destroy]] static std::mutex gProcessMutex; Loading