android在native层实现了进程间的binder通信,但是上层应用程序的开发及framework的实现都是java,用java层再实现一次肯定是不合理的,java可以通过jni调用native code,所以通过jni复用binder在native层的实现就是一个顺理成章的事情。
在init进程的init2阶段,系统启动了serverthread,在serverthread中会启动很多用java实现的系统服务,比如说powerservice:
新建server端实体,然后向servicemanager注册,从代码表面看是和native层binder一样的。powermanagerservice继承自java层的binder类:
所以在new powermanagerservice时会调用binder的构造函数,binder的构造函数中调用了init(),init是native方法,执行jni的android_os_binder_init:
在android_os_binder_init,新建了一个javabbinderholder对角,并将其指针保存在了obj即binder的gbinderoffsets.mobject域中,而gbinderoffsets.mobject又是个什么东西?看一下它的定义:
在androidruntine::startreg中会调用register_android_os_binder,register_android_os_binder会调用int_register_android_os_binder等函数建立java层binder、binderproxy、binderinternal、log等与native层的映射关系。比如在int_register_android_os_binder中会通过jni标准的方法getmethodid等初始化gbinderoffsets:
在android_os_binder_init中new了一个javabbinderholder,javabbinderholder new了一个javabbinder保存到了自己的成员wp<javabbinder> mbinder中。
javabbinder继承自native层的bbinder,并且将java层的binder对象(此处即powermanagerservice)保存到了成员mobject中,并通过object()方法返回。
现在我们发现,javabinder,binderbbinderholder,javabbinder存在相互引用关系:
powermanagerservice.mobject->javabbinderholder
javabbinderholder.mbinder->javabbinder
javabbinder.mobject->powermanagerservice
binder是一种client-server类型的ipc,powermanagerservice属于server端,从native binder中我们知道,client通过bpbinder经由binder driver、bbinder与serverr通信,powermanagerservice通过javabbinderholder引用javabbinder,而javabbinder继承自bbinder,符合了server的条件,server实体有了,接下来就要向servicemanager注册,通过以下方法:
binderinternal.getcontextobject是一个native方法,调用jniandroid_os_binderinternal_getcontextobject:
processstate::self()->getcontextobject就很熟悉了,在binder in native中可以知道,这个调用返回new bpbinder(0)。
javaobjectforibinder的作用就是,新建一个java层的binderproxy对象,将native层的bpbinder保存到binderproxy.mobject,并将binderproxy的弱引用通过attachobject保存到native层的bpbinder(成员mobjects中),这样java层的binderproxy与native层的bpbinder就可以相互引用了。java层的binderproxy及其在native层的表示间的映射关系同binder类一样也是在register_android_os_binder中建立的。
上面红色的部分就等效于:
servicemanagernative继承自iservicemanager与java层的binder类,binderproxy可以引用bpbinder。asinterface就像native binder中的interface_cast的,asinterface实现可以简化为:
obj是binderproxy对象。servicemanagerproxy直接将这个binderproxy对象保存在了成员mremote中,并通过asbinder返回。
servicemanagerproxy同时实现了iservicemanager,而且由其名字可知,servicemanagerproxy是作为servicemanager在client端的代理的,看下它的addservice的实现:
writestrongbinder是native方法,调用android_os_parcel_writestrongbinder,在android_os_parcel_writestrongbinder将java parcel转换成native parcel(native parcel的指针保存在java parcel的成员变量中),然后调用以下语句:
sp<ibinder> ibinderforjavaobject(jnienv* env, jobject obj)根据obj返回javabbinder或native bpbinder,在这里传入的obj 是powermanagerservice,返回javabbinder。接下来调用了mremote.transact,mremote是binderproxy的对象。
binderproxy的transact是native方法,调用jniandroid_os_binderproxy_transact,在android_os_binderproxy_transact中通过:
获取到binderproxy中保存的bpbinder,然后调用bpbinder的transact,到这里就和native binder的调用流程一样了,native servicemanager会注册我们的service,在这里是powermanagerservice。
service已经向servicemanager注册了,那么我们怎么获得所注册的service,或者更准确地说,怎么获得所注册的service的代理呢?
回想下我们在apk中是怎么获取系统服务的:
看一下getsystemservice的实现,位于contextimpl中:
1. servicemanager.getservice获得ibinder对象
同servicemanager.addservice一样,servicemanager.getservice首先获得一个servicemanagerproxy的对象,然后调用它的getservice方法:
mremote是binderproxy对象,内部引用了bpbinder,调用binderproxy的native方法transact与binder通信,然后通过readstrongbinder()读取返回的数据,一个ibinder对象。
readstrongbinder中通过javaobjectforibinder返回了binderproxy对象,前面已经说过。
2. 通过asinterface将获得的ibinder对象转换成ipowermanager对象
ipowermanager.stub.asinterface可以简化为:
proxy只是将传入的参数(binderproxy)保存到了成员mremote中并通过asbinder返回。
proxy与stub都是ipowermanager.aidl编译后生成的类,都位于ipowermanager.java中。关于aidl网上有很多资料。
3. ipowermanager对象是不向外暴露的,构造一个powermanager封装ipowermanager返回。
powermanager只是将ipowermanager保存在了成员变量中,powermanager中保存了binderproxy,binderproxy中引用了native bpbinder,就可以与server进行通信了。
server端接收到client的请求后会调用bbinder的transact处理请求,transact会调用虚函数ontransact,javabbinder继承自bbinder,所以会调用javabbinder::ontransact,在javabbinder::ontransact中有以下一句:
通过jni反向调用了java类的方法。前面我们知道了,java实现的service中,service对象,javabbinderholder,javabbinder存在相互引用关系,javabbinder的成员mobject引用了java中的service对象,比如此处的powermanagerservice,而且在int_register_android_os_binder中通过
将service的exectransact方法(其实是binder的方法)保存在了gbinderoffsets.mexectransact中,所在以javabbinder::ontransact中会调用binder.exectransact。在binder.exectransact中调用了ontransact,执行子类即stub类的ontransact方法,在ontransact中根据code值执行相应的方法,最终是调用service类(继承自stub)中相应的方法。
java层通过jni利用了native层的binder,在jni函数注册时会建立java层binder,binderproxy,binderproxy等类与native层的映射关系。java层service实体继承自java层的binder类,在binder类初始化时会创建一个javabbinderholder作为javabbinder的容器,javabbinder继承自bbinder,java层binder类引用javabbinderholder,javabbinderholder引用javabbinder,javabbinder继承自bbinder并引用java层的binder类,这三者互相引用,这样java层的service实体就可以通过bbinder与驱动进行通信了。
进程向java层的servicemanager代理发送get_service请求,然后通过jni向native层的servicemanager请求服务,native层的servicemanager返回请求的服务的代理对象bpbinder,通过javaobjectforibinder函数将native的bpbinder转化为java层对应的binderproxy,然后通过aidl生成的stub类asinterface方法将binderproxy封闭到请求的服务的代理对象中,这个代理对象引用了binderproxy,binderproxy内部保存了native层的bpbinder,这样就可以与驱动进行通信了。
当server端接收到client的请求时会通过bbinder的transact调用server的服务,bbinder的transact调用虚函数ontransact,这样就会调到bbinder的子类javabbinder的ontransact,而javabinder::ontransact会通过jni反向调用到java层binder类的exectransact,binder.exectransact调用ontransact即子类stub的ontransact,然后根据code值调用service实体类(继承自stub)相应的方法。