`

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

 
阅读更多

文章来源:http://www.itnose.net/detail/6043249.html
更多文章:http://www.itnose.net/type/85.html

一、测试代码:

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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics