当前位置:网站首页>(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
边栏推荐
猜你喜欢
Talking about, check the history of which famous computer viruses, 80% of the people do not know!
华为在5G手机市场占据绝对优势,市调机构对小米的市占出现分歧
It's just right. It's the ideal state
.NET 大数据量并发解决方案
非常规聚合问题举例
Flink从入门到真香(6、Flink实现UDF函数-实现更细粒度的控制流)
软件开发中如何与人协作? | 每日趣闻
This paper analyzes the top ten Internet of things applications in 2020!
新型存算一体芯片诞生,利好人工智能应用~
Tencent, which is good at to C, how to take advantage of Tencent's cloud market share in these industries?
随机推荐
Build simple business monitoring Kanban based on Alibaba cloud log service
Travel notes of Suzhou
Improvement of rate limit for laravel8 update
What is SVG?
浅谈OpenGL之DSA
GopherChina 2020大会
vim-配置教程+源码
C + + things: from rice cookers to rockets, C + + is everywhere
How does Alibaba cloud's maxcompute add (original ODPs) work?
谷歌开源能翻译101种语言的AI模型,只比Facebook多一种
B站stm32视频学习
What are the necessary laws and regulations to know when entering the Internet?
Improvement of maintenance mode of laravel8 update
Flink从入门到真香(6、Flink实现UDF函数-实现更细粒度的控制流)
金融领域首个开源中文BERT预训练模型,熵简科技推出FinBERT 1.0
构建者模式(Builder pattern)
How to make a correct summary for 7 years?
Workers, workers soul, draw lifelong members, become a person!
AQS解析
On the confirmation of original data assets