由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);只不过现在BpBinder的handle值是MediaPlayerService的handle值,发送的指令也变成了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.targetNaNr为NULL默认the_context_object(暂时不知道哪里来的)来处理;不为NULL,将tr.cookie强制转换为BBinder,由此可见BBinder就是Server与IPCThreadState沟通的桥梁。
先看看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做回调。
到此为止,虽然很多地方还没有了解清楚,但基本知道了BpBinder、BnBinder、BBinder的区别和联系,了解了ServiceManager的工作流程,也就是基本了解了android中Binder的通信原理。