一、MediaServer加载过程
Android启动过程中会去执行init.rc脚本,在这个脚本中将会启动一些关键的系统服务,其中之一就是MediaServer:- @init.rc(google-code\system\core\rootdir\init.rc)
- service media /system/bin/mediaserver
- class main
- user media
- group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc
- ioprio rt 4
1、需要启动一个media的service,路径在/system/bin/mediaserver
2、该服务的入口函数为main
3、该服务运行在media的用户名下
4、该服务属于以下组:audio camera inet等
这些信息中,我们只关心service的名字(mediaserver)和入口函数(main),那么这个服务的入口函数究竟在那个文件里面呢?
我们打开mediaserver模块,在模块的Android.mk文件中找到了这个Service的加载信息:
- @Android.mk(google-code\frameworks\av\media\mediaserver\)
- LOCAL_PATH:= $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:= main_mediaserver.cpp
- LOCAL_MODULE:= mediaserver
- @main_mediaserver.cpp
- int main(int argc, char** argv) {
- sp<ProcessState> proc(ProcessState::self());
- //得到ServiceManager
- sp<IServiceManager> sm = defaultServiceManager();
- //三个Service自身的初始化
- AudioFlinger::instantiate();
- MediaPlayerService::instantiate();
- CameraService::instantiate();
- AudioPolicyService::instantiate();
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
- }
下面我们就来详细看一下整个Service启动的流程。
二、ProcessState的初始化
我们先来分析main中的第一步,也就是ProcessState::self()的过程。- @ProcessState.cpp(google-code\frameworks\native\libs\binder\)
- sp<ProcessState> ProcessState::self() {
- if (gProcess != NULL) return gProcess;
- AutoMutex _l(gProcessMutex);
- if (gProcess == NULL) gProcess = new ProcessState;
- return gProcess;
- }
- ProcessState::ProcessState()
- : mDriverFD(open_driver())
- , mVMStart(MAP_FAILED)
- , mManagesContexts(false)
- , mBinderContextCheckFunc(NULL)
- , mBinderContextUserData(NULL)
- , mThreadPoolStarted(false)
- , mThreadPoolSeq(1)
- {
- if (mDriverFD >= 0) {
- //映射内存
- mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
- if (mVMStart == MAP_FAILED) {
- close(mDriverFD);
- mDriverFD = -1;
- }
- }
- }
1、 通过open_driver打开binder驱动,并把binder设备句柄传给mDriverFD
2、 通过mmap()将一块内核地址映射到用户空间,作为buffer传输数据。
由此,就完成了ProcessState的初始化工作。
三、得到ServiceManager代理对象的过程
main函数的下一个动作就是要得到ServiceManager的对象:- sp<IServiceManager> sm = defaultServiceManager();
- @IServiceManager.cpp(google-code\frameworks\native\libs\binder\)
- sp<IServiceManager> defaultServiceManager() {
- if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
- AutoMutex _l(gDefaultServiceManagerLock);
- if (gDefaultServiceManager == NULL) {
- //得到ServiceManager
- gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL));
- }
- return gDefaultServiceManager;
- }
- gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL));
- ProcessState::self()->getContextObject(NULL)
- interface_cast<IServiceManager>()
上面第一步可以得到ServiceManager的BpBinder对象,第二步把得到的BpBinder对象转换为IServiceManager对象,下面我们逐步分析这两个过程。
3.1、得到ServiceManager的BpBinder对象
- ProcessState::self()->getContextObject(NULL)
- ProcessState->getContextObject(NULL);
- @ProcessState.cpp
- sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) {
- return getStrongProxyForHandle(0);
- }
- sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) {
- sp<IBinder> result;
- //从数组中查找handle_entry,不存在的话就创建一个
- handle_entry* e = lookupHandleLocked(handle);
- if (e != NULL) {
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- //new一个BpBinder返回给调用者
- 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;
- }
这样一来,getStrongProxyForHandle()所返回的result就相当于我们刚刚new出来的BpBinder对象:
- sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) {
- return new BpBinder(handle);
- }
由此我们知道,通过:
- ProcessState::self()->getContextObject(NULL)
下面我们来看如何将这个对象转换为ServiceManager对象。
3.2、得到ServiceManager的BpServiceManager对象
经过3.1的分析,我们可以将第三节中的:- gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL));
- gDefaultServiceManager = interface_cast<IServiceManager>(BpBinder(0));
3.2.1、函数模版转换
我们先来看一下这个函数模版:- @IInterface.h(google-code\frameworks\native\include\binder\)
- template<typename INTERFACE>
- inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
- {
- return INTERFACE::asInterface(obj);
- }
首先,他表示一个函数,这个函数名就叫interface_cast,参数必须是const类型的IBinder指针。
其次,既然是“模版”,就说明他只提供了一个框架(或者一种形式),可以适应多种环境调用。
具体来说就是, 这个函数名叫interface_cast,调用这个函数必须传递进来一个IBinder的指针,但是他的返回值可以是不固定的,是根据传递进来的INTERFACE而定的。同时,返回值的具体值就是INTERFACE::asInterface(obj)。
结合上面的代码来说,下面的语句:
- gDefaultServiceManager = interface_cast<IServiceManager>(BpBinder(0));
1、调用名叫interface_cast函数模版;
2、模版参数为IServiceManager;
3、函数参数为BpBinder(0);
4、返回值赋值给了gDefaultServiceManager。
这样一来,这个函数模版就相当于:
- sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
- {
- return IServiceManager::asInterface(obj);
- }
- gDefaultServiceManager = interface_cast<IServiceManager>(BpBinder(0));
- gDefaultServiceManager = IServiceManager::asInterface(BpBinder(0));
3.2.2、IServiceManager的asInterface函数
在IServiceManager.cpp中我们并没有找到asInterface函数,但是在IServiceManager.h中却找到了一个宏控:- @IServiceManager.h
- class IServiceManager : public IInterface {
- DECLARE_META_INTERFACE(ServiceManager);
- };
- @IInterface.h(google-code\frameworks\native\include\binder\)
- #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 android::sp<I##INTERFACE> asInterface(const android::sp<android::IBinder>& obj);
- static android::sp<IServiceManager> asInterface(const android::sp<android::IBinder>& obj);
- #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() { }
- 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; \
- } \
- android::sp<IServiceManager> IServiceManager::asInterface( const android::sp<android::IBinder>& obj) {
- android::sp<IServiceManager> intr;
- if (obj != NULL) {
- intr = static_cast<IServiceManager*>(obj->queryLocalInterface(IServiceManager::descriptor).get());
- if (intr == NULL) {
- intr = new BpServiceManager(obj);
- }
- }
- return intr;
- }
也就是说,经过函数模版的转换,我们得到的是BpServiceManager对象。而且初始化该对象时,我们传递了BpBinder(0)。
3.3、BpServiceManager
经过上面3.1和3.2的分析,我们知道,通过defaultServiceManager()得到的是BpServiceManager对象,那么他是什么属性呢?功能又是什么呢?3.3.1、继承关系
我们先来看一下他的继承关系:- class BpServiceManager : public BpInterface<IServiceManager> { }
- template<typename INTERFACE>
- class BpInterface : public INTERFACE, public BpRefBase { };
- class BpInterface : public IServiceManager, public BpRefBase { };
3.3.2、构造函数初始化过程
下面我们再从BpServiceManager的构造函数来看他的初始化过程,在3.2节的最后我们分析到,创建BpServiceManager对象时,我们传递了BpBinder(0)作为参数,此时我们来看这样会发生什么。- @IServiceManager.cpp
- BpServiceManager(const sp<IBinder>& impl)
- : BpInterface<IServiceManager>(impl)
- {
- }
- template<typename INTERFACE>
- inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
- : BpRefBase(remote)
- {
- }
- inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote)
- : 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.
- }
- }
经过两级父类传递,我们发现, BpServiceManager对象的初始化过程中,会把BpBinder(0)这个对象赋值给BpServiceManager的祖先类(其实是他的爷爷类)BpRefBase的mRemote变量。
这样做的作用我们待会儿就会明白。
3.3.3、成员函数
前面分析了BpServiceManager的继承关系和构造函数初始化流程,下面我们来看一下他的成员函数。从继承关系上来讲,BpServiceManager既然继承了IServiceManager(他可是BpServiceManager的两个祖先类之一,另一个父类是BpRefBase),那么就应该实现IServiceManager所声明的所有虚函数,我们来看一下IServiceManager中的虚函数声明:
- class IServiceManager : public IInterface {
- public:
- //这个宏定义已经分析过,其中包含asInterface的信息
- DECLARE_META_INTERFACE(ServiceManager);
- //得到一个Service
- virtual sp<IBinder> getService( const String16& name) const = 0;
- //检测Service
- virtual sp<IBinder> checkService( const String16& name) const = 0;
- //添加一个Service
- virtual status_t addService( const String16& name, const sp<IBinder>& service, bool allowIsolated = false) = 0;
- virtual Vector<String16> listServices() = 0;
- enum {
- GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
- CHECK_SERVICE_TRANSACTION,
- ADD_SERVICE_TRANSACTION,
- LIST_SERVICES_TRANSACTION,
- };
- };
- class BpServiceManager : public BpInterface<IServiceManager> {
- virtual sp<IBinder> getService(const String16& name) const{}
- virtual sp<IBinder> checkService( const String16& name) const{}
- virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated){}
- virtual Vector<String16> listServices(){}
- };
3.3.4、BpServiceManager的作用
经过上面的分析,我们现在来看一下BpServiceManager的作用。严格来说,我们通过defaultServiceManager()方法得到的并不是ServiceManager对象本身,而是得到了BpServiceManager对象,但是通过这个对象我们可以调用ServiceManager所暴露出来的各个方法,整个过程就像是直接调用ServiceManager一样,因此BpServiceManager对象的作用就是建立ServiceManager的“代理”,所有客户端对ServiceManager的请求,都需要通过BpServiceManager来“转达”。
那么,为了得到BpServiceManager,我们经历了哪些步骤呢?
首先, 我们通过ProcessState::self()->getContextObject(NULL)得到了BpBinder(0)对象。
然后, 我们用interface_cast<IServiceManager>(BpBinder(0))这个模版,将BpBinder(0)转换为IServiceManager类型的BpServiceManager对象。
下面用一张图来总结一下得到ServiceManager代理对象的过程:
四、调用ServiceManager方法的过程
上面我们分析了,通过defaultServiceManager()我们得到的是ServiceManager的代理对象:BpServiceManager,那么我们究竟是如何通过其代理调用到ServiceManager中的方法呢?在3.3中我们看到BpServiceManager中提供了ServiceManager的getService、addService、checkService等操作方法,下面我们挑选addService来分析,其余方法的调用过程都是类似的。
- @IServiceManager.cpp
- virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated) {
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeStrongBinder(service);
- data.writeInt32(allowIsolated ? 1 : 0);
- status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
- return err == NO_ERROR ? reply.readExceptionCode() : err;
- }
那么,这里的remote()是什么呢?
这要看remote()函数的定义了,他的定义在BpServiceManager的父类BpRefBase中:
- @Binder.h
- inline IBinder* remote() {
- return mRemote;
- }
现在回顾一下,我们在分析BpServiceManager初始化时分析道,BpBinder(0)这个对象最终是给了BpServiceManager的父类BpRefBase的mRemote成员变量,而此时我们通过remote()函数得到的对象应该就是BpBinder(0)这个对象。
也就是说,在addService()中调用remote()->transact()的结果就相当于:
- BpBinder(0)->transact()
- @BpBinder.cpp
- status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
- if (mAlive) {
- //转移到IPCThreadState中的transact
- status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags);
- if (status == DEAD_OBJECT) mAlive = 0;
- return status;
- }
- return DEAD_OBJECT;
- }
- status_t IPCThreadState::transact(int32_t handle,uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags) {
- status_t err = data.errorCheck();
- flags |= TF_ACCEPT_FDS;
- if (err == NO_ERROR) {
- //封装数据
- err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
- }
- if ((flags & TF_ONE_WAY) == 0) {
- if (reply) {
- err = waitForResponse(reply);
- } else {
- Parcel fakeReply;
- err = waitForResponse(&fakeReply);
- }
- } else {
- err = waitForResponse(NULL, NULL);
- }
- return err;
- }
我们先来看封装数据的过程:
- status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) {
- binder_transaction_data tr;
- tr.target.handle = handle;
- tr.code = code;
- tr.flags = binderFlags;
- tr.cookie = 0;
- tr.sender_pid = 0;
- tr.sender_euid = 0;
- //错误检测
- const status_t err = data.errorCheck();
- if (err == NO_ERROR) {
- tr.data_size = data.ipcDataSize();
- tr.data.ptr.buffer = data.ipcData();
- tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
- tr.data.ptr.offsets = data.ipcObjects();
- } else if (statusBuffer) {
- tr.flags |= TF_STATUS_CODE;
- *statusBuffer = err;
- tr.data_size = sizeof(status_t);
- tr.data.ptr.buffer = statusBuffer;
- tr.offsets_size = 0;
- tr.data.ptr.offsets = NULL;
- } else {
- return (mLastError = err);
- }
- //这里的cmd内容是BC_TRANSACTION
- mOut.writeInt32(cmd);
- mOut.write(&tr, sizeof(tr));
- return NO_ERROR;
- }
然后我们来看发送的过程:
- status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) {
- int32_t cmd;
- while (1) {
- //发送数据
- if ((err=talkWithDriver()) < NO_ERROR) break;
- //检测接收的数据有效性
- err = mIn.errorCheck();
- if (err < NO_ERROR) break;
- if (mIn.dataAvail() == 0) continue;
- //得到返回数据的内容
- cmd = mIn.readInt32();
- //根据返回命令做不同处理
- switch (cmd) {
- case BR_TRANSACTION_COMPLETE:
- case BR_DEAD_REPLY:
- case BR_FAILED_REPLY:
- case BR_ACQUIRE_RESULT:
- case BR_REPLY:
- default:
- }
- }
- return err;
- }
- @IPCThreadState.cpp
- status_t IPCThreadState::talkWithDriver(bool doReceive) {
- binder_write_read bwr;
- const bool needRead = mIn.dataPosition() >= mIn.dataSize();
- const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
- //准备写入的数据
- bwr.write_size = outAvail;
- bwr.write_buffer = (long unsigned int)mOut.data();
- if (doReceive && needRead) {
- //准备要读取的数据
- bwr.read_size = mIn.dataCapacity();
- bwr.read_buffer = (long unsigned int)mIn.data();
- } else {
- bwr.read_size = 0;
- bwr.read_buffer = 0;
- }
- bwr.write_consumed = 0;
- bwr.read_consumed = 0;
- status_t err;
- do {
- //通过ioctl发送和接收数据
- if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
- err = NO_ERROR;
- else
- err = -errno;
- } while (err == -EINTR);
- if (err >= NO_ERROR) {
- if (bwr.write_consumed > 0) {
- //清空mOut
- if (bwr.write_consumed < (ssize_t)mOut.dataSize())
- mOut.remove(0, bwr.write_consumed);
- else
- mOut.setDataSize(0);
- }
- //把返回值放入mIn中
- if (bwr.read_consumed > 0) {
- mIn.setDataSize(bwr.read_consumed);
- mIn.setDataPosition(0);
- }
- return NO_ERROR;
- }
- return err;
- }
数据交互完成之后,就把mOut中内容删除,并把拿到的bwr中的read_buffer内容放入mIn和reply中。
由此就 同时完成了数据的读写操作。
以上就是addService()的过程,下面我们对比一下getService()的过程:
- virtual sp<IBinder> getService(const String16& name) const {
- unsigned n;
- for (n = 0; n < 5; n++){
- //调用了checkService()
- sp<IBinder> svc = checkService(name);
- 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.writeString16(name);
- //传输数据
- remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
- //得到回应
- return reply.readStrongBinder();
- }
下面我们小节一下通过BpServiceManager对象调用ServiceManager对象方法的过程:
1、在BpServiceManager中的各项操作均转换为remote()->transact()方法,然后标记不同的命令,比如add、check、get等。
2、remote()得到的其实就是mRemote变量,而这个变量就是当初构建BpServiceManager时传递进来的BpBinder(0)。
3、在BpBinder对象的transact函数中,将会调用IPCThreadState的transact()方法,并且标明目标Service的handle(当前为0)
4、在IPCThreadState的transact中先通过writeTransactionData把数据封装,封装的内容包括目标Service(当前就是0号Service),最后把封装后的数据放入mOut中
5、在IPCThreadState的transact中接着逐步调用waitForResponse()和talkWithDriver()最终调用ioctl()将数据发送到远程的ServiceManager进程
下面我们用图来小结一下本节的要点:
五、MediaPlayerService的初始化过程
现在我们再回到最初的main中。- int main(int argc, char** argv) {
- //ProcessState初始化
- sp<ProcessState> proc(ProcessState::self());
- //得到ServiceManager的IServiceManager对象
- sp<IServiceManager> sm = defaultServiceManager();
- AudioFlinger::instantiate();
- MediaPlayerService::instantiate();
- CameraService::instantiate();
- AudioPolicyService::instantiate();
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
- }
- @MediaPlayerService.cpp(google-code\frameworks\av\media\libmediaplayerservice\)
- void MediaPlayerService::instantiate() {
- defaultServiceManager()->addService( String16("media.player"), new MediaPlayerService());
- }
下面我们来看一下MediaPlayerService对象的本质。
- class MediaPlayerService : public BnMediaPlayerService{}
- class BnMediaPlayerService: public BnInterface<IMediaPlayerService>{}
- @IInterface.h
- template<typename INTERFACE>
- class BnInterface : public INTERFACE, public BBinder { };
- class BBinder : public IBinder{}
也就是说,作为一个Service,向ServiceManager注册自己时,需要把继承自IXXXService和BBinder的传递给ServiceManager,注册完自己,Service就需要搭建自己的循环机制去检测客户端的请求了。
六、Service的线程池机制
在上面的过程中,我们完成了ProcessState的初始化,得到了ServiceManager的代理对象,又完成了MediaPlayerService等服务的初始化,下面要做的就是搭建一个线程池用于扫描和处理客户端的请求。搭建线程池的过程可以从以下两步中体现:
- ProcessState::self()->startThreadPool();
- IPCThreadState::self()->joinThreadPool();
- @ProcessState.cpp
- void ProcessState::startThreadPool() {
- AutoMutex _l(mLock);
- if (!mThreadPoolStarted) {
- mThreadPoolStarted = true;
- spawnPooledThread(true);
- }
- }
- void ProcessState::spawnPooledThread(bool isMain) {
- if (mThreadPoolStarted) {
- int32_t s = android_atomic_add(1, &mThreadPoolSeq);
- char buf[16];
- snprintf(buf, sizeof(buf), "Binder_%X", s);
- sp<Thread> t = new PoolThread(isMain);
- t->run(buf);
- }
- }
- @ProcessState.cpp
- class PoolThread : public Thread {
- public:
- PoolThread(bool isMain)
- : mIsMain(isMain)
- {
- }
- protected:
- virtual bool threadLoop()
- {
- IPCThreadState::self()->joinThreadPool(mIsMain);
- return false;
- }
- const bool mIsMain;
- };
下面我们就来看这个方法的具体作用。
6.1、IPCThreadState的初始化过程
为了弄明白IPCThreadState的joinThreadPool()方法,我们要先简要介绍一下IPCThreadState这个类。首先,他与ProcessState一样,都是单例模型,但是ProcessState是进程级别的,每个进程拥有同一个ProcessState,而IPCThreadState是线程级别的,每个线程拥有同一个IPCThreadState对象。
其次,从作用上来讲,ProcessState的作用是打开Binder驱动并映射虚拟地址,而IPCThreadState的作用则是构建循环机制扫描客户端对服务端的请求,并把具体请求发给服务端处理,同时给客户端提供返回值。
下面我们先来看IPCThreadState的初始化流程:
- @IPCThreadState.cpp(google-code\frameworks\native\libs\binder\)
- IPCThreadState* IPCThreadState::self() {
- //第一次调用gHaveTLS为false
- if (gHaveTLS) {
- restart:
- const pthread_key_t k = gTLS;
- //当前线程再次获取IPCThreadState时,可以用key取出当前线程的IPCThreadState对象
- IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
- if (st) return st;
- return new IPCThreadState;
- }
- if (gShutdown) return NULL;
- pthread_mutex_lock(&gTLSMutex);
- if (!gHaveTLS) {
- //创建当前线程的key
- if (pthread_key_create(&gTLS, threadDestructor) != 0) {
- pthread_mutex_unlock(&gTLSMutex);
- return NULL;
- }
- gHaveTLS = true;
- }
- pthread_mutex_unlock(&gTLSMutex);
- goto restart;
- }
- IPCThreadState::IPCThreadState()
- : mProcess(ProcessState::self()),
- mMyThreadId(androidGetTid()),
- mStrictModePolicy(0),
- mLastTransactionBinderFlags(0)
- {
- //把当前的IPCThreadState对象保存在key中
- pthread_setspecific(gTLS, this);
- clearCaller();
- mIn.setDataCapacity(256);
- mOut.setDataCapacity(256);
- }
到这里,就完成了IPCThreadState对象的初始化过程,在这个过程中主要完成了两个重要的操作:
1、初始化ProcessState对象,并将对象作为IPCThreadState的mProcess
2、初始化mIn和mOut,他们是与Binder驱动交换数据用的buffer,并且设置buffer的大小为256
6.2、IPCThreadState建立消息循环过程
前面说过,IPCThreadState的joinThreadPool()方法负责搭建消息循环机制。并且调用这个函数需要传递一个bool型的变量isMain,该变量标志着当前的IPCThreadState消息循环是否作为主循环在运作,在消息轮询的过程中,如果发生了超时的错误,非主循环将会退出,而主循环将会继续运行。现在回顾一下,在ProcessState中我们建立PoolThread线程并运行时,该线程调用的joinThreadPool()时传递的参数就是true。而我们在main_mediaserver.cpp中直接调用IPCThreadState的joinThreadPool()时没有传递参数,也就是为false。
这就说明,在整个Service的初始化流程中,有两个线程拥有IPCThreadState并通过joinThreadPool()建立了消息的轮询机制,而且在ProcessState中建立的循环是主循环。
下面我们来看具体的过程。
- @IPCThreadState.cpp
- void IPCThreadState::joinThreadPool(bool isMain) {
- //向Binder驱动发送命令,要进入/注册 Loop状态了
- mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
- status_t result;
- do {
- int32_t cmd;
- //清除接收缓存,准备接收数据
- if (mIn.dataPosition() >= mIn.dataSize()) {
- size_t numPending = mPendingWeakDerefs.size();
- if (numPending > 0) {
- for (size_t i = 0; i < numPending; i++) {
- RefBase::weakref_type* refs = mPendingWeakDerefs[i];
- refs->decWeak(mProcess.get());
- }
- mPendingWeakDerefs.clear();
- }
- numPending = mPendingStrongDerefs.size();
- if (numPending > 0) {
- for (size_t i = 0; i < numPending; i++) {
- BBinder* obj = mPendingStrongDerefs[i];
- obj->decStrong(mProcess.get());
- }
- mPendingStrongDerefs.clear();
- }
- }
- //与Binder交换数据,发送命令并读取返回值
- result = talkWithDriver();
- if (result >= NO_ERROR) {
- size_t IN = mIn.dataAvail();
- if (IN < sizeof(int32_t)) continue;
- cmd = mIn.readInt32();
- //处理返回值
- result = executeCommand(cmd);
- }
- if(result == TIMED_OUT && !isMain) {
- break;
- }
- } while (result != -ECONNREFUSED && result != -EBADF);
- //退出Loop状态
- mOut.writeInt32(BC_EXIT_LOOPER);
- talkWithDriver(false);
- }
下面我们详细分析一下得到数据和处理数据的过程。
6.2.1、从Binder读取数据
从Binder驱动读取数据是在talkWithDriver()中完成的,其实在3.3.4节中介绍BpServiceManager作用时就介绍过这个方法,其作用就是把mOut中的内容发送到Binder驱动中,同时把读取的数据放入mIn中。- status_t IPCThreadState::talkWithDriver(bool doReceive) {
- //确认Binder已经打开
- if (mProcess->mDriverFD <= 0) {
- return -EBADF;
- }
- binder_write_read bwr;
- const bool needRead = mIn.dataPosition() >= mIn.dataSize();
- const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
- bwr.write_size = outAvail;
- bwr.write_buffer = (long unsigned int)mOut.data();
- if (doReceive && needRead) {
- //准备接收缓存
- bwr.read_size = mIn.dataCapacity();
- bwr.read_buffer = (long unsigned int)mIn.data();
- } else {
- bwr.read_size = 0;
- bwr.read_buffer = 0;
- }
- if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
- bwr.write_consumed = 0;
- bwr.read_consumed = 0;
- status_t err;
- do {
- //通过ioctl()与Binder交换数据
- if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
- err = NO_ERROR;
- else
- err = -errno;
- if (mProcess->mDriverFD <= 0) {
- err = -EBADF;
- }
- } while (err == -EINTR);
- if (err >= NO_ERROR) {
- if (bwr.write_consumed > 0) {
- if (bwr.write_consumed < (ssize_t)mOut.dataSize())
- mOut.remove(0, bwr.write_consumed);
- else
- mOut.setDataSize(0);
- }
- //将接收数据放入mIn中
- if (bwr.read_consumed > 0) {
- mIn.setDataSize(bwr.read_consumed);
- mIn.setDataPosition(0);
- }
- return NO_ERROR;
- }
- return err;
- }
6.2.2、IPCThreadState把数据转移给相应的Service过程
经过上面的talkWithDriver()方法,就把数据读取到了mIn缓存中,接下来IPCThreadState将会把从Binder得到的请求通过executeCommand()转发给相应的Service。- status_t IPCThreadState::executeCommand(int32_t cmd) {
- BBinder* obj;
- RefBase::weakref_type* refs;
- status_t result = NO_ERROR;
- switch (cmd) {
- case BR_ERROR: break;
- case BR_OK: break;
- case BR_ACQUIRE: break;
- case BR_RELEASE: break;
- case BR_INCREFS: break;
- case BR_DECREFS: break;
- case BR_ATTEMPT_ACQUIRE: break;
- case BR_TRANSACTION: break;
- case BR_DEAD_BINDER: break;
- case BR_CLEAR_DEATH_NOTIFICATION_DONE: break;
- case BR_FINISHED: break;
- case BR_NOOP: break;
- case BR_SPAWN_LOOPER: break;
- default: break;
- }
- return result;
- }
另外一个部分就是BR_TRANSACTION消息的处理。这里要特别说明一下,与ServiceManager类似,其他Service的客户端在得到Service的远程代理对象之后调用的所有方法都会转换成代理对象(BpXXXService)的transact()方法,经过BpBinder的传递,最终调用到IPCThreadState的transact()方法,在IPCThreadState的transact()内部将数据封装,而封装的过程就是把所有请求打包为BC_TRANSACTION消息发送到Binder驱动,并在数据内部标记当初客户端调用的是Service的哪个方法。
因此这里拿到的mIn中数据的cmd将会是BR_TRANSACTION。
- status_t IPCThreadState::executeCommand(int32_t cmd) {
- BBinder* obj;
- RefBase::weakref_type* refs;
- status_t result = NO_ERROR;
- switch (cmd) {
- case BR_ERROR: break;
- case BR_OK: break;
- case BR_ACQUIRE: break;
- case BR_RELEASE: break;
- case BR_INCREFS: break;
- case BR_DECREFS: break;
- case BR_ATTEMPT_ACQUIRE: break;
- case BR_TRANSACTION: {
- binder_transaction_data tr;
- //读取从Binder驱动得到的客户端请求数据,并放到tr中
- result = mIn.read(&tr, sizeof(tr));
- if (result != NO_ERROR) break;
- Parcel buffer;
- //将tr数据封装到Parcel型的buffer中
- buffer.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(size_t), freeBuffer, this);
- const pid_t origPid = mCallingPid;
- const uid_t origUid = mCallingUid;
- //记录当前客户端的进程信息
- mCallingPid = tr.sender_pid;
- mCallingUid = tr.sender_euid;
- int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
- if (gDisableBackgroundScheduling) {
- if (curPrio > ANDROID_PRIORITY_NORMAL) {
- //设置线程优先级
- setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
- }
- } else {
- if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
- set_sched_policy(mMyThreadId, SP_BACKGROUND);
- }
- }
- Parcel reply;
- if (tr.target.ptr) {
- sp<BBinder> b((BBinder*)tr.cookie);
- //把数据转交给相应Service
- 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) {
- sendReply(reply, 0);
- } else {
- LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
- }
- mCallingPid = origPid;
- mCallingUid = origUid;
- }
- break;
- default: break;
- }
- return result;
- }
那么这个BBinder对象和目标Service有什么关系呢?
我们再来看一下Service把自己注册给ServiceManager时传递的参数:
- defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService());
由此,我们看到了完整的IPCThreadState中消息循环的流程,简单来说就是:
1、在joinThreadPool()中搭建do-while死循环。
2、while循环中通过talkWithDriver()从Binder驱动读取客户端请求。
3、while循环中得到请求后,调用executeCommand将客户端请求重新打包成Parcel数据发送给Service的BBinder对象。
6.3、Service处理数据的过程
上一节我们看到,IPCThreadState是把数据交给了Service的BBinder对象,这一节中我们将会分析BBinder如何把数据转移给相应的Service对象本身。我们直接来看BBinder的transact()方法的实现。
- @Binder.cpp(google-code\frameworks\native\libs\binder\)
- 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:
- //调用onTransact方法
- err = onTransact(code, data, reply, flags);
- break;
- }
- if (reply != NULL) {
- reply->setDataPosition(0);
- }
- return err;
- }
- @IMediaPlayerService.cpp(google-code\frameworks\av\media\libmedia\)
- status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
- switch (code) {
- case CREATE: { } break;
- case DECODE_URL: { } break;
- case DECODE_FD: { } break;
- case CREATE_MEDIA_RECORDER: { } break;
- case CREATE_METADATA_RETRIEVER: { } break;
- case GET_OMX: { } break;
- case MAKE_CRYPTO: { } break;
- case MAKE_HDCP: { } break;
- case ADD_BATTERY_DATA: { } break;
- case PULL_BATTERY_DATA: { } break;
- case LISTEN_FOR_REMOTE_DISPLAY: { } break;
- default: return BBinder::onTransact(code, data, reply, flags);
- }
- }
- status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
- switch (code) {
- case CREATE: {
- //权限检查
- CHECK_INTERFACE(IMediaPlayerService, data, reply);
- //得到调用者的pid
- pid_t pid = data.readInt32();
- sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
- int audioSessionId = data.readInt32();
- //调用create()
- sp<IMediaPlayer> player = create(pid, client, audioSessionId);
- reply->writeStrongBinder(player->asBinder());
- return NO_ERROR;
- } break;
- }
- }
- @MediaPlayerService.cpp(google-code\frameworks\av\media\libmediaplayerservice\)
- sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId) {
- int32_t connId = android_atomic_inc(&mNextConnId);
- //创建客户端对象
- sp<Client> c = new Client(this,pid,connId,client,audioSessionId,IPCThreadState::self()->getCallingUid());
- //把客户端对象返回给申请者
- return c;
- }
至此,IPCThreadState的消息机制就把一个客户端的请求从Binder驱动拿到后,完整的交给了Service并由Service完成了所有的处理。
但是,这只是跨进程的“远端”操作部分,那么近端的流程是怎样的呢?
也就是说,一个客户端是如何把请求发送到Binder驱动呢?
七、客户端发送请求的过程
其实我们在前面介绍MediaPlayerService向ServiceManager注册自己的过程中,就可以看到客户端发送请求的过程。因为对于ServiceManager来说,刚刚我们分析的MediaPlayerService对象就是他的客户端之一,而MediaPlayerService发起的addService()的请求过程就是一个典型的客户端对服务端请求的过程。
但为了理顺思路,我们重新来分析一下作为MediaPlayerService的客户端,是如何将请求发送到Binder驱动的。
在stream.cpp的main()中我们找到了MediaPlayerService的客户端用法:
- @stream.cpp(google-code\frameworks\av\cmds\stagefright\stream.cpp)
- int main(int argc, char **argv) {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.player"));
- sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
- sp<IMediaPlayer> player = service->create(getpid(), client, 0);
- }
我们需要在以下分析过程中,解决2个疑问:
1、客户端是如何得到Service的远程代理对象的?
2、调用代理对象service的方法,是如何发送到binder驱动的?
7.1、客户端得到Service的远程代理对象
我们用两个步骤得到了Service的远程代理对象:- sp<IBinder> binder = sm->getService(String16("media.player"));
- sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
在前面我们已经分析过,通过defaultServiceManager()得到的是BpServiceManager对象,他是ServiceManager的代理对象,那么这里的getService()就应该是在BpServiceManager中:
- @IServiceManager.cpp
- virtual sp<IBinder> getService(const String16& name) const
- {
- unsigned n;
- for (n = 0; n < 5; n++){
- //调用checkService()方法
- sp<IBinder> svc = checkService(name);
- 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.writeString16(name);
- //调用ServiceManager的CHECK_SERVICE_TRANSACTION命令
- remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
- return reply.readStrongBinder();
- }
1、remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
2、reply.readStrongBinder();
下面我们逐步来分析。
7.1.1、得到ServiceManager的返回值
在前面的分析中我们应该熟悉remote()->transact()这个过程。其实就是调用BpBinder(0)对象的transact()方法,并间接调用到IPCThreadState的transact()方法,然后经过IPCThreadState封装数据后,把Parcel类型的数据发送到binder驱动中。同时在binder驱动的另一侧,ServiceManager将会通过svcmgr_handler()方法去处理所有的请求,而对于CHECK_SERVICE_TRANSACTION这个请求,其具体操作如下:
- @service_manager.c
- int svcmgr_handler(struct binder_state *bs,struct binder_txn *txn,struct binder_io *msg,struct binder_io *reply){
- switch(txn->code) {
- case SVC_MGR_GET_SERVICE:
- case SVC_MGR_CHECK_SERVICE:
- s = bio_get_string16(msg, &len);
- //查找目标Service
- ptr = do_find_service(bs, s, len, txn->sender_euid);
- if (!ptr)
- break;
- //构建返回值
- bio_put_ref(reply, ptr);
- return 0;
- case SVC_MGR_ADD_SERVICE:
- case SVC_MGR_LIST_SERVICES:
- default:
- }
- return 0;
- }
- @binder.c
- void bio_put_ref(struct binder_io *bio, void *ptr) {
- struct binder_object *obj;
- if (ptr)
- //分配结构体内存
- obj = bio_alloc_obj(bio);
- else
- obj = bio_alloc(bio, sizeof(*obj));
- if (!obj)
- return;
- obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- //标记类型为BINDER_TYPE_HANDLE
- obj->type = BINDER_TYPE_HANDLE;
- obj->pointer = ptr;
- obj->cookie = 0;
- }
到这里,ServiceManager就完成了他的任务,接下来将会再次经过Binder驱动,把返回值数据经过IPCThreadState返回给BpServiceManager,这就是我们通过BpServiceManager的remote()->transact()得到的数据。
7.1.2、用ServiceManager的返回值构建BpBinder对象
得到ServiceManager的数据之后,这一步需要把数据解析成客户端可用的IBinder类型的对象。我们来看reply.readStrongBinder()的细节:
- @Parcel.cpp
- 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) {
- //读取ServiceManager给出的返回值
- 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:
- //在ServiceManager构建返回值时用的就是这个type
- *out = proc->getStrongProxyForHandle(flat->handle);
- return finish_unflatten_binder( static_cast<BpBinder*>(out->get()), *flat, in);
- }
- }
- return BAD_TYPE;
- }
- @ProcessState.cpp
- sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) {
- sp<IBinder> result;
- //先去查找,看有没有目标Service的缓存
- handle_entry* e = lookupHandleLocked(handle);
- if (e != NULL) {
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- //看到了吧,客户端得到的是IBinder对象其实就是BpBinder对象
- 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;
- }
也就是说,我们通过ServiceManager去得到的所有Service对象,都是BpBinder对象,而不同的Service的BpBinder对象的handle是不同的。
联系到ServiceManager的分析,每个Service注册自己的时候,ServiceManager都将为其分配不同的id,而客户端申请得到某个Service的时候,就是用目标Service的id生成的不同BpBinder对象。
7.1.3、利用BpBinder得到BpMediaPlayerService对象
现在我们得到了IBinder类型的BpBinder对象,但是客户端拿到这个对象还不能直接调用到相应Service的方法,需要经过interface_cast的转换才可以使用。并且这个函数模版在3.2节已经介绍的很清晰,经过interface_cast的转换,我们将会得到相应的BpXXXService对象。对于当前环境来说,得到的就是BpMediaPlayerService对象。
7.2、如何通过代理对象将请求发送到Binder驱动
经过7.1节的介绍,客户端得到了MediaPlayerService的BpMediaPlayerService对象,然后就可以调用其中的方法了,下面我们就来看调用其create()方法后,如何将请求发送到Binder驱动。- @IMediaPlayerService.cpp(google-code\frameworks\av\media\libmedia\IMediaPlayerService.cpp)
- virtual sp<IMediaPlayer> create( pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId) {
- Parcel data, reply;
- data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
- data.writeInt32(pid);
- data.writeStrongBinder(client->asBinder());
- data.writeInt32(audioSessionId);
- //调用BpBinder的transact()
- remote()->transact(CREATE, data, &reply);
- return interface_cast<IMediaPlayer>(reply.readStrongBinder());
- }
接下来的过程就是第四节中介绍的步骤了,BpBinder会在transact()中调用IPCThreadState的transact(),IPCThreadState接着在transact()内部经过waitForResponse()-->talkWithDriver()-->ioctl()将数据发送到Binder驱动中。
发送到Binder驱动之后,MediaPlayerService将会在IPCThreadState的joinThreadPool中检测到该请求,然后就是第六节中介绍的Service端处理数据的过程了。
下面我们结合第六节中的消息循环来看一下从客户端到服务端整个数据流的过程:
八、总结
现在我们来总结一下整个数据传输的过程:1、一个Service向ServiceManager注册自己的时候,需要向ServiceManager传递2个数据:name+BnXXXService
这个BnXXXService是双继承结构,同时继承了IMediaPlayerService和BBinder
ServiceManager会针对该Service生成一个ID,也就是handle值
2、客户端向ServiceManager申请Service代理对象的时候,将会得到目标Service的BpBinder对象
ServiceManager只负责把相应Service的handle值返回出来
BpServiceManager得到handle之后,经过Parcel的解析,调用到ProcessState的getStrongProxyForHandle()
而ProcessState将会在getStrongProxyForHandle()中利用得到的handle创建目标Service的BpBinder(handle)对象
如果要得到的目标Service就是ServiceManager,那么其handle值就是0
3、然后客户端用interface_cast<IXXXService>的模版将BpBinder对象转换为BpXXXService对象
interface_cast的函数模版转换的原理是在内部调用IMediaPlayerService的asInterface()方法
而asInterface()方法的结果就是用得到的BpBinder对象作为参数,去创建BpXXXService的对象
而BpXXXService的构造函数中会把BpBinder暂存在其祖先类BpRefBase的mRemote变量中
4、客户端拿到BpXXXService对象之后,可以调用IXXXService中的各种方法
客户端无论调用哪个方法,都会调用到remote()->transact()方法,只是参数不同而已
而remote()所返回的就是BpXXXService祖先类中暂存的BpBinder对象
调用BpBinder的transact()方法将会调用到IPCThreadState的transact()方法
IPCThreadState的transact()调用writeTransactionData()将客户端的请求封装到mOut中,然后经过waitForResponse()和talkWithDriver()最终调用ioctl()将请求发送到Binder驱动中
5、服务端的IPCThreadState通过内部建立的joinThreadPool()循环机制不断检测客户端请求
得到请求后调用executeCommand()和BR_TRANSACTION的case分支,将请求发送到服务侧所注册的BBinder对象的transact()方法
调用BBinder的transact()将会在内部调用到onTransact()方法,并且这个方法是在BBinder的子类BnXXXService所实现
BnXXXService内部的onTransact()构建了switc语句来处理各种请求,而各个请求所调用的方法,都会在子类中实现
而BnXXXService的子类就是MediaPlayerService本身
完