Binder機制(1)

參考:

http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html


基於Binder通信的C/S架構體系中,除了C/S架構所包括的Client端和Server端外,Android還有一個全局的ServiceManager端,它的作用是管理系統中的各種服務(Service)。這三者的關係如下:


注意:一個Server進程可以註冊多個Service.


選擇MediaServer做爲切入點,因爲這個Server是很多重要的Service的棲息地。包括:

AudioFlinger :音頻系統的核心服務

AudioPolicyService:音頻系統中關於音頻策略的重要服務

MediaPlayerService: 多媒體系統的重要服務(本節以這個爲例

CameraService: 有關攝像 / 照相的重要服務


這裏以MediaPlayerService 爲切入點,先分析MediaServer本身。

MediaServer(MS)是一個可執行程序,入口函數是main,代碼如下:


上面代碼有5個關鍵點。下面一一分析。

一、ProcessState

每個進程只有一個ProcessState,它是獨一無二的。

sp<ProcessState> proc(ProcessState::self());
關於sp<> ,wp<>的用法可以參考:http://blog.csdn.net/lksodit_yiyi/article/details/8086059

定義了一個ProcessState sp指針proc,併爲proc賦值爲ProcessState::self()。下面看下其實現:

ProcessState的構造:

這個構造函數很重要,它悄悄地打開了Binder設備。代碼如下:



打開binder設備:

open_driver的作用就是打開/dev/binder這個設備。它是Android在內核中爲完成進程間通信而專門設置的一個虛擬設備。實現如下:


到這裏ProcessState::self函數分析完成,總結:

1. 打開/dev/binder設備,這就相當與與內核的Binder驅動有了交互的通道

2. 對返回的fd使用mmap,這樣Binder驅動就會分配一塊內存來接收數據。

3. 由於ProcessState具有唯一性,因此一個進程只打開設備一次。


二、defaultServiceManager

defaultServiceManager函數的實現在IServiceManager.cpp中完成,它會返回一個IServiceManager對象,通過這個對象,就可以與ServiceManager進行交互了

下面看看這個函數的實現:


interface_case相關可以參考:http://blog.csdn.net/myarrow/article/details/7054589

我瞭解的意思是創建一個IServiceManager對象。

調用了ProcessState的getContextObject函數。


getStrongProxyForHandle 這個函數的調用參數名叫handle。它是對資源的一種標識。說白了,其實就是有一個資源項,保存在一個資源數組中,handle的值正式該資源項在數組中的索引。


上面的BpBinder是什麼?

BpBinder和BBinder都是Android中與Binder通信相關的代表它們都是從IBinder類中派生而來。


1. BpBinder是客戶端與Server交互的代理類,p即Proxy的意思

2. BBinder是與proxy相對的一端,它是proxy交互的目的端。如果說Proxy代表客戶端,那麼BBinder則代表服務端,這裏的BpBinder和BBinder是一一對應的,即某個BpBinder只能和對應的BBinder交互。我們當然不希望通過BpBinderA發送的請求,卻由BBinderB來處理。


剛纔在defaultServiceManager中創建了這個BpBinder。這裏有兩個問題:

1. 爲什麼創建的不是BBinder?

因爲我們是SeviceManager的客戶端,檔案使用代理端和ServiceManger進行交互。

2. BpBinder和BBinder是一一對應的,那麼BpBinder如何標識它所對應的BBinder端呢?

答案: Binder系統通過handler來標識對應的BBinder。以後我再確認這個Handle值的作用。

注意: 這裏我們給BpBinder構造函數傳的參數handle的值是0.這個0在整個Binder系統中有重要含義:0代表的就是ServiceManager所對應的BBinder

BpBinder是如此重要,必須對它進行深入分析,代碼如下所示:


仔細查看,發現BpBinder,BBinder這兩個類沒有任何地方操作ProcessState打開的那個/dev/binder設備,換言之,這兩個Binder類沒有和binder設備直接交互。

爲什麼說BpBinder與通信相關呢?

BpBinde只是個道具,它的後面一定另有機關

下面看下道具的出場過程:


現在這個函數調用將變成如下所示的樣子:


這裏的interface_cast是一個障眼法,下面進行分析。

interface_case的具體實現:


下面看看IServiceManager

(1) 定義業務邏輯

IServiceManager定義在IServiceManager.h中,代碼如下:


(2)業務與通信的掛鉤:

Android巧妙地通過DECLARE_META_INTERFACEIMPLENT宏,將業務和通信牢牢地鉤在了一起。他倆都定義在IInterface.h中。先看DECLARE_META_INTERFACE這個宏,如下所示:


將IServiceManager的DECLARE宏進行相應的替換後得到的代碼如下所示:


DECLARE宏聲明瞭一些函數和一個變量,那麼IMPLEMENT宏的作用肯定就是定義它們了。IMPLEMENT的定義在IInterface.h 中,IServiceManager是如何使用這個宏的呢?只有一行代碼,在IServiceManager.cpp中。如下所示:


將這個宏展開,如下所示:


之前疑問:interface_case是如何把BpBinder指針轉換爲一個IServiceManager指針的。答案就在asInterface函數的這一行代碼中,如下所示:


interface_cast不是指針的轉換,而是利用BpBinder對象作爲參數新建了一個BpServiceManager對象。我們已經直到BpBinder和BBinder與通信有關係,這裏怎麼突然冒出來一個BpServiceManager?他們有什麼關係?


IServiceManager家族

要搞清楚上面問題,必須先了解IServiceManager家族之間的關係。下圖展示了IServiceManager的家族圖譜:


1. IServiceManager,BpServiceManager和BnServiceManager都與業務邏輯相關

2. BnServiceManager同時從IServiceManager BBinder派生,表示它可以直接參與Binder通信

3. BpServiceManager雖然從BpInterface中派生,但是這條分支似乎與BpBinder沒有關係

4. BnServiceManager是一個虛類,它的業務函數最終需要子類來實現。


在上圖中的BpServiceManager,既然不像BnServicemanager哪樣與Binder有直接的血緣關係,那麼它是如何與Binder交互的呢?簡言之,BpRefBase中的mRemote值就是BpBinder


BpInterface的實現代碼如下所示:


BpRefBse()的實現如下所示:


原來,是BpServiceManager的一個變量mRemote指向了BpBinder。至此,我們的魔術結束。回想defaultServiceManager函數,可以得到一下兩個關鍵對象:

1. 有一個BpBinder對象,它的handle值是0

2. 有一個BpServiceManager對象,它的mRemote值是BpBinder。

BpServiceManager對象實現了IServiceManager的業務函數,現在又有BpBinder作爲通信的代表,接下來的工作就簡單了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章