Android_Binder—获取BpBinder到BBinder执行对应方法的过程

\frameworks\av\media\libmedia\IMediaDeathNotifier.cpp:

const sp<IMediaPlayerService> IMediaDeathNotifier::getMediaPlayerService()
{
    ALOGV("getMediaPlayerService");
    Mutex::Autolock _l(sServiceLock);
    if (sMediaPlayerService == 0) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            binder = sm->getService(String16("media.player"));
            if (binder != 0) {
                break;
            }
            ALOGW("Media player service not published, waiting...");
            usleep(500000); // 0.5 s
        } while (true);

        if (sDeathNotifier == NULL) {
            sDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(sDeathNotifier);
        sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    }
    ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    return sMediaPlayerService;
}

getService获取服务对应的Binder对象,如果获取不到就一直循环。

获取之后将服务封装成对应的BPMediaPlayerService,有了BpMediaPlayerService,就能够使用任何IMediaPlayerService提供的业务逻辑函数了。

我们知道BpMediaPlayerService只是一个服务代理对象,当我们调用IMediaPlayerService的方法时是怎么调用到服务本体BnMediaPlayerService的方法的呢?

比如调用BpMediaPlayerService的createMetadataRetriever方法

frameworks\av\media\libmedia\IMediaPlayerService.cpp:

    virtual sp<IMediaMetadataRetriever> createMetadataRetriever()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
        remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply);
        return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
    }

frameworks\native\libs\binder\BpBinder.cpp:

status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

这里调用IPCThreadState的transact方法,从前文

Android_Binder—分析MediaServer解析服务的初始化和注册

我们知道服务开启后会进入轮询等待请求接入,而transact该方法就是跟Binder设备通信的,这里我们发送信息给Binder设备。我们知道IPCThreadState是一个线程一个单例,所以我们跟到IPCThreadState的executeCommand方法中:

    case BR_TRANSACTION:
        {
            binder_transaction_data_secctx tr_secctx;
            binder_transaction_data& tr = tr_secctx.transaction_data;

            if (cmd == (int) BR_TRANSACTION_SEC_CTX) {
                result = mIn.read(&tr_secctx, sizeof(tr_secctx));
            } else {
                result = mIn.read(&tr, sizeof(tr));
                tr_secctx.secctx = 0;
            }

            ALOG_ASSERT(result == NO_ERROR,
                "Not enough command data for brTRANSACTION");
            if (result != NO_ERROR) break;

            //Record the fact that we're in a binder call.
            mIPCThreadStateBase->pushCurrentState(
                IPCThreadStateBase::CallState::BINDER);
            Parcel buffer;
            buffer.ipcSetDataReference(
                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                tr.data_size,
                reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);

            const pid_t origPid = mCallingPid;
            const char* origSid = mCallingSid;
            const uid_t origUid = mCallingUid;
            const int32_t origStrictModePolicy = mStrictModePolicy;
            const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
            const int32_t origWorkSource = mWorkSource;
            const bool origPropagateWorkSet = mPropagateWorkSource;
            // Calling work source will be set by Parcel#enforceInterface. Parcel#enforceInterface
            // is only guaranteed to be called for AIDL-generated stubs so we reset the work source
            // here to never propagate it.
            clearCallingWorkSource();
            clearPropagateWorkSource();

            mCallingPid = tr.sender_pid;
            mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
            mCallingUid = tr.sender_euid;
            mLastTransactionBinderFlags = tr.flags;

            Parcel reply;
            status_t error;
            if (tr.target.ptr) {
                // We only have a weak reference on the target object, so we must first try to
                // safely acquire a strong reference before doing anything else with it.
                if (reinterpret_cast<RefBase::weakref_type*>(
                        tr.target.ptr)->attemptIncStrong(this)) {
                    error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags);
                    reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
                } else {
                    error = UNKNOWN_TRANSACTION;
                }

            } else {
                error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
            }

            mIPCThreadStateBase->popCurrentState();

            if ((tr.flags & TF_ONE_WAY) == 0) {
                LOG_ONEWAY("Sending reply to %d!", mCallingPid);
                if (error < NO_ERROR) reply.setError(error);
                sendReply(reply, 0);
            } else {
                LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
            }

            mCallingPid = origPid;
            mCallingSid = origSid;
            mCallingUid = origUid;
            mStrictModePolicy = origStrictModePolicy;
            mLastTransactionBinderFlags = origTransactionBinderFlags;
            mWorkSource = origWorkSource;
            mPropagateWorkSource = origPropagateWorkSet;
        }
        break;

主要看这句

error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags);

 这里将tr.cookie强转成BBinder对象并调用了他的transact方法。

所以如果我们忽略掉两个进程底层IPCThreadState之间的通信的话,从一开始的BPBinder调用transact变成了BBinder调用transact方法,相当于BPBinder变成了BBinder,这里的BBinder实际上是MediaPlayerService对象本体,这里只是转化成BBinder,后面会产生动态联编。

frameworks\native\libs\binder\Binder.cpp:

status_t BBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    data.setDataPosition(0);

    status_t err = NO_ERROR;
    switch (code) {
        case PING_TRANSACTION:
            reply->writeInt32(pingBinder());
            break;
        default:
            err = onTransact(code, data, reply, flags);
            break;
    }

    if (reply != nullptr) {
        reply->setDataPosition(0);
    }

    return err;
}

transact又执行了onTransact,关键的地方来了,我们看回MediaPlayerService,为什么是MediaPlayerService呢,回想我们之前分析

frameworks\av\media\mediaserver\main_mediaserver.cpp时,

void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}

 我们添加服务,把MediaPlayerService添加进去了,所以可以看出MediaPlayerService就是服务本体。

frameworks\av\media\libmediaplayerservice\MediaPlayerService.h:

class MediaPlayerService : public BnMediaPlayerService

可以看到MediaPlayerService其实是BnMediaPlayerService的子类,看下BnMediaPlayerService:

frameworks\av\media\libmedia\include\media\IMediaPlayerService.h:

class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

}; // namespace

可以看到头文件BnMediaPlayerService类里面只有一个onTransact的虚方法。

frameworks\native\libs\binder\include\binder\IInterface.h:

这里又回到了IInterface

template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;

protected:
    typedef INTERFACE           BaseInterface;
    virtual IBinder*            onAsBinder();
};

所以继承关系:

MediaPlayerService:BnMediaPlayerService:BnInterface:BBinder 

找一下这些类里哪实现了onTransact方法:

frameworks\av\media\libmedia\IMediaPlayerService.cpp:

status_t BnMediaPlayerService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch (code) {
....
        case CREATE_METADATA_RETRIEVER: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp<IMediaMetadataRetriever> retriever = createMetadataRetriever();
            reply->writeStrongBinder(IInterface::asBinder(retriever));
            return NO_ERROR;
        } break;
....
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

回到一开始我们调用的是BpMediaPlayerService的createMetadataRetriever方法,可以看到onTransact直接调用了createMetadataRetriever,哪里实现了这个方法呢?

frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp

sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever()
{
    pid_t pid = IPCThreadState::self()->getCallingPid();
    sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid);
    ALOGV("Create new media retriever from pid %d", pid);
    return retriever;
}

这里还有个问题,MediaPlayerService不是BnMediaPlayerService的子类吗,为什么onTransact里面父类BnMediaPlayerService可以直接调用子类的createMetadataRetriever?这里就实际到动态联编了。

class BnMediaPlayerService: public BnInterface<IMediaPlayerService>

重新看回BnInterface,

template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder

替换一下

template<typename IMediaPlayerService>
class BnInterface : public IMediaPlayerService, public BBinder

可以发现BnInterface实现了 IMediaPlayerService接口,

frameworks\av\media\libmedia\include\media\IMediaPlayerService.h:

class IMediaPlayerService: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayerService);

    virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) = 0;
    virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0;
.....
}

IMediaPlayerService接口里面的createMediaRecorder是纯虚函数,因为当前指针指向的其实是MediaPlayerService所以明面是的BBinder调用onTransact,然后调用createMediaRecorder,实际上都是MediaPlayerService类里面的方法。

真相大白了。

所以Client向ServiceManager获取了BpBinder的对象后,调用transact方法通过Client线程的IPCThreadState通信,Service进程的IPCThreadState接受到请求,进入executeCommand方法,调用BnBinder的onTransact方法(该方法具体实现在对应的BnXXService里面),onTransact方法再根据Client请求调用了对应的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值