在了解完binder在native层以及驱动层的基本流程之后(参考Android如何注册服务到ServiceManager; Android 系统服务管家servicemanager启动过程详解 ),接下来这篇文章我们就来分析下binder在framework层(Java层)的具体原理与实现,重点围绕Java层如何添加服务到系统中这一主题展开。这里会谈到以下几个方面的问题:

  • binder在Java层的具体架构与实现
  • binder在Java层的ServiceManager又是如何实现
  • Android中如何加载注册binder相关的JNI方法

binder源码涉及面广,错误之处难以避免,欢迎各位批评指正

binder在Java层的具体实现

下图为Android框架层ServiceManager的结构简图。可以看到,框架层的ServiceManager主要是为上层应用或服务提供一个统一的接口,用于向系统注册、查询或者获取服务,在另一端Binder以及BinderProxy则通过JNI方法调用native层的方法,以此来使用binder底层提供的接口。

  • ServiceManager是一个不可初始化的类,其向外提供了addService(添加服务)、getService(获取服务)、checkService(检查服务)、listService列举所有系统服务等接口,并返回系统服务相关的IBinder接口;
  • IServiceManager是一个接口,ServiceManager正是通过该接口的实现ServiceManagerProxy来调用native层的代码的;
  • ServiceManagerProxy代理对象有一个mRemote变量,该变量实际是一个BinderProxy实例,通过BinderProxy就可以将Java层的RPC请求发送给native层,进而传递给binder驱动;
  • IBinder是RPC调用的一个抽象接口,代表了一个远程对象,通过该接口,我们可以向服务端发送RPC请求,该接口的核心函数是transact:
    public boolean transact(int code, Parcel data, Parcel reply, int flags)        throws RemoteException;

这是一个同步调用,只有当服务端返回时,该函数才会返回结果。

源码(以下分析均基于Android N7.0): /android/frameworks/base/core/java/android/os/ServiceManager.java

接下来,就来看看上层如何调用ServiceManager接口将系统服务注册到系统中的?

注册服务到servicemanager

在系统服务进程SystemServer启动后,会注册很多服务,包括系统核心服务以及其他非系统服务:

    private void run() {        ....        // 启动服务        try {            //启动自举服务:PowerManager,DisplayManger 等等            startBootstrapServices();            //启动系统核心服务            startCoreServices();            //启动其他服务:Vibrator,TelecomRegistry,NetworkConnectivity...            startOtherServices();        } catch (Throwable ex) {            throw ex;        } finally {            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);        }        ....    }    private void startOtherServices() {        ....        telephonyRegistry = new TelephonyRegistry(context);        ServiceManager.addService("telephony.registry", telephonyRegistry);        ....        vibrator = new VibratorService(context);        ServiceManager.addService("vibrator", vibrator);        ....    }

代码路径:/android/frameworks/base/services/java/com/android/server/SystemServer.java

调用ServiceManager方法addService:

    public static void addService(String name, IBinder service) {        try {            getIServiceManager().addService(name, service, false);        } catch (RemoteException e) {            Log.e(TAG, "error in addService", e);        }    }    private static IServiceManager sServiceManager;    // 获取IServiceManager接口    private static IServiceManager getIServiceManager() {        if (sServiceManager != null) {            return sServiceManager;        }        // 获取servicemanager        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());        return sServiceManager;    }

这里,BinderInternal.getContextObject()究竟返回的是什么了?进去一看,发现getContextObject()是一个本地化方法,需要通过JNI来调用native的代码:

    // 一个本地化方法    public static final native IBinder getContextObject();

直接搜索 getContextObject,发现在android_util_Binder.cpp这个JNI文件中,定义了相应的JNI函数:

    static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)    {        // 获取serviemanager对应的binder对象: BpBinder(0)        sp b = ProcessState::self()->getContextObject(NULL);        // 这里返回的是什么了?        return javaObjectForIBinder(env, b);    }    jobject javaObjectForIBinder(JNIEnv* env, const sp& val)    {        ....        // 新建一个BinderProxy对象?        object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);        if (object != NULL) {            // The proxy holds a reference to the native object.            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));            val->attachObject(&gBinderProxyOffsets, refObject,                    jnienv_to_javavm(env), proxy_cleanup);            // Also remember the death recipients registered on this proxy            sp drl = new DeathRecipientList;            drl->incStrong((void*)javaObjectForIBinder);            env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast(drl.get()));            // Note that a new object reference has been created.            android_atomic_inc(&gNumProxyRefs);            incRefsCreated(env);        }        return object;    }    // 保存了BinderProxy类的信息    static struct binderproxy_offsets_t    {        // Class state.        jclass mClass;        jmethodID mConstructor;        jmethodID mSendDeathNotice;        // Object state.        jfieldID mObject;        jfieldID mSelf;        jfieldID mOrgue;    } gBinderProxyOffsets;

从这里,我们大概可以判断出,javaObjectForIBinder实际返回的是一个Java对象BinderProxy,该对象有一个成员变量mObject保存了一个本地的BpBinder引用(参考Android如何注册服务到ServiceManager)。那么,与BinderProxy紧密相关的结构体变量gBinderProxyOffsets又是在何时被初始化的,这个疑问留到下一节“binder JNI方法的初始化”再来分析。暂时,我们知道BinderInternal.getContextObject()返回的是一个servicemanager对应的BinderProxy。这样

    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());

就等价于: sServiceManager = ServiceManagerNative.asInterface(new BinderProxy());,接着看一看asInterface这个方法:

    /**     * Cast a Binder object into a service manager interface, generating     * a proxy if needed.     */    static public IServiceManager asInterface(IBinder obj)    {        if (obj == null) {            return null;        }        // BinderProxy直接返回null        IServiceManager in =            (IServiceManager)obj.queryLocalInterface(descriptor);        if (in != null) {            return in;        }        // 新建一个ServiceManagerProxy(BindProxy)对象        return new ServiceManagerProxy(obj);    }    // ServiceManagerProxy构造函数,将BinderProxy实例保存到mRemote中    public ServiceManagerProxy(IBinder remote) {        mRemote = remote;    }

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

到这里,不难看出,调用ServiceManager.addService()实际调用的就是ServiceManagerProxy中的addService方法:

    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);        data.writeStrongBinder(service);        data.writeInt(allowIsolated ? 1 : 0);        // 调用BinderProxy的transact,发送RPC请求到servicemanager        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);        reply.recycle();        data.recycle();    }    // BinderProxy    final class BinderProxy implements IBinder {        public IInterface queryLocalInterface(String descriptor) {            return null;        }        ....        public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {            Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");            ....            return transactNative(code, data, reply, flags);        }        //调用JNI方法发送RPC请求        public native boolean transactNative(int code, Parcel data, Parcel reply,int flags) throws RemoteException;    }

那么,transactNative又是如何调用到native层的方法的了?同样在android_util_Binder.cpp中定义了BinderProxy相关的JNI方法,其中transactNative对应的JNI方法是android_os_BinderProxy_transact

    static const JNINativeMethod gBinderProxyMethods[] = {         /* name, signature, funcPtr */        {"pingBinder",          "()Z", (void*)android_os_BinderProxy_pingBinder},        {"isBinderAlive",       "()Z", (void*)android_os_BinderProxy_isBinderAlive},        {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},        {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},        {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},        {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},        {"destroy",             "()V", (void*)android_os_BinderProxy_destroy},    };    static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,            jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException    {        if (dataObj == NULL) {            jniThrowNullPointerException(env, NULL);            return JNI_FALSE;        }        // gBinderProxyOffsets.mObject 就是指向servicemanger的远程对BpBinder(0)        IBinder* target = (IBinder*)            env->GetLongField(obj, gBinderProxyOffsets.mObject);        if (target == NULL) {            jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");            return JNI_FALSE;        }        ....        // BpBinder->transact(...)        status_t err = target->transact(code, *data, reply, flags);        ....    }

到这了BpBinder以后,就与之前的一篇文章Android如何注册服务到ServiceManager所讲的流程完全一样了。

binder JNI方法的初始化

在上文中提到,BinderInternal.getContextObject()返回的是一个BinderProxy对象,同时该对象会引用一个native层的BpBinder实例。那么,Android究竟是如何初始化JNI?又是如何根据gBinderProxyOffsets这个结构体变量来构造一个Java对象BinderProxy的了?

在Android启动过程中(参考Android开机流程,init进程通过init.zygotexxx.rc来启动zygote系统服务用于加载虚拟机实例(系统只有一个zygote进程,但是不同进程会有不同的VM实例,不同的VM实例会通过zygote来共享一些共有的数据):

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server        class main        socket zygote stream 660 root system        onrestart write /sys/android_power/request_state wake        onrestart write /sys/power/state on        onrestart restart audioserver        onrestart restart cameraserver        onrestart restart media        onrestart restart netd

找到app_process进程的代码入口:

    int main(int argc, char* const argv[])    {        //获取runtime实例        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));        // ignore argv[0]        argc--;        argv++;        bool zygote = false;        bool startSystemServer = false;        ++i;  // Skip unused "parent dir" argument.        while (i < argc) {            const char* arg = argv[i++];            if (strcmp(arg, "--zygote") == 0) {                zygote = true;                niceName = ZYGOTE_NICE_NAME;            } else if (strcmp(arg, "--start-system-server") == 0) {                startSystemServer = true;                }            }             if (startSystemServer) {                args.add(String8("start-system-server"));            }            ....        }        ....        // 创建第一个Dalvik VM实例,启动ZygoteInit进程        if (zygote) {            runtime.start("com.android.internal.os.ZygoteInit", args, zygote);        } else if (className) {            runtime.start("com.android.internal.os.RuntimeInit", args, zygote);        }        ....    }

源码: /android/frameworks/base/cmds/app_process/app_main.cpp

    void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)    {        ....        //初始化VM参数,创建VM实例        JniInvocation jni_invocation;        jni_invocation.Init(NULL);        JNIEnv* env;        if (startVm(&mJavaVM, &env, zygote) != 0) {            return;        }        onVmCreated(env);        // 注册JNI函数        if (startReg(env) < 0) {            ALOGE("Unable to register all android natives\n");            return;        }        ....        //启动zygote进程:新建一个SystemServer进程,加载系统基础类与库        char* slashClassName = toSlashClassName(className);        jclass startClass = env->FindClass(slashClassName);        if (startClass == NULL) {            ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);            /* keep going */        } else {            jmethodID startMeth = env->GetStaticMethodID(startClass, "main",                "([Ljava/lang/String;)V");            if (startMeth == NULL) {                ALOGE("JavaVM unable to find main() in '%s'\n", className);            } else {                //调用ZygoteInit的main函数                env->CallStaticVoidMethod(startClass, startMeth, strArray);            ....        }        ....    }

系统JNI方法都是在函数startReg(env)中注册上的:

    /*static*/ int AndroidRuntime::startReg(JNIEnv* env)    {        ....        env->PushLocalFrame(200);        //注册所有的JNI函数到系统中        if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {            env->PopLocalFrame(NULL);            return -1;        }        env->PopLocalFrame(NULL);        return 0;    }    //gRegJni是系统JNI函数指针结构体数组    #define REG_JNI(name)      { name }    struct RegJNIRec {        int (*mProc)(JNIEnv*);    };    static const RegJNIRec gRegJNI[] = {        ....        REG_JNI(register_android_os_Process),        REG_JNI(register_android_os_SystemProperties),        //注册binder相关的JNI函数        REG_JNI(register_android_os_Binder),        REG_JNI(register_android_os_Parcel),        REG_JNI(register_android_nio_utils),        ....    };

找到register_android_os_Binder函数所在源码:android_util_Binder.cpp,在这个函数里,会注册所有和Binder框架层相关的JNI函数:

    int register_android_os_Binder(JNIEnv* env)    {        //注册Binder.java对应的JNI        if (int_register_android_os_Binder(env) < 0)            return -1;        //注册BinderInternal.java对应的JNI        if (int_register_android_os_BinderInternal(env) < 0)            return -1;        //注册BinderProxy.java对应的JNI        if (int_register_android_os_BinderProxy(env) < 0)            return -1;        ....        return 0;    }

正是在int_register_android_os_BinderProxy这个函数里,初始化了结构体变量gBinderProxyOffsets,其中mClass指向一个全局的BinderProxy引用,mConstructor指向BinderProxy的构造函数,而mObject初始化为BinderProxy的成员变量的ID值。这样初始化后,我们就可以使用gBinderProxyOffsets直接返回一个BinderProxy实例了。

    const char* const kBinderProxyPathName = "android/os/BinderProxy";    static int int_register_android_os_BinderProxy(JNIEnv* env)    {        //查找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");        ....        //注册BinderProxy相关的JNI        return RegisterMethodsOrDie(            env, kBinderProxyPathName,            gBinderProxyMethods, NELEM(gBinderProxyMethods));    }

至此,我们对Binder框架层也有了一个比较深入的理解与认识。这里,对如何在框架层添加系统服务的流程做一个简单的总结:

  1. 调用ServiceManageraddService()接口时,getIServiceManager返回一个ServiceManagerProxy对象;
  2. 调用ServiceManagerProxyaddService()接口;
  3. ServiceManagerProxy中有一个mRomote成员变量指向一个BinderProxy对象,它是本地servicemanager的远程代理;
  4. 通过JNI接口transactNative()发送数据到libbinder;

更多相关文章

  1. Android8.0 蓝牙系统
  2. android JNI层线程回调Java函数
  3. Android AOSP基础(四)Source Insight和Android Studio导入系统源码
  4. 硬件访问服务4之Android硬件访问服务框架及系统函数全详细实现
  5. Android下生成core dump的方法
  6. ubuntu下eclipse Android ADT中SDK Manager中安装SDK失败的方法
  7. 3D激光扫描三维重建——6.(android)系统框架
  8. [置顶] Android 从硬件到应用:一步一步向上爬 4 -- 使用 JNI 方法
  9. Android异步加载图像小结(含线程池,缓存方法)[转]

随机推荐

  1. TextView 借助Linkify,使用自定义模式设置
  2. android之PULL解析xml文档
  3. Project Ara 开发者大会后的进展
  4. android 2.3 ubuntu 下编译环境配置
  5. [推荐] 一个android个人开发者的总结[问
  6. [ 转]Android 监控网络状态
  7. 向Button上添加OnclickListener的另一种
  8. Android中ActivityManagerService与应用
  9. Android Media系统主框架
  10. android之从SD卡读取数据