ServiceManager的启动流程与核心机制
一、ServiceManager的进程与继承体系
- ServiceManager是独立的系统进程,启动时机早于Zygote,在init.rc中配置。
- 其service.rc文件列出了ServiceManager相关服务及依赖:
注:如果ServiceManager重启,将导致诸如healthd、zygote等关键服务一并重启。
二、ServiceManager主流程源码梳理
main函数
int main(int argc, char** argv) {
// 参数判断与Binder驱动路径选择
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
}
const char* driver = argc == 2 ? argv[1] : "/dev/binder";
// (1) 初始化Binder驱动
sp<ProcessState> ps = ProcessState::initWithDriver(driver);
ps->setThreadPoolMaxThreadCount(0);
ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
// 实例化ServiceManager
sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
// 自注册
if (!manager->addService("manager", manager, false, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
// (2) 设置上下文对象
IPCThreadState::self()->setTheContextObject(manager);
// 成为Binder驱动的context manager
ps->becomeContextManager(nullptr, nullptr);
// Looper初始化,监听Binder事件
sp<Looper> looper = Looper::prepare(false);
BinderCallback::setupTo(looper);
// (3) 注册监听
ClientCallbackCallback::setupTo(looper, manager);
while(true) {
looper->pollAll(-1);
}
return EXIT_FAILURE; // 不应该到达这里
}
-
说明:
- 首先初始化Binder驱动
- 创建ServiceManager对象并自注册
- 设置为全局context对象,成为Binder的上下文管理者
- 使用Looper监听Binder fd,进行事件分发
- 死循环poll,持续处理Binder事务
线程本地存储与IPCThreadState
// IPCThreadState线程本地单例获取
IPCThreadState* IPCThreadState::self() {
if (gHaveTLS.load(std::memory_order_acquire)) {
restart:
const pthread_key_t k = gTLS;
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
return new IPCThreadState;
}
if (gShutdown.load(std::memory_order_relaxed)) {
ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
return nullptr;
}
pthread_mutex_lock(&gTLSMutex);
if (!gHaveTLS.load(std::memory_order_relaxed)) {
int key_create_value = pthread_key_create(&gTLS, threadDestructor);
if (key_create_value != 0) {
pthread_mutex_unlock(&gTLSMutex);
ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
strerror(key_create_value));
return nullptr;
}
gHaveTLS.store(true, std::memory_order_release);
}
pthread_mutex_unlock(&gTLSMutex);
goto restart;
}
- 重点:IPCThreadState通过TLS(线程本地存储)实现线程隔离的状态管理,本质上和Java的ThreadLocal非常相似。
BinderCallback实现(监听事件分发)
class BinderCallback : public LooperCallback {
public:
static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
sp<BinderCallback> cb = new BinderCallback;
int binder_fd = -1;
IPCThreadState::self()->setupPolling(&binder_fd);
LOG_ALWAYS_FATAL_IF(binder_fd < 0, "Failed to setupPolling: %d", binder_fd);
IPCThreadState::self()->flushCommands();
int ret = looper->addFd(binder_fd, Looper::POLL_CALLBACK,
Looper::EVENT_INPUT, cb, nullptr);
LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");
return cb;
}
int handleEvent(int, int, void*) override {
IPCThreadState::self()->handlePolledCommands();
return 1;
}
};
- 说明:核心作用就是监听Binder fd,一旦有事件发生即调用handlePolledCommands处理命令。
Binder消息处理流程
在IPCThreadState里:
status_t IPCThreadState::handlePolledCommands() {
status_t result;
do {
result = getAndExecuteCommand();
} while (mIn.dataPosition() < mIn.dataSize());
processPendingDerefs();
flushCommands();
return result;
}
status_t IPCThreadState::getAndExecuteCommand() {
// ...省略读取cmd
result = executeCommand(cmd);
return result;
}
- 说明:循环读取、解析、执行来自Binder驱动的所有命令,直至全部处理完毕。
executeCommand核心片段
status_t IPCThreadState::executeCommand(int32_t cmd) {
// ...省略部分
if (tr.target.ptr) {
// 普通Binder服务
if (reinterpret_cast<RefBase::weakref_type*>(tr.target.ptr)->attemptIncStrong(this)) {
error = reinterpret_cast<BHwBinder*>(tr.cookie)->transact(tr.code, buffer, &reply, tr.flags, reply_callback);
reinterpret_cast<BHwBinder*>(tr.cookie)->decStrong(this);
} else {
error = UNKNOWN_TRANSACTION;
}
} else {
// context manager对象,特指ServiceManager
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags, reply_callback);
}
}
-
说明:
- 普通服务:通过BBinder子类(如BnXXXService)的transact/onTransact处理
- context对象(ServiceManager):直接走ServiceManager的transact
BBinder转发至onTransact
status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
err = pingBinder();
break;
case EXTENSION_TRANSACTION:
err = reply->writeStrongBinder(getExtension());
break;
case DEBUG_PID_TRANSACTION:
err = reply->writeInt32(getDebugPid());
break;
default:
err = onTransact(code, data, reply, flags);
break;
}
if (reply != nullptr) {
reply->setDataPosition(0);
}
return err;
}
- 说明:BBinder只做分发,所有核心命令最终都落到具体的服务子类(如ServiceManager)的onTransact实现。
三、服务端整体流程总结
源码主链路
驱动 ioctl → looper回调(BinderCallback) → IPCThreadState::self()->handlePolledCommands() → BBinder::transact → BnServiceManager::onTransact → ServiceManager::getService()
补充说明
-
服务端处理的主流程其实就是:
- Binder驱动通过ioctl事件通知
- Looper/BinderCallback监听fd
- IPCThreadState循环获取并解析命令
- 真正业务转发到ServiceManager对象或其它服务对象的onTransact处理
-
ServiceManager作为全局context对象,具有特殊性:
它的注册、管理、转发能力保障了整个系统服务发现与通信体系的稳定运转。
学后检测
单选题
1. ServiceManager进程在Android系统中的启动时机是?
A. Zygote启动后
B. SystemServer启动后
C. init.rc解析时,早于Zygote
D. 应用层启动后
答案:C
解析: ServiceManager属于系统原生守护服务,最早在init.rc阶段启动。
2. ServiceManager在注册为Binder的context manager时调用了哪个类的静态方法?
A. BBinder::becomeContextManager
B. ProcessState::becomeContextManager
C. IPCThreadState::setTheContextObject
D. ServiceManager::addService
答案:B
解析: 注册全局上下文管理者是ProcessState::becomeContextManager()。
多选题
3. 关于IPCThreadState,以下说法正确的是?
A. 每个进程只有一个IPCThreadState实例
B. 通过TLS(线程本地存储)实现线程隔离
C. 负责管理当前线程与Binder驱动的交互
D. 在每个线程中都是单例模式
答案:B、C、D
解析: IPCThreadState是线程级别的单例,通过TLS实现,负责当前线程与Binder交互。A错,每线程一个。
4. ServiceManager主循环中pollAll(-1)的作用有哪些?
A. 持续监听Binder fd
B. 监听并响应Binder事件
C. 只监听一次事件,处理完即退出
D. 支持阻塞模式下的事件分发
答案:A、B、D
解析: pollAll(-1)为无限阻塞监听,持续处理事件。
判断题
5. ServiceManager的BBinder对象本身实现了所有onTransact的业务处理。
(对/错)
答案:错
解析: BBinder只做分发,具体业务由ServiceManager或其子类实现onTransact。
6. BinderCallback用于监听Binder文件描述符事件,并转发给IPCThreadState处理。
(对/错)
答案:对
解析: 其本质是fd事件回调分发器。
简答题
7. 简述ServiceManager启动主流程(从main函数到业务分发),并说明其成为Binder全局context对象的原理。
答案:
- main函数首先初始化Binder驱动(ProcessState::initWithDriver),实例化ServiceManager并自注册addService("manager",...)。
- 调用IPCThreadState::setTheContextObject将自身设置为Binder上下文对象。
- ProcessState::becomeContextManager()将ServiceManager注册为驱动层的context manager(handle为0的特殊Binder实体)。
- Looper初始化并通过BinderCallback::setupTo注册监听Binder fd事件,回调时调用IPCThreadState::handlePolledCommands(),最终分发到ServiceManager的onTransact实现处理具体业务。
8. 为什么ServiceManager的crash或重启会影响到healthd、zygote等核心系统服务?
答案:
因为所有系统服务的发现、注册、Binder通信都依赖ServiceManager。如果它崩溃,所有通过Binder发现的服务都会失效。init.rc中配置有依赖关系,重启ServiceManager会自动重启相关核心服务以保障系统一致性。
源码填空题
9. 在ServiceManager进程main()函数中,设置Binder全局上下文管理者用到的两步核心调用分别是( 1 )和( 2 )。
答案:
- IPCThreadState::self()->setTheContextObject(manager);
- ProcessState::becomeContextManager(nullptr, nullptr);
10. 在BinderCallback的handleEvent()方法内部,实际负责解析Binder命令与分发的函数是( )。
答案:IPCThreadState::handlePolledCommands()
解析: 它会循环调用getAndExecuteCommand,最终通过executeCommand分发到BBinder或ServiceManager。