前面第二、三章,注册服务、获取服务的时候都是使用到了 ServiceManager,那么他是怎么获取的呢?
从前面可以知道,使用的是 defaultServiceManager() 方法,这个获取的就是 gDefaultServiceManager 对象。对于 gDefaultServiceManager 对象,如果存在则直接返回,如果不存在则需要创建该对象。
1 概述
1.1 流程图

1.2 defaultServiceManager
首先我们来看一下 defaultServiceManager 方法是怎么实现的,
路径在:frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager()
{
// std::call_once 保证全局只初始化一次,且线程安全
std::call_once(gSmOnce, []() {
gDefaultServiceManager = sp<CppBackendShim>::make(getBackendUnifiedServiceManager());
});
return gDefaultServiceManager;
}
获取 ServiceManager 对象采用单例模式,
然后通过 CppBackendShim + getBackendUnifiedServiceManager() 实现了后端统一抽象。
2 getBackendUnifiedServiceManager
路径是 frameworks/native/libs/binder/BackendUnifiedServiceManager.cpp
sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
// 线程安全单例
std::call_once(gUSmOnce, []() {
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
/* wait for service manager */
// 读取属性 servicemanager.installed,判断是否存在独立的 servicemanager 进程
if (hasOutOfProcessServiceManager()) {
using std::literals::chrono_literals::operator""s;
using android::base::WaitForProperty;
// 轮询等待系统属性 servicemanager.ready 变为 "true",超时 1 秒
while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
ALOGE("Waited for servicemanager.ready for a second, waiting another...");
}
}
#endif
sp<AidlServiceManager> sm = nullptr;
while (hasOutOfProcessServiceManager() && sm == 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) {
std::string contextObjectName = ps
? ps->getDriverName() + ", " + kUdsServiceManagerName
: kUdsServiceManagerName;
ALOGE("Waiting 1s on context object(s) on %s.", contextObjectName.c_str());
sleep(1);
}
}
gUnifiedServiceManager = sp<BackendUnifiedServiceManager>::make(sm);
});
return gUnifiedServiceManager;
}
上面的逻辑可以分成三个部分,第一部分判断是否存在独立的 servicemanager 进程然后循环等待进程是否初始化完毕,也就是 wait for service manager 部分。第二部分阻塞式地获取 servicemanager 的实际通信引用。第三部分保存结果。
先看一下 hasOutOfProcessServiceManager 的实现,如下
static bool hasOutOfProcessServiceManager() {
// 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
#ifdef __ANDROID_VNDK__
return true;
#else
return android::base::GetBoolProperty("servicemanager.installed", true);
#endif
#endif
}
就是通过 servicemanager.installed 属性是否为 true 来判断是否存在 servicemanager 进程。
2.1 wait for service manager
std::call_once(gUSmOnce, []() {
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) // 运行在 Android 系统上,而非普通 Linux
/* wait for service manager */
// 读取属性 servicemanager.installed,判断是否存在独立的 servicemanager 进程
if (hasOutOfProcessServiceManager()) {
using std::literals::chrono_literals::operator""s;
using android::base::WaitForProperty;
// 轮询等待系统属性 servicemanager.ready 变为 "true",超时 1 秒
while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
ALOGE("Waited for servicemanager.ready for a second, waiting another...");
}
}
#endif
......
});
来看上面的代码,首先是 call_once,老朋友了,线程安全单例,就是一个锁。
然后通过 hasOutOfProcessServiceManager 来判断是否存在,如果存在的话,轮询等待系统属性 servicemanager.ready,代表 ServiceManager 初始化完毕可以正常工作了,每次等待超时时间为 1 秒,会一直等待。
android::base::WaitForProperty 是 libbase 提供的函数,用来阻塞等待某个 Android 系统属性变为期望值。
可以看到第二部分在 ServiceManager 不存在时也不会执行,所以在初始化 BackendUnifiedServiceManager 这个单例时,必须阻塞等待 ServiceManager 真正就绪并可以通信后,才继续完成初始化。也就是第一部分必须成功之后才能执行第二部分和第三部分。
- 如何启动的 ServiceManager 请看后面的讲解。
2.2 阻塞获取引用
sp<AidlServiceManager> sm = nullptr;
while (hasOutOfProcessServiceManager() && sm == 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) {
std::string contextObjectName = ps
? ps->getDriverName() + ", " + kUdsServiceManagerName
: kUdsServiceManagerName;
ALOGE("Waiting 1s on context object(s) on %s.", contextObjectName.c_str());
sleep(1);
}
}
在第一部分结束之后进行,也就是 ServiceManager 存在且已经初始化完毕。
这一部分的逻辑就是为了获取 AidlServiceManager 的代理对象 sm。轮询获取,保险起见每次也需要通过 hasOutOfProcessServiceManager 来再次判断 ServiceManager 是否存在。
而获取 AIdlServiceManager 有两个路径,一个是传统的 Kernel Binder,了一个是 UDS 路径。
整个流程如下:

2.2.1 ProcessState
sp<ProcessState> ps = ProcessState::selfIfKernelBinderEnabled();
首先是这个,获取 ps,ps 是一个 ProcessState 单例。
ProcessState 在注册服务中见过,路径在 frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::selfIfKernelBinderEnabled() {
if (access(kDefaultDriver, R_OK) == -1) return nullptr;
return init(kDefaultDriver, false /*requireDefault*/);
}
kDefaultDriver 是一个常量,定义在 ProcessState.h 中,值是 "/dev/binder"。
access() 是 POSIX 系统调用,就是检查路径节点是否存在且可读,可以返回 0,否则返回 -1。
如果存在的话,就初始化并返回 ProcessState 对象。
至于 init 方法在注册服务中有讲解,此处不过多赘述。
这个函数的真正意义是判断当前运行环境是否支持传统的内核 Binder 驱动。
2.2.2 Kernel Binder
如果支持的话,也就是 ps 存在,则走传统 Binder 路径。
sm = interface_cast<AidlServiceManager>(ps->getContextObject(nullptr));
ps->getContextObject(nullptr) 会返回 sp<IBinder>,前面的 interface_cast<AidlServiceManager> 可以将 IBinder 转换为 AIDL 定义的服务管理接口代理,本质上创建 BpServiceManager。
getContextObject 也是 ProcessState 的方法,如下:
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
sp<IBinder> context = getStrongProxyForHandle(0);
if (context) {
// The root object is special since we get it directly from the driver, it is never
// written by Parcell::writeStrongBinder.
internal::Stability::markCompilationUnit(context.get());
} else {
ALOGW("Not able to get context object on %s.", mDriverName.c_str());
}
return context;
}
这里逻辑比较简单,直接调用的是 getStrongProxyForHandle 方法。
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
std::function<void()> postTask;
std::unique_lock<std::mutex> _l(mLock);
if (handle == 0 && the_context_object != nullptr) return the_context_object;
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one. The
// attemptIncWeak() is safe because we know the BpBinder destructor will always
// call expungeHandle(), which acquires the same lock we are holding now.
// We need to do this because there is a race condition between someone
// releasing a reference on this BpBinder, and a new reference on its handle
// arriving from the driver.
IBinder* b = e->binder;
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
// 需要创建新的 BpBinder
if (handle == 0) {
// Special case for context manager...
// The context manager is the only object for which we create
// a BpBinder proxy without already holding a reference.
// Perform a dummy transaction to ensure the context manager
// is registered before we create the first local reference
// to it (which will occur when creating the BpBinder).
// If a local reference is created for the BpBinder when the
// context manager is not present, the driver will fail to
// provide a reference to the context manager, but the
// driver API does not return status.
//
// Note that this is not race-free if the context manager
// dies while this code runs.
IPCThreadState* ipc = IPCThreadState::self();
CallRestriction originalCallRestriction = ipc->getCallRestriction();
ipc->setCallRestriction(CallRestriction::NONE);
Parcel data;
status_t status = ipc->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
ipc->setCallRestriction(originalCallRestriction);
if (status == DEAD_OBJECT)
return nullptr;
}
sp<BpBinder> bp = BpBinder::PrivateAccessor::create(handle, &postTask);
e->binder = bp.get();
if (bp) e->refs = bp->getWeakRefs();
result = bp;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
_l.unlock();
if (postTask) postTask();
return result;
}
这个方法的作用是,根据 handle 编号,查找或创建对应的 BpBinder 代理对象。
我们这里请求的是 handle = 0,也就是 servicemanager。
此时会触发快速路径,也就是
if (handle == 0 && the_context_object != nullptr) return the_context_object;
如果是获取的 servicemanager,且已经存在了,则直接返回。
如果没有的话,则往下执行 handle_entry* e = lookupHandleLocked(handle),这个是用来查找 handle 缓存表,用来判断是直接复用还是创建。不过 servicemanager 缓存上面已经确定没有了,所以这里必定是返回一个空槽位。
if (e != nullptr) {
IBinder* b = e->binder;
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
// 分支 A:创建新的 BpBinder
} else {
// 分支 B:复用已有的 BpBinder
}
}
也就是在这里会进入到分支 A,
if (handle == 0) {
IPCThreadState* ipc = IPCThreadState::self();
CallRestriction originalCallRestriction = ipc->getCallRestriction();
ipc->setCallRestriction(CallRestriction::NONE);
Parcel data;
status_t status = ipc->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
ipc->setCallRestriction(originalCallRestriction);
if (status == DEAD_OBJECT)
return nullptr;
}
sp<BpBinder> bp = BpBinder::PrivateAccessor::create(handle, &postTask);
e->binder = bp.get();
if (bp) e->refs = bp->getWeakRefs();
result = bp;
servicemanager 进行了特殊处理,handle 为 0 时,必须确认 context manage 已经注册完成。否则未注册完成时创建 BpBinder(0),后续所有发往 handle = 0 的事务都会静默失败。
在内核 Binder 体系中,handle = 0 是隐式映射到 servicemanager 的 —— servicemanager 启动时通过 ioctl(BINDER_SET_CONTEXT_MGR) 声明自己为 context manager,驱动自动将其关联到 handle=0。
servicemanager 特殊处理之后,就是创建 BpBinder
sp<BpBinder> bp = BpBinder::PrivateAccessor::create(handle, &postTask);
e->binder = bp.get();
if (bp) e->refs = bp->getWeakRefs();
result = bp;
旧版是 new BpBinder(handle) 直接构造,Android 16 改用 BpBinder::PrivateAccessor::create(handle, &postTask)。这个是 BpBinder 的内部 friend class,通过它可以访问 BpBinder 的私有内部构造逻辑。create 接收一个输出参数 &postTask,用于返回一个需要在锁外执行的回调任务。
分支 B 复用已有的 BpBinder
} else {
result.force_set(b);
e->refs->decWeak(this);
}
最后,解锁加延迟任务执行
_l.unlock();
if (postTask) postTask();
return result;
为什么 postTask 要在锁外执行?
BpBinder::PrivateAccessor::create() 可能需要执行一些操作,比如向 IPCThreadState 注册新创建的 handle。这类操作可能涉及其他锁,如果在 mLock 持有期间执行,有死锁风险。
流程如下:

2.2.3 UDS
也就是使用的这个方法进行获取。
sm = getUdsServiceManager();
看看这个方法
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;
}
共四个步骤。
- 创建 RpcSession,这个是 Android libbinder 中新增的跨进程 RPC 框架,类似于 gRPC 的客户端会话。它的职责是管理一次跨进程连接的全生命周期。
- 设置文件描述符传输模式。
- 建立 Unix Domain Socket 连接。
- 获取远端根对象并转换为接口代理。
这个的设计意义在于 Android 16 通过 UDS 路径,使得在没有内核 Binder 驱动的环境中(如容器、虚拟机),仍然可以使用 ServiceManager 的完整功能,保持上层应用代码零修改。
先不过多赘述了。
3 总结
defaultServiceManager() 通过 std::call_once 以线程安全单例模式获取全局唯一的 gDefaultServiceManager 对象,其内部首先轮询等待系统属性 servicemanager.ready 变为 "true" 以确保独立 servicemanager 进程已初始化就绪。
随后通过双路径阻塞式获取 AidlServiceManager 代理:若存在 /dev/binder 则走传统 Kernel Binder 路径(通过 ProcessState 获取 handle=0 的 BpBinder,并先执行 PING_TRANSACTION 确认 context manager 已注册),否则回退到 UDS 路径(通过 RpcSession 建立 Unix Domain Socket 连接),最终保证在 ServiceManager 真正可通信后才向上层返回可用的服务管理代理,支撑后续服务的注册与查询。