parent
6f32d56f21
commit
22731a435f
@ -0,0 +1,211 @@ |
||||
--- |
||||
ServiceManager 的启动和工作原理 |
||||
--- |
||||
|
||||
1. ServiceManager 启动流程是怎样的? |
||||
2. 怎么获取 ServiceManager 的 binder 对象? |
||||
3. 怎么向 ServiceManager 添加服务? |
||||
4. 怎么从 ServiceManager 获取服务? |
||||
|
||||
#### ServiceManager 的启动 |
||||
|
||||
1. 启动进程 |
||||
2. 启用 binder 机制 |
||||
3. 发布自己的服务 |
||||
4. 等待并响应请求 |
||||
|
||||
##### 启动进程 |
||||
|
||||
```ini |
||||
service servicemanager /system/bin/servicemanager |
||||
clas core |
||||
user system |
||||
group system |
||||
critical |
||||
//... |
||||
``` |
||||
|
||||
```c |
||||
int main(int argc, char **argv) { |
||||
struct binder_status *bs; |
||||
// 1.打开 binder 驱动 |
||||
bs = binder_open(128*1024); |
||||
// 2.把自己注册为上下文管理者 |
||||
binder_become_context_manager(bs); |
||||
// 3.进入 loop 循环,不断等待请求、处理请求 |
||||
binder_loop(bs, svcmgr_handler); |
||||
return 0; |
||||
} |
||||
``` |
||||
|
||||
```c |
||||
struct binder_status *binder_open(size_t, mapsize) { |
||||
struct binder_state *bs; |
||||
bs = malloc(sizeof(*bs)); |
||||
// 1.打开 binder 驱动,返回一个 fd |
||||
bs->fd = open("/dev/binder", O_RDWR); |
||||
bs->mapsize = mapsize; |
||||
// 2.给 fd 映射一块内存,128 kb |
||||
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); |
||||
return bs; |
||||
} |
||||
``` |
||||
|
||||
```c |
||||
// 注册成上下文,其实就是告诉 binder 驱动,ServiceManager 已经就绪了 |
||||
int binder_become_context_manager(struct binder_state *bs) { |
||||
return ioctl(bs->fd, BINDER_SET_CONTEXT_MSR, 0); |
||||
} |
||||
``` |
||||
|
||||
binder_loop 分为两个阶段,第一阶段主要是注册为 binder 线程: |
||||
|
||||
```c |
||||
void binder_loop(struct binder_state *bs, binder_handler func) { |
||||
uint32_t readbuf[32]; |
||||
// 把当前线程注册为 binder 线程,也就是告诉 binder 驱动,当前线程可以处理 binder 请求的 |
||||
readbuf[0] = BC_ENTER_LOOPER; |
||||
binder_write(bs, readbuf, sizeof(uint32_t)); |
||||
//... |
||||
} |
||||
``` |
||||
|
||||
```c |
||||
int binder_write(struct binder_state *bs, void *data, size_t len) { |
||||
// BINDER_WRITE_READ 表示可读可写 |
||||
// write_size > 0 执行写 |
||||
// read_size > 0 执行读 |
||||
// write_size > 0 && read_size > 0,先写再读 |
||||
struct binder_write_read bwr; |
||||
bwr.write_size = len; |
||||
bwr.write_consumed = 0; |
||||
bwr.write_buffer = (uintptr_t) data; |
||||
bwr.read_size = 0; |
||||
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); |
||||
return res; |
||||
} |
||||
``` |
||||
|
||||
第二阶段,就是读请求处理请求了: |
||||
|
||||
```c |
||||
void binder_loop(struct binder_state *bs, binder_handler func) { |
||||
struct binder_write_read bwr; |
||||
//... |
||||
bwr.write_size = 0; |
||||
for(;;) { |
||||
bwr.read_size = sizeof(readbuf); |
||||
bwr.read_buffer = (unitptr_t) readbuf; |
||||
ioctl(bs->fd, BINDER_WRITE_READ, &bwr); |
||||
// 解析请求,并在回掉函数 func 处理请求 |
||||
binder_parse(bs, 0, (uintptr_t)readbuf, bwr.read_consumed, func); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
#### 如何获取 ServiceManager? |
||||
|
||||
以 SurfaceFlinger 为例: |
||||
|
||||
```c |
||||
sp<IServiceManager> defaultServiceManager() { |
||||
if(gDefaultServiceManager != null) { |
||||
return gDefaultServiceManager; |
||||
} |
||||
while(gDefaultServiceManager == null) { |
||||
gDefaultServiceManager = getContextObject(); |
||||
if(gDefaultServiceManager==null) sleep(1); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
```c |
||||
sp<IBinder> ProcessState::getContextObject(...) { |
||||
// 返回 ServiceManager 的 Proxy 对象,注意 handler 值为 0 |
||||
return getStrongProxyForHandle(0); |
||||
} |
||||
``` |
||||
|
||||
```c |
||||
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { |
||||
// 以 binder handle 值作为索引,获取数组里面对应的 handle_entry |
||||
handle_entry* e = loopupHandleLocked(handle); |
||||
IBinder* b = e->binder; |
||||
if(b == NULL) { |
||||
// ServiceManager 的 Proxy 对象就是 BpBinder(0); |
||||
b = new BpBinder(handle); |
||||
e->binder = b; |
||||
} |
||||
return b; |
||||
} |
||||
``` |
||||
|
||||
#### 怎么向 ServiceManager 添加服务? |
||||
|
||||
```c |
||||
// 添加服务,Service 名称和 Service Binder 对象 |
||||
status_t addService(const String16& name, const sp<IBinder>& service, ...) { |
||||
//... |
||||
// 通过 remote 函数获取 BpBinder 对象,然后调用 BpBinder 的 transact 函数 |
||||
remote() -> transact(ADD_SERVICE_TRANSACTION, data, &reply); |
||||
} |
||||
``` |
||||
|
||||
```c |
||||
status_t BpBinder::transact(unit32_t code, const Parcel& data, Parcel* reply, ...) { |
||||
// IPCThreadState 线程单例,直接跟 binder 驱动交互 |
||||
IPCThreadState::self()->transact(mHandle, code, data, ...); |
||||
} |
||||
``` |
||||
|
||||
在 ServiceManager 收到请求之后,如何处理? |
||||
|
||||
```c |
||||
int svcmgr_handler(..., struct binder_transaction_data *txn, ...) { |
||||
switch(txn->code) { |
||||
//... |
||||
case SVC_MSR_ADD_SERVICE: |
||||
// 注册到 ServiceManage 的虽然传递的是 binder 实体对象 |
||||
// 但是真正 ServiceManager 收到的只是一个 handle 值 |
||||
// ServiceManager 会根据 handle 值还有 binder 相关信息封装成一个数据结构插入到单链表里 |
||||
do_add_service(bs, s, len, handle, ...); |
||||
break; |
||||
} |
||||
} |
||||
``` |
||||
|
||||
#### 怎么从 ServiceManager 获取服务? |
||||
|
||||
关于怎么获取服务呢,和注册服务差不多,都需要向 ServiceManager 发起一个 binder 调用。 |
||||
|
||||
```java |
||||
public static IBinder getService(String name) { |
||||
IBinder service = sCache.get(name); |
||||
if(service != null) { |
||||
return service; |
||||
}else { |
||||
// 获取 ServiceManager 的 binder 对象,然后调用它的 getService 函数 |
||||
return getIServiceManager().getService(name); |
||||
} |
||||
return null; |
||||
} |
||||
``` |
||||
|
||||
ServiceManager 在收到请求之后,是如何处理的呢? |
||||
|
||||
```c |
||||
int svcmgr_handler(..., struct binder_transaction_data *txn, ...) { |
||||
uint32_t handle; |
||||
switch(txn->code) { |
||||
case SVC_MGR_GET_SERVICE: |
||||
// 拿到服务的名称 |
||||
s = bio_get_string16(msg, &len); |
||||
// 找到对应服务的 handle 值 |
||||
handle = do_find_service(bs, s, len, ...); |
||||
// 返回 handle 值,Client 端再根据 handle 值封装一个 BpBinder 就行了 |
||||
bio_put_ref(reply, handle); |
||||
return 0; |
||||
} |
||||
} |
||||
``` |
||||
|
Loading…
Reference in new issue