Android Binder框架实现之Framework层Binder服务注册过程源码分析

Android Binder框架实现之Framework层Binder服务注册过程源码分析


Android Binder框架实现目录:

Android Binder框架实现之Binder的设计思想
Android Binder框架实现之何为匿名/实名Binder
Android Binder框架实现之Binder中的数据结构
Android Binder框架实现之Binder相关的接口和类
Android Binder框架实现之Parcel详解之基本数据的读写
Android Binder框架实现之Parcel read/writeStrongBinder实现
Android Binder框架实现之servicemanager守护进程
Android Binder框架实现之defaultServiceManager()的实现
Android Binder框架实现之Native层addService详解之请求的发送
Android Binder框架实现之Native层addService详解之请求的处理
Android Binder框架实现之Native层addService详解之请求的反馈
Android Binder框架实现之Binder服务的消息循环
Android Binder框架实现之Native层getService详解之请求的发送
Android Binder框架实现之Native层getService详解之请求的处理
Android Binder框架实现之Native层getService详解之请求的反馈
Android Binder框架实现之Binder Native Service的Java调用流程
Android Binder框架实现之Java层Binder整体框架设计
Android Binder框架实现之Framework层Binder服务注册过程源码分析
Android Binder框架实现之Java层Binder服务跨进程调用源码分析
Android Binder框架实现之Java层获取Binder服务源码分析


前言

  在前面的博客中Android Binder框架实现之Native层服务注册过程源码分析我们重点分析讲解了Android Native层的服务怎么注册的,但是我们知道Android中绝大部分的服务都是通过Java来实现的,那么Java层的服务是怎么注册到ServiceManager服务大管家中的呢,这个就是我们今天这个篇章要重点分析的了。通过前面Natvie层服务的注册过程中我们知道其大致可以分为三大步骤,而我们的Java层的服务注册过程也是如此,其三大步骤如下:

  • 注册服务请求的发送
  • 注册服务请求的处理
  • 注册服务请求的反馈

  而我们今天的篇章主要围绕服务的请求来开展分析讲解,并且由于本篇章牵涉的知识点比较多,各位小伙伴们可要打起十分精神了!好了不多说了,直接开干!

  • 注意:本篇的介绍是基于Android 7.xx平台为基础的,其中涉及的代码路径如下:
framework/base/core/java/android/os/
  ---IInterface.java
  ---IServiceManager.java
  ---ServiceManager.java
  ---ServiceManagerNative.java(内含ServiceManagerProxy类)

framework/base/core/java/android/os/
  ---IBinder.java
  ---Binder.java(内含BinderProxy类)
  ---Parcel.java

framework/base/core/java/com/android/internal/os/
  ---BinderInternal.java

framework/base/core/jni/
  ---AndroidRuntime.cpp
  ---android_os_Parcel.cpp
  ---android_util_Binder.cpp
  
frameworks/native/libs/binder/BpBinder.cpp
frameworks/native/include/binder/IBinder.h
frameworks/native/libs/binder/Binder.cpp
frameworks/native/include/binder/Parcel.h
frameworks/native/libs/binder/Parcel.cpp
frameworks/base/core/jni/core_jni_helpers.h
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
  • 为了后续的书写方便会将ActivityManagerService简述为AMS,ServiceManager简述为SM,ServiceManagerProxy简述为SMP,ServiceManagerNative简述为SMN,以上特此申明!


一. Android Binder整体概述

  在正式开始Android Framework层服务注册过程的源码分析前,还是老规矩磨刀不误砍柴工,先让我们来点前期知识储备再上马,更加事倍功倍!老子不打没有准备的仗!


1.1 Android Binder整体架构

  通过前面的博客Android Binder框架实现之Native层服务注册过程源码分析我们知道了Android Binder的核心框架层实现是在C++层实现的,但是我们也知道Android的绝大部分开发者和从业人员都是以Java语言为主的,所以Android的妈咪谷歌也充分考虑到了这种情况在Android Framework层也实现了一套Binder机制。看到这里你是不是有点蒙蔽了,难不成Android还搞了两种Binder机制!当然不是,这里Android Framework层的Binder和Native层的Binder是相辅相成,协同合作从而完成Android Binder的千秋大业的。

  前面遗留了一个小的知识点即Android Framework层和Native 层的Binder是怎么协同关联起来的呢?那就是Java和C++连接的万能膏药JNI技术了,Framework层的Binder通过JNI来调用(C/C++)层的Binder框架,从而为上层应用程序提供服务。 通过前面的博客我们知道在Native Binder层中,Binder采用的是C/S架构,分为Bn端(Server)和Bp端(Client)。而Java层在命名与架构上和Native也非常相近,基本上是无缝衔接,同样也实现了一套类似的IPC通信架构供应用开发使用(当然最后都是通过Native层的Binder框架实现的)。这里Framework层的Binder从另外一个层面来说,就是怼底层Native BInder的二次封装。Android BInder的整体框架图如下所示:

在这里插入图片描述


1.2 Android Binder类图

1.2.1 Android Native Binder类图

  在前面的博客Android Binder框架实现之Native层服务注册过程源码分析中我们知道了Android Native Binder的涉及的类图关系如下(前方高能,请做好心理准备,要理清楚这其中的关系得花费一费时间的):

在这里插入图片描述

  虽然我们在前面的博客对Android Native层的Binder类图关系有了详细的介绍,这里我们还是简单简单的归纳下:

  • BpBinder和BBinder共同继承与IBinder类,BpBinder是客户端进程中的Binder代理对象,BBinder是服务进程中用于IPC通信的工具对象,BpBinder类通过IPCThreadState类来与Binder驱动交互,访问服务进程中的BBinder,BpBinder代表了客户进程,BBinder代表了服务进程,数据从BpBinder发送到BBinder的整个过程就是Android系统的整个Binder通信过程,BpBinder与BBinder负责IPC通信,和上层业务并无关系。

  • Android系统的Binder通信实现了RPC远程调用,BpXXX和BnXXX则负责RPC远程调用的业务,XXX就代表不同的服务业务。BpXXX和BnXXX都实现了IXXX接口,IXXX定义了业务接口函数,BpXXX则是客户进程对服务进程中的BnXXX的影子对象,客户进程在调用服务进程中的某个接口函数时,只需调用BpXXX中的对应函数即可,BpXXX屏蔽了进程间通信的整个过程,让远程函数调用看起来和本地调用一样,这就是Android系统的Binder设计思想。

  • 进程要与Binder驱动交互,必须通过ProcessState对象来实现,ProcessState在每个使用了Binder通信的进程中唯一存在,其成员变量mDriverFD保存来/dev/binder设备文件句柄。对于某个服务来说,可能同时接受多个客户端的RPC访问,因此Android系统就设计了一个Binder线程池,每个Binder线程负责处理一个客户端的请求,对于每个Binder线程都存在一个属于自己的唯一IPCThreadState对象,IPCThreadState对象封装来Binder线程访问Binder驱动的接口,同一个进程中的所有Binder线程所持有的IPCThreadState对象使用线程本地存储来保存。

1.2.2 Android Framework层Binder类图

  那么Android Framework层的Binder类图关系是啥样的呢!怎么说呢和Android Native层Binder类图关系基本上是一一对应的,但是又有所差别,其基本类图关系如下:
在这里插入图片描述

  是不是看到这个有点茫然无助的感觉,这里我们先简单介绍下(等在后续分析代码的时候可以将涉及到的相关类按图索翼,就理解起来容易了):

  • XXXManager:通过ServiceManager.getService方法可以获取到IXXXManagerService.Stub.Proxy对象,譬如我们通过该方法能获取到Android提供的的PMS,AMS,PKMS等相关服务的代理端。,然后我们可以通过该代理对象调用相关服务端完成指定的操作

  • IXXXManagerService.Stub.Proxy:其成员变量mRemote指向BinderProxy对象,IXXXManagerService.Stub.Proxy调用的相关方法最终是交由mRemote来完成相关操作的(注意这里的mRemote也是一个一个代理,真正完成相关的是在服务端)

  • IXXXManagerService.Stub:其方法asInterface()返回的是IXXXManagerService.Stub.Proxy对象,XXXManager便是借助IXXXManagerService.Stub类来找到IXXXManagerService.Stub.Proxy

  • Binder:其成员变量mObject和方法execTransact()用于native方法,和Native层Binder的BBinder对应

  • BinderInternal:内部有一个GcWatcher类,用于处理和调试与Binder相关的垃圾回收。

  • IBinder:接口中常量FLAG_ONEWAY:客户端利用binder跟服务端通信是阻塞式的,但如果设置了FLAG_ONEWAY,这成为非阻塞的调用方式,客户端能立即返回,服务端采用回调方式来通知客户端完成情况。另外IBinder接口有一个内部接口DeathDecipient(死亡通告)。

  • BinderProxy: 该类实现了IBinder接口,和Android Native Binder层的BpBinder是对应关系,最后借助BpBinder完成Binder间的数据传输

是不是上面的描述的描述还是有点抽象,那么以我们Framework层的ServiceManager(Java层的服务大管家)为例,将相关的实现带入类图(通常涉及到具体的实现会对Proxy和Stub类进行一下封装)。

在这里插入图片描述


1.3 Android Binder的层级关系

  通过前面1.1章节我们知道Android Framework层和Native 层Binder之间是通过JNI串联起来的,那么这两者之间的层级关系如何呢?我这边小小的归纳总结了一下,可以用如下的两个图来表示:

在这里插入图片描述
在这里插入图片描述


1.4 Android Binder的类层级构架

  如果对Android Binder涉及的类图关系也进行一次分层划分,那么整个Binder从kernel至,Native,JNI,Framework层所涉及的全部类可以使用如下gityuan大神的图归纳总结一下:

在这里插入图片描述



二. Android Framework层Binder框架的初始化

  通过前面博客Android之init进程启动源码分析我们可知Android Native Binder的大管家servicemanager进程及其相关的Native Binder Service进程是在init进程解析相关的init.xx.rc文件中的service块时启动的。那么我们的Android Framework Binder框架又是何时启动的呢?也许对Android启动过程有一定了解的小伙伴们会说是在system_server进程启动过程中,此时会启动相关核心服务并将其加入ServiceManager中。其实不然在Android Zygote进程启动源码分析指南中,我们知道Zygote进程会调用AndroidRuntime::startReg函数注册一系列的JNI函数,而这其中就包括我们的Android Framework层的Binder框架层相关的JNI,此时就标志着Framework层BInder框架的启动,而不是到了system_server进程才开始启动的。至于为什么要在此处注册,这个就留个小伙伴们自行思考了?


2.1 AndroidRuntime::startReg

//AndroidRuntime.cpp
static const RegJNIRec gRegJNI[] = {
	...
	REG_JNI(register_android_os_Binder),//详见章节2.2
	...
}
int AndroidRuntime::startReg(JNIEnv* env)
{
	...
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
	...

    return 0;
}

  这个流程没有过多好讲的,就是注册一系列的JNI方法,其中gRegJNI是一个数组保存了一系列的待注册的JNI方法列表,而这其中就包括我们今天的主人公Framework Binder相关的JNI方法register_android_os_Binder。


2.2 register_android_os_Binder

  这里顺带说一句,如果对JNI有不熟悉的小伙伴,强烈建议先阅读一下JNI/NDK入门指南,带你开启JNI世界的大门!

//android_util_Binder.cpp
int register_android_os_Binder(JNIEnv* env)
{
	//注册Binder类的JNI方法
	if (int_register_android_os_Binder(env) < 0)//详见章节2.3
        return -1;

	//注册BinderInteral类的JNI方法
    if (int_register_android_os_BinderInternal(env) < 0)//详见章节2.4
        return -1;

	//注册BinderProxy类的JNI方法
    if (int_register_android_os_BinderProxy(env) < 0)//详见章节2.5
        return -1;
	...
    return 0;
}

  register_android_os_Binder函数比较简单,就是调用另外的函数继续进行相关的Binder的JNI方法的注册。
在继续分析相关的函数前,我们来先看一下frameworks/base/core/jni/core_jni_helpers.h中对JNI环境提供的基本函数进行二次封装的相关工具函数集合(为啥要先介绍,因为后续会用到这些工具函数),如下:

//frameworks/base/core/jni/core_jni_helpers.h

/*
*查找对应Java类
*/
static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
    jclass clazz = env->FindClass(class_name);
    LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
    return clazz;
}

/*
*返回类的实例(非静态)域的属性ID
*/
static inline jfieldID GetFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
                                       const char* field_signature) {
    jfieldID res = env->GetFieldID(clazz, field_name, field_signature);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name);
    return res;
}

/*
*返回Java类或者接口实例非静态方法的方法ID
*/
static inline jmethodID GetMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name,
                                         const char* method_signature) {
    jmethodID res = env->GetMethodID(clazz, method_name, method_signature);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find method %s", method_name);
    return res;
}
/*
*返回类的静态域的属性ID
*/
static inline jfieldID GetStaticFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
                                             const char* field_signature) {
    jfieldID res = env->GetStaticFieldID(clazz, field_name, field_signature);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name);
    return res;
}

/*
*返回类的静态方法ID
*/
static inline jmethodID GetStaticMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name,
                                               const char* method_signature) {
    jmethodID res = env->GetStaticMethodID(clazz, method_name, method_signature);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static method %s", method_name);
    return res;
}

/*
*基于局部引用创建一个全局引用
*/
template <typename T>
static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) {
    jobject res = env->NewGlobalRef(in);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to create global reference.");
    return static_cast<T>(res);
}

/*
*注册Java类对应的JNI方法
*/
static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className,
                                       const JNINativeMethod* gMethods, int numMethods) {
    int res = AndroidRuntime::registerNativeMethods(env, className, gMethods, numMethods);
    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
    return res;
}

2.3 int_register_android_os_Binder

  小伙伴们,这个标题没有错,不要怀疑我是把2.2的标题给复制了一篇粘贴过来了。

//android_util_Binder.cpp
const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
	//kBinderPathName = "android/os/Binder",用来查找kBinderPathName路径所属的类,即我们的Binder.java
	jclass clazz = FindClassOrDie(env, kBinderPathName);//关于该函数的功能参见2.2

	//将Java层的Binder类保存到mClass中
	gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);//关于该函数的功能参见2.2
	//将Java层execTransact()方法保存到mExecTransact变量
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");//关于该函数的功能参见2.2
	//将Java层的mObject属性保存到mObject中
	gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");//关于该函数的功能参见2.2

    return RegisterMethodsOrDie(
        env, kBinderPathName,
        gBinderMethods, NELEM(gBinderMethods));
}

  有了前面章节2.2最后关于JNI工具函数的的知识铺垫int_register_android_os_Binder函数应该理解起来就很简单了,主要干了两件事情:

  • 将Java层Binder类的相关信息保存到gBinderOffsets结构体中,供后面Framework层Binder框架使用(关于结构体gBinderOffsets详见2.3.1)
  • 调用RegisterMethodsOrDie函数,动态注册Java层Binder类的对应的JNI方法(具体注册了那些JNI方法详见2.3.2)

2.3.1 bindernative_offsets_t

//android_util_Binder.cpp
static struct bindernative_offsets_t
{
    jclass mClass;//   保存Java层Binder类信息
    jmethodID mExecTransact;// 保存Java层Binder类execTransact()方法ID

    jfieldID mObject;//保存Java层Binder类mObject属性域ID

} gBinderOffsets;

  这里的gBinderOffsets是全局静态结构体变量,该结构体主要的功能是用来设计保存Java层Binder类本身以及其成员方法execTransact()和成员属性mObject的,这为JNI层访问Java层提供通道。另外通过查询获取Java层Binder信息后保存到gBinderOffsets,而不是每次在需要使用Binder的时候再来进行相关的查找这样能大幅的提高效率,这是由于每次查询需要花费较多的CPU时间,尤其是频繁访问时,但是我们这里提前使用额外的结构体来保存这些信息,是以空间换时间的方法来达到提升效率(现在的Android设备存储空间都比较大,所以这些开销基本可以忽略不计)。

2.3.2 gBinderMethods

//jni.h
typedef struct {
    const char* name;//Java本地方法名称
    const char* signature;//Java本地方法签名
    void*       fnPtr;//对应的JNI函数
} JNINativeMethod;
//android_util_Binder.cpp
static const JNINativeMethod gBinderMethods[] = {
     /* name, signature, funcPtr */
    { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
    { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
    { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
    { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
    { "init", "()V", (void*)android_os_Binder_init },
    { "destroy", "()V", (void*)android_os_Binder_destroy },
    { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};

  这里的gBinderMethods是一个全局的结构体数组,通过RegisterMethodsOrDie将该结构体数组中的本地方法和JNI函数建立一一对应的关系,通俗的来讲就是JNI的动态注册。

  经过上面的操作以后建立了Java层到JNI层的访问通道,进而为打通Java层和Native层之间的通道做好了前期的准备,此时也标志着Framework层的Binder和Native 层Binder之间的连接桥梁已经开始进行施工了。


2.4 int_register_android_os_BinderInternal

//android_util_Binder.cpp
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, kBinderInternalPathName);

    gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");

    return RegisterMethodsOrDie(
        env, kBinderInternalPathName,
        gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

  有了前面的分析,这里的流程基本就是依葫芦画瓢了,int_register_android_os_BinderInternal函数主要干了如下两件事情:

  • 将Java层BinderInternal类的相关信息保存到gBinderInternalOffsets结构体中,供后面Framework层Binder框架使用(关于结构体gBinderInternalOffsets详见2.4.1)
  • 调用RegisterMethodsOrDie函数,动态注册Java层BinderInternal类的对应的JNI方法(具体注册了那些JNI方法详见2.4.2)

2.4.1 binderinternal_offsets_t

//android_util_Binder.cpp
static struct binderinternal_offsets_t
{
    
    jclass mClass;//保存Java层BinderInternal类信息
    jmethodID mForceGc;//保存Java层BinderInternal类forceBinder()方法ID

} gBinderInternalOffsets;

  这里的gBinderInternalOffsets是全局静态结构体变量,该结构体主要的功能是用来设计保存Java层BinderInternal类本身以及其成员方法forceBinder()信息。

2.4.2 gBinderInternalMethods

  这里的gBinderInternalMethods也是一个全局的结构体数组,保存的是BinderInternal类本地方法以及对应的JNI方法对应关系表,如下所示:

//jni.h
typedef struct {
    const char* name;//Java本地方法名称
    const char* signature;//Java本地方法签名
    void*       fnPtr;//对应的JNI函数
} JNINativeMethod;
//android_util_Binder.cpp
static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
    { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};

  分析至此,Framework层的BinderInternal类和JNI之间的关系已经建立,进而为后续Android Framewrok层Binder和Native层Binder关系的建立夯实了坚定的基础。


2.5 int_register_android_os_BinderProxy

//android_util_Binder.cpp
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
     //gErrorOffsets保存了Error类信息
    jclass clazz = FindClassOrDie(env, "java/lang/Error");
    gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);

    //gBinderProxyOffsets保存了BinderProxy类的信息
    //其中kBinderProxyPathName = "android/os/BinderProxy"
    clazz = FindClassOrDie(env, kBinderProxyPathName);
    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
    gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
            "(Landroid/os/IBinder$DeathRecipient;)V");

    gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
    gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
                                                "Ljava/lang/ref/WeakReference;");
    gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
    
	//gClassOffsets保存了Class.getName()方法
    clazz = FindClassOrDie(env, "java/lang/Class");
    gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");

    return RegisterMethodsOrDie(
        env, kBinderProxyPathName,
        gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

  依然是老套路,还是来个依葫芦画瓢算了,int_register_android_os_BinderProxy函数主要干了如下两件事情:

  • 将Java层BinderProxy类的相关信息保存到gBinderProxyOffsets结构体中,供后面Framework层Binder框架使用(关于结构体gBinderProxyOffsets详见2.5.1)
  • 调用RegisterMethodsOrDie函数,动态注册Java层BinderProxy类的对应的JNI方法(具体注册了那些JNI方法详见2.4.2)

2.5.1 binderproxy_offsets_t

//android_util_Binder.cpp
static struct binderproxy_offsets_t
{
    
    jclass mClass;
    jmethodID mConstructor;
    jmethodID mSendDeathNotice;

    
    jfieldID mObject;
    jfieldID mSelf;
    jfieldID mOrgue;

} gBinderProxyOffsets;

  这里的gBinderProxyOffsets是全局静态结构体变量,该结构体主要的功能是用来设计保存Java层BinderProxy类本身以及其成员方法ID和变量域ID等相关信息。

2.5.2 gBinderProxyMethods

  这里的gBinderProxyMethods也是一个全局的结构体数组,保存的是BinderProxy类本地方法以及对应的JNI方法对应关系表,如下所示:

//jni.h
typedef struct {
    const char* name;//Java本地方法名称
    const char* signature;//Java本地方法签名
    void*       fnPtr;//对应的JNI函数
} JNINativeMethod;
//android_util_Binder.cpp
static const JNINativeMethod gBinderProxyMethods[] = {
     /* name, signature, funcPtr */
    {"pingBinder",          "()Z", (void*)android_os_BinderProxy_pingBinder},
    {"isBinderAlive",       "()Z", (void*)android_os_BinderProxy_isBinderAlive},
    {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
    {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},//这个函数是重点
    {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
    {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
    {"destroy",             "()V", (void*)android_os_BinderProxy_destroy},
};

  分析至此,Framework层的BinderProxy类和JNI之间的关系已经建立,进而为后续Android Framewrok层Binder和Native层Binder关系的建立夯实了坚定的基础。


2.6 Android Framework层Binder框架的初始化小结

  到这里Android Framework层Binder框架在Zygote进程中的初始化也告一段落了,通过这一些列的初始化工作Android Framework层的Binder和JNI建立起了相关的关联,进而为后续的和Native Binder关联建立起了通道。此时关于Android Framework层Binder相关类和JNI之间的联系,可以使用下述的图示来表示,如下:

在这里插入图片描述



三. Framework层服务注册

  在博客中Android system_server启动大揭秘我们讲述了在system_server启动的过程中会启动一系列的Android Framework层的BInder服务,这里我们以AMS(的注册为例来说明,Android Framework层的Binder服务是怎么注册到servicemanager中的(注意这里我们只重点关注AMS的注册,而对于AMS本身的功能不做过多分析和说明)。

  在AMS服务启动的setSystemProcess阶段会将自己注册到servicemanager进程中,源码如下:

//ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
       ...
	   public void setSystemProcess() {
	   		...
	   		ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);//详细分析过程见3.1
	   		...
	   }
	   ...

3.1 ServiceManager.addService

	//ServiceManager.java
    public static void addService(String name, IBinder service, boolean allowIsolated) {
        try {
        	/**
        	*看着精简的两句代码,蕴含着无限的能力
        	*这里会分为两个步骤来分解:
        	*一:getIServiceManager()获取ServiceManagerProxy代理端,详见章节3.2
        	*二:调用ServiceManagerProxy代理端addService方法注册服务,详见章节3.5
        	*/
            getIServiceManager().addService(name, service, allowIsolated);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

  ServiceManager.addService会调用getIServiceManager()方法获取SMN的代理端SMP,并且调用其方法addService将AMS注册到servicemanager中。


3.2 ServiceManager.getIServiceManager

//ServiceManager.java
private static IServiceManager sServiceManager;

    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

     
        //等价于new ServiceManagerProxy(new BinderProxy(0))
        /**
       	*看着精简的两句代码,蕴含着无限的能力,其实我是想吐糟谷歌你为啥就不能好好的写代码呢
       	*这里会分为两个步骤来分解:
       	*一:BinderInternal.getContextObject(),创建new BinderProxy(0),详见章节3.2.1
       	*二:调用ServiceManagerNative.asInterface(),创建SMP服务代理端,详见章节3.3
       	*/
        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

  该段代码短小精悍,但是却孕育着无限的力量!getIServiceManager采用了单例模式最终获取的是new ServiceManagerProxy(new BinderProxy(0)),不要问我是怎么来的,我只能说路途艰辛且行且珍惜!

3.2.1 BinderInternal.getContextObject

//BinderInternal.java
public class BinderInternal {
	...
	public static final native IBinder getContextObject();
	...
}

  一看就是一个本地方法,通过前面的章节我们知道在android_util_Binder.cpp中完成了对BinderInternal 本地方法的注册,其对应的JNI函数为android_os_BinderInternal_getContextObject,让我们前往一探究竟。

//android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
	//此处返回的是new BpBinder(0)
	sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
	//此处返回的是new BinderProxy(0)
    return javaObjectForIBinder(env, b);//详见2.3.2
}

  关于ProcessState::self()->getContextObject(NULL)这里就不展开进行具体相关的分析了,详见博客Android Binder框架实现之defaultServiceManager()的实现的2.3章节,总之最后如上代码会转换成new BpBinder(0)返回回来。

3.2.2 javaObjectForIBinder


//Binder.cpp
bool IBinder::checkSubclass(const void* /*subclassID*/) const
{
    return false;
}


//android_util_Binder.cpp
//此处的入参val是BpBinder
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    if (val == NULL) return NULL;

    if (val->checkSubclass(&gBinderOffsets)) {//返回false,这个得val是BpBinder其父类是IBinder并且没有重写checkSubclass,所以直接返回false不会走该分支
        // One of our own!
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
        return object;
    }

    // For the rest of the function we will hold this lock, to serialize
    // looking/creation/destruction of Java proxies for native Binder proxies.
    AutoMutex _l(mProxyLock);

    // Someone else's...  do we know about it?
    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
    if (object != NULL) {//第一次object为null
        jobject res = jniGetReferent(env, object);
        if (res != NULL) {
            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
            return res;
        }
        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
        android_atomic_dec(&gNumProxyRefs);
        val->detachObject(&gBinderProxyOffsets);
        env->DeleteGlobalRef(object);
    }

	//创建BinderProxy对象
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
        // The proxy holds a reference to the native object.
        //BinderProxy.mObject成员变量记录BpBinder对象
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        val->incStrong((void*)javaObjectForIBinder);

        // The native object needs to hold a weak reference back to the
        // proxy, so we can retrieve the same proxy if it is still active.
        jobject refObject = env->NewGlobalRef(
                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
		//将BinderProxy对象信息附加到BpBinder的成员变量mObjects中
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);

        // Also remember the death recipients registered on this proxy
        sp<DeathRecipientList> drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);
		//BinderProxy.mOrgue成员变量记录死亡通知对象
        env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));

        // Note that a new object reference has been created.
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }

    return object;
}

  还记得大明湖畔的夏雨荷吗,走错片场了!还记得章节2.5 int_register_android_os_BinderProxy吗,里面有将BinderProxy类的相关信息保存到了gBinderProxyOffsets结构体中,而在这里正是借助这个gBinderProxyOffsets结构体保存的信息,以BpBinder(0)为参数在C++层通过JNI操作创建Java层的BinderProxy实例对象,并把BpBinder对象地址保存到BinderProxy.mObject成员变量中。至此BinderInternal.getContextObject()就已经分析完成了,将其扩展开来可以得到如下代码:

BinderInternal.getContextObject() = new BinderProxy(0);

3.3 ServiceManagerNative.asInterface

//ServiceManagerNative.java
public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
	...
	//注意这里的入参是BinderProxy
    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        //由于入参为BinderProxy,其方法queryLocalInterface返回为null
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);//详见3.3.1
        if (in != null) {
            return in;
        }
        
        return new ServiceManagerProxy(obj);//详见3.3.2
    }
    ...
}

  我们通过前面的分析可知ServiceManagerNative.asInterface的入参为BinderProxy,然后调用其方法queryLocalInterface返回为null,所以ServiceManagerNative.asInterface(new BinderProxy(0))最后等价为:

ServiceManagerNative.asInterface(new BinderProxy(0)) = ServiceManagerProxy(new BinderProxy(0))

3.3.1 BinderProxy.queryLocalInterface

//BinderProxy.java
final class BinderProxy implements IBinder {
	...
	public IInterface queryLocalInterface(String descriptor) {
        return null;
    }
    ...
}

  无需多言,只是为了验证前面的结论!

3.3.2 ServiceManagerProxy的构造初始化

//ServiceManagerNative.java
class ServiceManagerProxy implements IServiceManager {
	//这里的入参为BinderProxy(0)
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }
   }

  ServiceManagerProxy的构造比较简单,就是将mRemote指向入参BinderProxy(0),该BinderProxy对象对应于BpBinder(0),其作为Binder代理端,指向Native层大管家service Manager。


3.4 getIServiceManager小结

//ServiceManager.java
private static IServiceManager sServiceManager;

    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

     
        //等价于new ServiceManagerProxy(new BinderProxy(0))
        /**
       	*看着精简的两句代码,蕴含着无限的能力,其实我是想吐糟谷歌你为啥就不能好好的写代码呢
       	*这里会分为两个步骤来分解:
       	*一:BinderInternal.getContextObject(),创建new BinderProxy(0)
       	*二:调用ServiceManagerNative.asInterface(),创建SMP服务代理端
       	*/
        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

  至此getIServiceManager就分析完成了,其基本功能就是获取SMP服务端代理对象SMP,其获取流程可以分为如下两步:

  • BinderInternal.getContextObject() 创建一个Java层的BinderProxy(0)对象,该对象与C++层的BpBinder(0)一一对应;

  • ServiceManagerNative.asInterface(obj) 创建一个Java层面的ServiceManagerProxy代理对象,作用与C++层的BpServiceManager相同。

对于上述的流程归纳总结起来即先创建一个BpBinder(0)用于和Binder驱动交互,接着以BpBinder(0)为参数创建Java层的BinderProxy(0)用于数据的传输,接着最后以BinderProxy(0)为参数创建ServiceManagerProxy用于数据的打包。上述对应的关系可以详见下列示意图:

在这里插入图片描述


3.5 ServiceManagerProxy.addService

	//ServiceManagerProxy.java
	//这里的入参为三个分别是服务的名字(主要供第三方通过name想servicemanager大管家查询),服务的实体
    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
		//最终等价于writeStrongBinder(new JavaBBinder(env, obj))
        data.writeStrongBinder(service);//详见3.6
        data.writeInt(allowIsolated ? 1 : 0);
		//成员变量mRemote指向BinderProxy
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//详见3.8
        reply.recycle();
        data.recycle();
    }

  回到章节3.1,如果说前面的分析是开胃菜,那么到这里就要开始正餐了。我们调用getIServiceManager得到了SMP,接着继续调用其方法addService注册Framework层系统服务。其中主要涉及到了Parcel对数据的打包和传输,关于Parcel对基本数据的打包和写入可以详见博客Android Binder框架实现之Parcel详解一,这里我们会重点关注Binder类型对象的写入和Parcel类型数据的transact。


3.6 Parcel.writeStrongBinder

//Parcel.java
private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
 public final void writeStrongBinder(IBinder val) {
     nativeWriteStrongBinder(mNativePtr, val);
 }

  在正式开始该流程分析前,我们先奉上writeStrongBinder整体式时序图,既是为了对后续流程的一个概述,也是一个小结:
在这里插入图片描述

  依然是老套路,通过JNI调用C++层的Parcel实现Binder对象的写入。

3.6.1 android_os_Parcel_writeStrongBinder

//android_os_Parcel.cpp
//注意此处的入参object是Framework层Binder服务实体
 static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);//强制将nativePtr转换成Parcel对象,这个见怪不怪了
    if (parcel != NULL) {
		//等价于parcel->writeStrongBinder(new JavaBBinder(env, obj));
		/**
		*我只能说此处代码短小精悍,力量无穷啊,此处的代码逻辑分为两步
		*第一:调用ibinderForJavaObject创建JavaBBinder,详见章节3.6.2
		*第二:调用C++层的Parcel对象函数writeStrongBinder写入JavaBBinder,这个内容有点只能详见3.7了
		*/
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
        }
    }
}

  谷歌的Binder是设计思想是如此的巧妙,可是为什么代码逻辑排版就不能好好的整理一下呢!android_os_Parcel_writeStrongBinder函数逻辑看着比较简单,也就干了两件事情(但是分析起来你懂的):

  • 调用ibinderForJavaObject创建JavaBBinder
  • 调用C++层的Parcel对象函数writeStrongBinder写入JavaBBinder

3.6.3 Binder.java的初始化

  在正式开始该函数分析前,让我们回过头捋一捋我们是要将什么Framework层Binder服务注册到servicemanager中的,对了是AMS,我们看看其继承和实现关系,如下:

//ActivityManagerService.java 
public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        ...
}

//ActivityManagerNative.java
//这里的父类Binder是重点
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
	...
}

  平谈无奇,没有啥重点!那还能咋样呢,继续往下分析Binder.java的构造方法,逻辑如下:

//Binder.java
private native final void init();
public class Binder implements IBinder {
	    public Binder() {
        init();

		...
    }
}

  又是老套路,调用到了JNI层的函数,如下所示:

//android_util_Binder.cpp
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
    JavaBBinderHolder* jbh = new JavaBBinderHolder();//构建一个JavaBBinderHolder对象
    if (jbh == NULL) {
        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
        return;
    }
    ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
	//增加引用计数
    jbh->incStrong((void*)android_os_Binder_init);
	/*
	*将JavaBBinderHolder对象保存在gBinderOffsets.mObject中,此时的gBinderOffsets.mObject已经在Zygote启动中和Binder.java中的mObject绑定了
	*/
    env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}

  这个函数还干了一点事情,捯饬捯饬来说可以分为两步:

  • 构建一个JavaBBinderHolder对象
  • 将JavaBBinderHolder对象保存在gBinderOffsets.mObject中,此时的gBinderOffsets.mObject已经在Zygote启动中和Binder.java中的mObject绑定了

此时的你我想会有一个疑问就是gBinderOffsets这些的初始化不都是在Zygote进程中吗,我注册AMS服务是在system_server进程中进行的,这个gBinderOffsets能用不。我只能说孩子不要忘了你来自那里,当然不是天上了,那怕你贵为system_server进程你不也是Zygote进程孵化出来的,我们的Zygote进程也是无私的你继承了其所有也包括上面初数化的相关变量空间。

  最后我要说一句,真的,我不是闲的蛋疼才加上上面的描述的,更加不是为了凑字数的,再说也没有稿费可骗啊!真的你们要相信我,接着继续分析ibinderForJavaObject。

3.6.4 ibinderForJavaObject

//android_os_Parcel.cpp
//此时的入参obj为Binder.java实例对象
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    if (obj == NULL) return NULL;
	//这里的IsInstanceOf和Java中的instanceof方法有点类似
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {//检测是否是Java层Binder类或者子类
        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            env->GetLongField(obj, gBinderOffsets.mObject);//以Binder(Java层)为参数生成JavaBBinderHolder(C++层),详见3.6.5
        return jbh != NULL ? jbh->get(env, obj) : NULL;//详见章节3.6.6
    }

    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {//检测是否是Java层BinderProxy类或者子类
        return (IBinder*)
            env->GetLongField(obj, gBinderProxyOffsets.mObject);
    }

    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
    return NULL;
}

  是吗,真的没有骗你吗!通过前面我们知道AMS是Binder的子类,所以会走第一个分支即此时的入参obj和gBinderOffsets.mClass保存的Bindre信息是属于同一类型都是Binder类型,这里的JNI提供的函数IsInstanceOf和Java层的instanceof方法类似即判断两个对象是否属于同一个类或者及其子类。接着根据Binde(Java)生成JavaBBinderHolder(C++)对象,然后调用其get返回一个IBinder对象实例。

3.6.5 JavaBBinderHolder类初始化

//android_util_Binder.cpp,又是在这个文件里面,你干的活还真多
class JavaBBinderHolder : public RefBase
{
public:
	...

    sp<JavaBBinder> getExisting()
    {
        AutoMutex _l(mLock);
        return mBinder.promote();
    }

private:
    Mutex           mLock;
    wp<JavaBBinder> mBinder;//注意这里的指针是wp类型的,即C++中的弱引用,可能会被回收
};

  JavaBBinderHolder它是如此朴实无华,没有构造函数,既然你这么绝情也不要怪我无意,老子不分析你了。

3.6.6 JavaBBinderHolder::get

	//android_util_Binder.cpp
    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
    {
        AutoMutex _l(mLock);
        sp<JavaBBinder> b = mBinder.promote();//判断是会被回收或者已经创建了
        if (b == NULL) {
            b = new JavaBBinder(env, obj);//创建JavaBBinder,注意参数obj为Binder.java实例对象,详见3.6.7
            mBinder = b;
            ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
        }

        return b;
    }

  通过前面的章节我们知道JavaBBinderHolder有一个名为mBinder的JavaBBinder对象的弱指针(C++层),mBinder是否被重新赋值的关键有两点第一其是否是第一次进入,第二由于mBinder是一个wp类型弱引用所以可能被系统垃圾回收机制回收,所以每次使用它的时候必须先行判断一下。

3.6.7 JavaBBinder

//android_util_Binder.cpp
class JavaBBinder : public BBinder
{
public:
    JavaBBinder(JNIEnv* env, jobject object)
        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
    {
        ALOGV("Creating JavaBBinder %p\n", this);
        android_atomic_inc(&gNumLocalRefs);
        incRefsCreated(env);
    }
}

  这里注意JavaBBinder的父类为BBinder,并且以传递过来的参数object构建一个全局的mObject引用(object为Java层的Binder.java)。

到这里我们的parcel->writeStrongBinder(ibinderForJavaObject(env, object))源码就等价于下面的转换了(等价交换):

parcel->writeStrongBinder(ibinderForJavaObject(env, object)) = parcel->writeStrongBinder(new JavaBBinder(env, obj));

3.6.8 JavaBBinder JavaBBinderHolder Binder关系小结

  分析至此,各位小伙们是不是对于JavaBBinder (C++),JavaBBinderHolder(C++),Binder(Java)三者之间的关系有理不断剪还乱的感觉!真的不要怪Android的妈咪谷歌,它这么做也是为了世界和平!这里我们可以使用下述的示意图来表述三者之间的关系:

在这里插入图片描述
上述三者是怎么关勾搭上的呢(不,关联上的),这要回到3.6.4 ibinderForJavaObject说起了:

  • 在该函数中首先将Binder.java构造方法创建的JavaBBinderHolder(C++)捯饬出来,
  • 接续创建一个JavaBBinder对象,并将传递过来的Framework层的Binder服务实例对象作为参数创建Java层服务Binder对象的全局引用,并将其保存到JavaBBinder对象的mObject变量中
  • 返回创建的JavaBBinder对象实例

是不是还是有点一脸蒙蔽,但是既然现在三者之间的关系已经创建既成事实了,那么就着这三者之间的关系再来捋一捋:

  • Android Framework层的Binder服务必须继承于Binder类,而我们的Binder对象在构造服务时,会首先在C++层构造一个JavaBBinderHolder对象,并将该对象的指针保存到Java层的服务的mObject变量中,即建立起了Binder(Java)到JavaBBinderHolder(C++)之间的关系了

  • 而我们的C++层的JavaBBinderHolder对象通过成员变量mBinder指向一个C++层的JavaBBinder对象,JavaBBinder类继承于BBinder类,是服务在C++层的表现形式,此时建立起了JavaBBinderHolder(C++)和JavaBBinder(C++)之间的关系了

  • 而我们的C++层的JavaBBinder对象又通过成员变量mObject指向Java层的Binder服务对象,即建立起了Binder(Java)和JavaBBinder(C++)之间的关联了

对于这三者之间的关系,我只想说一句话造孽啊!


3.7 Parcel::writeStrongBinder

  在前面的博客Android Binder框架实现之Native层服务注册过程源码分析中此处的源码相关逻辑其实已经有分析了,但是为了整体框架的完整和从上到下的贯通我们还是简单过一下(其实我是舍不得各位小伙伴们)!

//Parcel.cpp
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)//注意这里的入参val为JavaBBinder
{
    return flatten_binder(ProcessState::self(), val, this);//详见3.7.1
}

  该函数没有多说的直接调用flatten_binder写将入参参数JavaBBinder写入C++层Parcel容器中。

3.7.1 flatten_binder扁平化处理

//Parcel.cpp
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
    const sp<IBinder>& binder, Parcel* out)
{
    flat_binder_object obj;

    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    if (binder != NULL) {
        IBinder *local = binder->localBinder();
        if (!local) {
            BpBinder *proxy = binder->remoteBinder();
            if (proxy == NULL) {
                ALOGE("null proxy");
            }
            const int32_t handle = proxy ? proxy->handle() : 0;
            obj.type = BINDER_TYPE_HANDLE;//远程Binder
            obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
            obj.handle = handle;//记录Binder代理的句柄
            obj.cookie = 0;
        } else {
            obj.type = BINDER_TYPE_BINDER;//本地Binder进入该分支
            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
            obj.cookie = reinterpret_cast<uintptr_t>(local);//记录Binder实体的指针
        }
    } else {
        obj.type = BINDER_TYPE_BINDER;
        obj.binder = 0;
        obj.cookie = 0;
    }

    return finish_flatten_binder(binder, obj, out);
}

  我们这里的入参binder为JavaBBinder对象实例,我们回忆回忆其继承关系,其关系如下

IBinder(C++) ----> BBinder(C++) ---> JavaBBinder(C++)

而我们的BBinder的localBinder函数实现如下:

//Binder.cpp
BBinder* BBinder::localBinder()
{
    return this;
}

所以精简过后的flatten_binder函数如下:

//Parcel.cpp
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
    const sp<IBinder>& binder, Parcel* out)
{
    flat_binder_object obj;

    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    if (binder != NULL) {
        IBinder *local = binder->localBinder();
        if (!local) {
			...
        } else {
            obj.type = BINDER_TYPE_BINDER;//本地Binder进入该分支
            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
            obj.cookie = reinterpret_cast<uintptr_t>(local);//记录Binder实体的指针
        }
    } else {
		...
    }

    return finish_flatten_binder(binder, obj, out);//详见章节3.7.2
}

此时重要大哥flat_binder_object 要上场了,我们可以将其理解为它是用来专门描述BBinder对象的,将其带入实际代码,会得到如下的逻辑:

  • flat_binder_object结构体变量obj其成员type被赋值为BINDER_TYPE_BINDER,即表示此时的obj是一个BIndere实体对象
  • flat_binder_object结构体变量obj其成员binder记录Binder弱引用指针地址
  • flat_binder_object结构体变量obj其成员cookie 记录Binder实体指针地址

此时此刻关于flatten_binder扁平化的分析已经分析完毕了,此时flat_binder_object结构体中数据的映射关系如下:

在这里插入图片描述

3.7.2 finish_flatten_binder写入扁平化BInder数据

//Parcel.cpp
inline static status_t finish_flatten_binder(
    const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
{
    return out->writeObject(flat, false);
}

  好了这里真的不能扩展了,我们只需要知道此时会将扁平化的Binder实体数据写入Parcel的存储结构中,具体的真的小伙伴们只能移步到Android Binder框架实现之Native层服务注册过程源码分析中了(因为有些小伙们,可能只是向了解Framewrok层的实现)。


3.8 BinderProxy.transact

  假如时光倒流,你会做什么!这里给你一次机会让我们倒流到章节3.5你会做什么呢!

	//ServiceManagerProxy.java
	//这里的入参为三个分别是服务的名字(主要供第三方通过name想servicemanager大管家查询),服务的实体
    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
		//最终等价于writeStrongBinder(new JavaBBinder(env, obj))
        data.writeStrongBinder(service);//此处已经分析完毕,等价于parcel->writeStrongBinder(new JavaBBinder(env, obj));
        data.writeInt(allowIsolated ? 1 : 0);
		//成员变量mRemote指向BinderProxy
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//该轮到我上场了,这里通过前面的章节分析知道此时的mRemote指向BinderProxy,详见3.8.1
        reply.recycle();
        data.recycle();
    }

通过前面的分析,此时我们的ServiceManagerProxy代理服务端变量mRmote指向BinderProxy(0),而BinderProxy(0)又将会指向BpBinder(0),即数据结构关系如下:

在这里插入图片描述

3.8.1 BinderProxy.transact

	//Parcel.java
    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");//对Parcel做检查
        return transactNative(code, data, reply, flags);//一看命名就是老讨论,通过JNI调用到C++层,详见3.8.2
    }
	//检测大小是否超过800K
    static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
        if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
            // Trying to send > 800k, this is way too much
            StringBuilder sb = new StringBuilder();
            sb.append(msg);
            sb.append(": on ");
            sb.append(obj);
            sb.append(" calling ");
            sb.append(code);
            sb.append(" size ");
            sb.append(parcel.dataSize());
            sb.append(" (data: ");
            parcel.setDataPosition(0);
            sb.append(parcel.readInt());
            sb.append(", ");
            sb.append(parcel.readInt());
            sb.append(", ");
            sb.append(parcel.readInt());
            sb.append(")");
            Slog.wtfStack(TAG, sb.toString());
        }
    }

  依然是老套路,还是原来的配方还是原来的味道,通过JNI调用到C++层进行相关的处理。

3.8.2 android_os_BinderProxy_transact

//android_util_Binder.cpp
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
    if (dataObj == NULL) {
        jniThrowNullPointerException(env, NULL);
        return JNI_FALSE;
    }
	
	//Java Parcel转为Native 层的Parcel
    Parcel* data = parcelForJavaObject(env, dataObj);
    if (data == NULL) {
        return JNI_FALSE;
    }
    Parcel* reply = parcelForJavaObject(env, replyObj);
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }

	//这里得到存储在gBinderProxyOffsets.object中的BpBinder
    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
        return JNI_FALSE;
    }


    status_t err = target->transact(code, *data, reply, flags);//3.8.3
	...
    if (err == NO_ERROR) {
        return JNI_TRUE;
    } else if (err == UNKNOWN_TRANSACTION) {
        return JNI_FALSE;
    }
}

  该部分源码的逻辑可以分为如下三部分,如下:

  • 将Java层的Parcel对象转变成C++层的
  • 取出保存在gBinderProxyOffsets.mObject中的BpBinder对象
  • 调用BpBinder对象实例的transact方法传递打包好的Parcel数据

3.8.3 android_os_BinderProxy_transact

//BpBinder.cpp
status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    if (mAlive) {
    	间接调用IPCThreadState的transact函数来发送数据
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

  真的不能往下再深入了,先到这里了,关于后续的代码分析各位真的只能移步到Android Binder框架实现之Native层服务注册过程源码分析中了,那里会有更加广阔的天地来接着分析。


3.8 Binder驱动对注册服务的处理

  好吗,这里还是简单的介绍一下Binder驱动层怎么对通过BpBinder(0)发送过来的注册请求信息的处理,Binder驱动处理该流程如下:

  • Binder驱动在内核空间中为传输的Binder实体对象创建对应的Binder节点
  • Binder驱动在内核空间中为servicemanager进程创建引用该服务Binder节点的Binder引用对象
  • 修改Binder驱动中传输的flat_binder_object的类型和描述符
  • 然后唤醒servicemanager进程进行下一步的处理

3.9 servicemanager进程对注册服务的处理

  servicemanager进程被唤醒之后,会对通过Binder驱动发送过来的注册服务数据做出如下的处理:

  • 将服务名称和为servicemanager进程创建的Binder引用对象的描述符注册到servicemanager进程中的svclist结构体数组中
  • 然后servicemanager进程将处理结果通过BInder驱动反馈给注册服务进程system_server


四.Framework层Binder服务注册过程总结

  各位乡亲父老们,关于Framework层服务注册过程源码分析就至此了,下面我们对整个的流程分析一下复盘一下,其实Framework层Binder服务的核心代码可以使用如下几句代码概述,真的是有几句:

	//ServiceManagerNative.java
    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
		//最终等价于writeStrongBinder(new JavaBBinder(env, obj))
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
		//成员变量mRemote指向BinderProxy
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//通过Binder驱动传递数据
        reply.recycle();
        data.recycle();
    

  以上简简单单的几句代码,理解分析起来却是并不简单,经过重重险阻最后的最后会将一切托付给Native层的BpBInder带着全村的希望将注册服务的请求发送给Binder驱动来进行处理。

  而我们知道Framework层Binder服务注册会交由ServiceManagerProxy服务代理端来处理,让我们跳出代码思维站在设计者的思路来考虑ServiceManagerProxy的设计思路,很多人说Binder晦涩难懂,主要是Android的设计者将其业务层,通信层糅合了在一起,让我们站在这个高度来看看ServiceManagerProxy是怎么来注册服务的,如下:

在这里插入图片描述
这里有一点需要注意地是BinderProxy并没有真正的完成数据的传输,最后是借助Binde驱动来完成的。并且这里也可以看到ServiceManagerProxy的设计是一层嵌套一层的,对于上层开发者来说Android 的Binder设计只是暴露了业务层的相关逻辑接口,并没有暴露通信层的相关逻辑,我想这么做的原因也是为了让应用开发者更快的入手,只用关心业务层的实现!但是这种设计思想对于想真的理清Binder设计的小伙伴们来说还是有难度的。

  本篇博客重点的分析了Framework层Binder服务注册过程请求的发送流程,但是这个只是整个服务注册的一小部分,因为还牵涉服务注册请求的处理,请求的反馈等流程,这里我简单的总结一下Framework层Binder服务注册过程的全部流程如下:

  • 在Java层将服务名称及服务对应的Binder对象写入到Parcel对象中;
  • 在C++层为该服务创建对应的Binder实体对象JavaBBinder,并且将上层发送过来的数据序列化到C++的Parcel对象中,同时使用flat_binder_object结构体来描述Binder实体对象
  • 通过servicemanager的Binder代理对象BpBinder(0)将数据发送到Binder驱动中
  • Binder驱动在内核空间中为传输的Binder实体对象创建对应的Binder节点
  • Binder驱动在内核空间中为servicemanager进程创建引用该服务Binder节点的Binder引用对象
  • 修改Binder驱动中传输的flat_binder_object的类型和描述符
  • 将服务名称和为servicemanager进程创建的Binder引用对象的描述符注册到servicemanager进程中的svclist结构体数组中
  • 然后servicemanager进程将处理结果通过BInder驱动反馈给注册服务进程system_server

其中上述流程涉及的system_server进程和servicemanager进程之间的关系图如下:

在这里插入图片描述



写在最后

  至此Framework层服务注册过程源码分析基本就告一段落了,虽然源码分析over了!但是我相信基本没有小伙伴可以一口气可以看完,并且各位小伙伴们也不要指望能一下子理解清楚,这个过程中一定会有迷惘失落,有高兴也会有高兴。不要问我怎么知道的,因为我也是这么过来的。好了就到这里了,欢迎小伙伴们评论和点赞,后续篇章继续分析Framework层Binder服务的获取详见博客Android Binder框架实现之Java层获取Binder服务源码分析

猜你喜欢

转载自blog.csdn.net/tkwxty/article/details/108086456