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

    在这篇文章中,我们将深入剖析一下Android系统的服务管理员ServiceManager。

 

    ServiceManager是Android系统服务的管理者。所有需要通过Binder机制进行进程间通信的进程都要首先获得Service Manager的代理对象才能进行Binder通讯。比如系统中有用于音频混音的AudioFlingerService,用于照相的CameraService,用于媒体文件播放的MediaPlayerService。所有这些服务都会向ServiceManager注册,因此ServiceManager就维护了系统中所有服务的一个列表。任何应用程序要想使用这些服务,首先要向ServiceManager请求获得这些服务的引用,从而建立起和这些服务的联系。

 

    在本系列的第一篇文章中,ExampleService通过如下语句向系统注册服务。

 

// File: ExampleService.cpp int r = defaultServiceManager()->addService(String16("byn.example"), new ExampleService());

 

    这里有两个问题:

    1. defaultServiceManager()都完成了哪些工作,它返回的结果是什么?

    2. 为什么调用上一步返回对象的addService方法,就可以向系统注册服务?这一注册过程都完成了哪些工作?

 

    这篇文章先回答问题1。

    ServiceManager也是系统中的一个服务,那么应用程序如何和它取得联系呢?答案就是通过defaultServiceManager()函数。defaultServiceManager()是系统在Android命名空间中定义的一个全局函数,用来获得ServiceManager的代理对象的引用。我们看一下该函数的源代码。

// File: framework/base/libs/binder/IServiceManager.cpp sp<IServiceManager> defaultServiceManager() { if (gDefaultServiceManager != NULL) return gDefaultServiceManager; // 如果该代理对象已经存在,直接返回该对象 { AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager == NULL) { gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); } } return gDefaultServiceManager; }

    gDefaultServiceManager在libutil中定义,因此任何程序或库使用了libutil库都会有该变量,它在一个进程中是唯一的。gDefaultServiceManager的初始值为NULL,所以先调用ProcessState::self()方法获取一个ProcessState实例。这里用到了Singleton的设计模式,从而可知一个进程只有一个ProcessState实例。// File: Frameworks/base/libs/binder/ProcessState.cpp sp<ProcessState> ProcessState::self() { if (gProcess != NULL) return gProcess; AutoMutex _l(gProcessMutex); if (gProcess == NULL) gProcess = new ProcessState; return gProcess; }

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

// File: frameworks/base/libs/binder/ProcessState.cpp ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) { if (mDriverFD >= 0) { // XXX Ideally, there should be a specific define for whether we // have mmap (or whether we could possibly have the kernel module // availabla). #if !defined(HAVE_WIN32_IPC) // mmap the binder, providing a chunk of virtual address space to receive transactions. mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // *sigh* LOGE("Using /dev/binder failed: unable to mmap transaction memory./n"); close(mDriverFD); mDriverFD = -1; } #else mDriverFD = -1; #endif } if (mDriverFD < 0) { // Need to run without the driver, starting our own thread pool. } }

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

// File: frameworks/base/libs/binder/ProcessState.cpp static int open_driver() { if (gSingleProcess) { return -1; } int fd = open("/dev/binder", O_RDWR); if (fd >= 0) { fcntl(fd, F_SETFD, FD_CLOEXEC); int vers; #if defined(HAVE_ANDROID_OS) status_t result = ioctl(fd, BINDER_VERSION, &vers); #else status_t result = -1; errno = EPERM; #endif if (result == -1) { LOGE("Binder ioctl to obtain version failed: %s", strerror(errno)); close(fd); fd = -1; } if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { LOGE("Binder driver protocol does not match user space protocol!"); close(fd); fd = -1; } #if defined(HAVE_ANDROID_OS) size_t maxThreads = 15; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); if (result == -1) { LOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); } #endif } else { LOGW("Opening '/dev/binder' failed: %s/n", strerror(errno)); } return fd; }

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

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

// File: frameworks/base/libs/binder/ProcessState.cpp sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) { if (supportsProcesses()) { return getStrongProxyForHandle(0); } else { return getContextObject(String16("default"), caller); } }

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

// File: frameworks/base/libs/binder/ProcessState.cpp sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { // We need to create a new BpBinder if there isn't currently one, OR we // are unable to acquire a weak reference on this current one. See comment // in getWeakProxyForHandle() for more info about this. 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 { // This little bit of nastyness is to allow us to add a primary // reference to the remote proxy when this team doesn't have one // but another team is sending the handle to us. result.force_set(b); e->refs->decWeak(this); } } return result; }

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

// File: ProcessState.cpp ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle) { const size_t N=mHandleToObject.size(); if (N <= (size_t)handle) { handle_entry e; e.binder = NULL; e.refs = NULL; status_t err = mHandleToObject.insertAt(e, N, handle+1-N); if (err < NO_ERROR) return NULL; } 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类的构造函数做了什么。

// File: frameworks/base/libs/binder/BpBinder.cpp BpBinder::BpBinder(int32_t handle) : mHandle(handle) , mAlive(1) , mObitsSent(0) , mObituaries(NULL) { LOGV("Creating BpBinder %p handle %d/n", this, mHandle); extendObjectLifetime(OBJECT_LIFETIME_WEAK); IPCThreadState::self()->incWeakHandle(handle); }

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

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

// File: frameworks/base/include/utils/RefBase.h template<typename T> void sp<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方法:

// File: frameworks/base/include/binder/IInterface.h template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }

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

// File: frameworks/base/include/binder/IServiceManager.h class IServiceManager : public IInterface { public: DECLARE_META_INTERFACE(ServiceManager); /** * Retrieve an existing service, blocking for a few seconds * if it doesn't yet exist. */ virtual sp<IBinder> getService( const String16& name) const = 0; /** * Retrieve an existing service, non-blocking. */ virtual sp<IBinder> checkService( const String16& name) const = 0; /** * Register a service. */ virtual status_t addService( const String16& name, const sp<IBinder>& service) = 0; /** * Return list of all existing services. */ virtual Vector<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头文件中定义如下:

// File: frameworks/base/include/binder/IInterface.h #define DECLARE_META_INTERFACE(INTERFACE) / static const String16 descriptor; / static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); / virtual const String16& getInterfaceDescriptor() const; / I##INTERFACE(); / virtual ~I##INTERFACE(); /

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

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

    IMPLEMENT_META_INTERFACE宏定义如下:

// File: frameworks/base/include/binder/IInterface.h #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) / const String16 I##INTERFACE::descriptor(NAME); / const String16& I##INTERFACE::getInterfaceDescriptor() const { / return I##INTERFACE::descriptor; / } / sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) / { / 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() { } /

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

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

    可见,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,File,null,interface,Descriptor)