sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) { int32_t connId = android_atomic_inc(&mNextConnId); sp<Client> c = new Client(this, pid, connId, client); LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId); if (NO_ERROR != c->setDataSource(url)) { c.clear(); return c; } wp<Client> w = c; Mutex::Autolock lock(mLock); mClients.add(w); return c; }
这个new 了一个Client 并且函数将它返回为sp<IMediaPlayer>。
Client对象什么在文件MediaPlayerService.h中,并且是private类,说明它只被MediaPlayerService对象使用。Client对象继承自BnMediaPlayer,而BnMediaPlaye又继承自BnInterface<IMediaPlayer>,看来是用来响应binder的IPC的函数。MediaPlayerService::create函数调用以后,马上调用Client:setDataSource,其实现在MediaPlayerService.cpp中,
status_t MediaPlayerService::Client::setDataSource(const char *url) { if (strncmp(url, "content://", 10) == 0) { //不太明白,留着以后在研究吧 // get a filedescriptor for the content Uri and // pass it to the setDataSource(fd) method String16 url16(url); int fd = android::openContentProviderFile(url16); if (fd < 0) { LOGE("Couldn't open fd for %s", url); return UNKNOWN_ERROR; } setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus close(fd); return mStatus; } else { player_type playerType = getPlayerType(url); //通过url来取得playertype,例如对于midi,就用SONIVOX_PLAYER,mp3,mp4等就用PVPLAYER LOGV("player type = %d", playerType); // create the right type of player sp<MediaPlayerBase> p = createPlayer(playerType); //根据不同的playertype来创建不同的player实例 if (p == NULL) return NO_INIT; if (!p->hardwareOutput()) { mAudioOutput = new AudioOutput(); static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); } // now set data source LOGV(" setDataSource"); mStatus = p->setDataSource(url); if (mStatus == NO_ERROR) { mPlayer = p; } else { LOGE(" error: %d", mStatus); } return mStatus; } }注意这行代码:sp<MediaPlayerBase> p = createPlayer(playerType);
case XXX_PLAYER: LOGV(" create XXXFile"); p = new XXXPlayer(); break;非常方便,而这种扩展性和是由接口和实现的分离带来的,createPlayer 返回的是sp<MediaPlayerBase>类,而去看这个类的代码,发现这个类都是由virtual函数组成的,当你要实现具体实现时候,你可以继承它,然后写好这些virtual函数的实现。
void sendEvent(int msg, int ext1=0, int ext2=0) { MediaPlayerBase::sendEvent(msg, ext1, ext2); }
MediaPlayerBase::sendEvent的实现如下:
virtual void sendEvent(int msg, int ext1=0, int ext2=0) { if (mNotify) mNotify(mCookie, msg, ext1, ext2); }mNotify是MediaPlayerBase的一个成员变量,它是一个函数指针,原型如下:
typedef void (*notify_callback_f)(void* cookie, int msg, int ext1, int ext2);这个成员变量在调用createPlayer的时候就调用setNotifyCallback来赋值的。