开篇
本篇以aosp
分支android-11.0.0_r25
作为基础解析
我们在之前的文章中,从驱动层面分析了Binder
是怎样工作的,但Binder
驱动只涉及传输部分,待传输对象是怎么产生的呢,这就是framework
层的工作了。我们要彻底了解Binder
的工作原理,不仅要去看驱动层,还得去看framework
层以及应用层(AIDL
)
ServiceManager
getIServiceManager
我们还是以第一次见到Binder
的地方ServiceManager
开始分析,我们选取getService
方法来分析(这个方法既有入参也有返回),抛除掉它缓存和log
的部分,最核心的代码就一句getIServiceManager().getService(name)
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
BinderInternal.getContextObject
我们从BinderInternal.getContextObject()
开始看起,这个函数是一个native
函数,他被实现在frameworks/base/core/jni/android_util_Binder.cpp
中
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
ProcessState
我们在这里可以发现一个比较关键的类ProcessState
,它是一个负责打开binder
驱动并进行mmap
映射的单例对象,这从它的self
函数就可以看出来,每个进程只存在一个ProcessState
实例
位置:frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != nullptr) {
return gProcess;
}
gProcess = new ProcessState(kDefaultDriver);
return gProcess;
}
我们来看看它的构造函数
ProcessState::ProcessState(const char *driver)
: mDriverName(String8(driver))
, mDriverFD(open_driver(driver)) //打开binder驱动
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mStarvationStartTimeMs(0)
, mBinderContextCheckFunc(nullptr)
, mBinderContextUserData(nullptr)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
, mCallRestriction(CallRestriction::NONE)
{
if (mDriverFD >= 0) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
...
}
}
这里的:
后是c++
构造函数初始化赋值的一种语法,可以看到其中调用了open_driver
函数打开binder
驱动
static int open_driver(const char *driver)
{
//打开binder驱动
int fd = open(driver, O_RDWR | O_CLOEXEC);
int vers = 0;
//验证binder版本
status_t result = ioctl(fd, BINDER_VERSION, &vers);
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
...
}
//设置binder最大线程数
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
return fd;
}
这里做了三件事,打开binder
驱动、验证binder
版本、设置binder
最大线程数,接着构造函数调用mmap
建立binder
映射,这里面的实现我们已经在Android源码分析 - Binder驱动(上)、(中)、(下)中分析过了,感兴趣的同学可以回过头去看一看
ProcessState::self
函数执行完后,当前进程的binder
初始化工作已经执行完毕,接下来我们回过头来看它的getContextObject
函数
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
sp<IBinder> context = getStrongProxyForHandle(0);
if (context == nullptr) {
ALOGW("Not able to get context object on %s.", mDriverName.c_str());
}
// The root object is special since we get it directly from the driver, it is never
// written by Parcell::writeStrongBinder.
internal::Stability::tryMarkCompilationUnit(context.get());
return context;
}
我们在binder
驱动篇就提到了,handle
句柄0
代表的就是ServiceManager
,所以这里调用getStrongProxyForHandle
函数的参数为0
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
//查找或建立handle对应的handle_entry
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
IBinder* b = e->binder;
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
//当handle为ServiceManager的特殊情况
//需要确保在创建Binder引用之前,context manager已经被binder注册
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
if (status == DEAD_OBJECT)
return nullptr;
}
//创建BpBinder并保存下来以便后面再次查找
b = BpBinder::create(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
const size_t N=mHandleToObject.size();
//新建一个handle_entry并插入到vector中
if (N <= (size_t)handle) {
handle_entry e;
e.binder = nullptr;
e.refs = nullptr;
status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
if (err < NO_ERROR) return nullptr;
}
return &mHandleToObject.editItemAt(handle);
}
整条链路下来还是比较清晰的,最终获得了一个BpBinder
对象,这是native
中的类型,需要将它转换成java
中的类型,这里调用了javaObjectForIBinder
函数,位于frameworks/base/core/jni/android_util_Binder.cpp
中
javaObjectForIBinder
// If the argument is a JavaBBinder, return the Java object that was used to create it.
// Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
// same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
//JavaBBinder返回true,其他类均返回flase
if (val->checkSubclass(&gBinderOffsets)) {
// It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
jobject object = static_cast<JavaBBinder*>(val.get())->object();
return object;
}
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = val;
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.
return NULL;
}
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
//如果object是刚刚新建出来的BinderProxy
if (actualNativeData == nativeData) {
//处理proxy计数
...
} else {
delete nativeData;
}
return object;
}
我们先看一看这个gBinderProxyOffsets
是什么
static struct binderproxy_offsets_t
{
// Class state.
jclass mClass;
jmethodID mGetInstance;
jmethodID mSendDeathNotice;
// Object state.
//指向BinderProxyNativeData的指针
jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
} gBinderProxyOffsets;
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
...
jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDi