\frameworks\av\media\libmedia\IMediaDeathNotifier.cpp:
const sp<IMediaPlayerService> IMediaDeathNotifier::getMediaPlayerService()
{
ALOGV("getMediaPlayerService");
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> 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<IMediaPlayerService>(binder);
}
ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
return sMediaPlayerService;
}
getService获取服务对应的Binder对象,如果获取不到就一直循环。
获取之后将服务封装成对应的BPMediaPlayerService,有了BpMediaPlayerService,就能够使用任何IMediaPlayerService提供的业务逻辑函数了。
我们知道BpMediaPlayerService只是一个服务代理对象,当我们调用IMediaPlayerService的方法时是怎么调用到服务本体BnMediaPlayerService的方法的呢?
比如调用BpMediaPlayerService的createMetadataRetriever方法
frameworks\av\media\libmedia\IMediaPlayerService.cpp:
virtual sp<IMediaMetadataRetriever> createMetadataRetriever()
{
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply);
return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
}
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;
}
这里调用IPCThreadState的transact方法,从前文
Android_Binder—分析MediaServer解析服务的初始化和注册
我们知道服务开启后会进入轮询等待请求接入,而transact该方法就是跟Binder设备通信的,这里我们发送信息给Binder设备。我们知道IPCThreadState是一个线程一个单例,所以我们跟到IPCThreadState的executeCommand方法中:
case BR_TRANSACTION:
{
binder_transaction_data_secctx tr_secctx;
binder_transaction_data& tr = tr_secctx.transaction_data;
if (cmd == (int) BR_TRANSACTION_SEC_CTX) {
result = mIn.read(&tr_secctx, sizeof(tr_secctx));
} else {
result = mIn.read(&tr, sizeof(tr));
tr_secctx.secctx = 0;
}
ALOG_ASSERT(result == NO_ERROR,
"Not enough command data for brTRANSACTION");
if (result != NO_ERROR) break;
//Record the fact that we're in a binder call.
mIPCThreadStateBase->pushCurrentState(
IPCThreadStateBase::CallState::BINDER);
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
const pid_t origPid = mCallingPid;
const char* origSid = mCallingSid;
const uid_t origUid = mCallingUid;
const int32_t origStrictModePolicy = mStrictModePolicy;
const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
const int32_t origWorkSource = mWorkSource;
const bool origPropagateWorkSet = mPropagateWorkSource;
// Calling work source will be set by Parcel#enforceInterface. Parcel#enforceInterface
// is only guaranteed to be called for AIDL-generated stubs so we reset the work source
// here to never propagate it.
clearCallingWorkSource();
clearPropagateWorkSource();
mCallingPid = tr.sender_pid;
mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
mCallingUid = tr.sender_euid;
mLastTransactionBinderFlags = tr.flags;
Parcel reply;
status_t error;
if (tr.target.ptr) {
// We only have a weak reference on the target object, so we must first try to
// safely acquire a strong reference before doing anything else with it.
if (reinterpret_cast<RefBase::weakref_type*>(
tr.target.ptr)->attemptIncStrong(this)) {
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags);
reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
} else {
error = UNKNOWN_TRANSACTION;
}
} else {
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
mIPCThreadStateBase->popCurrentState();
if ((tr.flags & TF_ONE_WAY) == 0) {
LOG_ONEWAY("Sending reply to %d!", mCallingPid);
if (error < NO_ERROR) reply.setError(error);
sendReply(reply, 0);
} else {
LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
}
mCallingPid = origPid;
mCallingSid = origSid;
mCallingUid = origUid;
mStrictModePolicy = origStrictModePolicy;
mLastTransactionBinderFlags = origTransactionBinderFlags;
mWorkSource = origWorkSource;
mPropagateWorkSource = origPropagateWorkSet;
}
break;
主要看这句
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags);
这里将tr.cookie强转成BBinder对象并调用了他的transact方法。
所以如果我们忽略掉两个进程底层IPCThreadState之间的通信的话,从一开始的BPBinder调用transact变成了BBinder调用transact方法,相当于BPBinder变成了BBinder,这里的BBinder实际上是MediaPlayerService对象本体,这里只是转化成BBinder,后面会产生动态联编。
frameworks\native\libs\binder\Binder.cpp:
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
err = onTransact(code, data, reply, flags);
break;
}
if (reply != nullptr) {
reply->setDataPosition(0);
}
return err;
}
transact又执行了onTransact,关键的地方来了,我们看回MediaPlayerService,为什么是MediaPlayerService呢,回想我们之前分析
frameworks\av\media\mediaserver\main_mediaserver.cpp时,
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
我们添加服务,把MediaPlayerService添加进去了,所以可以看出MediaPlayerService就是服务本体。
frameworks\av\media\libmediaplayerservice\MediaPlayerService.h:
class MediaPlayerService : public BnMediaPlayerService
可以看到MediaPlayerService其实是BnMediaPlayerService的子类,看下BnMediaPlayerService:
frameworks\av\media\libmedia\include\media\IMediaPlayerService.h:
class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
}; // namespace
可以看到头文件BnMediaPlayerService类里面只有一个onTransact的虚方法。
frameworks\native\libs\binder\include\binder\IInterface.h:
这里又回到了IInterface
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
typedef INTERFACE BaseInterface;
virtual IBinder* onAsBinder();
};
所以继承关系:
MediaPlayerService:BnMediaPlayerService:BnInterface:BBinder
找一下这些类里哪实现了onTransact方法:
frameworks\av\media\libmedia\IMediaPlayerService.cpp:
status_t BnMediaPlayerService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch (code) {
....
case CREATE_METADATA_RETRIEVER: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp<IMediaMetadataRetriever> retriever = createMetadataRetriever();
reply->writeStrongBinder(IInterface::asBinder(retriever));
return NO_ERROR;
} break;
....
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
回到一开始我们调用的是BpMediaPlayerService的createMetadataRetriever方法,可以看到onTransact直接调用了createMetadataRetriever,哪里实现了这个方法呢?
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever()
{
pid_t pid = IPCThreadState::self()->getCallingPid();
sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid);
ALOGV("Create new media retriever from pid %d", pid);
return retriever;
}
这里还有个问题,MediaPlayerService不是BnMediaPlayerService的子类吗,为什么onTransact里面父类BnMediaPlayerService可以直接调用子类的createMetadataRetriever?这里就实际到动态联编了。
class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
重新看回BnInterface,
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
替换一下
template<typename IMediaPlayerService>
class BnInterface : public IMediaPlayerService, public BBinder
可以发现BnInterface实现了 IMediaPlayerService接口,
frameworks\av\media\libmedia\include\media\IMediaPlayerService.h:
class IMediaPlayerService: public IInterface
{
public:
DECLARE_META_INTERFACE(MediaPlayerService);
virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) = 0;
virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0;
.....
}
IMediaPlayerService接口里面的createMediaRecorder是纯虚函数,因为当前指针指向的其实是MediaPlayerService所以明面是的BBinder调用onTransact,然后调用createMediaRecorder,实际上都是MediaPlayerService类里面的方法。
真相大白了。
所以Client向ServiceManager获取了BpBinder的对象后,调用transact方法通过Client线程的IPCThreadState通信,Service进程的IPCThreadState接受到请求,进入executeCommand方法,调用BnBinder的onTransact方法(该方法具体实现在对应的BnXXService里面),onTransact方法再根据Client请求调用了对应的函数。