Love Binder system manufacturers to test the service registration of how broken?

Author | Liu Wang Shu

This article is reproduced since the plant technology officer (ID: houchangcto) authorized

Zebian | Hu Weiwei

In shu.cn/framework/binder/3-addservice.html this article, I introduce the registration process Native Binder of system services.

Central to this process is ServiceManager, while in Java Binder, there is also a ServiceManager, but this is ServiceManager Java files.

Since you want service registration system to ServiceManager, you need to select a system service, for example, here in the usual AMS example.

The AMS registered to ServiceManager

In the method of the AMS setSystemProcess, calls the ServiceManager addService method, as shown in FIG.

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);
        }
     ...
    }

Context.ACTIVITY_SERVICE of a comment is "activity", the role is to AMS registered to ServiceManager in. The method of ServiceManager addService then look.
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 main analysis method returns what is shown in the code below.
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;
    }

Mentioned here, we have accumulated a few points need to be analyzed, namely:

  • 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。

BpBinder是Native Binder中的Client端,这说明Java层的ServiceManager需要Native层的BpBinder。

但是这个BpBinder在Java层是无法直接使用,那么就需要传入javaObjectForIBinder函数来做处理。

其内部会创建一个BinderProxy对象,这样我们得知 BinderInternal.getContextObject()最终得到的是BinderProxy。

BinderProxy是Java Binder的客户端的代表。

需要注意的一点是,这个传入的BpBinder会保存到BinderProxy的成员变量mObject中,后续会再次提到这个点。

1.2 ServiceManagerNative.asInterface()

说到asInterface方法,在Native Binder中也有一个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驱动发送和接收数据。

引出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。

解析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函数来实现自身的业务功能。

Java Binder架构

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卷二》
《深入理解Android卷三》
http://gityuan.com/2015/11/21/binder-framework/

【END】

热 文 推 荐 

开发者在行动!中国防疫开源项目登上 GitHub TOP 榜

延迟上班别发愁,远程办公抗疫情!

华为百度美团驰援抗击疫情;自由软件基金会建议开源 Windows 7;印度超越美国成第二大智能手机市场 | 极客头条

☞疫情严重,潜伏期也有传染性?科技公司在行动

程序员谈从科比的曼巴精神中,我们能学到什么?

你点的每个在看,我都认真当成了喜欢

发布了1666 篇原创文章 · 获赞 4万+ · 访问量 1417万+

Guess you like

Origin blog.csdn.net/csdnnews/article/details/104112060