之前在SeystemService的使用中有讲到ServiceManager的作用:查找获取和注册添加系统服务,但是由于那篇文章主要是梳理SystemService的使用,就没有对ServiceManager其他方面进行梳理.今天对ServiceManager的相关源码进行梳理;
我们从以下几个方面对Servicemanager的启动进行分析
启动进程和服务
获取servicemanager
向Servicemanager中添加服务
向servicemanager中查找获取服务
启动进程和服务
servicemanager也是个系统服务,但是他和一班的系统服务不一样,一般的系统服务是在SystemServer进程中的(AMS,PMS,WMS...),但是Servicemanager是个单独的进程,
路径:/frameworks/native/cmds/servicemanager
├... ├── binder.c ├── binder.h ├── service_manager.c ├── servicemanager.rc └─....
在servicemanager.rc 文件中看到,(这是android 7 及以上版本把servicemanager.rc从init.rc中独立出来的,之前的版本ServiceManager 是由 init 进程通过解析 init.rc 文件而创建的,其所对应的可执行程序 /system/bin/servicemanager, 所对应的源文件是 service_manager.c,进程名为 servicemanager
service servicemanager /system/bin/servicemanager
class core animation
user system
group system readproc
critical
...
servicemanager的主要实现在service_manager.c中,我们看他的main函数:
int main(int argc, char** argv)
{
...
bs = binder_open(driver, 128*1024); // 打开Binder
...
if (binder_become_context_manager(bs)) { // 把自己注册为Binder管理者
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
...
binder_loop(bs, svcmgr_handler); // 进入loop.
return 0;
}
int svcmgr_handler(...)
{
....
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE: // 查找服务
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
if (!handle)
break;
bio_put_ref(reply, handle);
return 0;
case SVC_MGR_ADD_SERVICE: // 添加服务
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
dumpsys_priority = bio_get_uint32(msg);
if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
txn->sender_pid))
return -1;
break;
case SVC_MGR_LIST_SERVICES: {
...
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
main函数它主要做了三件事:
- 打开Binder
- 把自己注册为Binder管理者
- 进入loop监听,使用svcmgr_handler来处理应用请求
获取servicemanager
系统服务要能够被使用,都需要提前拿到servicemanager,才能从servicemanager中查询和添加服务,那是怎么获取到servicemanager的呢?这里使用一个和servicemanager一样是单进程的系统服务SurfaceFlinger为例,看看系统服务是怎么拿到servicemanager,并向其添加注册自己的.
int main(int, char**) {
...
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
....
// initialize before clients can connect
flinger->init();
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
...
// run surface flinger in this thread
flinger->run();
return 0;
}
从上述关键的代码我们可以看到. 在这里使用defaultServiceManager()函数拉获取IServiceManager对象,我们继续看看defaultServicemanager怎么执行的:
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
在defaultServiceManager中,首先检查gDefaultServiceManager存不存在,如果存在就直接返回,如果不存在那就创建一个新的,怎么创建呢,就是 interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
这里的ProcessState提供了self()方法,用于实例化ProcessState类.而在self()方法中执行了打开binder的操作,就是说拿到ProcessState的实例后就可以进行binder通信了;然后调用ProcessState的getContextObject()方法,最后将结果转换为IserviceManager,
getContextObject如下代码所示:getContextObject重视过去了一个Handler值为0的binder对象,[这里涉及binder,内容比较大先不继续,]Servicemanager他在binder中对应的Handler值就是0.段代码执行完,就可以理解成是获取到servicemanager,我们就可以操作servimanager了
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
向Servicemanager中添加服务
添加服务主要就是下面的代码所示,通过将服务写进parcel.然后和请求把服务加入到servicemanager中的请求码(ADD_SERVICE_TRAVSACTION)通过IPC调用,最后服务就会添加成功
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority) {
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
data.writeInt32(dumpsysPriority);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
向servicemanager中查找获取服务
获取服务和添加服务类似,都是通过binder调用,最后返回Ibinder,最后的操作都在service_manager.c的svcmgr_handler方法中根据不同的binder调用请求码进行处理的.然后封装成我们需要的系统服务.主要代码如下:
virtual sp<IBinder> getService(const String16& name) const
{
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
...
}
virtual sp<IBinder> checkService( const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}
int svcmgr_handler(...)
{
....
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE: // 查找服务
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
if (!handle)
break;
bio_put_ref(reply, handle);
return 0;
case SVC_MGR_ADD_SERVICE: // 添加服务
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
dumpsys_priority = bio_get_uint32(msg);
if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
txn->sender_pid))
return -1;
break;
case SVC_MGR_LIST_SERVICES: {
...
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}