Android(安卓)Binder框架实现之Framework层服务注册过程源码分析
Android Binder框架实现之Framework层服务注册过程源码分析
前言
在前面的博客中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.javaframework/base/core/java/com/android/internal/os/ ---BinderInternal.javaframework/base/core/jni/ ---AndroidRuntime.cpp ---android_os_Parcel.cpp ---android_util_Binder.cpp frameworks/native/libs/binder/BpBinder.cppframeworks/native/include/binder/IBinder.hframeworks/native/libs/binder/Binder.cppframeworks/native/include/binder/Parcel.hframeworks/native/libs/binder/Parcel.cppframeworks/base/core/jni/core_jni_helpers.hframeworks/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.cppstatic 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.cppint 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.cppconst char* const kBinderPathName = "android/os/Binder";static int int_register_android_os_Binder(JNIEnv* env){//kBinderPathName = "android/os/Binder",用来查找kBinderPathName路径所属的类,即我们的Binder.javajclass 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.cppstatic 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.htypedef struct { const char* name;//Java本地方法名称 const char* signature;//Java本地方法签名 void* fnPtr;//对应的JNI函数} JNINativeMethod;//android_util_Binder.cppstatic 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.cppconst 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.cppstatic 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.htypedef struct { const char* name;//Java本地方法名称 const char* signature;//Java本地方法签名 void* fnPtr;//对应的JNI函数} JNINativeMethod;//android_util_Binder.cppstatic 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.cppconst 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, "" , "()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.cppstatic 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.htypedef struct { const char* name;//Java本地方法名称 const char* signature;//Java本地方法签名 void* fnPtr;//对应的JNI函数} JNINativeMethod;//android_util_Binder.cppstatic 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.javapublic 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.javaprivate 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.javapublic class BinderInternal {...public static final native IBinder getContextObject();...}
一看就是一个本地方法,通过前面的章节我们知道在android_util_Binder.cpp中完成了对BinderInternal 本地方法的注册,其对应的JNI函数为android_os_BinderInternal_getContextObject,让我们前往一探究竟。
//android_util_Binder.cppstatic 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.cppbool IBinder::checkSubclass(const void* /*subclassID*/) const{ return false;}//android_util_Binder.cpp//此处的入参val是BpBinderjobject 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.javapublic 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.javafinal class BinderProxy implements IBinder {...public IInterface queryLocalInterface(String descriptor) { return null; } ...}
无需多言,只是为了验证前面的结论!
3.3.2 ServiceManagerProxy的构造初始化
//ServiceManagerNative.javaclass 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.javaprivate 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.javaprivate static native void nativeWriteStrongBinder(long nativePtr, IBinder val); public final void writeStrongBinder(IBinder val) { nativeWriteStrongBinder(mNativePtr, val); }
依然是老套路,通过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.javaprivate native final void init();public class Binder implements IBinder { public Binder() { init();... }}
又是老套路,调用到了JNI层的函数,如下所示:
//android_util_Binder.cppstatic 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
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)。
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.cppstatus_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.cppstatus_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.cppBBinder* BBinder::localBinder(){ return this;}
所以精简过后的flatten_binder函数如下:
//Parcel.cppstatus_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.cppinline 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层的实现)。
更多相关文章
- Flutter插件混编的各种奇葩问题以及Flutter与Native数据交互,Meth
- android Frame动画概述+示例
- android截图事件监听
- Android(安卓)控件架构
- 说说 Android(安卓)中的 SQLite 数据库
- Android之最简单的ImageView加边框方法
- Android的Message机制(简单小结)
- 图解Android:Touch事件传递机制
- Android(安卓)gallery 3D效果