在这篇文章中,我们将深入剖析一下Android系统的服务管理员ServiceManager。
ServiceManager是Android系统服务的管理者。所有需要通过Binder机制进行进程间通信的进程都要首先获得Service Manager的代理对象才能进行Binder通讯。比如系统中有用于音频混音的AudioFlingerService,用于照相的CameraService,用于媒体文件播放的MediaPlayerService。所有这些服务都会向ServiceManager注册,因此ServiceManager就维护了系统中所有服务的一个列表。任何应用程序要想使用这些服务,首先要向ServiceManager请求获得这些服务的引用,从而建立起和这些服务的联系。
在本系列的第一篇文章中,ExampleService通过如下语句向系统注册服务。
这里有两个问题:
1. defaultServiceManager()都完成了哪些工作,它返回的结果是什么?
2. 为什么调用上一步返回对象的addService方法,就可以向系统注册服务?这一注册过程都完成了哪些工作?
这篇文章先回答问题1。
ServiceManager也是系统中的一个服务,那么应用程序如何和它取得联系呢?答案就是通过defaultServiceManager()函数。defaultServiceManager()是系统在Android命名空间中定义的一个全局函数,用来获得ServiceManager的代理对象的引用。我们看一下该函数的源代码。
gDefaultServiceManager在libutil中定义,因此任何程序或库使用了libutil库都会有该变量,它在一个进程中是唯一的。gDefaultServiceManager的初始值为NULL,所以先调用ProcessState::self()方法获取一个ProcessState实例。这里用到了Singleton的设计模式,从而可知一个进程只有一个ProcessState实例。
- sp<ProcessState>ProcessState::self()
- {
- if(gProcess!=NULL)returngProcess;
- AutoMutex_l(gProcessMutex);
- if(gProcess==NULL)gProcess=newProcessState;
- returngProcess;
- }
该ProcessState会打开/dev/binder设备供IPCThreadState使用。查看其构造函数便知。
- ProcessState::ProcessState()
- :mDriverFD(open_driver())
- ,mVMStart(MAP_FAILED)
- ,mManagesContexts(false)
- ,mBinderContextCheckFunc(NULL)
- ,mBinderContextUserData(NULL)
- ,mThreadPoolStarted(false)
- ,mThreadPoolSeq(1)
- {
- if(mDriverFD>=0){
- #if!defined(HAVE_WIN32_IPC)
- mVMStart=mmap(0,BINDER_VM_SIZE,PROT_READ,MAP_PRIVATE|MAP_NORESERVE,mDriverFD,0);
- if(mVMStart==MAP_FAILED){
- LOGE("Using/dev/binderfailed:unabletommaptransactionmemory./n");
- close(mDriverFD);
- mDriverFD=-1;
- }
- #else
- mDriverFD=-1;
- #endif
- }
- if(mDriverFD<0){
- }
- }
再看一下open_driver()方法的源代码。
- staticintopen_driver()
- {
- if(gSingleProcess){
- return-1;
- }
- intfd=open("/dev/binder",O_RDWR);
- if(fd>=0){
- fcntl(fd,F_SETFD,FD_CLOEXEC);
- intvers;
- #ifdefined(HAVE_ANDROID_OS)
- status_tresult=ioctl(fd,BINDER_VERSION,&vers);
- #else
- status_tresult=-1;
- errno=EPERM;
- #endif
- if(result==-1){
- LOGE("Binderioctltoobtainversionfailed:%s",strerror(errno));
- close(fd);
- fd=-1;
- }
- if(result!=0||vers!=BINDER_CURRENT_PROTOCOL_VERSION){
- LOGE("Binderdriverprotocoldoesnotmatchuserspaceprotocol!");
- close(fd);
- fd=-1;
- }
- #ifdefined(HAVE_ANDROID_OS)
- size_tmaxThreads=15;
- result=ioctl(fd,BINDER_SET_MAX_THREADS,&maxThreads);
- if(result==-1){
- LOGE("Binderioctltosetmaxthreadsfailed:%s",strerror(errno));
- }
- #endif
- }else{
- LOGW("Opening'/dev/binder'failed:%s/n",strerror(errno));
- }
- returnfd;
- }
open_driver()方法打开binder设备(/dev/binder),获取binder版本号,设定最大线程个数,并返回binder设备的文件描述符。内核空间中分配约1M的连续空间(BINDER_VM_SIZE)给进程,并用mmap函数映射到进程的用户空间。该空间用于transaction交互数据用。
回到defaultServiceManager()方法。我们可以看到defaultServiceManager()是调用ProcessState对象的getContextObject方法获得ServiceManager的代理对象。我们再看一下getContextObject函数的源代码:
- sp<IBinder>ProcessState::getContextObject(constsp<IBinder>&caller)
- {
- if(supportsProcesses()){
- returngetStrongProxyForHandle(0);
- }else{
- returngetContextObject(String16("default"),caller);
- }
- }
因为支持binder驱动(supportsProcesses()函数会判断binder驱动是否打开,以此来检验是否支持binder),这里是以0为参数调用getStrongProxyForHandle()方法获得ServiceManager的代理对象。我们再看一下getStrongProxyForHandle()方法的源代码:
- sp<IBinder>ProcessState::getStrongProxyForHandle(int32_thandle)
- {
- 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=newBpBinder(handle);
- e->binder=b;
- if(b)e->refs=b->getWeakRefs();
- result=b;
- }else{
- result.force_set(b);
- e->refs->decWeak(this);
- }
- }
- returnresult;
- }
getStrongProxyForHandle()首先调用lookupHandleLocked()方法查找当前进程是否维护的Service代理对象的列表。我们再看一下lookupHandleLocked()方法的源代码。
- ProcessState::handle_entry*ProcessState::lookupHandleLocked(int32_thandle)
- {
- constsize_tN=mHandleToObject.size();
- if(N<=(size_t)handle){
- handle_entrye;
- e.binder=NULL;
- e.refs=NULL;
- status_terr=mHandleToObject.insertAt(e,N,handle+1-N);
- if(err<NO_ERROR)returnNULL;
- }
- return&mHandleToObject.editItemAt(handle);
- }
mHHandleToObject是一个以handle_entry类型为元素的Vector,维护当前进程的代理对象列表。其索引就是每个代理对象句柄的值。比如ServiceManager对应的句柄肯定是0,那么它就是这个列表的第1项。如果待查询的的句柄的值大于等于当前列表的大小,说明待创建的Service代理对象条目尚未在当前进程中创建,那么就需要插入新项。当前的列表大小是N,索引从0至N-1,如果待查询的索引是handle,那么就要插入handle-(N-1)项。如果该代理对象条目已经创建过了,那么直接返回其引用就可以了。
注:这里的“创建”只是在列表中创建相应的条目(e.binder = NULL;e.refs = NULL;),真正的代理对象要在稍后才创建。
现在回到getStrongProxyForHandle()方法。如果该代理对象尚未创建(e->binder==NULL),那么就创建一个,并更新代理对象列表中的相应记录。
我们再来看一下BpBinder类的构造函数做了什么。
- BpBinder::BpBinder(int32_thandle)
- :mHandle(handle)
- ,mAlive(1)
- ,mObitsSent(0)
- ,mObituaries(NULL)
- {
- LOGV("CreatingBpBinder%phandle%d/n",this,mHandle);
- extendObjectLifetime(OBJECT_LIFETIME_WEAK);
- IPCThreadState::self()->incWeakHandle(handle);
- }
这里调用了IPCThreadState类的incWeakHandle()方法来增加引用计数。我们再看看incWeakHandle()方法的源代码。
- voidIPCThreadState::incWeakHandle(int32_thandle)
- {
- LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)/n",handle);
- mOut.writeInt32(BC_INCREFS);
- mOut.writeInt32(handle);
- }
这里incWeakHandle()在输出缓冲区增加了一条BC_INCREFS命令。
如果该handle对应的代理对象已经创建过了,那么就增加它的引用计数。result是一个指向IBinder类型的强指针。Android系统中定义了sp(strong pointer)和wp(weak pointer)两种智能指针。注意这里的操作符"="已经被重载了。force_set是RefBase类专门为ProcessState类优化的一个方法,让我们看一下它的源代码。
- template<typenameT>
- voidsp<T>::force_set(T*other)
- {
- other->forceIncStrong(this);
- m_ptr=other;
- }
设定好引用计数之后,getStrongProxyForHandle()方法返回代理对象的句柄。接下来会通过interface_cast将其转换为IserviceManager类型。我们来看看这个转换是怎么实现的。
- gDefaultServiceManager=interface_cast<IServiceManager>(
- ProcessState::self()->getContextObject(NULL));
interface_cast<IServiceManager>,其实调用的是IServiceManager.asInterface方法:
- template<typenameINTERFACE>
- inlinesp<INTERFACE>interface_cast(constsp<IBinder>&obj)
- {
- returnINTERFACE::asInterface(obj);
- }
查看IServiceManager的源文件,好像并没有定义asInterface方法。不要急,我们先看一下IServiceManager的定义:
- classIServiceManager:publicIInterface
- {
- public:
- DECLARE_META_INTERFACE(ServiceManager);
- virtualsp<IBinder>getService(constString16&name)const=0;
- virtualsp<IBinder>checkService(constString16&name)const=0;
- virtualstatus_taddService(constString16&name,
- constsp<IBinder>&service)=0;
- virtualVector<String16>listServices()=0;
- enum{
- GET_SERVICE_TRANSACTION=IBinder::FIRST_CALL_TRANSACTION,
- CHECK_SERVICE_TRANSACTION,
- ADD_SERVICE_TRANSACTION,
- LIST_SERVICES_TRANSACTION,
- };
- };
这里的宏DECLARE_META_INTERFACE在IInterface.h头文件中定义如下:
- #defineDECLARE_META_INTERFACE(INTERFACE)/
- staticconstString16descriptor;/
- staticsp<I##INTERFACE>asInterface(constsp<IBinder>&obj);/
- virtualconstString16&getInterfaceDescriptor()const;/
- I##INTERFACE();/
- virtual~I##INTERFACE();/
这里,我们终于找到了asInterface方法的声明。该方法是通过在IServiceManager.cpp文件中的IMPLEMENT_META_INTERFACE宏来实现的。
- IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager");
IMPLEMENT_META_INTERFACE宏定义如下:
- #defineIMPLEMENT_META_INTERFACE(INTERFACE,NAME)/
- constString16I##INTERFACE::descriptor(NAME);/
- constString16&I##INTERFACE::getInterfaceDescriptor()const{/
- returnI##INTERFACE::descriptor;/
- }/
- sp<I##INTERFACE>I##INTERFACE::asInterface(constsp<IBinder>&obj)/
- {/
- sp<I##INTERFACE>intr;/
- if(obj!=NULL){/
- intr=static_cast<I##INTERFACE*>(/
- obj->queryLocalInterface(/
- I##INTERFACE::descriptor).get());/
- if(intr==NULL){/
- intr=newBp##INTERFACE(obj);/
- }/
- }/
- returnintr;/
- }/
- I##INTERFACE::I##INTERFACE(){}/
- I##INTERFACE::~I##INTERFACE(){}/
将上面这些宏展开后的最终结果就是,
- sp<IServiceManager>IServiceManager::asInterface(constsp<IBinder>&obj)
- {
- sp<IServiceManager>intr;
- if(obj!=NULL){
- intr=static_cast<IServiceManager*>(obj->queryLocalInterface(
- IServiceManager::descriptor).get());
- if(intr==NULL){
- intr=newBpServiceManager(obj);
- }
- }
- returnintr;
- }
可见,IServiceManager::asInterface()函数最终会用一个IBinder对象创建一个BpServiceManager对象,并将它返回。
好了,现在我们总结一下获取ServiceManager代理对象的全部过程:
defaultServiceManager(); // 获取ServiceManager代理对象
{
interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL)); // 将返回的BpBinder类型的代理对象转换成ServiceManager类型的代理对象
{
getStrongProxyForHandle(0); // 以0为参数即可获得ServiceManager的代理对象
{
lookupHandleLocked(0);
b = new BpBinder(0); // 新建一个代理对象
返回根据handle生成的代理对象
}
返回根据handle生成的代理对象
}
返回转换成ServiceManager类型的代理对象
}
最后,我们可以回答问题1了:
问题: defaultServiceManager()都完成了哪些工作,它返回的结果是什么?
答: 如果当前进程已经生成了ServiceManager的代理对象,那么该函数返回它的一个引用;如果当前进程还没有生成过ServiceManager的代理对象,那么创建它,并返回它的一个引用。
我们将在下篇文章中深入剖析为什么调用该引用指向的getService方法就可以获得ExampleService的代理对象的引用。