Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Binder進程間通信---ServiceManager代理對象的獲取過程

Android Binder進程間通信---ServiceManager代理對象的獲取過程

編輯:關於Android編程

本文參考《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 defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;//如果已經創建了代理對象,那麼就直接返回
    
    {
        AutoMutex _l(gDefaultServiceManagerLock);//使用鎖,來實現單例模式
        if (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast(//分三步獲取Service Manager代理對象
                ProcessState::self()->getContextObject(NULL));
        }
    }
    
    return gDefaultServiceManager;
}
其中gDefaultServiceManagerLock,gDefaultServiceManager都定義在Static.cpp中。

~/Android/frameworks/base/libs/binder

----Static.cpp

Mutex gDefaultServiceManagerLock;   //鎖
sp gDefaultServiceManager; //IServiceManager的強指針
全局變量gDefaultServiceManager是一個類型為IServiceManager的強指針,它指向進程內的一個BpServiceManager對象,即Service Manager代理對象;而全局變量gDefaultServiceManagerLock是用來保證一個進程至多只有一個Service Manager代理對象。結合鎖機制來保證對象在進程中的唯一性,這是單例設計模式的經典實現。

如果已經創建了代理對象,那麼就直接返回。如果沒有創建,那麼分三步創建:

(1)、調用ProcessState類的靜態成員函數self獲取進程內的一個ProcessState對象。

(2)、調用前面獲得的ProcessState對象的成員函數getContextObject創建一個Binder代理對象

(3)、調用模板函數interface_cast將前面獲得的Binder代理對象封裝成一個Service Manager代理對象。


2、調用ProcessState類的靜態成員函數self獲取進程內的一個ProcessState對象

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

sp 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 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 ProcessState::getContextObject(const sp& caller)
{
    if (supportsProcesses()) {
        return getStrongProxyForHandle(0);
    } else {
        return getContextObject(String16("default"), caller);
    }
}























  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved