当前位置: 代码迷 >> Android >> Android Binder进程间通信-ServiceManager署理对象的获取过程
  详细解决方案

Android Binder进程间通信-ServiceManager署理对象的获取过程

热度:96   发布时间:2016-04-28 05:37:46.0
Android Binder进程间通信---ServiceManager代理对象的获取过程

本文参考《Android系统源代码情景分析》,作者罗升阳。

一、测试代码:

       ~/Android/external/binder/server

        ----FregServer.cpp

        ~/Android/external/binder/common

        ----IFregService.cpp

        ----IFregService.h

       ~/Android/external/binder/client

       ----FregClient.cpp


       Binder库(libbinder)代码:

       ~/Android/frameworks/base/libs/binder

       ----BpBinder.cpp

       ----Parcel.cpp

       ----ProcessState.cpp

       ----Binder.cpp

       ----IInterface.cpp

       ----IPCThreadState.cpp

       ----IServiceManager.cpp

       ----Static.cpp

       ~/Android/frameworks/base/include/binder

       ----Binder.h

       ----BpBinder.h

       ----IInterface.h

       ----IPCThreadState.h

       ----IServiceManager.h

       ----IBinder.h

       ----Parcel.h

       ----ProcessState.h


        驱动层代码:

       ~/Android//kernel/goldfish/drivers/staging/android

       ----binder.c

       ----binder.h


二、源码分析

      1、程序首先开始从Service进程FregServer.cpp的main函数开始执行

     ~/Android/external/binder/server

     ----FregServer.cpp

class FregService : public BnFregService{        ...........public:	static void instantiate()	{		defaultServiceManager()->addService(String16(FREG_SERVICE), new FregService());	}        ...........};int main(int argc, char** argv){	FregService::instantiate();	ProcessState::self()->startThreadPool();	IPCThreadState::self()->joinThreadPool();	return 0;}
      main函数首先调用静态方法instantiate,在instantiate中调用了defaultServiceManager(),defaultServiceManager()函数实现如下:

     

      ~/Android/frameworks/base/libs/binder

      ----IServiceManager.cpp

sp<IServiceManager> defaultServiceManager(){    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;//如果已经创建了代理对象,那么就直接返回        {        AutoMutex _l(gDefaultServiceManagerLock);//使用锁,来实现单例模式        if (gDefaultServiceManager == NULL) {            gDefaultServiceManager = interface_cast<IServiceManager>(//分三步获取Service Manager代理对象                ProcessState::self()->getContextObject(NULL));        }    }        return gDefaultServiceManager;}
      其中gDefaultServiceManagerLock,gDefaultServiceManager都定义在Static.cpp中。

       ~/Android/frameworks/base/libs/binder

       ----Static.cpp

Mutex gDefaultServiceManagerLock;   //锁sp<IServiceManager> gDefaultServiceManager; //IServiceManager的强指针
       全局变量gDefaultServiceManager是一个类型为IServiceManager的强指针,它指向进程内的一个BpServiceManager对象,即Service Manager代理对象;而全局变量gDefaultServiceManagerLock是用来保证一个进程至多只有一个Service Manager代理对象。结合锁机制来保证对象在进程中的唯一性,这是单例设计模式的经典实现。

       如果已经创建了代理对象,那么就直接返回。如果没有创建,那么分三步创建:

       (1)、调用ProcessState类的静态成员函数self获取进程内的一个ProcessState对象。

       (2)、调用前面获得的ProcessState对象的成员函数getContextObject创建一个Binder代理对象

       (3)、调用模板函数interface_cast<IServiceManager>将前面获得的Binder代理对象封装成一个Service Manager代理对象。


        2、调用ProcessState类的静态成员函数self获取进程内的一个ProcessState对象

       ~/Android/frameworks/base/libs/binder

       ----ProcessState.cpp

sp<ProcessState> ProcessState::self(){    if (gProcess != NULL) return gProcess;//如果已经创建了,就直接返回        AutoMutex _l(gProcessMutex);    if (gProcess == NULL) gProcess = new ProcessState;//创建ProcessState对象    return gProcess;}
      其中gProcess,gProcessMutex都位于Static.cpp中

Mutex gProcessMutex;sp<ProcessState> gProcess;
      全局变量gProcess是一个类型为ProcessState的强指针,它指向进程内的一个ProcessState对象;而全局变量gProcessMutex是一个互斥锁,是用来保证一个进程至多只有一个ProcessState对象的,同样是一个单例模式。


      首次进入,故创建ProcessState对象。

      ~/Android/frameworks/base/libs/binder

      ----ProcessState.cpp

ProcessState::ProcessState()    : mDriverFD(open_driver())    , mVMStart(MAP_FAILED)    .....{    if (mDriverFD >= 0) {       ...........        // 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);       ...........}
     在初始化构造函数中调用了open_driver方法。

      ~/Android/frameworks/base/libs/binder

      ----ProcessState.cpp

static int open_driver(){    if (gSingleProcess) {        return -1;    }    int fd = open("/dev/binder", O_RDWR);//又一个进程打开了设备文件,binder_procs又多了一个进程的结构体    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首先调用了open打开设备文件,在http://blog.csdn.net/jltxgcy/article/details/25797011这盘文章中已经讲解了驱动层的binder_open所做的事。然后的调用ioctl传入BINDER_VERSION参数来获取vers。最后调用ioctl传入BINDER_SET_MAX_THREADS参数来设备该进程所支持的最大线程数。

     

      在初始化列表中调用mmap把设备文件/dev/binder映射到进程的地址空间,其实将/dev/binder映射到进程的地址空间实际上是请求Binder驱动程序为进程分配内核缓冲区。


      3、调用前面获得的ProcessState对象的成员函数getContextObject创建一个Binder代理对象

      ~/Android/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);    }}








        
















  相关解决方案