专栏名称: 刘望舒
腾讯云最具价值专家
目录
相关文章推荐
复利大王  ·  520怀孕事件? ·  8 小时前  
复利大王  ·  卷疯了:食堂档口末位淘汰 ·  昨天  
鸿洋  ·  2025 Google I/O 带来的 ... ·  2 天前  
复利大王  ·  北大软微男在女厕所偷拍! ·  2 天前  
复利大王  ·  工行软开不续签? ·  2 天前  
51好读  ›  专栏  ›  刘望舒

Android Binder原理(五)系统服务的获取过程

刘望舒  · 掘金  · android  · 2019-11-27 05:05

正文

请到「今天看啥」查看全文


注释2处的获取服务是本文的重点,BpServiceManager的getService函数如下所示。 frameworks/native/libs/binder/IServiceManager.cpp::BpServiceManager

 virtual sp<IBinder> getService(const String16& name) const
    {
       ...
        int n = 0;
        while (uptimeMillis() < timeout) {
            n++;
            if (isVendorService) {
                ALOGI("Waiting for vendor service %s...", String8(name).string());
                CallStack stack(LOG_TAG);
            } else if (n%10 == 0) {
                ALOGI("Waiting for service %s...", String8(name).string());
            }
            usleep(1000*sleepTime);

            sp<IBinder> svc = checkService(name);//1
            if (svc != NULL) return svc;
        }
        ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
        return NULL;
    }
复制代码

getService函数中主要做的事就是循环的查询服务是否存在,如果不存在就继续查询,查询服务用到了注释1处的checkService函数,代码如下所示。
frameworks/native/libs/binder/IServiceManager.cpp::BpServiceManager

    virtual sp<IBinder> checkService( const String16& name) const
    {
        Parcel data, reply;//1
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);//2
        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);//3
        return reply.readStrongBinder();
    }
复制代码

注释1处的data,看过上一篇文章的同学应该很熟悉,它出现在BpServiceManager的addService函数中,data是一个数据包,后面会不断的将数据写入到data中。注释2处将字符串"media.player"写入到data中。 注释3处的remote()指的是mRemote,也就是BpBinder,BpBinder的transact函数如下所示。

frameworks/native/libs/binder/BpBinder.cpp

status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}
复制代码

BpBinder将逻辑处理交给IPCThreadState,后面的调用链在= Android Binder原理(三)系统服务的注册过程 中讲过,这里再次简单的过一遍,IPCThreadState::self()会创建创建IPCThreadState,IPCThreadState的transact函数如下所示。
frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    status_t err;

    flags |= TF_ACCEPT_FDS;
    ...
    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);//1

    if (err != NO_ERROR) {
        if (reply) reply->setError(err);
        return (mLastError = err);
    }

    if ((flags & TF_ONE_WAY) == 0) {
       ...
        if (reply) {
            err = waitForResponse(reply);//2
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
       ...
    } else {
       //不需要等待reply的分支
        err = waitForResponse(NULL, NULL);
    }

    return err;
}
复制代码

调用BpBinder的transact函数实际上就是调用IPCThreadState的transact函数。注释1处的writeTransactionData函数用于传输数据,其中第一个参数BC_TRANSACTION代表向Binder驱动发送命令协议。 注释1处的writeTransactionData用于准备发送的数据,其内部会将BC_TRANSACTION和binder_transaction_data结构体写入到mOut中。 接着查看waitForResponse函数做了什么,代码如下所示。







请到「今天看啥」查看全文