Java Binder

426 阅读20分钟

在了解了Binder系统Native层后,再来看下Binder系统的Java层框架(即下图所示的Framework层)

1616036650(1).jpg

Java层的Binder架构是Native层Binder架构的一个镜像,需借助Native层Binder系统来开展工作,一定要在Java层Binder正式工作之前建立关系。下面分析Java层Binder框架是如何初始化的。

在Android系统启动过程中,Zygote启动时会有一个虚拟机注册过程,该过程调用AndroidRuntime::startReg方法来完成jni方法的注册。

源码路径4.2.2:/frameworks/base/core/jni/AndroidRuntime.cpp

/*
 * Register android native functions with the VM.
 */
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    /*
     * This hook causes all future threads created in this process to be
     * attached to the JavaVM.  (This needs to go away in favor of JNI
     * Attach calls.)
     */
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    ALOGV("--- registering native functions ---\n");

    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really
     * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);

    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;
}
static const RegJNIRec gRegJNI[] = {
    ...
    REG_JNI(register_android_os_Binder),
    ...
};

gRegJNI是一个记录所有需要注册的jni方法的数组,其中一项REG_JNI(register_android_os_Binder),register_android_os_Binder正是负责搭建Java Binder和Native Binder交互关系的函数,下面看下register_android_os_Binder。

源码路径:/frameworks/base/core/jni/android_util_Binder.cpp

int register_android_os_Binder(JNIEnv* env)
{
    if (int_register_android_os_Binder(env) < 0)//初始化Java Binder和Native层的关系
        return -1;
    if (int_register_android_os_BinderInternal(env) < 0)//初始化Java BinderInternal和Native层的关系
        return -1;
    if (int_register_android_os_BinderProxy(env) < 0)//初始化Java BinderProxy和Native层的关系
        return -1;
        ...
    return 0;
}

register_android_os_Binder完成了对Binder、BinderProxy和BinderInternal的初始化,下边分别分析

1、Binder类的初始化

static struct bindernative_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mExecTransact;//Binder类中成员函数execTransact()

    // Object state.
    jfieldID mObject;//Binder类中成员变量mObject

} gBinderOffsets;//静态类对象,保存Binder类的一些在JNI层中使用的信息

const char* const kBinderPathName = "android/os/Binder";

static int int_register_android_os_Binder(JNIEnv* env)
{
    jclass clazz;

    clazz = env->FindClass(kBinderPathName);//根据Binder类的全路径kBinderPathName找到代表该类的jclass对象
    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
  
    gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);//gBinderOffsets见上述结构
    gBinderOffsets.mExecTransact
        = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
    assert(gBinderOffsets.mExecTransact);

    gBinderOffsets.mObject
        = env->GetFieldID(clazz, "mObject", "I");
    assert(gBinderOffsets.mObject);
    //以下代码注册Binder类中native函数的实现
    return AndroidRuntime::registerNativeMethods(
        env, kBinderPathName,
        gBinderMethods, NELEM(gBinderMethods));
}

gBinderOffsets对象保存了和Binder类相关的在JNI层中使用的信息,用来在JNI层对Java层的Binder对象进行调用操作。

2、BinderInternal类的初始化

static struct binderinternal_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mForceGc;

} gBinderInternalOffsets;

const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";

static int int_register_android_os_BinderInternal(JNIEnv* env)
{
    jclass clazz;

    clazz = env->FindClass(kBinderInternalPathName);//根据BinderInternal类的全路径kBinderInternalPathName找到代表该类的jclass对象
    LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal");

    gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);//gBinderInternalOffsets见上述结构
    gBinderInternalOffsets.mForceGc
        = env->GetStaticMethodID(clazz, "forceBinderGc", "()V");//获取forceBinderGc的methodID
    assert(gBinderInternalOffsets.mForceGc);
    //以下代码注册BinderInternal类中native函数的实现
    return AndroidRuntime::registerNativeMethods(
        env, kBinderInternalPathName,
        gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

gBinderInternalOffsets对象保存了和BinderInternal类相关的在JNI层中使用的信息,用来在JNI层对Java层的BinderInternal对象进行调用操作。

3、BinderProxy类的初始化

static struct binderproxy_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mConstructor;
    jmethodID mSendDeathNotice;

    // Object state.
    jfieldID mObject;
    jfieldID mSelf;
    jfieldID mOrgue;

} gBinderProxyOffsets;

const char* const kBinderProxyPathName = "android/os/BinderProxy";

static int int_register_android_os_BinderProxy(JNIEnv* env)
{
    jclass clazz;

    clazz = env->FindClass("java/lang/ref/WeakReference");//gWeakReferenceOffsets用于使用Java WeakReference类
    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference");
    gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
    gWeakReferenceOffsets.mGet
        = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");//获取WeakReference类get()的methodID
    assert(gWeakReferenceOffsets.mGet);

    clazz = env->FindClass("java/lang/Error");//gErrorOffsets用于使用Java Error类
    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error");
    gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);

    clazz = env->FindClass(kBinderProxyPathName);
    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy");

    gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);//gBinderProxyOffsets见上述结构
    gBinderProxyOffsets.mConstructor
        = env->GetMethodID(clazz, "<init>", "()V");
    assert(gBinderProxyOffsets.mConstructor);
    gBinderProxyOffsets.mSendDeathNotice
        = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
    assert(gBinderProxyOffsets.mSendDeathNotice);

    gBinderProxyOffsets.mObject
        = env->GetFieldID(clazz, "mObject", "I");
    assert(gBinderProxyOffsets.mObject);
    gBinderProxyOffsets.mSelf
        = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
    assert(gBinderProxyOffsets.mSelf);
    gBinderProxyOffsets.mOrgue
        = env->GetFieldID(clazz, "mOrgue", "I");
    assert(gBinderProxyOffsets.mOrgue);

    clazz = env->FindClass("java/lang/Class");////gClassOffsets用于使用Java Class类
    LOG_FATAL_IF(clazz == NULL, "Unable to find java.lang.Class");
    gClassOffsets.mGetName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;");
    assert(gClassOffsets.mGetName);
    //以下代码注册BinderProxy类中native函数的实现
    return AndroidRuntime::registerNativeMethods(
        env, kBinderProxyPathName,
        gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

类似上述gBinderOffsets和gBinderInternalOffsets对象,gBinderProxyOffsets对象保存了和BinderProxy类相关的在JNI层中使用的信息,用来在JNI层对Java层的BinderProxy对象进行调用操作,除此之外,int_register_android_os_BinderProxy()还获取了WeakReference类和Error类的一些信息,也就是说BinderProxy对象的生命周期会委托WeakReference来管理。

经过上述分析,Java Binder几个重要成员的初始化已完成,同时在代码中定义了几个全局静态对象,分别是gBinderOffsets、gBinderInternalOffsets和gBinderProxyOffsets。框架的初始化其实就是提前获取一些JNI层的使用信息,如类成员函数的MethodID、类成员变量的fieldID等。这项工作是必需的,因为它能节省每次使用时获取这些信息的时间。当Binder调用频繁时,这些时间累积起来还是不容小觑的。另外,这个过程中所创建的几个全局静态对象为JNI层访问Java层的对象提供了依据。而在每个初始化函数中所执行的registerNativeMethods()方法则为Java层访问JNI层打通了道路。换句话说,Binder初始化的工作就是通过JNI建立起Native Binder与Java Binder之间互相通信的桥梁

下面我们分析一下Java Binder的工作流程。以ActivityManagerService(以下简称AMS)为例来揭示Java层Binder的工作原理。

分析分为两步进行:

1、分析AMS如何将自己注册到ServiceManager。

2、然后分析AMS如何响应客户端的Binder调用请求。

一、AMS如何将自己注册到ServiceManager

ActivityManagerService是在SystemServer进程里面注册的

SystemServer:main()
    ->run()
        ->startBootstrapServices()
            ->mActivityManagerService.setSystemProcess();

在ActivityManagerService的setSystemProcess()方法中会将AMS服务注册到ServiceManager中

源码路径:/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

1363    public static void setSystemProcess() {
1364        try {
1365            ActivityManagerService m = mSelf;
1366
1367            ServiceManager.addService("activity", m, true);//这里就是注册AMS的地方
1368            ServiceManager.addService("meminfo", new MemBinder(m));
1369            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1370            ServiceManager.addService("dbinfo", new DbBinder(m));
1371            if (MONITOR_CPU_USAGE) {
1372                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1373            }
1374            ServiceManager.addService("permission", new PermissionController(m));
1375
1376            ApplicationInfo info =
1377                mSelf.mContext.getPackageManager().getApplicationInfo(
1378                            "android", STOCK_PM_FLAGS);
1379            mSystemThread.installSystemApplicationInfo(info);
1380
1381            synchronized (mSelf) {
1382                ProcessRecord app = mSelf.newProcessRecordLocked(
1383                        mSystemThread.getApplicationThread(), info,
1384                        info.processName, false);
1385                app.persistent = true;
1386                app.pid = MY_PID;
1387                app.maxAdj = ProcessList.SYSTEM_ADJ;
1388                mSelf.mProcessNames.put(app.processName, app.uid, app);
1389                synchronized (mSelf.mPidsSelfLocked) {
1390                    mSelf.mPidsSelfLocked.put(app.pid, app);
1391                }
1392                mSelf.updateLruProcessLocked(app, true);
1393            }
1394        } catch (PackageManager.NameNotFoundException e) {
1395            throw new RuntimeException(
1396                    "Unable to find android system package", e);
1397        }
1398    }

在整个Android系统中有一个Native的ServiceManager进程,它统筹管理Android系统上的所有服务。成为一个服务的首要条件是先在SM中注册。下面来看Java层的服务是如何向SM注册的。

源码路径:/frameworks/base/core/java/android/os/ServiceManager.java

1、使用addService()向ServiceManager注册服务

78    /**
79     * Place a new @a service called @a name into the service
80     * manager.
81     *
82     * @param name the name of the new service
83     * @param service the service object
84     * @param allowIsolated set to true to allow isolated sandboxed processes
85     * to access this service
86     */
87    public static void addService(String name, IBinder service, boolean allowIsolated) {
88        try {
89            getIServiceManager().addService(name, service, allowIsolated);//service是AMS对象
90        } catch (RemoteException e) {
91            Log.e(TAG, "error in addService", e);
92        }
93    }

会调用getIServiceManager()的addService(),那就要看下getIServiceManager()方法了

33    private static IServiceManager getIServiceManager() {
34        if (sServiceManager != null) {
35            return sServiceManager;
36        }
37
38        // Find the service manager
39        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
40        return sServiceManager;
41    }

会调用ServiceManagerNative.asInterface()返回,asInterface()需要参数BinderInternal.getContextObject(),我们先看下BinderInternal.getContextObject()

源码路径:/frameworks/base/core/java/com/android/internal/os/BinderInternal.java

public static final native IBinder getContextObject();

可以看到BinderInternal的getContextObject()是一个native方法,具体会调用到android_os_BinderInternal_getContextObject()

源码路径:/frameworks/base/core/jni/android_util_Binder.cpp

862static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
863{
864    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
865    return javaObjectForIBinder(env, b);
866}

然后会调用ProcessState的getContextObject(),这个方法我们在Native Binder中讲解过,这里不再赘述,它会返回了一个IBinder对象,具体是一个BpBinder对象,其中NULL即0,代表通信目的端是ServiceManager,可以看到Java层的ServiceManager需要在Native层获取指向Native进程中ServiceManager的BpBinder对象。

我们看到拿到BpBinder对象对象后,调用了这个javaObjectForIBinder(),这是因为BpBinder对象不能由Java层的ServiceManager直接使用,于是通过javaObjectForIBinder()将创建一个封装了这个BpBinder的一个Java对象并返回给调用者。ServiceManager便可以通过这个Java对象实现对BpBinder的访问。下面看下javaObjectForIBinder()

555jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
556{
557    if (val == NULL) return NULL;
558
559    if (val->checkSubclass(&gBinderOffsets)) {
560        // One of our own!
561        jobject object = static_cast<JavaBBinder*>(val.get())->object();
562        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
563        return object;
564    }
565
566    // For the rest of the function we will hold this lock, to serialize
567    // looking/creation of Java proxies for native Binder proxies.
568    AutoMutex _l(mProxyLock);
569
570    // Someone else's...  do we know about it?
571    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);//根据上述分析,val是一个BpBinder对象
572    if (object != NULL) {
573        jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
574        if (res != NULL) {
575            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
576            return res;
577        }
578        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
579        android_atomic_dec(&gNumProxyRefs);
580        val->detachObject(&gBinderProxyOffsets);
581        env->DeleteGlobalRef(object);
582    }
583
584    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);//创建一个新的BinderProxy对象,这里便是使用到了上述的gBinderProxyOffsets来生成Java对象(JNI层对Java层的BinderProxy对象进行调用操作),并将该BinderProxy对象注册到Native BpBinder对象的ObjectManager中。
585    if (object != NULL) {
586        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
587        // The proxy holds a reference to the native object.
588        env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());//把Native层BpBinder的指针保存到BinderProxy对象的mObject成员变量中,这是连接BinderProxy和BpBinder的桥梁。
589        val->incStrong(object);
590
591        // The native object needs to hold a weak reference back to the
592        // proxy, so we can retrieve the same proxy if it is still active.
593        jobject refObject = env->NewGlobalRef(
594                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
595        val->attachObject(&gBinderProxyOffsets, refObject,
596                jnienv_to_javavm(env), proxy_cleanup);//将新建的BinderProxy对象注册(attach)到BpBinder的ObjectManager中,同时注册一个回收函数proxy_cleanup,当BinderProxy对象撤销(detach)时,proxy_cleanup会被调用用来释放一些资源。
597
598        // Also remember the death recipients registered on this proxy
599        sp<DeathRecipientList> drl = new DeathRecipientList;//DeathRecipientList保存一个用于死亡通知的list
600        drl->incStrong((void*)javaObjectForIBinder);
601        env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));//将死亡通知list和BinderProxy关联
602
603        // Note that a new object reference has been created.
604        android_atomic_inc(&gNumProxyRefs);//增加该BinderProxy对象的引用计数用于下面的incRefsCreated函数
605        incRefsCreated(env);//根据上面的引用计数,如果创建的BinderProxy对象超过200个,则会调用BinderInternal的ForceGC做一次垃圾回收。
606    }
607
608    return object;
609}

源码路径:/frameworks/native/libs/binder/BpBinder.cpp

295void* BpBinder::findObject(const void* objectID) const
296{
297    AutoMutex _l(mLock);
298    return mObjects.find(objectID);
299}

在BpBinder中,有一个ObjectManager(代码如下),用于管理在Native BpBinder上创建Java BpBinder(BinderProxy)对象,上述findObject()用来判断gBinderProxyOffsets是否已经保存在ObjectManager中,如果已经保存,就把旧的对象删除。

64    class ObjectManager
65    {
66    public:
67                    ObjectManager();
68                    ~ObjectManager();
69
70        void        attach( const void* objectID,
71                            void* object,
72                            void* cleanupCookie,
73                            IBinder::object_cleanup_func func);
74        void*       find(const void* objectID) const;
75        void        detach(const void* objectID);
76
77        void        kill();
78
79    private:
80                    ObjectManager(const ObjectManager&);
81        ObjectManager& operator=(const ObjectManager&);
82
83        struct entry_t
84        {
85            void* object;
86            void* cleanupCookie;
87            IBinder::object_cleanup_func func;
88        };
89
90        KeyedVector<const void*, entry_t> mObjects;
91    };

通过上述分析,可以看到BinderInternal.getContextObject()其实就是创建了一个Java层的BinderProxy对象,通过JNI,该BinderProxy对象和Native层的BpBinder对象挂钩,而BpBinder对象的通信目标就是ServiceManager。

BinderInternal.getContextObject()返回BinderProxy对象后,回传给ManagerNative.asInterface(BinderInternal.getContextObject());

接下来看下ManagerNative的sInterface方法

源码路径:/frameworks/base/core/java/android/os/ServiceManagerNative.java

33    static public IServiceManager asInterface(IBinder obj)
34    {
35        if (obj == null) {
36            return null;
37        }
38        IServiceManager in =
39            (IServiceManager)obj.queryLocalInterface(descriptor);
40        if (in != null) {
41            return in;
42        }
43
44        return new ServiceManagerProxy(obj);
45    }

上面代码和Native层interface_cast宏(已经在Native Binder一文中介绍过)非常类似,都是以一个BpProxy对象(Native层是BpBinder,Java层是BinderProxy)为参数构造一个和业务相关的Proxy对象,例如这里的ServiceManagerProxy对象。ServiceManagerProxy对象的各个业务函数会将相应请求打包后交给BpProxy对象,最终由BpProxy对象发送给Binder驱动以完成一次通信(真正和Binder驱动交互的是IPCThreadState)。

接着分析,setIServiceManager()返回ServiceManagerProxy对象后,会调用addService(),代码如下

源码路径:/frameworks/base/core/java/android/os/ServiceManagerNative.java

ServiceManagerNative中有个内部类ServiceManagerProxy,我们看下ServiceManagerProxy的addService()

142    public void addService(String name, IBinder service, boolean allowIsolated)
143            throws RemoteException {
144        Parcel data = Parcel.obtain();
145        Parcel reply = Parcel.obtain();
146        data.writeInterfaceToken(IServiceManager.descriptor);
147        data.writeString(name);
148        data.writeStrongBinder(service);
149        data.writeInt(allowIsolated ? 1 : 0);
150        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//mRemote就是上述创建的BinderProxy对象,调用transact,发送添加服务命令ADD_SERVICE_TRANSACTION。
151        reply.recycle();
152        data.recycle();
153    }

然后看下BinderProxy的transact方法,BinderProxy是定义Binder的内部类

源码路径:/frameworks/base/core/java/android/os/Binder.java

final class BinderProxy implements IBinder {
    ...
    public native boolean transact(int code, Parcel data, Parcel reply,
            int flags) throws RemoteException;
    ...
}

可以看到BinderProxy的transact是一个native函数,实现如下

1047static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1048        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1049{
1050    if (dataObj == NULL) {
1051        jniThrowNullPointerException(env, NULL);
1052        return JNI_FALSE;
1053    }
1054
1055    Parcel* data = parcelForJavaObject(env, dataObj);//从Java的Parcel对象中得到作为参数的Native的Parcel对象
1056    if (data == NULL) {
1057        return JNI_FALSE;
1058    }
1059    Parcel* reply = parcelForJavaObject(env, replyObj);//创建一个用于接收回复的Parcel
1060    if (reply == NULL && replyObj != NULL) {
1061        return JNI_FALSE;
1062    }
1063
1064    IBinder* target = (IBinder*)
1065        env->GetIntField(obj, gBinderProxyOffsets.mObject);//从Java的BinderProxy对象中得到Native层的BpBinder对象(保存在mObject中)
1066    if (target == NULL) {
1067        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1068        return JNI_FALSE;
1069    }
1070
1071    ALOGV("Java code calling transact on %p in Java object %p with code %d\n",
1072            target, obj, code);
1073
1074    // Only log the binder call duration for things on the Java-level main thread.
1075    // But if we don't
1076    const bool time_binder_calls = should_time_binder_calls();
1077
1078    int64_t start_millis;
1079    if (time_binder_calls) {
1080        start_millis = uptimeMillis();
1081    }
1082    //printf("Transact from Java code to %p sending: ", target); data->print();
1083    status_t err = target->transact(code, *data, reply, flags);//通过BpBinder对象将请求发送给ServiceManager
1084    //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
1085    if (time_binder_calls) {
1086        conditionally_log_binder_call(start_millis, target, code);
1087    }
1088
1089    if (err == NO_ERROR) {
1090        return JNI_TRUE;
1091    } else if (err == UNKNOWN_TRANSACTION) {
1092        return JNI_FALSE;
1093    }
1094
1095    signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
1096    return JNI_FALSE;
1097}

看到上述代码也就是最终还是要通过native层将请求发送出去。

从架构的角度看,在Java中搭建了一整套框架,如IBinder接口、Binder类和BinderProxy类。但是从通信角度看,不论架构的编写采用的是Native语言还是Java语言,只要把请求传递到Binder驱动就可以了,所以通信的目的是向binder发送请求和接收回复。在这个目的之上,考虑到软件的灵活性和可扩展性,于是编写了一个架构。反过来说,也可以不使用架构(即没有使用任何接口、派生之类的东西)而直接和binder交互,例如ServiceManager作为Binder的一个核心程序,就是直接读取/dev/binder设备,获取并处理请求。从这一点上看,Binder的目的虽然简单(即打开binder设备,然后读请求和写回复),但是架构复杂(编写各种接口类和封装类等)。我们在研究源码时,一定要先搞清楚目的。实现只不过是达到该目的的一种手段和方式。脱离目的的实现,如缘木求鱼,很容易偏离事物本质。

我们再回过头看一下ServiceManagerProxy.addService()方法中,有一处调用data.writeStrongBinder(service);这里我们单独分析一下,这个service是一个AMS对象,先介绍Binder、JavaBBinderHolder和JavaBBinder

首先ActivityManagerService从ActivityManagerNative类派生,并实现了一些接口

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

}

而ActivityManagerNative又继承自Binder,实现了IActivityManager

public abstract class ActivityManagerNative extends Binder implements IActivityManager{

}

看下ActivityManagerNative的父类Binder的构造函数,会调用init()

    /**
     * Default constructor initializes the object.
     */
    public Binder() {
        init();

        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Binder> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }
    }

private native final void init();

而init()是一个native方法,具体实现

源码路径:/frameworks/base/core/jni/android_util_Binder.cpp

766static void android_os_Binder_init(JNIEnv* env, jobject obj)
767{
768    JavaBBinderHolder* jbh = new JavaBBinderHolder();
769    if (jbh == NULL) {
770        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
771        return;
772    }
773    ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
774    jbh->incStrong((void*)android_os_Binder_init);
775    env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
776}

可以看到创建了一个JavaBBinderHolder对象,并且将这个JavaBBinderHolder对象保存到Java Binder对象的mObject成员中,那接下来我们看下JavaBBinderHolder是个什么东东。

源码路径:/frameworks/base/core/jni/android_util_Binder.cpp

335JavaBBinderHolder : public RefBase
336{
337public:
338    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
339    {
340        AutoMutex _l(mLock);
341        sp<JavaBBinder> b = mBinder.promote();
342        if (b == NULL) {
343            b = new JavaBBinder(env, obj);//创建一个JavaBBinder对象,obj是一个Java Binder对象
344            mBinder = b;
345            ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n",
346                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
347        }
348
349        return b;
350    }
351
352    sp<JavaBBinder> getExisting()
353    {
354        AutoMutex _l(mLock);
355        return mBinder.promote();
356    }
357
358private:
359    Mutex           mLock;
360    wp<JavaBBinder> mBinder;//和垃圾回收(内存管理)有关,可能也是不直接让Java层的Binder对象指向Native层的JavaBBinder对象的原因
361};

从派生关系上可以发现,JavaBBinderHolder仅从RefBase派生,所以它不属于Binder家族。Java层的Binder对象为什么会和Native层的一个与Binder家族无关的JavaBBinderHolder对象绑定呢?仔细观察JavaBBinderHolder的定义可知:JavaBBinderHolder类的get函数中创建了一个JavaBBinder对象,这个对象就是从BnBinder派生的。那么JavaBBinderHolder中的get函数是在哪里调用的呢?正是上述提到的data.writeStrongBinder(service),writeStrongBinder会做一个替换工作,下面是它的native代码实现

源码路径:/frameworks/base/core/jni/android_os_Parcel.cpp

252static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr, jobject object)
253{
254    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
255    if (parcel != NULL) {
256        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));//parcel是一个native对象,writeStrongBinder的参数是ibinderForJavaObject(env, object)
257        if (err != NO_ERROR) {
258            signalExceptionForError(env, clazz, err);
259        }
260    }
261}

然后看下ibinderForJavaObject(env, object)

611sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
612{
613    if (obj == NULL) return NULL;
614  //如果Java obj对象是Binder类型,就先获取它的JavaBBinderHolder对象(在Java Binder的mObject中),然后调用JavaBBinderHolder的get()函数,get()函数就会返回JavaBBinder对象
615    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
616        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
617            env->GetIntField(obj, gBinderOffsets.mObject);
618        return jbh != NULL ? jbh->get(env, obj) : NULL;
619    }
620   //如果Java obj对象是BinderProxy类型,则返回Native层的BpBinder对象(Native层的BpBinder对象保存在Java BinderProxy对象的mObject中)
621    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
622        return (IBinder*)
623            env->GetIntField(obj, gBinderProxyOffsets.mObject);
624    }
625
626    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
627    return NULL;
628}

根据上面的分析可以看到,addService实际添加到Parcel的并不是AMS本身,而是一个叫JavaBBinder的对象。而最终传递到Binder驱动的正是这个JavaBBinder对象。Java层中所有的Binder对应的都是这个JavaBBinder。当然,不同的Binder对象对应不同的JavaBBinder对象。下图展示了Java Binder、JavaBBinderHolder和JavaBBinder的关系。

1616120429(1).jpg

由上图可知:

1、Java层的Binder通过mObject指向一个Native层的JavaBBinderHolder对象。

2、Native层的JavaBBinderHolder对象通过mBinder成员变量指向一个Native的JavaBBinder对象。

3、Native的JavaBBinder对象又通过mObject变量指向一个Java层的Binder对象。

二、ActivityManagerService响应请求

根据上述分析,用户进程对AMS服务的跨进程请求,最终还是要调用到JavaBBinder,它是BBinder的子类。JavaBBinder并没有重写transact()函数,所以会复用BBinder中的transact()函数,transact()中会调用onTransact()函数。JavaBBinder重写了onTransact()的实现,也就是最后是会调到JavaBBinder的onTransact(),下面看下JavaBBinder的onTransact()的代码

源码路径:/frameworks/base/core/jni/android_util_Binder.cpp

263 virtual status_t onTransact(
264        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
265    {
266        JNIEnv* env = javavm_to_jnienv(mVM);
267
268        ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
269
270        IPCThreadState* thread_state = IPCThreadState::self();
271        const int strict_policy_before = thread_state->getStrictModePolicy();
272        thread_state->setLastTransactionBinderFlags(flags);
273
274        //printf("Transact from %p to Java code sending: ", this);
275        //data.print();
276        //printf("\n");
277        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
278            code, (int32_t)&data, (int32_t)reply, flags);//实际会调用Java Binder对象的execTransact()方法
279        jthrowable excep = env->ExceptionOccurred();
280
281        if (excep) {
282            report_exception(env, excep,
283                "*** Uncaught remote exception!  "
284                "(Exceptions are not yet supported across processes.)");
285            res = JNI_FALSE;
286
287            /* clean up JNI local ref -- we don't return to Java code */
288            env->DeleteLocalRef(excep);
289        }
290
291        // Restore the Java binder thread's state if it changed while
292        // processing a call (as it would if the Parcel's header had a
293        // new policy mask and Parcel.enforceInterface() changed
294        // it...)
295        const int strict_policy_after = thread_state->getStrictModePolicy();
296        if (strict_policy_after != strict_policy_before) {
297            // Our thread-local...
298            thread_state->setStrictModePolicy(strict_policy_before);
299            // And the Java-level thread-local...
300            set_dalvik_blockguard_policy(env, strict_policy_before);
301        }
302
303        jthrowable excep2 = env->ExceptionOccurred();
304        if (excep2) {
305            report_exception(env, excep2,
306                "*** Uncaught exception in onBinderStrictModePolicyChange");
307            /* clean up JNI local ref -- we don't return to Java code */
308            env->DeleteLocalRef(excep2);
309        }
310
311        // Need to always call through the native implementation of
312        // SYSPROPS_TRANSACTION.
313        if (code == SYSPROPS_TRANSACTION) {
314            BBinder::onTransact(code, data, reply, flags);
315        }
316
317        //aout << "onTransact to Java code; result=" << res << endl
318        //    << "Transact from " << this << " to Java code returning "
319        //    << reply << ": " << *reply << endl;
320        return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
321    }

就本例而言,上面代码中的mObject就是AMS,也就是调用它的execTransact()方法,该方法在Binder类中实现,具体代码如下:

源码路径:/frameworks/base/core/java/android/os/Binder.java

341    // Entry point from android_util_Binder.cpp's onTransact
342    private boolean execTransact(int code, int dataObj, int replyObj,
343            int flags) {
344        Parcel data = Parcel.obtain(dataObj);
345        Parcel reply = Parcel.obtain(replyObj);
346        // theoretically, we should call transact, which will call onTransact,
347        // but all that does is rewind it, and we just got these from an IPC,
348        // so we'll just call it directly.
349        boolean res;
350        try {
351            res = onTransact(code, data, reply, flags);//调用onTransact(),子类实现该方法,实现相应业务功能
352        } catch (RemoteException e) {
353            reply.setDataPosition(0);
354            reply.writeException(e);
355            res = true;
356        } catch (RuntimeException e) {
357            reply.setDataPosition(0);
358            reply.writeException(e);
359            res = true;
360        } catch (OutOfMemoryError e) {
361            RuntimeException re = new RuntimeException("Out of memory", e);
362            reply.setDataPosition(0);
363            reply.writeException(re);
364            res = true;
365        }
366        reply.recycle();
367        data.recycle();
368        return res;
369    }

这里那我们就看ActivityManagerNative类实现的onTransact函数

112public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
113            throws RemoteException {
114        switch (code) {
115        case START_ACTIVITY_TRANSACTION://启动Activity请求,下边其他请求太多了就不具体分析了,有兴趣的自己看吧
116        {
117            data.enforceInterface(IActivityManager.descriptor);
118            IBinder b = data.readStrongBinder();
119            IApplicationThread app = ApplicationThreadNative.asInterface(b);
120            Intent intent = Intent.CREATOR.createFromParcel(data);
121            String resolvedType = data.readString();
122            IBinder resultTo = data.readStrongBinder();
123            String resultWho = data.readString();
124            int requestCode = data.readInt();
125            int startFlags = data.readInt();
126            String profileFile = data.readString();
127            ParcelFileDescriptor profileFd = data.readInt() != 0
128                    ? data.readFileDescriptor() : null;
129            Bundle options = data.readInt() != 0
130                    ? Bundle.CREATOR.createFromParcel(data) : null;
131            int result = startActivity(app, intent, resolvedType,
132                    resultTo, resultWho, requestCode, startFlags,
133                    profileFile, profileFd, options);//比如START_ACTIVITY_TRANSACTION,这里就会由AMS实现startActivity()方法
134            reply.writeNoException();
135            reply.writeInt(result);
136            return true;
137        }
163        ...
            //其他请求处理case
1822       ...
1823        return super.onTransact(code, data, reply, flags);
1824    }

由此可以看出,JavaBBinder仅是一个中间传递者,它本身不实现任何业务函数,它完成的工作主要包括:

1、当它收到请求时,只是简单地调用它所绑定的Java层Binder对象的exeTransact。

2、该Binder对象的exeTransact调用其子类实现的onTransact函数。

3、子类的onTransact函数将业务又派发给其子类来完成。

通过这种多层继承关系方式,来自客户端的请求就能传递到正确的Java Binder对象了。下图(右上方框表示AMS对象,其中的虚线箭头表示调用子类重载的函数)展示了AMS响应请求的整个流程。

1616066674(1).jpg

经过对Binder的Native层和Framework层的分析,总结整体的结构见下图

1616119865(1).jpg