目录
前言
之前介绍 ,接上文《》(看做《MediaPlayer源码介绍1》)介绍到mediaplayer.cpp,这也是一个代理,真正处理的并不是这个。
今天以
涉及代码
frameworks\av\media\libmedia\mediaplayer.cpp frameworks\av\media\libmedia\IMediaPlayerService.cpp frameworks\av\media\libmedia\IMediaDeathNotifier.cpp frameworks\native\libs\binder\IServiceManager.cpp frameworks\native\libs\binder\include\binder\IInterface.h frameworks\native\libs\binder\include\binder/Binder.h frameworks\av\media\libmedia\IMediaPlayerService.cpp frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp frameworks\av\media\libmedia\IMediaPlayerClient.cpp
正文
直接进入mediaplayer.cpp的代码
setDataSource
status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length){ status_t err = UNKNOWN_ERROR; // getMediaPlayerService()获取的是BpMediaPlayerService // BpMediaPlayerService的对象service const sp<IMediaPlayerService> service(getMediaPlayerService()); if (service != 0) { //创建BpMediaPlayer对象player,具体看BpMediaPlayerService中create方法 sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); if ((NO_ERROR != doSetRetransmitEndpoint(player)) || (NO_ERROR != player->setDataSource(fd, offset, length))) { //BpMediaPlayer->setDataSource(); player.clear(); } //赋值,mPlayer = plyaer; //BpMediaPlayer在IMediaPlayer.cpp err = attachNewPlayer(player); } return err; }
由于跟上一篇太久了,我们重新分析一下。
const sp<IMediaPlayerService> service(getMediaPlayerService());
先看getMediaPlayerService(),这个是在IMediaDeathNotifier.cpp中。
getMediaPlayerService()
IMediaDeathNotifier::getMediaPlayerService(){ Mutex::Autolock _l(sServiceLock); //sMediaPlayerService 是BpMediaPlayerService对象。 if (sMediaPlayerService == 0) { //sm是BpServiceManager的对象 sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder; do { //获取media.player服务的binder binder = sm->getService(String16("media.player")); if (binder != 0) { break; } //binder空,延迟0.5s再获取 usleep(500000); } while (true); if (sDeathNotifier == NULL) { sDeathNotifier = new DeathNotifier(); } //服务死亡监听 binder->linkToDeath(sDeathNotifier); //通过这里获取BpMediaPlayerService的对象 sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); } return sMediaPlayerService; }
getMediaPlayerService()方法是单例模式,也就值创建一次。一般来说,默认进入sMediaPlayerService == 0,因此先创建。
晕,这有一个defaultServiceManager(),这个在IServiceManager.cpp中。
sp<IServiceManager> sm = defaultServiceManager();
defaultServiceManager()
//BpServiceManager,在interface_cast中进行转换的
sp<IServiceManager> defaultServiceManager(){
if (gDefaultServiceManager != NULL) return gDefaultServiceManager; {
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
也是单例模式,通过之前文章(《》)对interface_cast有一定的了解,那就可以得出 defaultServiceManager()放回的就是BpServiceManager,也就是ServiceManager的代理。
BpMediaPlayerService
上面可通过BpMediaPlayerService获取到media.player的binder。
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
又是interface_cast,由此可知sMediaPlayerService就是BpMediaPlayerService对象。
进入BpMediaPlayerService的构造函数,进入IMediaPlayerService.cpp。
class BpMediaPlayerService: public BpInterface<IMediaPlayerService>{ public: explicit BpMediaPlayerService(const sp<IBinder>& impl) : BpInterface<IMediaPlayerService>(impl) { } }
这里进入了父类BpInterface初始化BpInterface<IMediaPlayerService>(impl),这在IInterface.h中定义。
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote) { }
又进入父类的BpRefBase出货BpRefBase(remote)
BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(NULL), mState(0) { extendObjectLifetime(OBJECT_LIFETIME_WEAK); if (mRemote) { mRemote->incStrong(this); // Removed on first IncStrong(). mRefs = mRemote->createWeak(this); // Held for our entire lifetime. } }
经过一步一步父类的赋值,可以看出mRemote就是我们上面获取的binder。
PS: mRemote(o.get())这个是C++中构造函数赋值的写法!
小结
通过下面一条语句的操作
const sp<IMediaPlayerService> service(getMediaPlayerService());
我们已经获取了如下信息:
service是BpMediaPlayerService的对象
mRemote是[media.player]服务的的native层的binder对象
我们继续。
create()
sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
上面说了service就是BpMediaPlayerService的对象。
virtual sp<IMediaPlayer> create( const sp<IMediaPlayerClient>& client, audio_session_t audioSessionId) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(client)); data.writeInt32(audioSessionId); //通过remote()的transact()方法 remote()->transact(CREATE, data, &reply); //创建BpMediaPlayer return interface_cast<IMediaPlayer>(reply.readStrongBinder()); }
上面执行了两步(1)通过remote()的transact()方法传输CREATE命令(2)创建BpMediaPlayer。
remote()->transact(CREATE, data, &reply);
remote()是谁?这个在Binder.h中定义。
inline IBinder* remote() { return mRemote; }
也就是调用[media.player]服务的的native层的binder对象的transact()。
经过binder通信,最后进入BnMediaPlayerService::onTransact()。(其中细节不太明白,后面明白了再写,多谢)。
BnMediaPlayerService的实现也在IMediaPlayerService.cpp
onTransact
status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ switch (code) { case CREATE: { CHECK_INTERFACE(IMediaPlayerService, data, reply); //client是BpMediaPlayerClient对象 sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder()); audio_session_t audioSessionId = (audio_session_t) data.readInt32(); //MediaPlayerService继承BnMediaPlayerService,所以MediaPlayerService实现了create //这里的player是BnMediaPlayer对象,具体看create()中创建的 sp<IMediaPlayer> player = create(client, audioSessionId); //返回asBinder(BpMediaPlayer) reply->writeStrongBinder(IInterface::asBinder(player)); return NO_ERROR; } break; //略 default: return BBinder::onTransact(code, data, reply, flags); } }
我们看client
//client是BpMediaPlayerClient对象 //data.readStrongBinder()就是的MediaPlayer(继承BnMediaPlayerClient)的binder对象 sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
又是interface_cast,老朋友了,获取的client是BpMediaPlayerClient。
需要注意的是BpMediaPlayerClient里面有个notify()
virtual void notify(int msg, int ext1, int ext2, const Parcel *obj){ Parcel data, reply; data.writeInterfaceToken(IMediaPlayerClient::getInterfaceDescriptor()); data.writeInt32(msg); data.writeInt32(ext1); data.writeInt32(ext2); if (obj && obj->dataSize() > 0) { data.appendFrom(const_cast<Parcel *>(obj), 0, obj->dataSize()); } //remote()是BnMediaPlayerClient的binder remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY); }
后续会通过notify()进行返回状态通知。
如有错误,请指正,多谢
MediaPlayerService
sp<IMediaPlayer> player = create(client, audioSessionId);
看代码知道,MediaPlayerService继承BnMediaPlayerService的,而且上面create()没有实现,那就找他的子类。(哈哈,负债子还?)
MediaPlayerService在MediaPlayerService.cpp中。
sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client, audio_session_t audioSessionId){ pid_t pid = IPCThreadState::self()->getCallingPid(); int32_t connId = android_atomic_inc(&mNextConnId); //创建服务端Bn实现端(BnMediaPlayer)子类Client播放器对象 //Client 继承 BnMediaPlayer sp<Client> c = new Client( this, pid, connId, client, audioSessionId, IPCThreadState::self()->getCallingUid()); wp<Client> w = c; { Mutex::Autolock lock(mLock); mClients.add(w); } return c; }
创建了Client对象(BnMediaPlayer的子类),后面客户端是通过这个来跟服务端交互的。
player
sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
virtual sp<IMediaPlayer> create( //略 //reply.readStrongBinder()返回的是mClients(BnMediaPlayer子类)的binder //创建BpMediaPlayer return interface_cast<IMediaPlayer>(reply.readStrongBinder()); }
由上面分析,player就是BpMediaPlayer,继续
if (service != 0) { sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); if ((NO_ERROR != doSetRetransmitEndpoint(player)) || //BpMediaPlayer->setDataSource(source) (NO_ERROR != player->setDataSource(source))) { player.clear(); } err = attachNewPlayer(player); }
setDataSource
进入IMediaPlayer.cpp
status_t setDataSource(int fd, int64_t offset, int64_t length) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); data.writeFileDescriptor(fd); data.writeInt64(offset); data.writeInt64(length); //通过binder,就是BnMediaPlayer的binder remote()->transact(SET_DATA_SOURCE_FD, data, &reply); return reply.readInt32(); }
通过binder通信(暂时不关注细节哈),进入了BnMediaPlayer类onTransact(),进入IMediaPlayer.cpp
status_t BnMediaPlayer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ switch (code) { //略 case SET_DATA_SOURCE_FD: { CHECK_INTERFACE(IMediaPlayer, data, reply); int fd = data.readFileDescriptor(); int64_t offset = data.readInt64(); int64_t length = data.readInt64(); // MediaPlayerService中的Client继承BnMediaPlayer //也就进入MediaPlayerService::Client::setDataSource() reply->writeInt32(setDataSource(fd, offset, length)); return NO_ERROR; } //略 default: return BBinder::onTransact(code, data, reply, flags); } }
BnMediaPlayer没有实现父类的接口,那就找其子类(父债子还!)。Client是BnMediaPlayer的之类,而且Client的定义在MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length){ struct stat sb; int ret = fstat(fd, &sb); if (ret != 0) { return UNKNOWN_ERROR; } if (offset >= sb.st_size) { return UNKNOWN_ERROR; } if (offset + length > sb.st_size) { length = sb.st_size - offset; } player_type playerType = MediaPlayerFactory::getPlayerType(this, fd, offset, length); //创建播放器(NuPlayerDriver),这里暂时不深入,下次介绍哈 sp<MediaPlayerBase> p = setDataSource_pre(playerType); if (p == NULL) { return NO_INIT; } return mStatus = setDataSource_post(p, p->setDataSource(fd, offset, length)); }
好绕啊,哈哈,最终执行的是p->setDataSource(fd, offset, length)。
p又是谁?暂停打住哈,后面在分析。
attachNewPlayer
err = attachNewPlayer(player);
获取到了player(BpMediaPlayer的对象),这里进行赋值
status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player){ status_t err = UNKNOWN_ERROR; sp<IMediaPlayer> p; { Mutex::Autolock _l(mLock); if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) || (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) { return INVALID_OPERATION; } clear_l(); //p存在之前的mPlayer p = mPlayer; //赋值新的player mPlayer = player; if (player != 0) { mCurrentState = MEDIA_PLAYER_INITIALIZED; err = NO_ERROR; } else { ALOGE("Unable to create media player"); } } //如果之前的不为null,就通知disconnect() if (p != 0) { p->disconnect(); } return err; }
到这里,就获取到了mPlayer,然后可以通过这个mPlayer。
小结
上面只是setDataSource()的分析,但其他的方法都差不多,都是通过mPlayer中的mRemote->onTransact(),经过Binder通信,然后调用服务MediaPlayerService::Client对应的方法中。
BP(binder proxy)和BN(binder native)是通过binder来通信的,Bp端可以通过BinderProxy的transact()方法与Bn端发送请求,而Bn端通过继承Binder类并重写onTransact()接收并处理来自Bp端的请求。Bn意味着Binder Native端,Bp是Binder Proxy端,Bn端通过onTransact()方法接收来自Bp端的请求的代码,然后把结果写入reply,Bp端再从reply中读取返回值并返回给调用者。
参考文章
《》
《》
《》
《