Android学习(五)由MediaPlaye切入(2)

MediaPlayer切入

        sp<IServiceManager> sm = defaultServiceManager();

        sp<IBinder> binder;

        do {

            binder = sm->getService(String16("media.player"));

这里的sm就是上面的BpServiceManager

/*\frameworks\native\libs\binder\IServiceManager.cpp*/

class BpServiceManager : public BpInterface<IServiceManager>

{

public:

    BpServiceManager(const sp<IBinder>& impl)

        : BpInterface<IServiceManager>(impl)

    {

    }

 

    virtual sp<IBinder> getService(const String16& name) const

    {

        unsigned n;

        for (n = 0; n < 5; n++){

            sp<IBinder> svc = checkService(name);

            if (svc != NULL) return svc;

            ALOGI("Waiting for service %s...\n", String8(name).string());

            sleep(1);

        }

        return NULL;

    }

 

    virtual sp<IBinder> checkService( const String16& name) const

    {

        Parcel data, reply;

        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());

        data.writeString16(name);

        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);

        return reply.readStrongBinder();

    }

 

getService()函数最终调用remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);,先看看remote()是什么:

/*\Android4.4\frameworks\native\include\binder\Binder.h*/

class BpRefBase : public virtual RefBase

{

protected:

                            BpRefBase(const sp<IBinder>& o);

    virtual                 ~BpRefBase();

    virtual void            onFirstRef();

    virtual void            onLastStrongRef(const void* id);

    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);

 

    inline  IBinder*        remote()                { return mRemote; }

    inline  IBinder*        remote() const          { return mRemote; }

 

private:

                            BpRefBase(const BpRefBase& o);

    BpRefBase&              operator=(const BpRefBase& o);

 

    IBinder* const          mRemote;

    RefBase::weakref_type*  mRefs;

    volatile int32_t        mState;

};

所以remote()返回的就是ProcessState::self()->getContextObject(NULL)返回是一个new BpBinder(0)

remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);的代码:

/*\Android4.4\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,每个IPCThreadState中都有一个mIn,一个mOut,其中mIn是用来接收来自Binder设备的数据,而mOut则用来存储发往Binder设备的数据。

上面的BpBindertranscat调用了IPCThreadStatetransact函数,这个函数完成了与Binder的通信:

/*\Android4.4\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 = data.errorCheck();

 

flags |= TF_ACCEPT_FDS;

    if (err == NO_ERROR) {

        LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),

            (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");

        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);

    }

            err = waitForResponse(reply);

}

 

再看看writeTransactionData函数:

/*\Android4.4\frameworks\native\libs\binder\IPCThreadState.cpp*/

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,

    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)

{

    binder_transaction_data tr;

 

    tr.target.handle = handle;

    tr.code = code;

    tr.flags = binderFlags;

    tr.cookie = 0;

    tr.sender_pid = 0;

    tr.sender_euid = 0;

   

    const status_t err = data.errorCheck();

    if (err == NO_ERROR) {

        tr.data_size = data.ipcDataSize();

        tr.dataNaNr.buffer = data.ipcData();

        tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);

        tr.dataNaNr.offsets = data.ipcObjects();

    } else if (statusBuffer) {

        tr.flags |= TF_STATUS_CODE;

        *statusBuffer = err;

        tr.data_size = sizeof(status_t);

        tr.dataNaNr.buffer = statusBuffer;

        tr.offsets_size = 0;

        tr.dataNaNr.offsets = NULL;

    } else {

        return (mLastError = err);

    }

   

    mOut.writeInt32(cmd);

    mOut.write(&tr, sizeof(tr));

   

    return NO_ERROR;

}

这个函数只是把命令写入到mOut中,接下来看waitForResponse(reply)

/*\Android4.4\frameworks\native\libs\binder\IPCThreadState.cpp*/

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)

{

    while (1) {

        if ((err=talkWithDriver()) < NO_ERROR) break;

        err = mIn.errorCheck();

        if (err < NO_ERROR) break;

        if (mIn.dataAvail() == 0) continue;

err = executeCommand(cmd);

}

/*\Android4.4\frameworks\native\libs\binder\IPCThreadState.cpp*/

status_t IPCThreadState::executeCommand(int32_t cmd)

{

case BR_TRANSACTION:

binder_transaction_data tr;

            if (tr.targetNaNr) {

                sp<BBinder> b((BBinder*)tr.cookie);

                const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);

                if (error < NO_ERROR) reply.setError(error);

 

            } else {

                const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);

                if (error < NO_ERROR) reply.setError(error);

            }

}

这里可以看出BBinder是返回结果中的类对象。

先看看remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);CHECK_SERVICE_TRANSACTION是多少:

\Android4.4\frameworks\native\include\binder \ IServiceManager.h

enum {

        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,à1

        CHECK_SERVICE_TRANSACTION,

        ADD_SERVICE_TRANSACTION,

        LIST_SERVICES_TRANSACTION,

};

CHECK_SERVICE_TRANSACTION中值应该为2.

\Android4.4\frameworks\native\cmds\servicemanager\ binder.h

enum {

    SVC_MGR_GET_SERVICE = 1,

    SVC_MGR_CHECK_SERVICE,

    SVC_MGR_ADD_SERVICE,

    SVC_MGR_LIST_SERVICES,

};

对应其中的SVC_MGR_CHECK_SERVICE指令。

\Android4.4\frameworks\native\cmds\servicemanager\ service_manager.c

int svcmgr_handler(struct binder_state *bs,

                   struct binder_txn *txn,

                   struct binder_io *msg,

                   struct binder_io *reply)

{

    struct svcinfo *si;

    uint16_t *s;

    unsigned len;

    void *ptr;

    uint32_t strict_policy;

    int allow_isolated;

 

//    ALOGI("target=%p code=%d pid=%d uid=%d\n",

//         txn->target, txn->code, txn->sender_pid, txn->sender_euid);

 

    if (txn->target != svcmgr_handle)

        return -1;

 

    // Equivalent to Parcel::enforceInterface(), reading the RPC

    // header with the strict mode policy mask and the interface name.

    // Note that we ignore the strict_policy and don't propagate it

    // further (since we do no outbound RPCs anyway).

    strict_policy = bio_get_uint32(msg);

    s = bio_get_string16(msg, &len);

    if ((len != (sizeof(svcmgr_id) / 2)) ||

        memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {

        fprintf(stderr,"invalid id %s\n", str8(s));

        return -1;

    }

 

    switch(txn->code) {

    case SVC_MGR_GET_SERVICE:

    case SVC_MGR_CHECK_SERVICE:

        s = bio_get_string16(msg, &len);

        ptr = do_find_service(bs, s, len, txn->sender_euid);

        if (!ptr)

            break;

        bio_put_ref(reply, ptr);

        return 0;

 

sp<BBinder> b((BBinder*)tr.cookie);

                const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);

这是一个BBinder类,但是针对不同的服务,到底是怎么调用transact的呢?

\Android4.4\frameworks\av\media\libmediaplayerservice\ MediaPlayerService.h

class MediaPlayerService : public BnMediaPlayerService

可见×××Service都是继承自Bn×××Service的,而在服务添加的时候都有这样的动作:

void MediaPlayerService::instantiate() {

    defaultServiceManager()->addService(

            String16("media.player"), new MediaPlayerService());

}

defaultServiceManager()就是返回一个IServiceManager对象

所以在服务注册之后,就返回了BBinder将会得到的对象。

\Android4.4\frameworks\av\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);

};

看看onTransact的定义:

status_t BnServiceManager::onTransact(

    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

    //printf("ServiceManager received: "); data.print();

    switch(code) {

        case GET_SERVICE_TRANSACTION: {

            CHECK_INTERFACE(IServiceManager, data, reply);

            String16 which = data.readString16();

            sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which);

            reply->writeStrongBinder(b);

            return NO_ERROR;

        } break;

        case CHECK_SERVICE_TRANSACTION: {

            CHECK_INTERFACE(IServiceManager, data, reply);

            String16 which = data.readString16();

            sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which);

            reply->writeStrongBinder(b);

            return NO_ERROR;

        } break;

 

看到这里有些容易混淆了,下一步准备好好分析一下getService的思路。

转载于:https://my.oschina.net/honeyandroid/blog/507435

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值