Binder之系统服务注册

本篇讲解系统服务的注册过程,即addService


注册MediaPlayerService

1
2
3
//frameworks/av/media/mediaserver/main_mediaserver.cpp
//注册MediaPlayerService
MediaPlayerService::instantiate();
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}

//frameworks/native/libs/binder/IServiceManager.cpp
//其中remote就是mRemote,即bpbinder
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;
}

//frameworks/native/libs/binder/BpBinder.cpp
//可以看到bpbinder把逻辑交个IPCThreadState
//其中IPCThreadState内包含了2个变量mIn,mOut
//mIn用来接收来自Binder驱动的数据,mOut用来存储发往Binder驱动的数据,它们默认大小都为256字节。
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}

//frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::transact(...){
......
//BC_TRANSACTION代表向Binder驱动发送命令协议
//向Binder设备发送的命令协议都以BC开头
//从Binder驱动返回数据以BR开头
//writeTransactionData内部逻辑:
//将 BC_TRANSACTION和tr结构体写入到mOut中(mOut用来存储发往Binder驱动的数据)

//此函数 准备 发送的数据
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data,NULL);
......

//内部调用了talkWithDriver
err = waitForResponse(reply);
......
}

status_t IPCThreadState::waitForResponse(......){
while (1) {
......
if ((err=talkWithDriver()) < NO_ERROR) break;//1
......
}
return err;
}

//talkWithDriver函数的内部通过ioctl与Binder驱动进行通信
//1.和Binder驱动通信的结构体
//4.通过ioctl和binder进行通信,进入kernel
status_t IPCThreadState::talkWithDriver(bool doReceive){
......
binder_write_read bwr;//1
......
bwr.write_buffer = (uintptr_t)mOut.data();//2
......
bwr.read_buffer = (uintptr_t)mIn.data();//3
......
ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)//4
}

1.sm进程内,循环监听bnder驱动有没有新消息
2.一旦有新消息,比如注册服务
3.根据 case SVC_MGR_ADD_SERVICE ,调用do_add_service()
4.服务名和handle值保存在svcinfo中,svcinfo保存到svclist列表中


总结:

  1. addService函数将数据打包发送给BpBinder来进行处理。
  2. BpBinder新建一个IPCThreadState对象,并将通信的任务交给IPCThreadState。
  3. IPCThreadState的writeTransactionData函数用于将命令协议和数据写入到mOut中。
  4. IPCThreadState的waitForResponse函数主要做了两件事,一件事是通过ioctl函数操作mOut和
    mIn来与Binder驱动进行数据交互,另一件事是处理各种命令协议。