javaObjectForIBinder和ibinderForJavaObject源码分析

494 阅读3分钟

android28 系统源码

参考文档ibinderForJavaObject 与 javaObjectForIBinder

主要类介绍

1 Binder代理:

BinderProxy(Java):java层对象,具有跨进程能力(通过BpBinder)

BinderProxyNativeData(C++结构体):持有BpBinder对象,BinderProxy.mNativeData中保存BinderProxyNativeData对象地址

BpBinder(C++):BinderProxy对象对应的C++对象,具有跨进程能力

2 Binder本地:

Binder(Java):java层对象,服务端实现类

JavaBBinderHolder(C++):持有JavaBBinder对象

JavaBBinder(C++):Binder对象的C++对象,继承BBinder

binder(1).png

JavaObjectForIBinder和ibinderForJavaObject负责native层Binder对象和java层Binder对象相互转换。

JavaObjectForIBinder()主要作用

1 JavaBBinder对象 =>  Binder对象

2 BpBinder对象  =>  BinderProxy对象

ibinderForJavaObject()主要作用

1 Binder对象  =>  JavaBBinder对象

2 BinderProxy对象  =>  BpBinder对象

具体注释看源码

/frameworks/base/core/jni/android_util_Binder.cpp 
class JavaBBinder : public BBinder{
    ......
    jobject object() const { 
        return mObject; // 保存Binder对象。 
    } 
    ......
} 

struct BinderProxyNativeData {
    // BpBinder对象指针 
    sp<IBinder> mObject;
    .......
};

class JavaBBinderHolder {
    ......
private: 
    Mutex mLock; 
    wp<JavaBBinder> mBinder; // JavaBBinder对象指针 
};

// val 可以JavaBBinder对象,或者BpBinder对象 
jobject javaObjectForIBinder(JNIEnv* env, const sp& val) {
    if (val == NULL) return NULL; 
    // 1 如果是JavaBBinder对象,直接返回对应的Binder对象。 
    if (val->checkSubclass(&gBinderOffsets)) {
        // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object. 
        jobject object = static_cast(val.get())->object(); 
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object); 
        return object; 
    } 
    // 2 如果是BpBinder对象
    AutoMutex _l(gProxyLock); 
    // 使用缓存的BinderProxyNativeData对象,避免重新分配 
    BinderProxyNativeData* nativeData = gNativeDataCache; 
    if (nativeData == nullptr) { 
        nativeData = new BinderProxyNativeData(); 
    }
    
    // 3 通过BinderProxy.getInstance(long nativeData, long iBinder)获得BinderProxy对象 
    // BinderProxy对象可能是新创建的,也可能是已存在的。 
    // 保证一个BpBinder对象对应一个BinderProxy对象。 
    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get()); 
    if (env->ExceptionCheck()) { 
        // In the exception case, getInstance still took ownership of nativeData. 
        gNativeDataCache = nullptr; 
        return NULL; 
    }
    
    // 通过BindProxy.mNativeData,获取对应的BinderProxyNativeData对象 
    BinderProxyNativeData* actualNativeData = getBPNativeData(env, object); 
    if (actualNativeData == nativeData) { 
        // New BinderProxy; we still have exclusive access. 
        // 4 新创建BinderProxy,actualNativeData == nativeData为true。 
        nativeData->mOrgue = new DeathRecipientList; 
        nativeData->mObject = val; 
        gNativeDataCache = nullptr; 
        ++gNumProxies; 
        if (gNumProxies >= gProxiesWarned + PROXY_WARN_INTERVAL) { 
            ALOGW("Unexpectedly many live BinderProxies: %d\n", gNumProxies); 
            gProxiesWarned = gNumProxies; 
        } 
    } else { 
        // 5 使用已存在的BinderProxy,则nativeData在缓存起来,以后使用 
        // nativeData wasn't used. Reuse it the next time. 
        gNativeDataCache = nativeData; 
    } 
    // 返回BinderProxy对象 
    return object;
}

BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) { 
    // 通过BinderProxy.mNativeData获得BinderProxyNativeData对象 
    return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData); 
}

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj){ 
    if (obj == NULL) return NULL; 
    // Instance of Binder? 
    // 1 如果是Binder对象,直接去Binder.mObject(这是JavaBBinderHolder对象) 
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
        JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject); 
        //JavaBBinderHolder.get() 获得JavaBBinder对象 
        return jbh->get(env, obj); 
    } 
    // Instance of BinderProxy? 
    // 2 如果是BinderProxy对象,通过BinderProxy.mNativeData获得BinderProxyNativeData对象 
    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { 
        // BinderProxyNativeData.mObject就是BpBinder对象
        return getBPNativeData(env, obj)->mObject;
    } 
    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj); return NULL; 
}


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); 
    
    // BinderProxy.getInstance() 根据BpBinder地址,获得BinderProxy 
    gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance", "(JJ)Landroid/os/BinderProxy;"); 
    
    gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V"); 
    gBinderProxyOffsets.mDumpProxyDebugInfo = GetStaticMethodIDOrDie(env, clazz, "dumpProxyDebugInfo", "()V"); 
    
    // BinderProxy.mNativeData,保存C++的BinderProxyNativeData对象 
    gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
    
    clazz = FindClassOrDie(env, "java/lang/Class"); 
    gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;"); 
    return RegisterMethodsOrDie( env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods)); 
}

static int int_register_android_os_Binder(JNIEnv* env) { 
    jclass clazz = FindClassOrDie(env, kBinderPathName); 
    gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz); 
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z"); 
    
    // Binder.mObject保存JavaBBinderHolder对象地址,JavaBBinderHolder对象保存这BBinder对象 
    gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
    
    return RegisterMethodsOrDie( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); 
}

final class BinderProxy implements IBinder 

private static BinderProxy getInstance(long nativeData, long iBinder) { 
    BinderProxy result; 
    try { 
        // 以Bpbinder地址为key
        result = sProxyMap.get(iBinder); 
        if (result != null) {
            return result; 
        }
        // 创建BinderProxy,传入BinderProxyNativeData地址
        result = new BinderProxy(nativeData); 
    } catch (Throwable e) { 
        // We're throwing an exception (probably OOME); don't drop nativeData.
        NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer, nativeData); 
        throw e; 
   } 
   NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData); 
   // The registry now owns nativeData, even if registration threw an exception. 
   // 设置map,map的value是弱引用
   sProxyMap.set(iBinder, result); 
   return result; 
}