MediaPlayer(三)--C++ binder框架

在看这篇文章前,建议先阅读
C++ Binder机制学习(转载)
只是介绍c++层binder通讯的使用流程,并未涉及binder原理机制

结构框架

上一篇文章MediaPlayer--MediaPlayer基本框架没有将C++的mediaplayer binder通讯展开,这篇文章主要展开这一部分。
大概画了下C++ MediaPlayer的uml图,不是很满意,请高手指教

MediaPlayer(三)--C++ binder框架_第1张图片
MediaPlayerBinder.png

这里面主要的client和service实现类是以下两个文件(Android8.1 路径)
frameworks/av/media/libmedia/mediaplayer.cpp
frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

这里面涉及了三对IPC的通讯,即
IMediaPlayerClient
IMediaPlayerService
IMediaPlayer

其中 IMediaPlayerService , IMediaPlayer 的服务端在MediaPlayerService.cpp, 客户端在mediaplayer.cpp。IMediaPlayerClient 的服务端在mediaplayer.cpp, 客户端在MediaPlayerService.cpp, 这是MediaPlayerService回调mediaplayer使用的。 IMediaPlayerService会创建IMediaPlayer的实例

流程

MediaPlayer 同MediaPlayerService通讯 是通过变量 sp mPlayer, mPlayer赋值是在setDataSource

status_t MediaPlayer::setDataSource(
        const sp &httpService,
        const char *url, const KeyedVector *headers)
{
    ALOGV("setDataSource(%s)", url);
    status_t err = BAD_VALUE;
    if (url != NULL) {
        const sp service(getMediaPlayerService());
        if (service != 0) {
            sp player(service->create(this, mAudioSessionId));
            if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
                (NO_ERROR != player->setDataSource(httpService, url, headers))) {
                player.clear();
            }
            err = attachNewPlayer(player);
        }
    }
    return err;
}

关于创建mPlayer这块主要分3步:
1 const sp service(getMediaPlayerService()); 这一步其实是获取了BpMediaPlayerService
2 sp player(service->create(this, mAudioSessionId)); 这一步是通过BpMediaPlayerService 的create方法返回了BpMediaPlayer
3 attachNewPlayer 将player赋值给mPlayer
看一下 1 和 2 的两个函数的实现

/*static*/const sp
IMediaDeathNotifier::getMediaPlayerService()
{
    ALOGV("getMediaPlayerService");
    Mutex::Autolock _l(sServiceLock);
    if (sMediaPlayerService == 0) {
        sp sm = defaultServiceManager();
        sp 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(binder);
    }
    ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    return sMediaPlayerService;
}

这里简单讲一下
1 sp sm = defaultServiceManager(); 获取到ServiceManager
2 sm->getService(String16("media.player")); 通过ServiceManager获取到 MediaPlayerService,MediaPlayerService在android初始化时就向ServiceManager注册了
3 interface_cast(binder); 这里实际是new BpMediaPlayerService(binder)

class BpMediaPlayerService: public BpInterface
{
public:
    virtual sp create(
            const sp& client, audio_session_t audioSessionId) {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
        data.writeStrongBinder(IInterface::asBinder(client));
        data.writeInt32(audioSessionId);

        remote()->transact(CREATE, data, &reply);
        return interface_cast(reply.readStrongBinder());
    }

create方法做了两件事
1 remote()->transact(CREATE, data, &reply) 通过 IMediaPlayerService binder通讯,将IMediaPlayerClient的IBinder传给了MediaPlayerService, MediaPlayerServcie后面可以通过IMediaPlayerClient 回调MediaPlayer
2 interface_cast(reply.readStrongBinder()); 上一步binder通讯MeidaPlayer的binder对象, 同过binder是创建了 BpMediaPlayer 实例

Binder可分为实名binder和匿名binder, 实名binder是在ServiceManager注册的servce,可以通过ServiceManager的getService获取,而匿名binder没在ServiceManager中注册,没法通过ServiceManager获取,需要想办法获取service的binder实例才能通讯。对于MediaPlayer的结构,MediaPlayerServcie 属于实名binder, IMediaPlayer 和 IMediaPlayerClient 属于匿名binder。MediaPlayer 通过 MediaPlayerServcie实名binder, 将IMediaPlayerClient binder 传递给MediaPlayerServcie,同时MediaPlayerServcie将IMediaPlayer binder返回MediaPlayer。 这样MediaPlayer 就能通过 IMediaPlayer 调用 MediaPlayerServcie::client接口, MediaPlayerServcie可以通过IMediaPlayerClient调用MediaPlayer接口


MediaPlayer(三)--C++ binder框架_第2张图片
MediaPlayerBinderSeque.png

你可能感兴趣的:(MediaPlayer(三)--C++ binder框架)