Android Binder Mechanism (2) -- 如何获得ServiceManager的代理对象的引用

在这篇文章中,我们将深入剖析一下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实例。

  1. //File:Frameworks/base/libs/binder/ProcessState.cpp
  2. sp<ProcessState>ProcessState::self()
  3. {
  4. if(gProcess!=NULL)returngProcess;
  5. AutoMutex_l(gProcessMutex);
  6. if(gProcess==NULL)gProcess=newProcessState;
  7. returngProcess;
  8. }

该ProcessState会打开/dev/binder设备供IPCThreadState使用。查看其构造函数便知。

  1. //File:frameworks/base/libs/binder/ProcessState.cpp
  2. ProcessState::ProcessState()
  3. :mDriverFD(open_driver())
  4. ,mVMStart(MAP_FAILED)
  5. ,mManagesContexts(false)
  6. ,mBinderContextCheckFunc(NULL)
  7. ,mBinderContextUserData(NULL)
  8. ,mThreadPoolStarted(false)
  9. ,mThreadPoolSeq(1)
  10. {
  11. if(mDriverFD>=0){
  12. //XXXIdeally,thereshouldbeaspecificdefineforwhetherwe
  13. //havemmap(orwhetherwecouldpossiblyhavethekernelmodule
  14. //availabla).
  15. #if!defined(HAVE_WIN32_IPC)
  16. //mmapthebinder,providingachunkofvirtualaddressspacetoreceivetransactions.
  17. mVMStart=mmap(0,BINDER_VM_SIZE,PROT_READ,MAP_PRIVATE|MAP_NORESERVE,mDriverFD,0);
  18. if(mVMStart==MAP_FAILED){
  19. //*sigh*
  20. LOGE("Using/dev/binderfailed:unabletommaptransactionmemory./n");
  21. close(mDriverFD);
  22. mDriverFD=-1;
  23. }
  24. #else
  25. mDriverFD=-1;
  26. #endif
  27. }
  28. if(mDriverFD<0){
  29. //Needtorunwithoutthedriver,startingourownthreadpool.
  30. }
  31. }

再看一下open_driver()方法的源代码。

  1. //File:frameworks/base/libs/binder/ProcessState.cpp
  2. staticintopen_driver()
  3. {
  4. if(gSingleProcess){
  5. return-1;
  6. }
  7. intfd=open("/dev/binder",O_RDWR);
  8. if(fd>=0){
  9. fcntl(fd,F_SETFD,FD_CLOEXEC);
  10. intvers;
  11. #ifdefined(HAVE_ANDROID_OS)
  12. status_tresult=ioctl(fd,BINDER_VERSION,&vers);
  13. #else
  14. status_tresult=-1;
  15. errno=EPERM;
  16. #endif
  17. if(result==-1){
  18. LOGE("Binderioctltoobtainversionfailed:%s",strerror(errno));
  19. close(fd);
  20. fd=-1;
  21. }
  22. if(result!=0||vers!=BINDER_CURRENT_PROTOCOL_VERSION){
  23. LOGE("Binderdriverprotocoldoesnotmatchuserspaceprotocol!");
  24. close(fd);
  25. fd=-1;
  26. }
  27. #ifdefined(HAVE_ANDROID_OS)
  28. size_tmaxThreads=15;
  29. result=ioctl(fd,BINDER_SET_MAX_THREADS,&maxThreads);
  30. if(result==-1){
  31. LOGE("Binderioctltosetmaxthreadsfailed:%s",strerror(errno));
  32. }
  33. #endif
  34. }else{
  35. LOGW("Opening'/dev/binder'failed:%s/n",strerror(errno));
  36. }
  37. returnfd;
  38. }

open_driver()方法打开binder设备(/dev/binder),获取binder版本号,设定最大线程个数,并返回binder设备的文件描述符。内核空间中分配约1M的连续空间(BINDER_VM_SIZE)给进程,并用mmap函数映射到进程的用户空间。该空间用于transaction交互数据用。

回到defaultServiceManager()方法。我们可以看到defaultServiceManager()是调用ProcessState对象的getContextObject方法获得ServiceManager的代理对象。我们再看一下getContextObject函数的源代码:

  1. //File:frameworks/base/libs/binder/ProcessState.cpp
  2. sp<IBinder>ProcessState::getContextObject(constsp<IBinder>&caller)
  3. {
  4. if(supportsProcesses()){
  5. returngetStrongProxyForHandle(0);
  6. }else{
  7. returngetContextObject(String16("default"),caller);
  8. }
  9. }

因为支持binder驱动(supportsProcesses()函数会判断binder驱动是否打开,以此来检验是否支持binder),这里是以0为参数调用getStrongProxyForHandle()方法获得ServiceManager的代理对象。我们再看一下getStrongProxyForHandle()方法的源代码:

  1. //File:frameworks/base/libs/binder/ProcessState.cpp
  2. sp<IBinder>ProcessState::getStrongProxyForHandle(int32_thandle)
  3. {
  4. sp<IBinder>result;
  5. AutoMutex_l(mLock);
  6. handle_entry*e=lookupHandleLocked(handle);
  7. if(e!=NULL){
  8. //WeneedtocreateanewBpBinderifthereisn'tcurrentlyone,ORwe
  9. //areunabletoacquireaweakreferenceonthiscurrentone.Seecomment
  10. //ingetWeakProxyForHandle()formoreinfoaboutthis.
  11. IBinder*b=e->binder;
  12. if(b==NULL||!e->refs->attemptIncWeak(this)){
  13. b=newBpBinder(handle);
  14. e->binder=b;
  15. if(b)e->refs=b->getWeakRefs();
  16. result=b;
  17. }else{
  18. //Thislittlebitofnastynessistoallowustoaddaprimary
  19. //referencetotheremoteproxywhenthisteamdoesn'thaveone
  20. //butanotherteamissendingthehandletous.
  21. result.force_set(b);
  22. e->refs->decWeak(this);
  23. }
  24. }
  25. returnresult;
  26. }

getStrongProxyForHandle()首先调用lookupHandleLocked()方法查找当前进程是否维护的Service代理对象的列表。我们再看一下lookupHandleLocked()方法的源代码。

  1. //File:ProcessState.cpp
  2. ProcessState::handle_entry*ProcessState::lookupHandleLocked(int32_thandle)
  3. {
  4. constsize_tN=mHandleToObject.size();
  5. if(N<=(size_t)handle){
  6. handle_entrye;
  7. e.binder=NULL;
  8. e.refs=NULL;
  9. status_terr=mHandleToObject.insertAt(e,N,handle+1-N);
  10. if(err<NO_ERROR)returnNULL;
  11. }
  12. return&mHandleToObject.editItemAt(handle);
  13. }

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类的构造函数做了什么。

  1. //File:frameworks/base/libs/binder/BpBinder.cpp
  2. BpBinder::BpBinder(int32_thandle)
  3. :mHandle(handle)
  4. ,mAlive(1)
  5. ,mObitsSent(0)
  6. ,mObituaries(NULL)
  7. {
  8. LOGV("CreatingBpBinder%phandle%d/n",this,mHandle);
  9. extendObjectLifetime(OBJECT_LIFETIME_WEAK);
  10. IPCThreadState::self()->incWeakHandle(handle);
  11. }

这里调用了IPCThreadState类的incWeakHandle()方法来增加引用计数。我们再看看incWeakHandle()方法的源代码。

  1. //File:frameworks/base/libs/binder/IPCThreadState.cpp
  2. voidIPCThreadState::incWeakHandle(int32_thandle)
  3. {
  4. LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)/n",handle);
  5. mOut.writeInt32(BC_INCREFS);
  6. mOut.writeInt32(handle);
  7. }

这里incWeakHandle()在输出缓冲区增加了一条BC_INCREFS命令。

如果该handle对应的代理对象已经创建过了,那么就增加它的引用计数。result是一个指向IBinder类型的强指针。Android系统中定义了sp(strong pointer)和wp(weak pointer)两种智能指针。注意这里的操作符"="已经被重载了。force_set是RefBase类专门为ProcessState类优化的一个方法,让我们看一下它的源代码。

  1. //File:frameworks/base/include/utils/RefBase.h
  2. template<typenameT>
  3. voidsp<T>::force_set(T*other)
  4. {
  5. other->forceIncStrong(this);
  6. m_ptr=other;
  7. }

设定好引用计数之后,getStrongProxyForHandle()方法返回代理对象的句柄。接下来会通过interface_cast将其转换为IserviceManager类型。我们来看看这个转换是怎么实现的。

  1. gDefaultServiceManager=interface_cast<IServiceManager>(
  2. ProcessState::self()->getContextObject(NULL));

interface_cast<IServiceManager>,其实调用的是IServiceManager.asInterface方法:

  1. //File:frameworks/base/include/binder/IInterface.h
  2. template<typenameINTERFACE>
  3. inlinesp<INTERFACE>interface_cast(constsp<IBinder>&obj)
  4. {
  5. returnINTERFACE::asInterface(obj);
  6. }

查看IServiceManager的源文件,好像并没有定义asInterface方法。不要急,我们先看一下IServiceManager的定义:

  1. //File:frameworks/base/include/binder/IServiceManager.h
  2. classIServiceManager:publicIInterface
  3. {
  4. public:
  5. DECLARE_META_INTERFACE(ServiceManager);
  6. /**
  7. *Retrieveanexistingservice,blockingforafewseconds
  8. *ifitdoesn'tyetexist.
  9. */
  10. virtualsp<IBinder>getService(constString16&name)const=0;
  11. /**
  12. *Retrieveanexistingservice,non-blocking.
  13. */
  14. virtualsp<IBinder>checkService(constString16&name)const=0;
  15. /**
  16. *Registeraservice.
  17. */
  18. virtualstatus_taddService(constString16&name,
  19. constsp<IBinder>&service)=0;
  20. /**
  21. *Returnlistofallexistingservices.
  22. */
  23. virtualVector<String16>listServices()=0;
  24. enum{
  25. GET_SERVICE_TRANSACTION=IBinder::FIRST_CALL_TRANSACTION,
  26. CHECK_SERVICE_TRANSACTION,
  27. ADD_SERVICE_TRANSACTION,
  28. LIST_SERVICES_TRANSACTION,
  29. };
  30. };

这里的宏DECLARE_META_INTERFACE在IInterface.h头文件中定义如下:

  1. //File:frameworks/base/include/binder/IInterface.h
  2. #defineDECLARE_META_INTERFACE(INTERFACE)/
  3. staticconstString16descriptor;/
  4. staticsp<I##INTERFACE>asInterface(constsp<IBinder>&obj);/
  5. virtualconstString16&getInterfaceDescriptor()const;/
  6. I##INTERFACE();/
  7. virtual~I##INTERFACE();/

这里,我们终于找到了asInterface方法的声明。该方法是通过在IServiceManager.cpp文件中的IMPLEMENT_META_INTERFACE宏来实现的。

  1. //File:frameworks/base/include/binder/IServiceManager.cpp
  2. IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager");

IMPLEMENT_META_INTERFACE宏定义如下:

  1. //File:frameworks/base/include/binder/IInterface.h
  2. #defineIMPLEMENT_META_INTERFACE(INTERFACE,NAME)/
  3. constString16I##INTERFACE::descriptor(NAME);/
  4. constString16&I##INTERFACE::getInterfaceDescriptor()const{/
  5. returnI##INTERFACE::descriptor;/
  6. }/
  7. sp<I##INTERFACE>I##INTERFACE::asInterface(constsp<IBinder>&obj)/
  8. {/
  9. sp<I##INTERFACE>intr;/
  10. if(obj!=NULL){/
  11. intr=static_cast<I##INTERFACE*>(/
  12. obj->queryLocalInterface(/
  13. I##INTERFACE::descriptor).get());/
  14. if(intr==NULL){/
  15. intr=newBp##INTERFACE(obj);/
  16. }/
  17. }/
  18. returnintr;/
  19. }/
  20. I##INTERFACE::I##INTERFACE(){}/
  21. I##INTERFACE::~I##INTERFACE(){}/

将上面这些宏展开后的最终结果就是,

  1. sp<IServiceManager>IServiceManager::asInterface(constsp<IBinder>&obj)
  2. {
  3. sp<IServiceManager>intr;
  4. if(obj!=NULL){
  5. intr=static_cast<IServiceManager*>(obj->queryLocalInterface(
  6. IServiceManager::descriptor).get());
  7. if(intr==NULL){
  8. intr=newBpServiceManager(obj);
  9. }
  10. }
  11. returnintr;
  12. }

可见,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的代理对象的引用。

你可能感兴趣的:(android)