文章轉載至CSDN社區羅昇陽的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6627260html
在前面一篇文章淺談Service Manager成爲Android進程間通訊(IPC)機制Binder守護進程之路中,介紹了Service Manager是如何成爲Binder機制的守護進程的。既然做爲守護進程,Service Manager的職責固然就是爲Server和Client服務了。那麼,Server和Client如何得到Service Manager接口,進而享受它提供的服務呢?本文將簡要分析Server和Client得到Service Manager的過程。android
在閱讀本文以前,但願讀者先閱讀Android進程間通訊(IPC)機制Binder簡要介紹和學習計劃一文提到的參考資料Android深刻淺出之Binder機制,這樣能夠加深對本文的理解。函數
咱們知道,Service Manager在Binder機制中既充當守護進程的角色,同時它也充當着Server角色,然而它又與通常的Server不同。對於普通的Server來講,Client若是想要得到Server的遠程接口,那麼必須經過Service Manager遠程接口提供的getService接口來得到,這自己就是一個使用Binder機制來進行進程間通訊的過程。而對於Service Manager這個Server來講,Client若是想要得到Service Manager遠程接口,卻沒必要經過進程間通訊機制來得到,由於Service Manager遠程接口是一個特殊的Binder引用,它的引用句柄必定是0。學習
獲取Service Manager遠程接口的函數是defaultServiceManager,這個函數聲明在frameworks/base/include/binder/IServiceManager.h文件中:spa
實如今frameworks/base/libs/binder/IServiceManager.cpp文件中:.net
gDefaultServiceManagerLock和gDefaultServiceManager是全局變量,定義在frameworks/base/libs/binder/Static.cpp文件中:code
從這個函數能夠看出,gDefaultServiceManager是單例模式,調用defaultServiceManager函數時,若是gDefaultServiceManager已經建立,則直接返回,不然經過interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))來建立一個,並保存在gDefaultServiceManager全局變量中。htm
在繼續介紹interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))的實現以前,先來看一個類圖,這可以幫助咱們瞭解Service Manager遠程接口的建立過程。blog
參考資料Android深刻淺出之Binder機制一文的讀者,應該會比較容易理解這個圖。這個圖代表了,BpServiceManager類繼承了BpInterface<IServiceManager>類,BpInterface是一個模板類,它定義在frameworks/base/include/binder/IInterface.h文件中:繼承
IServiceManager類繼承了IInterface類,而IInterface類和BpRefBase類又分別繼承了RefBase類。在BpRefBase類中,有一個成員變量mRemote,它的類型是IBinder*,實現類爲BpBinder,它表示一個Binder引用,引用句柄值保存在BpBinder類的mHandle成員變量中。BpBinder類經過IPCThreadState類來和Binder驅動程序並互,而IPCThreadState又經過它的成員變量mProcess來打開/dev/binder設備文件,mProcess成員變量的類型爲ProcessState。ProcessState類打開設備/dev/binder以後,將打開文件描述符保存在mDriverFD成員變量中,以供後續使用。
理解了這些概念以後,就能夠繼續分析建立Service Manager遠程接口的過程了,最終目的是要建立一個BpServiceManager實例,而且返回它的IServiceManager接口。建立Service Manager遠程接口主要是下面語句:
看起來簡短,卻暗藏玄機,具體可閱讀Android深刻淺出之Binder機制這篇參考資料,這裏做簡要描述。
首先是調用ProcessState::self函數,self函數是ProcessState的靜態成員函數,它的做用是返回一個全局惟一的ProcessState實例變量,就是單例模式了,這個變量名爲gProcess。若是gProcess還沒有建立,就會執行建立操做,在ProcessState的構造函數中,會經過open文件操做函數打開設備文件/dev/binder,而且返回來的設備文件描述符保存在成員變量mDriverFD中。
接着調用gProcess->getContextObject函數來得到一個句柄值爲0的Binder引用,即BpBinder了,因而建立Service Manager遠程接口的語句能夠簡化爲:
再來看函數interface_cast<IServiceManager>的實現,它是一個模板函數,定義在framework/base/include/binder/IInterface.h文件中:
這裏的INTERFACE是IServiceManager,因而調用了IServiceManager::asInterface函數。IServiceManager::asInterface是經過DECLARE_META_INTERFACE(ServiceManager)宏在IServiceManager類中聲明的,它位於framework/base/include/binder/IServiceManager.h文件中:
展開即爲:
IServiceManager::asInterface的實現是經過IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")宏定義的,它位於framework/base/libs/binder/IServiceManager.cpp文件中:
展開即爲:
估計寫這段代碼的員工是從Microsoft跳槽到Google的。這裏咱們關注IServiceManager::asInterface的實現:
這裏傳進來的參數obj就則剛纔建立的new BpBinder(0)了,BpBinder類中的成員函數queryLocalInterface繼承自基類IBinder,IBinder::queryLocalInterface函數位於framework/base/libs/binder/Binder.cpp文件中:
因而可知,在IServiceManager::asInterface函數中,最終會調用下面語句:
即爲:
回到defaultServiceManager函數中,最終結果爲:
這樣,Service Manager遠程接口就建立完成了,它本質上是一個BpServiceManager,包含了一個句柄值爲0的Binder引用。
在Android系統的Binder機制中,Server和Client拿到這個Service Manager遠程接口以後怎麼用呢?
對Server來講,就是調用IServiceManager::addService這個接口來和Binder驅動程序交互了,即調用BpServiceManager::addService 。而BpServiceManager::addService又會調用經過其基類BpRefBase的成員函數remote得到原先建立的BpBinder實例,接着調用BpBinder::transact成員函數。在BpBinder::transact函數中,又會調用IPCThreadState::transact成員函數,這裏就是最終與Binder驅動程序交互的地方了。回憶一下前面的類圖,IPCThreadState有一個PorcessState類型的成中變量mProcess,而mProcess有一個成員變量mDriverFD,它是設備文件/dev/binder的打開文件描述符,所以,IPCThreadState就至關於間接在擁有了設備文件/dev/binder的打開文件描述符,因而,即可以與Binder驅動程序交互了。
對Client來講,就是調用IServiceManager::getService這個接口來和Binder驅動程序交互了。具體過程上述Server使用Service Manager的方法是同樣的,這裏就再也不累述了。
IServiceManager::addService和IServiceManager::getService這兩個函數的具體實現,在下面兩篇文章中,會深刻到Binder驅動程序這一層,進行詳細的源代碼分析,以便更好地理解Binder進程間通訊機制,敬請關注。
老羅的新浪微博:http://weibo.com/shengyangluo,歡迎關注!