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

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框架:

Android Framework:Binder(6)-Java层Service的注册及跨进程调用_第1张图片

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

  
Android Framework:Binder(6)-Java层Service的注册及跨进程调用_第2张图片

这图是学完整个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.cpp
int 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, "", "()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.java
public 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.java
public static final native IBinder getContextObject();

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

//frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp 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.cpp
jobject javaObjectForIBinder(JNIEnv* env, const sp& 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.java
static 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::ServiceManagerProxy
class 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.java
public final void writeStrongBinder(IBinder val) {
        nativeWriteStrongBinder(mNativePtr, val);
    }

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

//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(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.java
public Binder() {
    init();
    ...
}

private native final void init();

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

//frameworks/base/core/jni/android_util_Binder.cpp
static 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 get(JNIEnv* env, jobject obj)
    {
        sp b = mBinder.promote();
        if (b == NULL) { b = new JavaBBinder(env, obj);mBinder = b; }
        return b;
    }
private:
    wp 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(&data), reinterpret_cast(reply), flags);
    }
private:
    JavaVM* const   mVM;
    jobject const   mObject;
};

  看到JavaBBinder中有个成员变量mObject指向一个Java层的Binder对象。
三者的关系:
    Android Framework:Binder(6)-Java层Service的注册及跨进程调用_第3张图片
从上面1.1.2小节中我们知道BinderProxy中的mObject指向native层中对应的BpBinder对象,同时该BpBinder对象也持有者BinderProxy的一份弱引用,两者相互引用:
      Android Framework:Binder(6)-Java层Service的注册及跨进程调用_第4张图片

  2.1.3 Native层的writeStrongBinder:

//frameworks/native/libs/binder/Parcel.cpp
status_t Parcel::writeStrongBinder(const sp& val)
{
    return flatten_binder(ProcessState::self(), val, this);
}

status_t flatten_binder(const sp& /*proc*/,
    const sp& 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(local->getWeakRefs());
            obj.cookie = reinterpret_cast(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注册自己的过程。
上图总结下:

Android Framework:Binder(6)-Java层Service的注册及跨进程调用_第5张图片
  

四、跨进程调用PKMS服务

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

/packages/apps/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
private 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.cpp
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
    Parcel* parcel = reinterpret_cast(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* 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& proc,
    const Parcel& in, sp* out)
{
    const flat_binder_object* flat = in.readObject(false);

    if (flat) {
        switch (flat->type) {
            case BINDER_TYPE_BINDER:
                *out = reinterpret_cast(flat->cookie);
                return finish_unflatten_binder(NULL, *flat, in);
            case BINDER_TYPE_HANDLE:
                *out = proc->getStrongProxyForHandle(flat->handle);
                return finish_unflatten_binder(
                    static_cast(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.java
public 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家族主要结构

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

  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.cpp
virtual void onZygoteInit()  {  
    sp 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(&data), reinterpret_cast(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.java
public 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机制的跨进程调用主要可以通过以下这张图高度概括:
    Android Framework:Binder(6)-Java层Service的注册及跨进程调用_第7张图片
    • 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 邓凡平

你可能感兴趣的:(Android Framework:Binder(6)-Java层Service的注册及跨进程调用)