您的位置:首页 > 移动开发 > Objective-C

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

2017-08-18 15:07 417 查看
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
4000
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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: