Android Framework:Binder(6)-Java层Service的注册及跨进程调用

来源:互联网 发布:广发期货模拟软件 编辑:程序博客网 时间:2024/05/22 16:57

Android Framework:Binder(6)-Java层Service的注册及跨进程调用

一、Java层Binder概述

   Java层中的binder和Native层的Binder在命名上尽量保持了一致,且Java层的Binder依托于Native层的Binder,其实就是对底层的Binder的真正实现的一个封装,最终还是通过JNI技术调用到C/C++代码的实现。。
  本文我们从PKMS服务的初始化注册和PKMS的服务调用来学习Java层Binder的知识。
  废话不说先上图:

1. Java Binder及PKMS框架:

这里写图片描述

2. Java Binder跨进程调用服务的整体框架

  
这里写图片描述

这图是学完整个Java层Binder机制之后总结出来的,先放这里引导一下:
  1. 从该图中我们发现Java层的Binder框架的确是依靠Native层的Binder框架的,通过JNI层使得两者联系在一起。Native Service中Client端会有一个BpBinder的引用,Service端会有一个BBinder的引用来实现通信;而Java层Service在Client端会有个BinderProxy的引用,在Service端会有个JavaBBinder对象的引用来实现通信。当然Java层的Binder机制是基于native层的,native层的binder机制是基于Binder驱动的。
  2. 同Native层Service调用一样,Client端调用远程Service时需要向ServiceManager进程请求Service的代理对象,Service代理对象XXSeviceProxy是通过BinderProxy对象new出来的,而BinderProxy对象是由ServiceManager根据查询到的Service的Bp端的Binder代理BpBinder(handle)构造出来的,供java层Client端中的XXServiceProxy使用。Java层的BinderProxy与native层的BpBinder对应。
  3. Java Service进行注册服务时将Java service的name和通过JNI层封装后service的JavaBBinder对象注册至service_manager中。
  4. JavaService响应请求时,在Native层的IPCThreadState中调用BBinder的transact进而调用到JavaService的JavaBBinder的onTransact()函数,通过JNI层调用到Binder子类的IXXServiceInterface.stub中的onTransact()方法,在xx.stub类中的onTransact()方法中调用到指定的xx.stub的具体实现函数即XXService中的具体实现方法,从而完成Java Service的响应。

二、Java层Binder框架初始化

  Android启动初期,系统会提前一个专门负责搭建Java Binder和Native Binder交互关系的函数,该函数是register_android_os_Binder,代码如下:

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

1.Java层Binder框架JNI层的初始化

1.1 Binder类JNI层初始化

//java层的Binder类的全路径名const char* const kBinderPathName = "android/os/Binder";static int int_register_android_os_Binder(JNIEnv* env){    //找到java层的Binder类,保存至clazz变量中    jclass clazz = FindClassOrDie(env, kBinderPathName);    gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);    //将Binder类中的execTransact方法保存至gBinderOffsets的mExectransact变量中    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");    //将Binder的mObject变量保存到gBinderOffsets的mObject中    gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");    //注册Java Binder类的native函数实现    return RegisterMethodsOrDie(        env, kBinderPathName,        gBinderMethods, NELEM(gBinderMethods));}

我们看到gBinderOffsets对象保存了Binder类相关的信息,这些信息将在JNI层中使用到,下面两个方法类似;

1.2 BinderInternal类JNI层初始化

const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";static int int_register_android_os_BinderInternal(JNIEnv* env){    jclass clazz = FindClassOrDie(env, kBinderInternalPathName);    gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);    gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");    return RegisterMethodsOrDie(env, kBinderInternalPathName, gBinderInternalMethods, NELEM(gBinderInternalMethods));}

1.3 BinderProxy类JNI层初始化

const char* const kBinderProxyPathName = "android/os/BinderProxy";static int int_register_android_os_BinderProxy(JNIEnv* env){    jclass clazz = FindClassOrDie(env, "java/lang/Error");    gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);    clazz = FindClassOrDie(env, kBinderProxyPathName);    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);    gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");    gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",            "(Landroid/os/IBinder$DeathRecipient;)V");    gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");    gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",                                                "Ljava/lang/ref/WeakReference;");    gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");    clazz = FindClassOrDie(env, "java/lang/Class");    gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");    return RegisterMethodsOrDie(env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods));}

  至此,初始了JavaBinder重要成员变量,gBinderOffsets,gBinderInternalOffsets,gBinderProxyOffsets,分别保存了对应的Java对象类的方法和变量等信息,这些信息将会在JNI层native和java对象类型转换时使用到,先保存下来能节约一定的时间。

2. Java Binder中重要Native方法映射

2.1 Java层Binder类中的native方法:

static const JNINativeMethod gBinderMethods[] = {     /* name, signature, funcPtr */    { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },    { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },    { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },    { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },    { "init", "()V", (void*)android_os_Binder_init },    { "destroy", "()V", (void*)android_os_Binder_destroy },    { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }};

2.2 Java层BinderInternal类中的native方法:

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

2.3 Java层BinderProxy类中的native方法:

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},};

  保存一下方便日后查看。

三、PKMS初始化注册服务

  我们以PKMS初始化作为分析Binder java层的入口。
  在SystemServer启动PMKS的时候会在PackageManagerService的main函数中new出一个PKMS的实例m,并将PKMS的名称和实例注册至ServiceManager:

//frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.javapublic static PackageManagerService main(Context context, Installer installer,            boolean factoryTest, boolean onlyCore) {        PackageManagerService m = new PackageManagerService(context, installer,                factoryTest, onlyCore);        ServiceManager.addService("package", m);       }

  从这个地方我们继续跟下去:

//frameworks\base\core\java\android\os\ServiceManager.java   public static void addService(String name, IBinder service) {        try {            getIServiceManager().addService(name, service, false);        } catch (RemoteException e) {            Log.e(TAG, "error in addService", e);        }    }

1. 获取ServiceManager的代理对象:

  getIServiceManager通过ServiceManagerNative类获取到ServiceManager的代理对象:

 private static IServiceManager getIServiceManager() {        if (sServiceManager != null) {            return sServiceManager;        }        // Find the service manager        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());        return sServiceManager;    }

1.1 获取Service的Binder代理BinderProxy

  看下BinderInternal.getContextObject是如何活的SM的Binder代理的:

//frameworks\base\core\java\com\android\internal\os\BinderInternal.javapublic static final native IBinder getContextObject();

  看到getContextObject是个native方法,我们找到它native的实现:

//frameworks/base/core/jni/android_util_Binder.cppstatic jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz){    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//1,获得native的BpBinder(0)对象    return javaObjectForIBinder(env, b);//2,利用BpBinder对象构造出java层使用的对应的BinderProxy对象}
1.1.1 获取SM的Bp端的BpBinder(0)

   首先获取native service_manager的Bp端代理BpBinder(0),在 Android Framework:Binder(4)-Native Service的注册中的第二段的第2小结得知这里最终获得的是Native的BpBinder(0).

1.1.2 javaObjectForIBinder方法构造出BinderProxy对象

  然后将Native层的BpBinder(0)通过javaObjectForIBinder()方法包装成java层使用的BinderProxy对象:

//frameworks/base/core/jni/android_util_Binder.cppjobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val){    if (val == NULL) return NULL;    //创建一个新的BinderProxy对象    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);    if (object != NULL) {        // The proxy holds a reference to the native object.        //代理持有一份native对象的的应用,这里的native对象即指的是BpBinder(0),        //将BpBinder对象保存到BinderProxy的mObject成员变量中        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));        //native对象需要持有对应java对象BinderProxy的一份弱引用。        val->attachObject(&gBinderProxyOffsets, refObject,                jnienv_to_javavm(env), proxy_cleanup);        ...    }    //返回这个BinderProxy对象    return object;}

  javaObjectForIBinder的作用是,新建一个Java层的BinderProxy对象,将Native层的BpBinder保存到BinderProxy.mObject,并将BinderProxy的弱引用通过attachObject保存到Native层的BpBinder(0)(成员mObjects中),这样Java层的BinderProxy与Native层的BpBinder就可以相互引用了。
  
  通过上的分析可知,BinderInternal.getContextObject()的目的就是得到ServiceManager进程对应的BpBinder,即BpBinder(0),这里需要利用该BpBinder构造出java层使用的BinderProxy对象。
  

1.2 ISM asInterface方法利用BinderProxy构造服务代理对象SMProxy:

//frameworks\base\core\java\android\os\ServiceManagerNative.javastatic final String descriptor = "android.os.IServiceManager";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);    }

  看到IServiceManager asInterface的方法中将返回一个ServiceManagerProxy的ServiceManager的代理对象,即类似于ServiceManagerProxy(BinderProxy(BpBinder(0)))【当然这种写法不准确,仅仅表示结构关系,下面类似的情况也是相同原因】。

1.3.分析ServiceManagerProxy

  我们来看下ServiceManagerProxy,ServiceManagerProxy实现了IServiceManager中的方法,提供了SM的方法接口:

//frameworks/base/core/java/android/os/ServiceManagerNative.java::ServiceManagerProxyclass ServiceManagerProxy implements IServiceManager {    public ServiceManagerProxy(IBinder remote) {        //这里看到在ServiceManagerProxy的构造函数时就将remote赋值给了ServiceManagerProxy的成员变量mRemote        //而这里的remote值即是上一步中包装给java层用的BpBinder(0)        mRemote = remote;     }    public IBinder asBinder() { return mRemote; }    public IBinder checkService(String name) {mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);}    public void addService(String name, IBinder service,){mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);}    public String[] listServices() { boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);}    private IBinder mRemote;}

  从上面的分析得知getIServiceManager()方法得到的是ServiceManager的代理实例,ServiceManagerProxy(BinderProxy(BpBinder(0)));当调用SM代理的接口方法时会调用成员变量mRemote的transact()方法,由上面的分析我们知道这里的mRemote变量即是由BpBinder(0)构造来的BinderProxy对象;

  至此,我们在Client端,PKMS的进程中获得了SM进程的代理对象ServiceManagerProxy,这个SM的代理对象与Native层的service_manager进程息息相关,通过BinderProxy与BpBinder(0)之间的关系传递着联系。

2. 跨进程调用ServiceManager的addService方法:

  获得Servicemanager代理对象ServiceManagerProxy(BinderProxy(BpBinder(0))),所以调用addService方法即调用到ServiceManagerProxy中的addService方法:

//frameworks/base/core/java/android/os/ServiceManagerNative.java::ServiceManagerProxy 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);        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//发送不同的执行code        reply.recycle();        data.recycle();    }

2.1 数据Binder的封装 data.writeStrongBinder(service):

  这里我们看到java层的Binder子类即Service通过writeStrongBinder()方法写到Parcel载体对象data中,看下writeStrongBinder()是做什么的:

//frameworks/base/core/java/android/os/Parcel.javapublic final void writeStrongBinder(IBinder val) {        nativeWriteStrongBinder(mNativePtr, val);    }

  这是个Native方法实现的,找到该方法native实现的地方:

//frameworks/base/core/jni/android_os_Parcel.cppstatic 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));    }}

  看到writeStrongBinder中调用Native Parcel类中writeStrongBinder方法,参数是通过ibinderForJavaObject()函数生成的对象,首先看看这个ibinderForJavaObject()函数做了什么:
  
  2.1.1 iBinderForJavaObject():

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj){    if (obj == NULL) return NULL;    //查看这个java对象是否是Binder.java子类,PKMS继承自IPackageManager.Stub,在生成的IPackageManager.java文件中    //可以看到子类Stub类是继承自android.os.binder的,因此这里PKMS应该是Binder子类    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {    //如果是则先获得JavaBBinderHolder对象,然后调用他的get函数,get函数返回一个JavaBBinder对象        JavaBBinderHolder* jbh = (JavaBBinderHolder*)            env->GetLongField(obj, gBinderOffsets.mObject);        return jbh != NULL ? jbh->get(env, obj) : NULL;    }    //如果这个java对象是BinderProxy类,则返回Native层的BpBinder对象    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {        return (IBinder*)            env->GetLongField(obj, gBinderProxyOffsets.mObject);    }    return NULL;}

  从上面的分析至从事obj正是PKMS的实例对象,而PKMS继承自IPackageManager.stub类,IPackageManager.stub继承自android.os.Binder类,因此这里的obj这个java对象是Binder的子类,所以经过ibinderForJavaObject()函数,通过JavaBBinderHolder对象的get方法获得并返回一个JavaBBinder对象。

  2.1.2 JavaBBinder,Binder,BinderProxy
  PKMS继承自IPackageManager.stub,IPackageManager.stub继承自Binder,在注册PKMS之前,需要new一个PKMS实例,因此这时会调用到爷爷类的Binder的构造函数Binder();

//frameworks/base/core/java/android/os/Binder.javapublic Binder() {    init();    ...}private native final void init();

init是一个native实现的方法,我们找到它实现的地方:

//frameworks/base/core/jni/android_util_Binder.cppstatic void android_os_Binder_init(JNIEnv* env, jobject obj){    JavaBBinderHolder* jbh = new JavaBBinderHolder();    ...    jbh->incStrong((void*)android_os_Binder_init);    env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);}

  我们看到Binder初始化时new了一个JavaBBinderHolder对象,然后把这个JavaBBinderHolder对象保存在了Binder类中的mObject对象中。
再看JavaBBinderHolder的定义:

class JavaBBinderHolder : public RefBase{public:    sp<JavaBBinder> get(JNIEnv* env, jobject obj)    {        sp<JavaBBinder> b = mBinder.promote();        if (b == NULL) { b = new JavaBBinder(env, obj);mBinder = b; }        return b;    }private:    wp<JavaBBinder> mBinder;};

  我们看到JavaBBinderHolder 中持有一个JavaBBinder类型的成员变量mBinder。
  而JavaBBinder定义:

class JavaBBinder : public BBinder{    virtual status_t onTransact(        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)    {        JNIEnv* env = javavm_to_jnienv(mVM);        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,            code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);    }private:    JavaVM* const   mVM;    jobject const   mObject;};

  看到JavaBBinder中有个成员变量mObject指向一个Java层的Binder对象。
三者的关系:
    这里写图片描述
从上面1.1.2小节中我们知道BinderProxy中的mObject指向native层中对应的BpBinder对象,同时该BpBinder对象也持有者BinderProxy的一份弱引用,两者相互引用:
      这里写图片描述

  2.1.3 Native层的writeStrongBinder:

//frameworks/native/libs/binder/Parcel.cppstatus_t Parcel::writeStrongBinder(const sp<IBinder>& val){    return flatten_binder(ProcessState::self(), val, this);}status_t flatten_binder(const sp<ProcessState>& /*proc*/,    const sp<IBinder>& binder, Parcel* out){    flat_binder_object obj;    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;    if (binder != NULL) {        IBinder *local = binder->localBinder();        if (!local) {            BpBinder *proxy = binder->remoteBinder();            const int32_t handle = proxy ? proxy->handle() : 0;            obj.type = BINDER_TYPE_HANDLE;            obj.handle = handle;        } else {            obj.type = BINDER_TYPE_BINDER;            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());            obj.cookie = reinterpret_cast<uintptr_t>(local);        }    } ...    return finish_flatten_binder(binder, obj, out);}

  可以看到Native层的writeStrongBinder最终将得到的JavaBBinder对象封装成一个flat_binder_object对象用于写到Parcel数据体中传给Binder驱动,flat_binder_object的数据结构我们在前几篇中见到很多,多为对binder与进程之间对传递的binder对象的封装。
  
  从这里看来,ServiceManagerProxy的addService方法中,data.writeStrongBinder(service);这一步加入的并不是PKMS本身,而是与PKMS对象对应的JavaBBinder对象,将这个JavaBBinder这个对象传递到binder驱动中,最终加入到service_manager中的也是这个JavaBBinder。

2.2 执行BinderProxy的transact方法:

  接着执行mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0)方法,由上面的分析我们得知mRemote实际上是BinderProxy(BpBinder(0)),因此下面会调用到BinderProxy中的transact方法:
  我们接着看下BinderProxy中的transact()方法:

//frameworks/base/core/java/android/os/Binder.java$BinderProxy final class BinderProxy implements IBinder {    ...    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");        if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }        return transactNative(code, data, reply, flags);    }    public native boolean transactNative(int code, Parcel data, Parcel reply,            int flags) throws RemoteException;    ...}

  BinderProxy的transact()方法调用到native方法transactNative(),我们看到transactNative()中的四个参数和native层的BpBinder的transact方法中的参数正好一一对应。
我们看下transactNative的实现地方:

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException{    //将java对象转化为native对象    Parcel* data = parcelForJavaObject(env, dataObj);    Parcel* reply = parcelForJavaObject(env, replyObj);    //得到native层的BpBinder,    IBinder* target = (IBinder*)        env->GetLongField(obj, gBinderProxyOffsets.mObject);    ...    //通过BpBinder利用IPCThreadState,将请求写入binder驱动,继而传给service_manager进程    status_t err = target->transact(code, *data, reply, flags);    ...}

  同过上面分析我们知道BinderProxy的mObject保存的是对应的BpBinder的引用,因此这里的target是构造BinderProxy对象时所用到的BpBinder对象,即BpBinder(0)。

2.3 Native层BpBinder向BinderDriver传输请求

  这里就比较熟悉了,最终调用到native层的BpBinder去与binder驱动进行通信,最终由service_manager进程向Binder驱动中去取指令与数据进行处理。这里我们知道发给service_manager进程的指令是ADD_SERVICE_TRANSACTION,
数据是ServiceName及Service对象对应的JavaBBinder。
  Native层的binder机制在前几篇文章中已经叙述的足够详细,请参考Android Framework:Binder(4)-Native Service的注册中的第二节的第3小节,这里不再赘述。

PKMS服务注册小结:
  ServiceManager是公开的管理类,ServiceManager中定义了公开的接口方法,而这些接口方法中通过ServiceManagerNative类调用ServiceManager代理对象ServiceManagerProxy中的方法来实现,
而ServiceManagerProxy中持有一个由service_manager的Bp端代理BpBinder(0)构造出来的BinderProxy对象,在执行ServiceManagerProxy中对应的方法时会执行到BinderProxy的transact方法,通过传入
BinderProxy的transact()中的操作指令不同来实现不同的方法。
  
  至此,我们跟踪了PKMS初始化向service_manager注册自己的过程。
上图总结下:

这里写图片描述
  

四、跨进程调用PKMS服务

  这里以PackageInstaller使用PackageManager卸载应用为例进行学习;

/packages/apps/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.javaprivate void uninstallPackage(Bundle argsBundle) {        final PackageManager pm = getPackageManager();        pm.deletePackage(packageName, new PackageDeleteObserver(lock, startId),                PackageManager.DELETE_ALL_USERS);    }

1.获取PKMS服务的代理:

  通过前面的学习我们知道要调用Service方法需要先获得Service的代理,所以这里先看如何得到PKMS的代理:

    public static IPackageManager getPackageManager() {        if (sPackageManager != null) {            return sPackageManager;        }        IBinder b = ServiceManager.getService("package");        sPackageManager = IPackageManager.Stub.asInterface(b);        return sPackageManager;    }

1.1 获取SM服务代理,向SM请求获取PKMS的服务代理:

  要得到PKMS的代理需要借助ServiceManager的getService()方法,参数为PKMS注册时注册的名字”package”,而ServiceManager的getService()方法大部分步骤和第三节分析的addService步骤是一致的:
1. 获取ServiceManager的代理对象ServiceManagerProxy(BinderProxy(BpBinder(0))),
2. 调用ServiceManagerProxy的getService方法,
3. 调用BinderProxy的transact()方法,传入的操作指令code是GET_SERVICE_TRANSACTION,

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

  从上面的分析知mRemote实际是BinderProxy(BpBinder(0)),执行BinderProxy的transact()方法,然后调用到其native的实现方法,android_os_BinderProxy_transact(),在这个native方法中先获取该BinderProxy中mObject中保存的BpBinder对象,再调用该BpBinder的transact()方法实现与binder驱动通信,进而与service_manager进程通信得到写在指针reply地址中的返回数据。
  在native层的binder介绍中我们知道reply指针指向的地址中是service_manager返回的包含PKMS handle值的flat_binder_object类型对象;
  

1.2 readStongBinder获取Java层PKMS的代理Binder对象:

  看下面这一步:

 Binder binder = reply.readStrongBinder();

  调用了Parcel.java中的readStrongBinder()方法:

    public final IBinder readStrongBinder() {        return nativeReadStrongBinder(mNativePtr);    }

  nativeReadStrongBinder方法是个Native方法,找到它native实现的地方:

//frameworks/base/core/jni/android_os_Parcel.cppstatic jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr){    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);    if (parcel != NULL) {        return javaObjectForIBinder(env, parcel->readStrongBinder());    }    return NULL;}

  又是两步操作,第一步是Native的Parcel的readStrongBinder()方法,第二步又是这个javaObejctForIBinder()方法。
 
1.2.1 Native Parcell的readStrongBinder
  先看这一步,parcel->readStrongBinder():

status_t Parcel::readStrongBinder(sp<IBinder>* val) const{   //    return unflatten_binder(ProcessState::self(), *this, val);}

unflatten_binder()中主要将binder驱动传过来的包含PMS的handle值的flat_binder_object对象还原成BpBinder(handle)对象写至val指针指向的地址上。

status_t unflatten_binder(const sp<ProcessState>& proc,    const Parcel& in, sp<IBinder>* out){    const flat_binder_object* flat = in.readObject(false);    if (flat) {        switch (flat->type) {            case BINDER_TYPE_BINDER:                *out = reinterpret_cast<IBinder*>(flat->cookie);                return finish_unflatten_binder(NULL, *flat, in);            case BINDER_TYPE_HANDLE:                *out = proc->getStrongProxyForHandle(flat->handle);                return finish_unflatten_binder(                    static_cast<BpBinder*>(out->get()), *flat, in);        }    }    return BAD_TYPE;}

  之前在第二节的第2.1.3小节中分析过Native Parcel类的writeStrongBinder方法,是将JavaBBinder对象打扁成flat_binder_object类型的对象,以这样的类型向binder驱动传递binder对象;这里的readStrongBinder方法正好和它相反,是将Binder驱动传递过来的flat_binder_object对象(service_manager查询到PKMS的handle值然后构造封装成flat_binder_object对象通过binder驱动返回请求的cilent端)unflatten还原成一个对应的BpBinder(handle)对象,这个BpBinder对象就是PKMS 在native层Bp端的代理BpBinder。
1.2.2 JNI层中的javaObjectForIBinder方法:
  而在上面第二节的1.1小节中我们分析了javaObjectForIBinder函数的作用:javaObjectForIBinder(env,BpBinder(handle))会将第二个参数BpBinder(handle)转化成一个BinderProxy对象返回给Java层。
  这样Client端就得到了PMSjava层的代理Binder对象BinderProxy(BpBinder(handle)).

1.3 xx.stub.asInterface获取PKMS服务的proxy(BinderProxy)

sPackageManager = IPackageManager.Stub.asInterface(b);

  我们在Android Framework源码中没有搜到IPackageManager.Stub.asInterface的定义的地方,原因是这个定义的地方是Android跟据IPackageManager.aidl文件在编译时生成的在out目录下我们搜到了IPackageManager.java。
  简要摘录点IPackageManager.java的code,整理下结构方便查看:

//out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/pm/IPackageManager.javapublic interface IPackageManager extends android.os.IInterface {    public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager {        private static final java.lang.String DESCRIPTOR = "android.content.pm.IPackageManager";        public Stub() {            this.attachInterface(this, DESCRIPTOR);        }        public static android.content.pm.IPackageManager asInterface(android.os.IBinder obj) {            if ((obj == null)) {                return null;            }            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);            if (((iin != null) && (iin instanceof android.content.pm.IPackageManager))) {                return ((android.content.pm.IPackageManager) iin);            }            return new android.content.pm.IPackageManager.Stub.Proxy(obj);        }        @Override        public android.os.IBinder asBinder() {            return this;        }        @Override        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {            switch (code) {                case INTERFACE_TRANSACTION: {...}                case TRANSACTION_checkPackageStartable: {...}                case TRANSACTION_isPackageAvailable: {...}                ....            }            ...        }        ...        private static class Proxy implements android.content.pm.IPackageManager        {            private android.os.IBinder mRemote;            Proxy(android.os.IBinder remote)            {                mRemote = remote;            }            @Override public android.os.IBinder asBinder()            {                return mRemote;            }            public java.lang.String getInterfaceDescriptor()            {                return DESCRIPTOR;            }            @Override public void checkPackageStartable(java.lang.String packageName, int userId) throws android.os.RemoteException            {   ...                mRemote.transact(Stub.TRANSACTION_checkPackageStartable, _data, _reply, 0);            }            @Override public boolean isPackageAvailable(java.lang.String packageName, int userId) throws android.os.RemoteException            {                ...                    mRemote.transact(Stub.TRANSACTION_isPackageAvailable, _data, _reply, 0);                ...            }        }    }    ...}

  查看上面的code之后看到IPackageManager.Stub.asInterface(b)之后得到一个android.content.pm.IPackageManager.Stub.Proxy(obj)的对象(下面简写为PKMProxy实在是太长了好吓人)赋值给sPackageManager。这个对象即是PackageManagerService的代理对象,obj是传入的Binderproxy(BpBinder(handle))的PMS的代理Binder对象。
  这里和上面得到ServiceManager的代理对象类似,ServiceManager得到的是ServiceManagerProxy(BinderProxy(BpBinder(0)))。
至此,我们及得到了PKMS服务的代理类对象PKMProxy,下面就可以使用PKMSProxy类对象进行PKMS的方法调用了。

2. 使用PKMProxy类对象调用PKMS方法

2.1 PKMS家族主要结构

  
这里写图片描述

  1. android.content.pm.IPackageManager.Stub.Proxy是在IPackageManager.java中IPackageManager内部类Stub中的内部类,我们看PMS的proxy中实现了IPackageManager的接口,而PKMProxy具体是通过mRemote的transact方法实现。而这个mRemote就是我们new PKMProxy(obj)时传入的BinderProxy(BpBidner(handle))对象。
  2. BinderProxy由对应的BpBinder构造而来,且BinderProxy与BpBinder相互引用,BinderProxy的transact()方法会通过JNI层调用到对应的成员变量mObject中的BpBinder的transact()方法;
  3. 通过JNI层的支持,native层的JavaBBinder对象对java层的Binder持有引用,在Binder初始化时即通过JavaBBinderHolder持有了Java Binder的引用,Java Binder的引用保存在JavaBBinder的成员变量mObject中,因此PKMS响应时是由JavaBBinder这个BBinder的子类通过JNI层通知上层Java Binder继而实现java层服务的响应请求。

2.2 使用PKMS服务代理调用服务方法

  同Servicemanager中分析的,执行BinderProxy对象的transact()方法通过JNI层的传递调用到native层中对应的BpBinder(handle)的transact()方法,接下来就是通过BpBinder中的IPCThreadState与Binder驱动进行交互了。

3 PKMS服务响应Client端请求

  我们知道PackageManagerService是跑在SystemServer进程里的,Zygote的第一个子进程就是SystemServer,在启动SystemServer进程后期会去为SystemServer起一个Binder线程用于SystemServer与Binder驱动进程通信。

///frameworks/base/cmds/app_process/app_main.cppvirtual void onZygoteInit()  {      sp<ProcessState> proc = ProcessState::self();      proc->startThreadPool(); // 启动一个线程,用于Binder通信。  }  

  从之前的BinderNative学习中知道proc->startThreadPool()即是启动了一个线程用于Binder通信了,具体可以看Android Framework:Binder(4)-Native Service的注册中的第二节的第4小节 “4.Service线程池管理,处理请求”相关的分析。
  也就是说同样的SystemServer进程中也是有个Binder线程在不断向Binder驱动查看是否有请求数据。
  

3.1 PKMS进程读取Binder驱动请求数据调用JavaBBinder的onTransact()方法

  当有个systemServer的请求时会调用systemserver进程的IPCThreadState的joinThreadPool里调用getAndExecuteCommand()函数去处理请求,最终会调用到BBinder的transact()处理请求,transact会调用虚函数onTransact(),而此时JavaBBinder继承自BBinder,所以会调用JavaBBinder::onTransact()方法:

//frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinder  virtual status_t onTransact(        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)    {        JNIEnv* env = javavm_to_jnienv(mVM);        ...        //通过JNI调用了java类的方法        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,            code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);        return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;    }

3.2 JavaBBinder通过JNI层调用到Java Binder的execTransact方法:

  前面我们知道了,Java实现的Service中,Service对象,JavaBBinderHolder,JavaBBinder存在相互引用关系,JavaBBinder的成员mObject引用了Java中的Service的Binder对象,比如此处的PMS,而且在int_register_android_os_Binder中通过

gBinderOffsets.mExecTransact  = env->GetMethodID(clazz, "execTransact", "(IIII)Z");

将Service的execTransact方法(其实是Binder的方法)保存在了gBinderOffsets.mExecTransact中,所在以JavaBBinder::onTransact中会调用Binder.execTransact。

public class Binder implements IBinder { // Entry point from android_util_Binder.cpp's onTransact    private boolean execTransact(int code, long dataObj, long replyObj,            int flags) {        Parcel data = Parcel.obtain(dataObj);        Parcel reply = Parcel.obtain(replyObj);        boolean res;        try {            res = onTransact(code, data, reply, flags);        } catch{...}    }}

3.3 Java Binder调用子类stub类中的onTransact()方法:

  在Binder.execTransact中调用了onTransact,执行子类即IPackageManager.stub类的onTransact()方法

//out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/pm/IPackageManager.javapublic static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager {    ...  @Override   public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {            switch (code){                case INTERFACE_TRANSACTION:{return;}                ...                case TRANSACTION_deletePackage:{                    data.enforceInterface(DESCRIPTOR);                    java.lang.String _arg0;                    _arg0 = data.readString();                    android.content.pm.IPackageDeleteObserver2 _arg1;                    _arg1 = android.content.pm.IPackageDeleteObserver2.Stub.asInterface(data.readStrongBinder());                    int _arg2;                    _arg2 = data.readInt();                    int _arg3;                    _arg3 = data.readInt();                    this.deletePackage(_arg0, _arg1, _arg2, _arg3);//调到这里                    reply.writeNoException();                    return true;                }                ...              }              ...      }    ...}

3.4 stub类onTransact()方法调用子类Service类的接口方法完成服务调用:

  在IPackageManager.stub的onTransact方法中中根据code值执行相应的方法这里即调用 this.deletePackage()方法,最终则调用PackageManagerService类(继承自Stub)中相应的deletePackage()接口方法,执行该接口方法的功能。
  
  至此,完成了Client端跨进程调用PKMS的deletePackage服务方法。

五、Java层Binder机制总结

  1. Java层Binder机制依赖于Native层的Binder框架,是对Native层的binder进行了java层的封装,通过JNI层进行联系。
  2. java层的binder机制的跨进程调用主要可以通过以下这张图高度概括:
    这里写图片描述
    • Client端通过获取Service端的服务代理XXServiceProxy来和Binder驱动进行通信;
    • Service端有一个Binder线程监听着Binder驱动,监听到有发向自己的请求即通过native层的BBinder子类JavaBBinder经由JNI层通知到Java层的Binder子类IXXService.stub,从而通知到stub的子类Service的实现方法;
    • Client端Service的服务代理XXServiceProxy持有一个BinderProxy类型的成员变量mRemote,该变量通过JNI层技术与native层的BpBinder对象相互持有引用,而BpBinder中的IPCThreadState与Binder驱动进行交流,通过这样的联系达到Java层Client端与Binder驱动交流的目的
    • JavaBBinder对象通过JavaBBinderHolder与Java层的Binder类相互引用联系,而JavaBBinder的父类BBinder与BpBinder是一一对应的,这样Client端Binder代理对象经过Binder驱动与Server端Binder对象也建立了对应的
      关系.
  3. Java层的Service其实就是个Binder,Service是Binder的子类的子类 ,Client端获取的是Binder的代理。
  4. 引用邓凡平的书中的经典的话,从通信的角度看,Binder的架构不论采用Native语言还是Java语言,都是Client要把请求传递到Binder驱动,Server端从Binder驱动中获取数据,通信的目的是向binder发送请求和接收回复。
  5. 本文只讲述了系统核心服务PKMS的注册及跨进程调用,当然跨进程调用的服务不止这些,日后继续分析普通service的跨进程调用,aidl的使用,以及应用层service的注册及调用细节。

参考博客:
Android FrameWork——Binder机制详解(1)
http://blog.csdn.net/stonecao/article/details/6657438
Android情景分析之深入解析system_server
http://blog.csdn.net/hu3167343/article/details/38375167
Binder in java
http://www.cnblogs.com/angeldevil/p/3328748.html
Android7.0 Binder通信(4) Java层中的Binder
http://blog.csdn.net/gaugamela/article/details/52577381
Binder机制4—Framework层
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0319/2622.html
《深入理解Android卷2》第2章 深入理解Java Binder 邓凡平

阅读全文
0 0
原创粉丝点击