Android开发之MediaPlayerService服务详解(一)

来源:互联网 发布:stat.apk是什么软件 编辑:程序博客网 时间:2024/05/06 21:24

       前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState。ProcessState负责打开Binder
驱动,每个进程只有一个。而 IPCThreadState负责提供与Binder通信相关的接口,每个线程有一个。下面我们通过具体
示例MediaPlayerService来分析我们应用程序中怎么通过Binder通信的。


frameworks/base/media/mediaserver/main_mediaserver.cpp

int main(int argc, char*argv[]){sp<ProcessState> proc(ProcessState)::self();// 获得ProcessState在构造函数中打开binder驱动sp<IServiceManager> sm = defaultServiceManager();MediaPlayService::instantiate();ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();}

1)获得ServiceManager的代理BpServiceManager

sp<IServiceManager> sm = defaultServiceManager();sp<IServiceManager> defaultServiceManager(){if(gDefaultServiceManager != NULL) return gDefaultServiceManager;{AutoMutex -l(gDefaultServiceManagerLock);if(gDefaultServiceManager == NULL)gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));}return gDefaultServiceManager;}

这里又是一个单例模式,每个进程只需要一个BpServiceManager代理,通过interface_cast获得。
首先看看ProcessState::self()->getContextObject(NULL)

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller){return getStrongProxyForHandle(0);}sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){sp<IBinder> result;AutoMutex _l(mLock);handle_entry *e = lookupHandleLocked(handle);if( e != NULL) {IBinder* b = e->binder;if(b == NULL || !e->refs->attemptIncWeak(this)) {b = new BpBinder(handle);e->binder = b;if(b) e->refs = b->getWeakRefs();result = b;}else{result.force_set(b);e->refs->decWeak(this);}}return result;}struct handle_entry{IBinder* binder;RefBase::weakref_type* refs;}

ProcessState::handle_entry* ProcessState::lookupHandleLocked()从数组mHandleToObject里面根据handle索引,查找
一个handle_entry结构体。然后根据传入的句柄handle这里为0,表示ServiceManager,new一个BpBinder
所以现在相当于:
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));

现在我们看看interface_cast是什么?

frameworks/base/include/binder/IInterface.htemplate<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){return INTERFACE::asInterface(obj);}等价于:inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj){return IServiceManager::asInterface(obj);}继续我们跟到IServiceManager里面去:frameworks/base/include/binder/IServiceManager.hclass IServiceManager:public IInterface{public:DECLARE_META_INTERFACE(ServiceManager);// MLGB的又是宏!!!virtual status_t addService(const String16& name, const sp<IBinder>& service) = 0;virtual sp<IBinder> getService(const String16& name) const = 0;}#define DECLARE_META_INTERFACE(INTERFACE)\static const android::String16 descriptor;\static android::sp<I##INTERFACE> asInterface(\const android::sp<android::IBinder>& obj);\virtual const android::String16& getInterfaceDescriptor() const;\I##INTERFACE();\virtual !I##INTERFACE();替换之后就是:static const android::String16 descriptor;static android::sp<IServiceManager> asInterface(const android::sp<android::IBinder>& obj);virtual const android::String16& getInterfaceDescriptor() const;IServiceManager();virtual !IServiceManager();都是一些函数声明,既然有声明的地方,肯定有实现的地方了。#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \    const android::String16 I##INTERFACE::descriptor(NAME);             \    const android::String16&                                            \            I##INTERFACE::getInterfaceDescriptor() const {              \        return I##INTERFACE::descriptor;                                \    }                                                                   \    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \            const android::sp<android::IBinder>& obj)                   \    {                                                                   \        android::sp<I##INTERFACE> intr;                                 \        if (obj != NULL) {                                              \            intr = static_cast<I##INTERFACE*>(                          \                obj->queryLocalInterface(                               \                        I##INTERFACE::descriptor).get());               \            if (intr == NULL) {                                         \                intr = new Bp##INTERFACE(obj);                          \            }                                                           \        }                                                               \        return intr;                                                    \    }                                                                   \    I##INTERFACE::I##INTERFACE() { }                                    \    I##INTERFACE::~I##INTERFACE() { }                                   继续替换:{    const android::String16 IServiceManager::descriptor(NAME);                 const android::String16&                                                       IServiceManager::getInterfaceDescriptor() const {                      return IServiceManager::descriptor;                                    }                                                                       android::sp<IServiceManager> IServiceManager::asInterface(                            const android::sp<android::IBinder>& obj)   // 参数为new BpBinder(0)                    {                                                                           android::sp<IServiceManager> intr;                                         if (obj != NULL) {                                                          intr = static_cast<IServiceManager*>(                                          obj->queryLocalInterface(                                                       IServiceManager::descriptor).get());                           if (intr == NULL) {                                                         intr = new BpServiceManager(obj);     // 原来在这里new 了一个BpServiceManager对象                                 }                                                                   }                                                                       return intr;                                                        }                                                                       IServiceManager::IServiceManager() { }                                        IServiceManager::~IServiceManager() { }                                   }

总结:根据句柄handle 0 创建一个new BpBinder(0),根据这个BpBinder创建了一个BpServiceManager代理。

下面来看看BpServiceManager代理:

class BpServiceManager : public BpInterface<IServiceManager>{public:BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(iml){}} 

这里BpInterface是一个模板类,表示这里BpServiceManager同时继承与BpInterface和IServiceManager类

template<typename INTERFACE>class BpInterface : public INTERFACE, public BpRefBase{public: BpInterface(const sp<IBinder>& remote);...}调用了基类BpInterface构造函数:BpInterface<IServiceManager>::BpInterace(const sp<IBinder>& remote) : BpRefBase(remote){}//这里的remote就是刚刚的new BpBinder(0)BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()),mRefs(NULL), mState(0){}

 

2)添加服务 MediaPlayerService::instantiate();

frameworks/base/media/libmediaplayerservice/ibMediaPlayerService.cppvoid MediaPlayerService::instantiate(){defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService);}

defaultServiceManager()返回的是刚创建的BpServiceManager,调用add函数。
BpMediaPlayService作为服务代理端,那么BnMediaPlayerService一定是实现端,MediaPlayerService继承于
BnMediaPlayerService,实现了真正的业务函数。

来看看BpServiceManager的addService()函数:

virtual status_t addService(const String16& name, const sp<IBinder>& service){Parcel data, reply;data.writeInterfaceToken(IServiceManager.getInterfaceDescriptor());// android.os.IServiceManagerdata.writeString16(name);// media.playerdata.writeStrongBinder(service);// 也就是MediaPlayerServicestatus_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);return err == NO_ERROR ? reply.readInt32() : err;}

这里remote()就是前面创建的BpBinder(0)对象。

status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){IPCThreadState::self()->transact(mHandle, code, data, reply, flags);}status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){// 发送ADD_SERVICE_TRANSACTION请求writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);if(reply)// 等待响应waitForResponse(NULL, reply);}status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t *statusBuffer){// cmdBC_TRANSACTION应用程序向BINDER发送的命令binder_transaction_data tr;tr.target.handle = handle;// 0tr.code = code;// ADD_SERVICE_TRANSACTIONtr.flags = binderFlags;// 把命令和数据一起发送到 Parcel mOut中mOut.writeInt32(cmd);mOut.write(&tr, sizeof(tr));}status_t IPCThreadState::waitForResponse(Parcel* reply, status_t *acquireResult){int32_t cmd;while(1) talkWithDriver();cmd = mIn.readInt32();switch(cmd) {case BR_TRANSACTION_COMPLETE:...break;}{return err;}status_t IPCThreadState::talkWithDriver(bool doReceive){binder_write_read bwr;bwr.write_size = outAvail;bwr.write_buf = (long unsigned int)mOut.data();// 写入mOut的数据bwr.read_size = mIn.dataCapacity;bwr.read_buffer = (long unsigned int)mIn.data();ioctl(mProcess->mDriverFD, BINDER_WRITE_READm &bwr);// 把mOut写到Binder,并读取mIn数据}


 

3)IPCThreadState::joinThreadPool(), ProcessState::self()->startThreadPool()
进入线程循环talkWithDriver 等待客户端Client请求,从Binder读取命令请求进行处理。

 

到现在为止MediaPlayerService的服务端已经向服务总管ServiceManager注册了,下面我们看看客户端是如何获得服务的代理并和服务端通信的。
我们以MediaPlayer的业务函数decode解析播放一个URL为例

sp<IMemory> MediaPlayer::decode(const char*url, uint32_t *pSampleRate, ...){sp<IMemory> p;const sp<IMediaPlayerService>& service = getMediaPlayerService();// 获得BpMediaPlayerSerivce代理if(service != 0)p = service->decode(url, ....);return p;}

这里我们主要分析getMediaPlayerService,客户端是如何向ServiceManager总管查询服务并获得代理的。

sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService(){sp<IServiceManager> sm = defaultServiceManager(); // 生成一个BpServiceManager代理对象sp<IBinder> binder;do {binder = sm->getService(String16("media.player"));if(binder != 0)break;usleep(500000)} while(true);sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);return sMediaPlayerService;}

 

1)首先获得BpServiceManager的代理,然后调用getService()函数向服务总管ServiceManager查询服务。
frameworks/base/libs/binder/IServiceManager.cpp

class BpServiceManager : public BpInterface<IServiceManager>{public:virtual sp<IBinder> getService(const String16& name) const{for(n = 0; n < 5; n++) {sp<IBinder> svc = checkService(name);// 调用checkService函数if(svc != NULL) return svc;sleep(1);}return NULL;}virtual sp<IBinder> checkService(const String16& name) const {Parcel data, reply;data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());// 首先调用data.writeInt32(IPCThreadState::self()->getStrictModePolicy())// 然后再写入android.os.IServiceManagerdata.writeString16(name);// 写入 media.playerremote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);return reply.readStrongBinder();}}

这里首先将请求打包成Parcel各式,然后调用remote()->transact()函数,前面我们分析过BpServiceManager::remote()返回
的就是前面new BpBinder(0)对应句柄为ServiceManager。继续去BpBinder中寻找实现代码:
frameworks/base/libs/binder/BpBinder.cpp

status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){IPCThreadState::self()->transact(mHandle, code, data, reply, flags);}

最后调用的IPCThreadState的transact()函数,IPCThreadState是专门提供通过Binder进程间通信的接口的。

status_t IPCTheadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){// 填充binder_transaction_data 结构体,写入到mOut中去writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);// 调用talkWithDriver() 将mOut写到Binder驱动,并从Binder驱动读取mIn数据waitForResponse(reply);}

首先通过writeTransactionData函数来填充mOut结构体,mOut里面内容为:
 mOut.writeInt32(BC_TRANSACTION);
 mOut.write(&tr, sizeof(tr));
这里binder_transaction_data tr内容为:
 tr.target.handle = 0; // 表面是发往ServiceManager的
 tr.code = CHECK_SERVICE_TRANSACTION;
 tr.flags = 0;
tr.data内容为:
 data.writeInt32(IPCThreadState::self()->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
 data.writeString16("android.os.IServiceManager");
 data.writeString16("media.player");
根据前面Android开发之ServiceManager一章中我们分析,svcmgr_handler处理从句柄为0的Binder的请求:
strict_policy = bio_get_string32();
s = bio_get_string16(); // 就是上面的android.os.IServiceManager
s = bio_get_string16(); // 就是上面的 media.player
根据media.player遍历全局链表svclist找到相应的服务,调用bio_put_ref(reply, ptr) 返回目标Binder实体。


这个waitForResponse()函数是关键:

status_t IPCThreadState::waitForResponse(Parcel* reply){while(1) {talkWithDriver();// 输入mOut 输出mIncmd = mIn.readInt32();switch(cmd) {case BR_REPLY:{binder_transaction_data tr;mIn.read(&tr, sizeof(tr));if(reply) {reply->ipcSetDataReference(reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(sizt_t), freeBuffer, this);} else {err = *static_cast<const status_t*>(tr.data.ptr.buffer);freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(sizt_t), freeBuffer, this)}}}}}最后返回的是:return reply.readStrongBinder();进入到Parcel的readStrongBinder()函数sp<IBinder> Parcel::readStrongBinder() const{sp<IBinder> val;unflatten_binder(ProcessState::self(), *this, &val);return val;}status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out){const flat_binder_object* flat = in.readObject(false);if(flat) {switch(flat->type) {case BINDER_TYPE_BINDER:*out = static_cast<IBinder*>(flat->cookie);return finish_unflatten_binder(NULL, *flat, in);case BINDER_TYPE_HANDLE:*out = proc->getStrongProxyForHandle(flat->handle);return finish_unflatten_binder(static_cast<BpBinder*>(out->get()), *flat, in);}}}

这里flat->type是BINDER_TYPE_HANDLE,所以调用ProcessState::getStrongProxyForHandle()函数

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){sp<IBinder> result;handle_entry* e = lookupHandleLocked(handle);if(e != NULL) {IBinder* b = e->binder;if(b == NULL || !e->refs->attemptIncWeak(this)) {b = new BpBinder(handle);e->binder = b;if( b ) e->refs = e->getWeakRefs();result = b;} else {result.force_set(b);e->refs->decWeak(this);}}return result;}

这里的handle就是ServiceManager内维护的MediaPlayerService对应的Binder句柄,这个ProcessState根据这个句柄
new 了一个BpBinder,并将其保存起来,这样下次需要从ServiceManager请求获取到相同句柄的时候就可以直接返回了。
最后根据这个返回的BpBinder获得MediaPlayerService的代理:
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
根据前面ServiceManager一样,最后调用的是IMediaPlayerService的asInterface()宏函数

android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const android::sp<android::IBinder>& obj){android::sp<IMediaPlayerService> intr;if(obj != NULL ) {intr = static_cast<IMediaPlayerService>(obj->queryLocalInterface(IMediaPlayerService::descriptor).get);if (intr == NULL) {intr = new BpMediaPlayerService(obj);}}return intr;}

 

这样我就获得了一个代理BpMediaPlayerService对象,它的remote()为BpBinder(handle),这个handle就是向服务总共ServiceManager
查询到的MediaPlayerService对应的Binder句柄。

   下一章我们分析,客户端如何通过这个BpServiceManager代理对象调用服务端MediaPlayerService的业务函数的?