Binder之系统服务获取

本篇讲解系统服务的获取过程,即getService,其中addService过程参考Binder一文


MPS服务获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//frameworks/av/media/libmedia/IMediaDeathNotifier.cpp
IMediaDeathNotifier::getMediaPlayerService(){
//获取BpServoceManager
sp<IServiceManager> sm = defaultServiceManager();//1
sp<IBinder> binder;

//每个0.5s循环直到获取MPS服务(因为可能那个时候MPS还没注册)
do {
//返回一个BpBinder
binder = sm->getService(String16("media.player"));//2
if (binder != 0) {//3
break;
}
ALOGW("Media player service not published, waiting...");
usleep(500000); //4
} while (true);

//将BpBinder转换成BpMediaPlayerService,其原理就是通过 BpBinder的handle来找到对应的服务,即BpMediaPlayerService。(此处转换有待研究)
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);//5
......
return sMediaPlayerService;
}

IServiceManager.h中的

  • getService()
  • checkService()
  • addService()

都交给了IServiceManager.cpp中的内部类BpServiceManager来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//frameworks/native/libs/binder/IServiceManager.cpp #BpServiceManager
virtual sp<IBinder> getService(const String16& name) const{
......
//在规定时间内,循环查询,直到获取服务
while (uptimeMillis() < timeout) {
......
sp<IBinder> svc = checkService(name);
if (svc != nullptr) return svc;
}
......
}

virtual sp<IBinder> checkService( const String16& name) const{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
//这里transact的逻辑参考Binder一文和sm启动一文
//这里最终会调用ioctl函数,进入内核Binder驱动
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}




上面是MS进程,给Binder驱动发了消息
########################
Binder驱动
########################
SM进程循环监听Binder驱动是否有新消息,一旦有,就拿出来解析binder_parse


SM的binder_loop函数,在无限循环中不断的调用ioctl函数,它不断的使用BINDER_WRITE_READ指令查询Binder驱动中是否有 新的请求,如果有就交给binder_parse函数处理

res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//frameworks/native/cmds/servicemanager/binder.c
int binder_parse(......){
......
switch(cmd) {
......
case BR_TRANSACTION: {
......
res = func(bs, txn, &msg, &reply);
......
}
......
}

//frameworks/native/cmds/servicemanager/service_manager.c
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,
(const char*) txn_secctx->secctx);
if (!handle)
break;
bio_put_ref(reply, handle);
return 0;
......
}

//frameworks/native/cmds/servicemanager/service_manager.c
uint32_t do_find_service(......){
......
//find_svc函数中会遍历svclist 列表,根据服务名查找对应服务是否已经注册,如果已经注册就会返回对应的svcinfo,如果没有注册就 返回NULL。
struct svcinfo *si = find_svc(s, len);
......
//返回服务的handle值
return si->handle;
......
}