Binder源码解析(二)
Binder系列传送门
ServiceManager的启动流程
1 | system\core\roodir\init.rc: |
分析Android启动流程可知,Android启动时会解析init.rc,servicemanager 服务的孵化器的目录为/system/bin/servicemanager,在此目录下有service_manager.c、binder.c
1 | frameworks\native\cmds\servicemanager\Service_manager.c: |
分析binder_state:
1 | struct binder_state |
分析BINDER_SERVICE_MANAGER:
1 | define BINDER_SERVICE_MANAGER 0U //表示Service Manager的句柄为0 |
1. binder_open
1 | frameworks/native/cmds/servicemanager/Binder.c: |
执行open(“/dev/binder”, O_RDWR);时从用户态进入内核态,因此会执行:
1 | drivers/staging/android/binder.c |
在此函数中创建Service_manager进程对应的binder_proc,保存Service_manager进程的信息,并将binder_proc保存在打开文件file的私有数据成员变量private_data中
1 | //分析下面这个函数可以得出:函数功能是将proc->proc_node放入binder_procs链表的头部,注意是从右向左,最开始插入的binder_proc在binder_procs链表的最右边 |
1.1 binder_open总结
- 创建binder_state结构体保存/dev/binder文件句柄fd、内存映射的起始地址和大小
- 创建binder_procs链表,将保存Service_manager进程信息的binder_proc对应的binder_proc->proc_node加入binder_procs的list中(proc->proc_node是一个hlist_node链表)
2.binder_become_context_manager(bs)
1 | frameworks\native\cmds\servicemanager\Binder.c: |
2.1 binder_get_thread
1 | static struct binder_thread *binder_get_thread(struct binder_proc *proc) //proc对应Service_manager进程 |
此函数为获得proc对应进程下的所有线程中和当前线程pid相等的binder_thread
2.2 binder_context_mgr_node = binder_new_node
1 | static struct binder_thread *binder_get_thread(struct binder_proc *proc) //proc对应Service_manager进程 |
2.3 binder_become_context_manager总结
- 创建ServiceManager线程的binder_thread,binder_thread.proc保存ServiceManager进程对应的binder_proc,binder_thread.pid保存当前进程ServiceManager的PID
- 创建ServiceManager进程的binder_node,binder_node.proc保存binder_proc
- 把ServiceManager进程对应的binder_proc保存到全局变量filp->private_data中
3. binder_loop
1 | frameworks\native\cmds\servicemanager\Binder.c: |
3.1 binder_write(bs, readbuf, sizeof(uint32_t));
1 | int binder_write(struct binder_state *bs, void *data, size_t len) |
3.2 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
1 | static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) //cmd = BINDER_WRITE_READ |
3.2.1 分析binder_thread_write
1 | int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, |
3.2.2 分析binder_thread_read
1 | static int binder_thread_read(struct binder_proc *proc, |
3.3 binder_loop总结
- 进入for (;;)死循环,执行binder_thread_write
- 执行binder_thread_read,从binder_thread->todo队列中取出待处理的事项并处理,处理完thread->todo队列中待处理的事项后:cmd = bwr.read_buffer = BR_TRANSACTION
4.ServiceManager启动总结:
ServiceManager 的启动分为三步
- 打开Binder驱动,建立128K = 128*1024内存映射
- 设置自己(ServiceManager)为Binder的大管家
- 开启for循环,充当Server的角色,等待Client连接
- 在Binder驱动程序中为ServiceManager建立了三个结构体:binder_proc、binder_thread、binder_node
binder_node.proc保存binder_proc,进程间通信的数据会发送到binder_proc的todo链表
binder_proc进程里有很多线程,每个线程对应一个binder_thread,每个binder_thread用来处理一个Client的跨进程通信的请求
ServiceManager 注册服务
以注册WindowManagerService为例
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
向ServiceManager注册WMS,wm为WindowManagerService,WindowManagerService继承
等价:ServiceManager.addService(“window”, new WindowManagerService(…));
1 | frameworks/base/core/java/android/os/ServiceManager.java: |
1. getIServiceManager()
1 | private static IServiceManager getIServiceManager() { |
1.1 BinderInternal.getContextObject():
1 | frameworks/base/core/java/com/android/internal/os/BinderInternal.java: |
1.1.1 sp b = ProcessState::self()->getContextObject(NULL)
1 | sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) |
1.1.2 return javaObjectForIBinder(env, b)
1 | frameworks/base/core/jni/android_util_Binder.cpp: |
因此:BinderInternal.getContextObject()相当于new BinderProxy(),且BinderProxy.mObject成员记录了new BpBinder(0)对象的地址
1.2 ServiceManagerNative.asInterface(…)
1 | ServiceManagerNative.asInterface(new BinderProxy()) |
1.2.1 总结
分析getIServiceManager()可知,最终返回ServiceManagerProxy,其中ServiceManagerProxy.mRemote = new BinderProxy(),且BinderProxy.mObject成员记录了new BpBinder(0)对象的地址
2. ServiceManagerProxy.addService(…)
因此:getIServiceManager().addService(name, service, false);
等价:ServiceManagerProxy.addService(“window”, new WindowManagerService(…), false);
1 | frameworks/base/core/java/android/os/ServiceManagerNative.java: |
2.1 Parcel.obtain();
1 | frameworks/base/core/java/android/os/Parcel.java: |
2.2 data.writeString(“window”)
1 | frameworks/base/core/java/android/os/Parcel.java: |
分析data.writeString(“window”);可知:data.mData保存着”window”
2.3 data.writeStrongBinder(new WindowManagerService(…));
1 | frameworks/base/core/java/android/os/Parcel.java: |
分析data.writeStrongBinder(new WindowManagerService(…));可知:data.mObjects保存new WindowManagerService(…)的服务端
2.4 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
1 | frameworks/base/core/java/android/os/Binder.java: |
2.5 Binder_Loop
ServiceManager线程的thread->todo队列保存着binder_transaction结构体t,t->buffer->data = tr->data.ptr.buffer = “window”
1 | frameworks/native/cmds/servicemanager/Binder.c: |
3. ServiceManager注册服务总结
ServiceManager 注册服务过程
例如ServiceManager.addService(“window”, new WindowManagerService(…));
- 创建一个binder_node结构体,binder_node.cookie = new WindowManagerService(…)的服务端
- 向ServiceManager的todo队列里面添加一条注册服务”window”的事务
- 创建一个svcinfo结构体放入链表,且svcinfo.handle对应new WindowManagerService(…)的服务端,svcinfo.name保存服务的名称”window”
ServiceManager获取服务
frameworks/base/services/core/java/com/android/server/InputMethodManagerService.java:
ServiceManager.getService(Context.WINDOW_SERVICE);
等价:ServiceManager.getService(“window”);
1 | frameworks/base/core/java/android/os/ServiceManager.java: |
getIServiceManager().getService(name)
等价:ServiceManagerProxy.getService(“window”) //ServiceManagerProxy.mRemote = new BinderProxy()
1 | //frameworks/base/core/java/android/os/ServiceManagerNative.java: |
- Parcel.obtain(); //1. 创建一个Parcel对象
- data.writeString(“window”); //2. 向Parcel中写入需要跨进程传输的数据
- mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0); //传入参数data(保存Proxy向native发送的数据),reply(保存native向Proxy返回的数据)
1. mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
由前面的分析可知:mRemote = new BinderProxy()
最终会调用:
1 | frameworks/native/libs/binder/IPCThreadState.cpp: |
1.1 总结
分析mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);可知
在ServiceManager进程的todo链表中保存着一个binder_transaction结构体,其中
binder_transaction.code = binder_transaction_data.code = GET_SERVICE_TRANSACTION
binder_transaction.buffer.data = binder_transaction_data.data.ptr.buffer = “window”
2. Binder_Loop
ServiceManager线程的thread->todo队列保存着binder_transaction结构体t,t->buffer->data = tr->data.ptr.buffer = “window”
1 | frameworks/native/cmds/servicemanager/Binder.c: |
2.1 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
1 | static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) //cmd = BINDER_WRITE_READ |
2.1.1 总结
分析res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);可知 bwr.read_buffer = BR_TRANSACTION
2.2 res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
1 | int binder_parse(struct binder_state *bs, struct binder_io *bio, |
3. ServiceManager获取服务总结:
ServiceManager 服务获得过程例如ServiceManager.getService(“window”);
- 向ServiceManager的todo队列里面添加一条获得服务”window”的事务
- ServiceManager从svclist链表中寻找name = “window”的svcinfo并返回,最终返回svcinfo.handle即为name = “window”对应的new WindowManagerService(…)的服务端