Android10.0 Binder通讯原理(八)-Framework层分析

摘要:本节主要来说解Android10.0 Binder 在Framework的使用分析html

阅读本文大约须要花费15分钟。java

文章首发微信公众号:IngresGelinux

专一于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!android

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析git

[Android取经之路] 系列文章:数组

《系统启动篇》缓存

  1. Android系统架构
  2. Android是怎么启动的
  3. Android 10.0系统启动之init进程
  4. Android10.0系统启动之Zygote进程
  5. Android 10.0 系统启动之SystemServer进程
  6. Android 10.0 系统服务之ActivityMnagerService
  7. Android10.0系统启动之Launcher(桌面)启动流程
  8. Android10.0应用进程建立过程以及Zygote的fork流程
  9. Android 10.0 PackageManagerService(一)工做原理及启动流程
  10. Android 10.0 PackageManagerService(二)权限扫描
  11. Android 10.0 PackageManagerService(三)APK扫描
  12. Android 10.0 PackageManagerService(四)APK安装流程

《日志系统篇》微信

  1. Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
  2. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
  3. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
  4. Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​

《Binder通讯原理》cookie

  1. Android10.0 Binder通讯原理(一)Binder、HwBinder、VndBinder概要
  2. Android10.0 Binder通讯原理(二)-Binder入门篇
  3. Android10.0 Binder通讯原理(三)-ServiceManager篇
  4. Android10.0 Binder通讯原理(四)-Native-C\C++实例分析
  5. Android10.0 Binder通讯原理(五)-Binder驱动分析
  6. Android10.0 Binder通讯原理(六)-Binder数据如何完成定向打击
  7. Android10.0 Binder通讯原理(七)-Framework binder示例
  8. Android10.0 Binder通讯原理(八)-Framework层分析
  9. 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;
}

做用:

  1. 容许在给定接口上阻塞调用,重写请求的{setWarnOnBlocking(boolean)}值。
  2. 只有当您彻底肯定远程接口是一个永远没法升级的内置系统组件时,才应该不多调用此命令。尤为是,决不能对包托管的、可升级或替换的接口调用此命令,不然,若是远程接口接入,将有系统不稳定的风险。

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
 



参考:

《Binder framework层分析》

 

个人微信公众号:IngresGe

发布了25 篇原创文章 · 获赞 60 · 访问量 5万+
相关文章
相关标签/搜索