摘要:本节主要来说解Android10.0 Binder 在Framework的使用分析html
阅读本文大约须要花费15分钟。java
文章首发微信公众号:IngresGelinux
专一于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!android
[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析git
[Android取经之路] 系列文章:数组
《系统启动篇》缓存
- Android系统架构
- Android是怎么启动的
- Android 10.0系统启动之init进程
- Android10.0系统启动之Zygote进程
- Android 10.0 系统启动之SystemServer进程
- Android 10.0 系统服务之ActivityMnagerService
- Android10.0系统启动之Launcher(桌面)启动流程
- Android10.0应用进程建立过程以及Zygote的fork流程
- Android 10.0 PackageManagerService(一)工做原理及启动流程
- Android 10.0 PackageManagerService(二)权限扫描
- Android 10.0 PackageManagerService(三)APK扫描
- Android 10.0 PackageManagerService(四)APK安装流程
《日志系统篇》微信
- Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
- Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
- Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
- Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现
《Binder通讯原理》:cookie
- Android10.0 Binder通讯原理(一)Binder、HwBinder、VndBinder概要
- Android10.0 Binder通讯原理(二)-Binder入门篇
- Android10.0 Binder通讯原理(三)-ServiceManager篇
- Android10.0 Binder通讯原理(四)-Native-C\C++实例分析
- Android10.0 Binder通讯原理(五)-Binder驱动分析
- Android10.0 Binder通讯原理(六)-Binder数据如何完成定向打击
- Android10.0 Binder通讯原理(七)-Framework binder示例
- Android10.0 Binder通讯原理(八)-Framework层分析
- Android10.0 Binder通讯原理(九)-AIDL Binder示例
1.概述
前面几节,咱们已经把Native层和Binder驱动层的Binder数据流转给理清楚了,也知道了相应的概念。这一节让咱们继续往上进行分析,咱们进入到Framework层,看看Framework是如何实现服务的注册、获取的流程。架构
2.Binder架构
Framework层要实现服务的注册须要经过JNI 来调用Native C\C++层的相应接口,最终把服务注册到Native层的ServiceManager中。
应用层的进行经过Framework的接口,也通过JNI技术进入Native C\C++,最终在Native层的ServiceManager中获得服务handle,最终转成相应的服务对象。
3.源码分析
3.1 Binder-JNI
当Init进程启动后,孵化Zygote进程时,会有一个虚拟机注册过程,在这个过程当中完成了JNI的注册,咱们如今不须要深刻去理解JNI的原理,后面有时间,我再单独出一章来进行分析。
如今咱们只要知道 JAVA和Native侧的函数对应关系在哪里便可。
Binder的JNI中有个三个Binder的映射数组:gBinderMethods、gBinderInternalMethods、gBinderInternalMethods。
咱们在撸代码时,是要根据JAVA的函数入口找到JNI的函数调用便可,不要太追求细枝末节。
gBinderMethods:
[/frameworks/base/core/jni/android_util_Binder.cpp] static const JNINativeMethod gBinderMethods[] = { /* name, signature, funcPtr */ // @CriticalNative { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid }, // @CriticalNative { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid }, // @CriticalNative { "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction }, // @CriticalNative { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity }, { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity }, // @CriticalNative { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy }, // @CriticalNative { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy }, // @CriticalNative { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid }, // @CriticalNative { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid }, // @CriticalNative { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource }, { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource }, { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands }, { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder }, { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer }, { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable } };
gBinderInternalMethods:
[/frameworks/base/core/jni/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 }, { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled }, { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts }, { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount }, { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks} };
gBinderInternalMethods:
[/frameworks/base/core/jni/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 }, { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled }, { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts }, { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount }, { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks} };
3.2 服务注册
在上一节的Framework Binder Demo示例中,咱们知道服务注册的时候,调用的是ServiceManager.java的addService(),那咱们就拿addService()开刀。
注册服务调用栈:
3.2.1 addService()
[/frameworks/base/core/java/android/os/ServiceManager.java] public static void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) { try { //获取ServiceManagerProxy对象,执行addService操做 getIServiceManager().addService(name, service, allowIsolated, dumpPriority); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } }
拿到ServiceManagerProxy对象,来执行addService操做,这个ServiceManagerProxy对象须要咱们来揭开面纱。
3.2.2 getIServiceManager()
[/frameworks/base/core/java/android/os/ServiceManager.java] private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); return sServiceManager; }
这里也采用了单例模式来获取ServiceManagerProxy对象,减小对象重复建立。
[/frameworks/base/core/java/android/os/ServiceManagerNative.java] static public IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ServiceManagerProxy(obj); }
asInterface()中的主要做用就是建立ServiceManagerProxy()对象,可是须要带一个IBinder的 obj,我来看看这个obj是如何拿到的。
3.2.3 getContextObject()
[/frameworks/base/core/java/com/android/internal/os/BinderInternal.java] public static final native IBinder getContextObject();
BinderInternal.java中有一个native方法getContextObject(),JNI调用执行上述方法,在JNI的 gBinderInternalMethods数组中找到了getContextObject的对应关系,即为android_os_BinderInternal_getContextObject。
android_os_BinderInternal_getContextObject() [/frameworks/base/core/jni/android_util_Binder.cpp] static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { sp<IBinder> b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b); }
ProcessState::self()->getContextObject(NULL) 在《Binder--Native-C\C++实例分析》 的[5.3.1]节已经进行了详细分析,最终等价于 new BpBinder(0),这里就不重复展开了。
javaObjectForIBinder()
若是参数是JavaBBinder,返回用于建立它的Java对象;不然返回一个BinderProxy的对象。
若是上一个调用被传递给同一个IBinder,而原来的BinderProxy还活着,返回一样的BinderProxy。
[/frameworks/base/core/jni/android_util_Binder.cpp] jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { if (val == NULL) return NULL; if (val->checkSubclass(&gBinderOffsets)) { //若是参数是JavaBBinder,返回用于建立它的Java对象;不然返回一个BinderProxy的对象。 jobject object = static_cast<JavaBBinder*>(val.get())->object(); LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object); return object; } //申请一个BinderProxyNativeData的内存 BinderProxyNativeData* nativeData = new BinderProxyNativeData(); nativeData->mOrgue = new DeathRecipientList; nativeData->mObject = val; //建立BinderProxy对象,设置BinderProxy的相关参数,可以与JAVA层的BinderProx参与工做 jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get()); if (env->ExceptionCheck()) { return NULL; } BinderProxyNativeData* actualNativeData = getBPNativeData(env, object); if (actualNativeData == nativeData) { // Created a new Proxy uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed); uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed); if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) { if (gProxiesWarned.compare_exchange_strong(numLastWarned, numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) { ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies); } } } else { delete nativeData; } return object; }
javaObjectForIBinder()中,申请一个BinderProxyNativeData的内存,传入的BpBinder的对象地址保存到BinderProxyNativeData.mObject成员变量中,经过虚拟机的转换,BinderProxyNativeData在JAVA空间会被转换成 BinderProxy对象。
最终,BinderInternal.getContextObject()等价于 new BinderProxy(),因此getIServiceManager等价于new ServiceManagerProxy(new BinderProxy())。
3.2.4 ServiceManagerProxy.addService()
上一节,咱们已经拿到了ServiceManager在JAVA空间的代理,即ServiceManagerProxy,接着调用addService()来进行服务的注册。
[/frameworks/base/core/java/android/os/IServiceManager.java] public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); //将Binder对象扁平化,转换成flat_binder_object对象,这里为服务注册,对应的是Binder实体 data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); data.writeInt(dumpPriority); //Code:ADD_SERVICE_TRANSACTION ,parcel的数据 发到C空间,进行事务处理,注册服务。 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }
组装一个Parcel数据,把服务的名称和对象写入Parcel中,而后把它拍扁,服务转成flat_binder_object对象,在Native层为Binder实体。
3.2.5 writeStrongBinder()
把传入的服务对象拍扁,转成flat_binder_object对象,代码流程太罗嗦,这里列出如下调用栈流程:
data.writeStrongBinder(service)等价于parcel->writeStrongBinder(new JavaBBinder(env, obj));最终调用的是flatten_binder(),目的是把一个Binder实体“压扁”并写入Parcel。
这里"压扁"的含义,其实就是把Binder对象整理成flat_binder_object变量。若是压扁的是Binder实体,那么flat_binder_object用cookie域记录binder实体的指针,即BBinder指针,而若是打扁的是Binder代理,那么flat_binder_object用handle域记录的binder代理的句柄值。
接着flatten_binder()调用了一个关键的finish_flatten_binder()函数。这个函数内部会记录下刚刚被扁平化的flat_binder_object在parcel中的位置。说得更详细点儿就是,parcel对象内部会有一个buffer,记录着parcel中全部扁平化的数据,有些扁平数据是普通数据,而另外一些扁平数据则记录着binder对象。因此parcel中会构造另外一个mObjects数组,专门记录那些binder扁平数据所在的位置,示意图以下:
flatten_binder()的流程能够参考《Binder--Native-C\C++实例分析》 的[5.4]节
3.2.6 mRemote对象
class ServiceManagerProxy implements IServiceManager { public ServiceManagerProxy(IBinder remote) { mRemote = remote; } @UnsupportedAppUsage private IBinder mRemote; }
mRemote 是ServiceManagerProxy的一个成员,执行一个IBinder对象,mRemote在ServiceManagerProxy()构造函数中进行了赋值,从[4.2.3]和[4.2.4] 可知getIServiceManager()中调用了 以下内容:
sServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()))
从而可知 mRemote = BinderInternal.getContextObject() = new BinderProxy(),因此mRemote就是BinderProxy的对象。
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0) 等价于BinderProxy.transact(ADD_SERVICE_TRANSACTION, data, reply, 0)
3.2.7 BiderProxy.transact()
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { //检查Parcel的大小是否大于800K Binder.checkParcel(this, code, data, "Unreasonably large binder buffer"); try { return transactNative(code, data, reply, flags); } finally { ... } }
逻辑很简单,先检查Parcel的大小是否大于800K,而后调用了transactNative()进行数据传递。
public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException;
transactNative()一个Native方法,根据以前的JNI数组表,能够查到JNI的对应入口。
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException { ... Parcel* data = parcelForJavaObject(env, dataObj); ... Parcel* reply = parcelForJavaObject(env, replyObj); ... IBinder* target = getBPNativeData(env, obj)->mObject.get(); ... //根据咱们以前获取的对象流程来看,BinderProxy在Native空间,对应的是BpBinder,target即为BpBinder对象 status_t err = target->transact(code, *data, reply, flags); ... return JNI_FALSE; }
根据咱们以前获取的对象流程来看,BinderProxy在Native空间,对应的是BpBinder,target即为BpBinder对象。因此target->transact() 等价于BpBinder::transact(), 接下来的流程参考前面Native-C\C++层的分析,这里的细节再也不阐述,参考 《Binder--Native-C\C++实例分析》 和 《Binder数据如何定向打击》,也能够看到上面注册服务的调用栈。
3.2.8 服务注册总结
framework层的ServiceManager的调用实际的工做确实交给ServiceManagerProxy的成员变量BinderProxy;而BinderProxy经过jni方式,最终会调用BpBinder对象;可见上层binder架构的核心功能依赖native架构的服务来完成的。
注册服务的核心部分,就是JAVA侧把服务名称和对象,转入Parcel“扁平”数据,经过Native BpBinder,把code:ADD_SERVICE_TRANSACTION发给Binder驱动,再转到Native的ServiceManager,ServiceManager把服务名称和转换后的handler进行存储,供Client进行服务获取。
3.3 服务获取
在上一节的Framework Binder Demo示例中,咱们知道服务注册的时候,调用的是ServiceManager.java的getService(),那么获取服务就从getService()入口。
[/frameworks/base/core/java/android/os/ServiceManager.java] public static IBinder getService(String name) { try { //从缓存中获取服务对象 IBinder service = sCache.get(name); if (service != null) { return service; } else { //从Native层服务列表中取服务对象 return Binder.allowBlocking(rawGetService(name)); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; }
3.3.2 rawGetService()
[/frameworks/base/core/java/android/os/ServiceManager.java] private static IBinder rawGetService(String name) throws RemoteException { ... // //即为ServiceManagerProxy().getService final IBinder binder = getIServiceManager().getService(name); ... return binder; }
从上面可知getIServiceManager() 等价于 new ServiceManagerProxy(new BinderProxy()),getIServiceManager().getService(name)等价于ServiceManagerProxy().getService(name)
3.3.3 getService()
[/frameworks/base/core/java/android/os/ServiceManagerNative.java] public IBinder getService(String name) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0); IBinder binder = reply.readStrongBinder(); reply.recycle(); data.recycle(); return binder; }
从[4.2.6]可知,mRemote.transact(XXX) 等价于BinderProxy.transact(xx),这里不展开,和[4.2.7流程]同样,只是ServiceManager获取到服务的handle后,存入了reply信息中,这里会再调用reply.readStrongBinder()把binder对象给取出来。
3.3.4 readStrongBinder()
public final IBinder readStrongBinder() { return nativeReadStrongBinder(mNativePtr); }
调用栈以下:
Parcel.cpp -> readStrongBinder() 参考 《Binder--Native-C\C++实例分析》 中的[6.4]节, javaObjectForIBinder()参考[4.2.3]
readStrongBinder()最终是从reply的Parcel数据中得到BpBinder对象,再转成BinderProxy对象,参与JAVA层的工做。
3.3.5 allowBlocking
[/frameworks/base/core/java/android/os/Binder.java] public static IBinder allowBlocking(IBinder binder) { try { //若是binder是代理类,则设置非阻塞式 if (binder instanceof BinderProxy) { ((BinderProxy) binder).mWarnOnBlocking = false; } else if (binder != null && binder.getInterfaceDescriptor() != null && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) { //若是binder是本地对象,binder描述符不为空,且和本地binder描述符不相同 Log.w(TAG, "Unable to allow blocking on interface " + binder); } } catch (RemoteException ignored) { } return binder; }
做用:
- 容许在给定接口上阻塞调用,重写请求的{setWarnOnBlocking(boolean)}值。
- 只有当您彻底肯定远程接口是一个永远没法升级的内置系统组件时,才应该不多调用此命令。尤为是,决不能对包托管的、可升级或替换的接口调用此命令,不然,若是远程接口接入,将有系统不稳定的风险。
3.3.6 获取服务小结
和注册服务相似,都是须要依赖Native层的接口与Binder驱动通讯,获取服务主要是从Native的ServieManager取到Binder对象。
3.4 Client-Server接口调用
在[3.2] 和[3.3]中,咱们知道了服务注册addService()和获取服务getService()的流程,接下来咱们再看一看接口调用是如何进行的。
[MyServiceProxy.java] public void setValue(String str) throws RemoteException { Parcel data = Parcel.obtain(); //准备发送数据,结构为Parcel Parcel reply = Parcel.obtain();//准备返回数据,结构为Parcel try { //写入服务的Token,用来验证服务的准确性 data.writeInterfaceToken(IMyService.descriptor); data.writeString(str); //把参数写入Parcel,服务端会获取该参数 mRemote.transact(SET_VALUE_TRANSACTION, data, reply, 0); //code:SET_VALUE_TRANSACTION reply.readException(); } finally { reply.recycle(); data.recycle(); } }
上面调用的流程,其实和addService()、getService()相似,都是组装Parcel数据,准备服务端的code,调用BinderProxy.transact()发送到服务端。
可是和服务注册不一样的是,在服务注册中,Native的ServiceManager是Server端,服务实体是Client端。接口调用时,服务实体是Server端。
服务端接收到CLient的请求后,根据下图的流程,最终流转到服务实体的onTransact()中,对解析出来的Parcel数据进行处理。
4.总结
Framework层获取服务、注册服务,其实都是由JAVA层的ServiceManager代理 ServiecManagerProxy ,经过Binder驱动,访问Native层的ServiceManager,进行服务注册和获取动做。
这一节只是单独在Framework层进行了分析,不少状况下咱们都是在应用层进行处理流程,经过AIDL接口进行通讯,下一节会对AIDL进行一下分析。
代码路径:
Framework:
/frameworks/base/core/java/android/os/Binder.java
/frameworks/base/core/java/android/os/IBinder.java
/frameworks/base/core/java/android/os/BinderProxy.java
/frameworks/base/core/java/android/os/BinderProxy.java
/frameworks/base/core/java/android/os/ServiceManager.java
/frameworks/base/core/java/android/os/IServiceManager.java
/frameworks/base/core/java/android/os/ServiceManagerNative.java
/frameworks/base/core/java/com/android/internal/os/BinderInternal.java
JNI:
/frameworks/base/core/jni/android_util_Binder.h
/frameworks/base/core/jni/android_util_Binder.cpp
/frameworks/base/core/jni/android_os_Parcel.h
/frameworks/base/core/jni/android_os_Parcel.cpp
参考:
个人微信公众号:IngresGe