在回顾上篇文章的时候,在

我注意到: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:

参考:

https://www.jianshu.com/p/72bc48d59f0e

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注