binder、aidl(二)mRemote对象拾遗
在回顾上篇文章的时候,在
我注意到:Binder和BinderProxy两个类都实现了transact,它们也都是IBinder的实现类
那么mRemote调用的transact究竟是哪个类的方法?并且我们都知道CameraService并没有Stub类的实例,也就是说其java接口是没有实现的,如果如上篇文章所述,调用尽头将会是一个没有实现的接口
所以我们要重新探究mRemote.transact的调用过程
回到CameraManager:
通过上一篇文章的分析我们已经知道,第二个框中的asInterface传入的参数cameraServiceBinder最终会传到ICameraService.Stub.Proxy中,在Proxy的构造函数中将值赋给mRemote
既然mRemote的类型最终是由cameraServiceBinder这个对象决定,那么其类型就是我们要关注的重点,显然我们要回到CameraManager第一个框,看看cameraServiceBinder的前世今生:
不难看出cameraServiceBinder来自ServiceManager.getService,那么我们去看看:
\frameworks\base\core\java\android\os\ServiceManager.java
cache里有就取出来,没有的话就通过rawGetService获得
函数很大,但是通过返回值判断看上去有用的就框中一个调用
看上去和我们熟悉的binder调用很像,看ServiceManagerNative之前,先看一下参数,来自
BinderInternal.getContextObject()
\frameworks\base\core\java\com\android\internal\os\BinderInternal.java
没想到!居然是一个native方法
openGrok之,找到这个native方法的定义位置:
\frameworks\base\core\jni\android_util_Binder.cpp
接下来跟一下这个android_os_BinderInternal_getContextObject方法的实现
这里看到创建了一个native层IBinder类型的对象b,进去看一下b的详细赋值过程
\frameworks\native\libs\binder\ProcessState.cpp
285行可以看出,返回的b是BpBinder创建出来的对象,Native的binder类我们之后再探索,先知道这个类型即可,回到
现在我们知道b是个BpBinder类,接下来把这个BpBinder传入javaObjectForIBinder中处理
框里应该是一个JNI调用,参数分别是对应的java类,java方法和传入的参数
那么去找gBinderProxyOffsets这个结构体的赋值
1403行开始的一系列赋值行为说明了gBinderProxyOffsets这个结构体对应的就是BinderProxy这个类,那么上一步的CallStaticObjectMethod调用实际上就是Binder.java其内部类BinderProxy的getInstance方法!真够复杂的
去确认一下,方法名和参数都可以对得上
于是我们需要狠狠地回顾一下,1067行这个new出来的BinderProxy对象最后返回到哪里去了呢
想必有些彭友已经懵了,我也懵了,所以我整理了目前至此的流程:
这下我们可以看到,BinderProxy对象一路返回到了ServiceManager.java的getIServiceManager方法,并作为参数传进了ServiceManagerNative.asInterface中:
\frameworks\base\core\java\android\os\ServiceManager.java
至此,ServiceManagerNative.asInterface的参数来历解释清楚了,接下去看asInterface
\frameworks\base\core\java\android\os\ServiceManagerNative.java
如上图,传入的这个obj就是上述过程中新建的BinderProxy对象
和上一篇分析类似,在跨进程的情况下,asInterface最终会返回一个Proxy对象
这里是ServiceManagerProxy的构造方法,于是就将BinderProxy类型的对象传给mRemote了
回去看一下流程图,至此我们知道了rawGetService中调用的getIserviceManager实际上返回的sServiceManager对象类型是ServiceManagerProxy,其内部的mRemote是BinderProxy类型
再往回看一层:
因为getIServiceManager返回的对象是ServiceManagerProxy类型
这下我们就知道了253行调用的getService是ServiceManagerProxy中的方法,
于是去看一下ServiceManagerProxy中getService的实现:
还是通过返回值找值得关注的调用,126行可以看到,getService的返回值binder是通过一个Parcel类的对象reply调用readStrongBinder来获得:
\frameworks\base\core\java\android\os\Parcel.java
这里又要调用native方法了
对应关系在:
\frameworks\base\core\jni\android_os_Parcel.cpp
455行的javaObjectForIBinder方法在之前有解释过,第二个参数接受一个BpBinder对象,且这个方法返回一个BinderProxy对象,如果忘记了可以回到这里回顾
说了这么深,我们到底探究到了哪一步?我帮你整理好了这个BinderProxy对象的返回路径:
这样一路回到了CameraManager中,我们大致走完了ServiceManager.getService的整个流程:
并且知道了cameraServiceBinder这个对象是BinderProxy类型的
那么,传入asInterface,并最终为Proxy对象赋值的参数也就是BinderProxy类型
那那么,这里的说法就需要修改一下,此时mRemote.transact调用的不再是Binder类的transact,而应该是BinderProxy类的transact
==============================================================================
也就是说,parcel->readStrongBinder返回的应该是一个BpBinder对象,那么我们顺着去看看:
这里我们简单补充一下664行这一步调用的的细节
通过上一篇文章已经知道,这一步调用实际上是BinderProxy类的getInstance,传入了一个nativeData,并最终用于实例化BinderProxy:
参考: