当前位置:网站首页>(O)ServiceManager分析(一)之BinderInternal.getContextObject

(O)ServiceManager分析(一)之BinderInternal.getContextObject

2020-11-08 16:12:00 天王盖地虎626

1. Binder, JNI函数的注册
在分析BinderInternal的getContextObject函数之前,我们有必要先看一下Binder中JNI函数的注册情况

android_os_Binder.cpp

int register_android_os_Binder(JNIEnv* env)
{
    // Leo, 注册Binder的相关JNI函数
    if (int_register_android_os_Binder(env) < 0)
        return -1;
    // Leo, 注册Binderinternal的相关JNI函数
    if (int_register_android_os_BinderInternal(env) < 0)
        return -1;
    // Leo, 注册BinderProxy的相关JNI函数
    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;
 
    jclass clazz = FindClassOrDie(env, "android/util/Log");
    gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
 
    clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
    gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
                                                                 "(Ljava/io/FileDescriptor;)V");
 
    clazz = FindClassOrDie(env, "android/os/StrictMode");
    gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
            "onBinderStrictModePolicyChange", "(I)V");
 
    return 0;
}
至于为什么会开始走到这个方法,我们在此不讨论
这个方法,主要是,调用了各个register方法,注册了一些JNI函数,那么具体怎么注册的,我们进入方法中查看,先看int_register_android_os_Binder
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 }
};
 
const char* const kBinderPathName = "android/os/Binder";
 
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");
    gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
 
    return RegisterMethodsOrDie(
        env, kBinderPathName,
        gBinderMethods, NELEM(gBinderMethods));
}
static struct bindernative_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mExecTransact;
 
    // Object state.
    jfieldID mObject;
 
} gBinderOffsets;
那么,从这个方法,我们可以看到,将gBinderOffsets和Java世界android.os.Binder类,进行关联,并且指定
gBinderOffsets.mClass为android.os.Binder类

gBinderOffsets.mExecTransact为android.os.Binder.execTransact方法

gBinderOffsets.mObject对应为android.os.Binder的mObject对象所对应的值

并且,将gBinderMethods中所对应的Java世界的方法和C世界的相对应的方法一一对应

那么上述的其他两个方法,所达到的目的也是和上述方法一致,我们可以得出如下的其他结论

1). BinderInternal

static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    // Leo, 将android_os_BinderInternal_getContextObject方法和com.android.internal.os.BinderInternal.getContextObject方法进行绑定
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    // Leo, 将android_os_BinderInternal_joinThreadPool方法和com.android.internal.os.BinderInternal.joinThreadPool方法进行绑定
    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
    // Leo, 将android_os_BinderInternal_disableBackgroundScheduling方法和com.android.internal.os.BinderInternal.disableBackgroundScheduling方法进行绑定
    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
    // Leo, 将android_os_BinderInternal_setMaxThreads方法和com.android.internal.os.BinderInternal.setMaxThreads方法进行绑定
    { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
    // Leo, 将android_os_BinderInternal_handleGc方法和com.android.internal.os.BinderInternal.handleGc方法进行绑定
    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
 
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
 
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
 
    // Leo, gBinderInternalOffsets.mClass赋值为BinderInternal.java文件
    gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
 
    // Leo, 注册JNI函数
    return RegisterMethodsOrDie(
        env, kBinderInternalPathName,
        gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
static struct binderinternal_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mForceGc;
 
} gBinderInternalOffsets;
gBinderInternalOffsets.mClass和Java世界的com.android.internal.os.BinderInternal类对应

gBinderInternalOffsets.mForceGc和com.android.internal.os.BinderInternal类中的forceBinderGc方法对应

并且将gBinderInternalMethods所对应的Java世界的方法和C世界对应方法一一对应

2). BinderProxy

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},
};
 
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));
}
static struct binderproxy_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mConstructor;
    jmethodID mSendDeathNotice;
 
    // Object state.
    jfieldID mObject;
    jfieldID mSelf;
    jfieldID mOrgue;
 
} gBinderProxyOffsets;
gBinderProxyOffsets.mClass和Java世界的android.os.BinderProxy类对应

gBinderProxyOffsets.mConstructor和android.os.BinderProxy类中的init方法对应

gBinderProxyOffsets.mSendDeathNotice和android.os.BinderProxy类中的sendDeathNotice方法对应

gBinderProxyOffsets.mSelf和android.os.BinderProxy类中的mSelf对象对应
gBinderProxyOffsets.mObject和android.os.BinderProxy类中的mObject对象对应
并且将gBinderProxyMethods所对应的Java世界的方法和C世界对应方法一一对应

2. BinderInternal.getContextObject函数分析

BinderInternal.java

/**
     * Return the global "context object" of the system.  This is usually
     * an implementation of IServiceManager, which you can use to find
     * other services.
     */
    public static final native IBinder getContextObject();
调用的是native层的getContextObject方法,还记得此前的Binder的JNI注册中,注册的BinderInternal方法么?
static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    // Leo, 将android_os_BinderInternal_getContextObject方法和com.android.internal.os.BinderInternal.getContextObject方法进行绑定
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    // Leo, 将android_os_BinderInternal_joinThreadPool方法和com.android.internal.os.BinderInternal.joinThreadPool方法进行绑定
    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
    // Leo, 将android_os_BinderInternal_disableBackgroundScheduling方法和com.android.internal.os.BinderInternal.disableBackgroundScheduling方法进行绑定
    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
    // Leo, 将android_os_BinderInternal_setMaxThreads方法和com.android.internal.os.BinderInternal.setMaxThreads方法进行绑定
    { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
    // Leo, 将android_os_BinderInternal_handleGc方法和com.android.internal.os.BinderInternal.handleGc方法进行绑定
    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
getContextObject和android_util_Binder.cpp文件中的android_os_BinderInternal_getContextObject方法对应
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    // Leo, 返回的是new BpBinder(0)
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    // Leo, 这个方法是JNI的应用,返回的是BinderProxy
    return javaObjectForIBinder(env, b);
}
此处主要是调用了两个方法,那么我们一个个地来看
3. ProcessState的getContextObject方法

ProcessState.cpp

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    // Leo, 初始化ProcessState对象
    gProcess = new ProcessState;
    return gProcess;
}
OK,单例模式,初始化ProcessState
ProcessState::ProcessState()
    : mDriverFD(open_driver()) // Leo, 打开binder设备
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
    if (mDriverFD >= 0) {
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        // Leo, 为binder设备分配地址空间
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
            close(mDriverFD);
            mDriverFD = -1;
        }
    }
 
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}
ProcessState的初始化中,打开了/dev/binder设备,并且为该设备分配地址空间
接下来,调用了其getContextObject方法

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}
再接下来
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
 
    AutoMutex _l(mLock);
 
    handle_entry* e = lookupHandleLocked(handle);
 
    if (e != NULL) {
        ......
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
               ......
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }
 
            b = new BpBinder(handle); 
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            // This little bit of nastyness is to allow us to add a primary
            // reference to the remote proxy when this team doesn't have one
            // but another team is sending the handle to us.
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }
 
    return result;
}
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {
        handle_entry e;
        e.binder = NULL;
        e.refs = NULL;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return NULL;
    }
    return &mHandleToObject.editItemAt(handle);
}
从这儿看,先调用lookupHandleLocked方法,由于是第一次调用,因此新建一个handle_entry,并返回,而且其binder和refs为NULL
那么getStrongProxyForHandle方法接着往下走,由于binder为NULL,mHandle传入的是0,因此进入判断条件中,最后new BpBinder,且参数为0

因此,
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
返回的是new BpBinder(0)
4. javaObjectForIBinder方法解析

// Leo, val 为 new BpBinder(0)
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    // Leo, 不为NULL
    if (val == NULL) return NULL;
 
    /*
     * Leo, 由于BpBinder没有继承Binder的checkSubclass方法
     *      因此调用的是Binder.cpp中的checkSubclass方法,返回false
    */
    if (val->checkSubclass(&gBinderOffsets)) {
        // One of our own!
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
        return object;
    }
 
    // For the rest of the function we will hold this lock, to serialize
    // looking/creation/destruction of Java proxies for native Binder proxies.
    AutoMutex _l(mProxyLock);
 
    // Someone else's...  do we know about it?
    // Leo, 第一次进来,显然是没有的
    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
    if (object != NULL) {
        jobject res = jniGetReferent(env, object);
        if (res != NULL) {
            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
            return res;
        }
        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
        android_atomic_dec(&gNumProxyRefs);
        val->detachObject(&gBinderProxyOffsets);
        env->DeleteGlobalRef(object);
    }
 
    // Leo, gBinderProxyOffsets.mClass = android/os/BinderProxy
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
        // The proxy holds a reference to the native object.
        // Leo, gBinderProxyOffsets.mObject赋值为new BpBinder(0)
        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));
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);
 
        // Also remember the death recipients registered on this proxy
        sp<DeathRecipientList> drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);
        env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
 
        // Note that a new object reference has been created.
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }
 
    return object;
}
传入的参数,我们刚刚分析过了,第二个参数为new BpBinder(0),而BpBinder没有继承父类的checkSubclass方法,因此调用了其父类的该方法,返回false
而jobject object = (jobject)val->findObject(&gBinderProxyOffsets);第一次,显然为NULL,因此,接着往下

gBinderProxyOffsets.mClass,这个,此前我们有分析Binder的JNI注册,确认该值为android.os.BinderProxy

gBinderProxyOffsets.mConstructor,为其构造方法

因此,该语句返回的是Java层的对象BinderProxy

接下来,

env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
将new BpBinder(0)赋值给gBinderProxyOffsets.mObject
至此,整个BinderInternal.getContextObject的流程,分析到此,就清晰了,初始化并返回的是BinderProxy对象,而且将BinderInternal的mObject对象赋值为new BpBinder(0)

版权声明
本文为[天王盖地虎626]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/920274/blog/4706964