Android Binder原理(七)Java Binder中系统服务的注册过程

刘望舒 等级 1016 1 0
  • Binder原理
  • Android框架层

本文首发于微信公众号「后厂技术官」

前言

Android Binder原理(三)系统服务的注册过程这篇文章中,我介绍的是Native Binder中的系统服务的注册过程,这一过程的核心是ServiceManager,而在Java Binder中,也有一个ServiceManager,只不过这个ServiceManager是Java文件。 既然要将系统服务注册到ServiceManager,那么需要选择一个系统服务为例,这里以常见的AMS为例。

1.将AMS注册到ServiceManager

在AMS的setSystemProcess方法中,会调用ServiceManager的addService方法,如下所示。 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);//1
           ....
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find android system package", e);
        }
     ...
    }

注释1处的Context.ACTIVITY_SERVICE的值为"activity",作用就是将AMS注册到ServiceManager中。接着来看 ServiceManager的addService方法。 frameworks/base/core/java/android/os/ServiceManager.java

    public static void addService(String name, IBinder service, boolean allowIsolated,
            int dumpPriority) {
        try {
            getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

主要分析getIServiceManager方法返回的是什么,代码如下所示。 frameworks/base/core/java/android/os/ServiceManager.java

   private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

讲到这里,已经积累了几个点需要分析,分别是:

  • BinderInternal.getContextObject()
  • ServiceManagerNative.asInterface()
  • getIServiceManager().addService()

现在我们来各个击破它们。

1.1 BinderInternal.getContextObject()

Binder.allowBlocking的作用是将BinderProxy的sWarnOnBlocking值置为false。主要来分析BinderInternal.getContextObject()做了什么,这个方法是一个Native方法,找到它对应的函数: frameworks/base/core/jni/android_util_Binder.cpp

static const JNINativeMethod gBinderInternalMethods[] = {
    { "getContextObject", "()Landroid/os/IBinder;", (void*)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);//1
    return javaObjectForIBinder(env, b);
}

ProcessState::self()的作用是创建ProcessState,注释1处最终返回的是BpBinder,不理解的可以查看Android Binder原理(二)ServiceManager中的Binder机制这篇文章。

BpBinder是Native Binder中的Client端,这说明Java层的ServiceManager需要Native层的BpBinder,但是这个BpBinder在Java层是无法直接使用,那么就需要传入javaObjectForIBinder函数来做处理,其内部会创建一个BinderProxy对象,这样我们得知 BinderInternal.getContextObject()最终得到的是BinderProxy。 在Android Binder原理(六)Java Binder的初始化这篇文章我们讲过,BinderProxy是Java Binder的客户端的代表。 需要注意的一点是,这个传入的BpBinder会保存到BinderProxy的成员变量mObject中,后续会再次提到这个点。

1.2 ServiceManagerNative.asInterface()

说到asInterface方法,在Native Binder中也有一个asInterface函数。在Android Binder原理(二)ServiceManager中的Binder机制这篇文章中讲过IServiceManager的asInterface函数,它的作用是用BpBinder做为参数创建BpServiceManager。那么在Java Binder中的asInterface方法的作用又是什么? 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);
    }

根据1.1小节,我们得知obj的值为BinderProxy,那么asInterface方法的作用就是用BinderProxy作为参数创建ServiceManagerProxy。 BinderProxy和BpBinder分别在Jave Binder和Native Binder作为客户端的代表,BpServiceManager通过BpBinder来实现通信,同样的,ServiceManagerProxy也会将业务的请求交给BinderProxy来处理。 分析到这里,那么:

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

可以理解为:

        sServiceManager = new ServiceManagerProxy(BinderProxy);
    }

1.3 getIServiceManager().addService()

根据1.2节的讲解,getIServiceManager()返回的是ServiceManagerProxy,ServiceManagerProxy是ServiceManagerNative的内部类,它实现了IServiceManager接口。

来查看ServiceManagerProxy的addService方法, frameworks/base/core/java/android/os/ServiceManagerNative.java::ServiceManagerProxy

    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);
        data.writeStrongBinder(service);//1
        data.writeInt(allowIsolated ? 1 : 0);
        data.writeInt(dumpPriority);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//2
        reply.recycle();
        data.recycle();
    }

注释1处的data.writeStrongBinder很关键,后续会进行分析。这里又看到了Parcel,它是一个数据包装器,将请求数据写入到Parcel类型的对象data中,通过注释1处的mRemote.transact发送出去,mRemote实际上是BinderProxy,BinderProxy.transact是native函数,实现的函数如下所示。 frameworks/base/core/jni/android_util_Binder.cpp

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;
    }
    Parcel* data = parcelForJavaObject(env, dataObj);//1
    if (data == NULL) {
        return JNI_FALSE;
    }
    Parcel* reply = parcelForJavaObject(env, replyObj);//2
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }
    IBinder* target = getBPNativeData(env, obj)->mObject.get();//3
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
        return JNI_FALSE;
    }
   ...
    status_t err = target->transact(code, *data, reply, flags);//4
    return JNI_FALSE;
}

注释1和注释2处,将Java层的Parcel对象转化成为Native层的Parcel对象。在1.1小节中,我们得知BpBinder会保存到BinderProxy的成员变量mObject中,因此在注释3处,从BinderProxy的成员变量mObject中获取BpBinder。最终会在注释4处调用BpBinder的transact函数,向Binder驱动发送数据,可以看出Java Binder是需要Native Binder支持的,最终的目的就是向Binder驱动发送和接收数据。

2.引出JavaBBinder

接着回过头来分析1.3小节遗留下来的data.writeStrongBinder(service),代码如下所示。 frameworks/base/core/java/android/os/Parcel.java

  public final void writeStrongBinder(IBinder ll) {
        nativeWriteStrongBinder(mNativePtr, val);
    }

nativeWriteStrongBinder是Native方法,实现的函数为android_os_Parcel_writeStrongBinder: frameworks/base/core/jni/android_os_Parcel.cpp

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));//1
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
        }
    }
}

接着查看注释1处ibinderForJavaObject函数: frameworks/base/core/jni/android_util_Binder.cpp

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    if (obj == NULL) return NULL;
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {//1
        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh->get(env, obj);//2
    }
    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return getBPNativeData(env, obj)->mObject;
    }

    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
    return NULL;
}

注释2处,如果obj是Java层的BinderProxy类,则返回BpBinder。 注释1处,如果obj是Java层的Binder类,那么先获取JavaBBinderHolder对象,然后在注释2处调用JavaBBinderHolder的get函数,代码如下所示。 frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder

class JavaBBinderHolder
{
public:
    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
    {
        AutoMutex _l(mLock);
        sp<JavaBBinder> b = mBinder.promote();//1
        if (b == NULL) {
            //obj是一个Java层Binder对象
            b = new JavaBBinder(env, obj);//2
            mBinder = b;
            ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
        }
        return b;
    }
    sp<JavaBBinder> getExisting()
    {
        AutoMutex _l(mLock);
        return mBinder.promote();
    }
private:
    Mutex           mLock;
    wp<JavaBBinder> mBinder;
};

成员变量mBinder是wp<JavaBBinder>类型的弱引用,在注释1处得到sp<JavaBBinder>类型的强引用b,在注释2处创建JavaBBinder并赋值给b。那么,JavaBBinderHolder的get函数返回的是JavaBBinder。

data.writeStrongBinder(service)在本文中等价于:

data.writeStrongBinder(new JavaBBinder(env,Binder))。

讲到这里可以得知ServiceManager.addService()传入的并不是AMS本身,而是JavaBBinder。

3.解析JavaBBinder

接着来分析JavaBBinder,查看它的构造函数: frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder

class JavaBBinder : public BBinder
{
public:
    JavaBBinder(JNIEnv* env, jobject /* Java Binder */ c)
        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
    {
        ALOGV("Creating JavaBBinder %p\n", this);
        gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
        gcIfManyNewRefs(env);
    }
...

可以发现JavaBBinder继承了BBinder,那么JavaBBinder的作用是什么呢?当Binder驱动得到客户端的请求,紧接着会将响应发送给JavaBBinder,这时会调用JavaBBinder的onTransact函数,代码如下所示。 frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder

 virtual status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    {                            
        JNIEnv* env = javavm_to_jnienv(mVM);
        ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
        IPCThreadState* thread_state = IPCThreadState::self();
        const int32_t strict_policy_before = thread_state->getStrictModePolicy();
        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
            code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);//1

        ...
        return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
    }

在注释1处会调用Java层Binder的execTransact函数: frameworks/base/core/java/android/os/Binder.java

    private boolean execTransact(int code, long dataObj, long replyObj,
            int flags) {
...
        try {
            if (tracingEnabled) {
                Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
            }
            res = onTransact(code, data, reply, flags);//1
        } catch (RemoteException|RuntimeException e) {
           ...
        }
       ...
        return res;
    }

关键点是注释1处的onTransact函数,AMS实现了onTransact函数,从而完成业务实现。 从这里可有看出,JavaBBinder并没有实现什么业务,当它接收到请求时,会调用Binder类的execTransact函数,execTransact函数内部又调用了onTransact函数,系统服务会重写onTransact函数来实现自身的业务功能。

4.Java Binder架构

Binder架构如下图所示。 Android Binder原理(七)Java Binder中系统服务的注册过程

Native Binder的部分在此前的文章已经讲过,这里主要来说说Java Binder部分,从图中可以看到: 1.Binder是服务端的代表,JavaBBinder继承BBinder,JavaBBinder通过mObject变量指向Binder。 2.BinderProxy是客户端的代表,ServiceManager的addService等方法会交由ServiceManagerProxy处理。 3.ServiceManagerProxy的成员变量mRemote指向BinderProxy对象,所以ServiceManagerProxy的addService等方法会交由BinderProxy来处理。 4.BinderProxy的成员变量mObject指向BpBinder对象,因此BinderProxy可以通过BpBinder和Binder驱动发送数据。

收藏
评论区

相关推荐

Android深入浅出之Binder机制
Android深入浅出之Binder机制 一 说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。 我们这里将以MediaService的例子来分析Binder的使用: ServiceMan
Android应用程序进程启动过程(后篇)
本文首发于微信公众号「后厂技术官」 前言在前篇中我们讲到了Android应用程序进程启动过程,这一篇我们来讲遗留的知识点:在应用程序进程创建过程中会启动Binder线程池以及在应用程序进程启动后会创建消息循环。<more 1.Binder线程池启动过程我们首先来看RuntimeInit类的zygoteInit
Android Binder原理(一)学习Binder前必须要了解的知识点
本文首发于微信公众号「刘望舒」 前言Binder原理是掌握系统底层原理的基石,也是进阶高级工程师的必备知识点,这篇文章不会过多介绍Binder原理,而是讲解学习Binder前需要的掌握的知识点。 1.Linux和Android的IPC机制种类IPC全名为interProcess Communication,含义为进程间
Android Binder原理(二)ServiceManager中的Binder机制
Binder原理 Android框架层本文首发于微信公众号「刘望舒」<more 前言在上一篇文章中,我们了解了学习Binder前必须要了解的知识点,其中有一点就是Binder机制的三个部分:Java Binder、Native Binder、Kernel Binder,其中Java Binder和Native
Binder Driver缺陷导致定屏的案例
本文讲解异步binder call是如何阻塞整个系统的,通过ramdump信息以及binder通信协议来演绎并还原定屏现场。 一、背景知识点解决此问题所涉及到的基础知识点有:Trace、CPU调度、Ramdump推导、Crash工具、GDB工具、Ftrace, 尤其深入理解binder IPC机制。 1.1 工具简介 Trace:分析死锁
Android Binder原理(三)系统服务的注册过程
Binder原理 Android框架层本文首发于微信公众号「刘望舒」<!more 前言在上一篇文章中,我们学习了ServiceManager中的Binder机制,有一个问题由于篇幅问题没有讲完,那就是MediaPlayerService是如何注册的。通过了解MediaPlayerService是如何注册的,可以得知系统服务的注册过程。 1.从调用链角度说明M
Android Binder原理(四)ServiceManager的启动过程
Binder原理 Android框架层本文首发于微信公众号「刘望舒」<!more 前言在上一篇文章中,我们以MediaPlayerService为例,讲解了系统服务是如何注册的(addService),既然有注册就势必要有获取,但是在了解获取服务前,我们最好先了解ServiceManager的启动过程,这样更有助于理解系统服务的注册和获取的过程。另外还有一点
Android Binder原理(六)Java Binder的初始化
Binder原理 Android框架层本文首发于微信公众号「刘望舒」<!more 前言在这篇文章中,我根据Android系统的分层,将Binder机制分为了三层:1. Java Binder (对应Framework层的Binder)2. Native Binder(对应Native层的Binder)3. Kernel Binder(对应Kernel层的Bi
Android Binder原理(七)Java Binder中系统服务的注册过程
Binder原理 Android框架层本文首发于微信公众号「后厂技术官」<!more 前言在这篇文章中,我介绍的是Native Binder中的系统服务的注册过程,这一过程的核心是ServiceManager,而在Java Binder中,也有一个ServiceManager,只不过这个ServiceManager是Java文件。既然要将系统服务注册到Ser
JNI 基础 - Android 共享内存的序列化过程
1. 进程间的通信方式有哪些2. binder 和 socket 通信的区别有哪些3. Android 为什么在大部分场景下用 Binder 进行进程间通信4. Serializable 和 Parcelable 之间的区别5. Parcelable 序列化和反序列化的具体过程不知道大家在面试中的过程中,有没有碰到上面类似的问题,我在腾讯和 oppo 面试的
Android的Binder机制浅析
** 1\. 引言**  一般实际的软件系统中进程间通信(IPC)的实现方法有命名管道(named pipe),共享内存(shared memory),消息队列(message queue),Socket等方法。在Android的框架(Framework)中,以Binder作为框架内进程间(通常如服务和客户间)通信的主要实现手段。这可能是出于效
Android Binder 设计与实现
关键词 **Binder Android IPC Linux** **内核** **驱动** 摘要 Binder是Android系统进程间通信(IPC)方式之一。Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具有无可比拟的优势。深入了解Binder并将之与传统IPC做
Android Binder——framework
上一篇[Binder mRemote的前世今生](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fwww.jianshu.com%2Fp%2F72bc48d59f0e)PowerManger.isScreenOn()的调用流程已经调用到了BinderProxy.transact(); >
Android深入浅出之Binder机制
Android深入浅出之Binder机制 一 说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。 我们这里将以MediaService的例子来分析Binder的使用: l ServiceMana
Binder学习指南
毫不夸张地说,Binder是Android系统中最重要的特性之一;正如其名“粘合剂”所喻,它是系统间各个组件的桥梁,Android系统的开放式设计也很大程度上得益于这种及其方便的跨进程通信机制。 理解Binder对于理解整个Android系统有着非常重要的作用,Android系统的四大组件,AMS,PMS等系统服务无一不与Binder挂钩;如果对Binde