Android学习(七)由MediaPlayer切入(3)

MediaPlayer切入(3

继续MediaPlayer的分析:

/*\frameworks\av\media\libmedia\mediaplayer.cpp*/

status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)

{

    ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);

    status_t err = UNKNOWN_ERROR;

    const sp<IMediaPlayerService>& service(getMediaPlayerService());

    if (service != 0) {

        sp<IMediaPlayer> player(service->create(this, mAudioSessionId));

        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||

            (NO_ERROR != player->setDataSource(fd, offset, length))) {

            player.clear();

        }

        err = attachNewPlayer(player);

    }

    return err;

}

通过getMediaPlayerService()的调用,得到了一个BpMediaPlayerService对象了。

接下来分析service->create(this, mAudioSessionId)

    virtual sp<IMediaPlayer> create(

            const sp<IMediaPlayerClient>& client, int audioSessionId) {

        Parcel data, reply;

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

        data.writeStrongBinder(client->asBinder());

        data.writeInt32(audioSessionId);

 

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

        return interface_cast<IMediaPlayer>(reply.readStrongBinder());

    }

同样是调用remote()->transact(CREATE, data, &reply);只不过现在BpBinderhandle值是MediaPlayerServicehandle值,发送的指令也变成了CREATE

/*\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;

}

看看CREATE的定义:

enum {

    CREATE = IBinder::FIRST_CALL_TRANSACTION,

    DECODE_URL,

    DECODE_FD,

    CREATE_MEDIA_RECORDER,

    CREATE_METADATA_RETRIEVER,

    GET_OMX,

    MAKE_CRYPTO,

    MAKE_DRM,

    MAKE_HDCP,

    ADD_BATTERY_DATA,

    PULL_BATTERY_DATA,

    LISTEN_FOR_REMOTE_DISPLAY,

    UPDATE_PROXY_CONFIG,

};

可见CREATE值为1

status_t IPCThreadState::executeCommand(int32_t cmd)

{

    case BR_TRANSACTION:

        {

            binder_transaction_data tr;

            result = mIn.read(&tr, sizeof(tr));

            ALOG_ASSERT(result == NO_ERROR,

                "Not enough command data for brTRANSACTION");

            if (result != NO_ERROR) break;

           

            Parcel buffer;à定义一个buff,然后填充数据

            buffer.ipcSetDataReference(

                reinterpret_cast<const uint8_t*>(tr.dataNaNr.buffer),

                tr.data_size,

                reinterpret_cast<const size_t*>(tr.dataNaNr.offsets),

                tr.offsets_size/sizeof(size_t), freeBuffer, this);

           

                        

          

            Parcel reply;

 

            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);

            }

           

           if ((tr.flags & TF_ONE_WAY) == 0) {

                LOG_ONEWAY("Sending reply to %d!", mCallingPid);

                sendReply(reply, 0);

            } else {

                LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);

            }

           

            mCallingPid = origPid;

            mCallingUid = origUid;

           

        }

        break;

 

tr.targetNaNrNULL默认the_context_object(暂时不知道哪里来的)来处理;不为NULL,将tr.cookie强制转换为BBinder,由此可见BBinder就是ServerIPCThreadState沟通的桥梁。

先看看MediaPlayerService的注册过程:

int main(int argc, char** argv)

{

        sp<ProcessState> proc(ProcessState::self());

        sp<IServiceManager> sm = defaultServiceManager();

        ALOGI("ServiceManager: %p", sm.get());

        AudioFlinger::instantiate();

        MediaPlayerService::instantiate();

        CameraService::instantiate();

        AudioPolicyService::instantiate();

        registerExtensions();

        ProcessState::self()->startThreadPool();

        IPCThreadState::self()->joinThreadPool();

}

 

void MediaPlayerService::instantiate() {

    defaultServiceManager()->addService(

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

}

这个地方已经new MediaPlayerService ()一个服务对象。

而看看MediaPlayerService的定义:

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

class MediaPlayerService : public BnMediaPlayerService

{

}

class BnMediaPlayerService: public BnInterface<IMediaPlayerService>

{

}

template<typename INTERFACE>

class BnInterface : public INTERFACE, public BBinder

{

public:

    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);

    virtual const String16&     getInterfaceDescriptor() const;

 

protected:

    virtual IBinder*            onAsBinder();

};

可见MediaPlayerService就是一个BBinder

class BnMediaPlayerService: public BnInterface<IMediaPlayerService>

{

public:

    virtual status_t    onTransact( uint32_t code,

                                    const Parcel& data,

                                    Parcel* reply,

                                    uint32_t flags = 0);

};

然后用onTransact做回调。

到此为止,虽然很多地方还没有了解清楚,但基本知道了BpBinderBnBinderBBinder的区别和联系,了解了ServiceManager的工作流程,也就是基本了解了androidBinder的通信原理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值