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实例。

view plain copy to clipboard print ?
  1. // File: Frameworks/base/libs/binder/ProcessState.cpp  
  2. sp<ProcessState> ProcessState::self()  
  3. {  
  4.     if (gProcess != NULL) return gProcess;  
  5.       
  6.     AutoMutex _l(gProcessMutex);  
  7.     if (gProcess == NULL) gProcess = new ProcessState;  
  8.     return gProcess;  
  9. }  

 

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

 

view plain copy to clipboard print ?
  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.         // XXX Ideally, there should be a specific define for whether we  
  13.         // have mmap (or whether we could possibly have the kernel module  
  14.         // availabla).  
  15. #if !defined(HAVE_WIN32_IPC)  
  16.         // mmap the binder, providing a chunk of virtual address space to receive transactions.  
  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/binder failed: unable to mmap transaction memory./n");  
  21.             close(mDriverFD);  
  22.             mDriverFD = -1;  
  23.         }  
  24. #else  
  25.         mDriverFD = -1;  
  26. #endif  
  27.     }  
  28.     if (mDriverFD < 0) {  
  29.         // Need to run without the driver, starting our own thread pool.  
  30.     }  
  31. }  

 

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

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/libs/binder/ProcessState.cpp  
  2. static int open_driver()  
  3. {  
  4.     if (gSingleProcess) {  
  5.         return -1;  
  6.     }  
  7.   
  8.     int fd = open("/dev/binder", O_RDWR);  
  9.     if (fd >= 0) {  
  10.         fcntl(fd, F_SETFD, FD_CLOEXEC);  
  11.         int vers;  
  12. #if defined(HAVE_ANDROID_OS)  
  13.         status_t result = ioctl(fd, BINDER_VERSION, &vers);  
  14. #else  
  15.         status_t result = -1;  
  16.         errno = EPERM;  
  17. #endif  
  18.         if (result == -1) {  
  19.             LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));  
  20.             close(fd);  
  21.             fd = -1;  
  22.         }  
  23.         if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {  
  24.             LOGE("Binder driver protocol does not match user space protocol!");  
  25.             close(fd);  
  26.             fd = -1;  
  27.         }  
  28. #if defined(HAVE_ANDROID_OS)  
  29.         size_t maxThreads = 15;  
  30.         result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);  
  31.         if (result == -1) {  
  32.             LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));  
  33.         }  
  34. #endif  
  35.           
  36.     } else {  
  37.         LOGW("Opening '/dev/binder' failed: %s/n", strerror(errno));  
  38.     }  
  39.     return fd;  
  40. }  

 

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

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

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/libs/binder/ProcessState.cpp  
  2. sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)  
  3. {  
  4.     if (supportsProcesses()) {  
  5.         return getStrongProxyForHandle(0);  
  6.     } else {  
  7.         return getContextObject(String16("default"), caller);  
  8.     }  
  9. }  

 

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

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/libs/binder/ProcessState.cpp  
  2. sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)  
  3. {  
  4.     sp<IBinder> result;  
  5.   
  6.     AutoMutex _l(mLock);  
  7.   
  8.     handle_entry* e = lookupHandleLocked(handle);  
  9.   
  10.     if (e != NULL) {  
  11.         // We need to create a new BpBinder if there isn't currently one, OR we  
  12.         // are unable to acquire a weak reference on this current one.  See comment  
  13.         // in getWeakProxyForHandle() for more info about this.  
  14.         IBinder* b = e->binder;  
  15.         if (b == NULL || !e->refs->attemptIncWeak(this)) {  
  16.             b = new BpBinder(handle);   
  17.             e->binder = b;  
  18.             if (b) e->refs = b->getWeakRefs();  
  19.             result = b;  
  20.         } else {  
  21.             // This little bit of nastyness is to allow us to add a primary  
  22.             // reference to the remote proxy when this team doesn't have one  
  23.             // but another team is sending the handle to us.  
  24.             result.force_set(b);  
  25.             e->refs->decWeak(this);  
  26.         }  
  27.     }  
  28.   
  29.     return result;  
  30. }  

 

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

 

view plain copy to clipboard print ?
  1. // File: ProcessState.cpp  
  2. ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)  
  3. {  
  4.     const size_t N=mHandleToObject.size();  
  5.     if (N <= (size_t)handle) {  
  6.         handle_entry e;  
  7.         e.binder = NULL;  
  8.         e.refs = NULL;  
  9.         status_t err = mHandleToObject.insertAt(e, N, handle+1-N);  
  10.         if (err < NO_ERROR) return NULL;  
  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类的构造函数做了什么。

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/libs/binder/BpBinder.cpp  
  2. BpBinder::BpBinder(int32_t handle)  
  3.     : mHandle(handle)  
  4.     , mAlive(1)  
  5.     , mObitsSent(0)  
  6.     , mObituaries(NULL)  
  7. {  
  8.     LOGV("Creating BpBinder %p handle %d/n"this, mHandle);  
  9.   
  10.     extendObjectLifetime(OBJECT_LIFETIME_WEAK);  
  11.     IPCThreadState::self()->incWeakHandle(handle);  
  12. }  

 

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

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/libs/binder/IPCThreadState.cpp  
  2. void IPCThreadState::incWeakHandle(int32_t handle)  
  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类优化的一个方法,让我们看一下它的源代码。

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/include/utils/RefBase.h  
  2. template<typename T>      
  3. void sp<T>::force_set(T* other)  
  4. {  
  5.     other->forceIncStrong(this);  
  6.     m_ptr = other;  
  7. }  

 

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

 

view plain copy to clipboard print ?
  1. gDefaultServiceManager = interface_cast<IServiceManager>(  
  2.                 ProcessState::self()->getContextObject(NULL));  

 

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

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/include/binder/IInterface.h  
  2. template<typename INTERFACE>  
  3. inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)  
  4. {  
  5.     return INTERFACE::asInterface(obj);  
  6. }  

 

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

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/include/binder/IServiceManager.h  
  2. class IServiceManager : public IInterface  
  3. {  
  4. public:  
  5.     DECLARE_META_INTERFACE(ServiceManager);  
  6.   
  7.     /** 
  8.      * Retrieve an existing service, blocking for a few seconds 
  9.      * if it doesn't yet exist. 
  10.      */  
  11.     virtual sp<IBinder>         getService( const String16& name) const = 0;  
  12.   
  13.     /** 
  14.      * Retrieve an existing service, non-blocking. 
  15.      */  
  16.     virtual sp<IBinder>         checkService( const String16& name) const = 0;  
  17.   
  18.     /** 
  19.      * Register a service. 
  20.      */  
  21.     virtual status_t            addService( const String16& name,  
  22.                                             const sp<IBinder>& service) = 0;  
  23.   
  24.     /** 
  25.      * Return list of all existing services. 
  26.      */  
  27.     virtual Vector<String16>    listServices() = 0;  
  28.   
  29.     enum {  
  30.         GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,  
  31.         CHECK_SERVICE_TRANSACTION,  
  32.         ADD_SERVICE_TRANSACTION,  
  33.         LIST_SERVICES_TRANSACTION,  
  34.     };  
  35. };  

 

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

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/include/binder/IInterface.h  
  2. #define DECLARE_META_INTERFACE(INTERFACE)                               /  
  3.     static const String16 descriptor;                                   /  
  4.     static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj);        /  
  5.     virtual const String16& getInterfaceDescriptor() const;             /  
  6.     I##INTERFACE();                                                     /  
  7.     virtual ~I##INTERFACE();                                            /  

 

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

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/include/binder/IServiceManager.cpp  
  2. IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");  

 

    IMPLEMENT_META_INTERFACE宏定义如下:

 

view plain copy to clipboard print ?
  1. // File: frameworks/base/include/binder/IInterface.h  
  2. #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       /  
  3.     const String16 I##INTERFACE::descriptor(NAME);                      /  
  4.     const String16& I##INTERFACE::getInterfaceDescriptor() const {      /  
  5.         return I##INTERFACE::descriptor;                                /  
  6.     }                                                                   /  
  7.     sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<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 = new Bp##INTERFACE(obj);                          /  
  16.             }                                                           /  
  17.         }                                                               /  
  18.         return intr;                                                    /  
  19.     }                                                                   /  
  20.     I##INTERFACE::I##INTERFACE() { }                                    /  
  21.     I##INTERFACE::~I##INTERFACE() { }                                   /  

 

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

 

view plain copy to clipboard print ?
  1. sp<IServiceManager> IServiceManager::asInterface(const sp<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 = new BpServiceManager(obj);                             
  9.         }  
  10.     }  
  11.     return intr;  
  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,service,null,interface,Descriptor)