Android源码分析 - Framework层的Binder(客户端篇)

开篇

本篇以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
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值