在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ <span>第6章 深入理解Binder</span>
第4章 ?深入理解 Zygote
第10章 深入理解MediaScanner
第3章 ?深入理解init
第8章 ?深入理解Surface系統(tǒng)
第5章 深入理解常見(jiàn)類(lèi)
第7章 ?深入理解Audio系統(tǒng)
第一章 ?閱讀前的準(zhǔn)備工作
<span>第6章 深入理解Binder</span>
第9章 ?深入理解Vold和Rild
第2章? 深入理解JNI

<span>第6章 深入理解Binder</span>

本章主要內(nèi)容

·? 以MediaServer為切入點(diǎn),對(duì)Binder的工作機(jī)制進(jìn)行分析。

·? 剖析ServiceManager的原理。

·? 以MediaPlayerService為切入點(diǎn)對(duì)Client和Service的交互進(jìn)行分析。

·? 學(xué)以致用,探討如何寫(xiě)自己的Service。

本章涉及的源代碼文件名及位置

下面是我們本章分析的源碼文件名及其位置。

·? Main_mediaserver.cpp

framework/base/Media/MediaServer/Main_mediaserver.cpp

·? Static.cpp

framework/base/libs/binder/Static.cpp

·? ProcessState.cpp

framework/base/libs/binder/ProcessState.cpp

·? IServiceManager.cpp

framework/base/libs/binder/IServiceManager.cpp

·? BpBinder.cpp

framework/base/libs/binder/BpBinder.cpp

·? IInterface.h

framework/base/include/binder/IInterface.h

·? IServiceManager.h

framework/base/include/binder/IServiceManager.h

·? IServiceManager.cpp

framework/base/libs/binder/IServiceManager.cpp

·? binder.cpp

framework/base/libs/binder/binder.cpp

·? MediaPlayerService.cpp

framework/base/media/libmediaplayerservice/MediaPlayerService.cpp

·? IPCThreadState.cpp

framework/base/libs/binder/ IPCThreadState.cpp

·? binder_module.h

framework/base/include/private/binder.h

·? Service_manager.c

framework/base/cmds/ServiceManager/Service_manager.c

·? Binder.c

framework/base/cmds/ServiceManager/Binder.c

·? ?IMediaDeathNotifier

framework/base/media/libmedia/ IMediaDeathNotifier.cpp

·? MediaMetadataRetriever

framework/base/media/libmedia/ MediaMetadataRetriever.cpp

6.1 ?概述

Binder是Android系統(tǒng)提供的一種IPC(進(jìn)程間通信)機(jī)制。由于Android是基于Linux內(nèi)核的,因此,除了Binder外,還存在其他的IPC機(jī)制,例如管道和socket等。Binder相對(duì)于其他IPC機(jī)制來(lái)說(shuō),就更加靈活和方便了。對(duì)于初學(xué)Android的朋友而言,最難卻又最想掌握的恐怕就是Binder機(jī)制了,因?yàn)锳ndroid系統(tǒng)基本上可以看作是一個(gè)基于Binder通信的C/S架構(gòu)。Binder就像網(wǎng)絡(luò)一樣,把系統(tǒng)各個(gè)部分連接在了一起,因此它是非常重要的。

在基于Binder通信的C/S架構(gòu)體系中,除了C/S架構(gòu)所包括的Client端和Server端外,Android還有一個(gè)全局的ServiceManager端,它的作用是管理系統(tǒng)中的各種服務(wù)(Service)。Client、Server和ServiceManager這三者之間的交互關(guān)系,如圖6-1所示 :

http://wiki.jikexueyuan.com/project/deep-android-v1/images/chapter6/image001.png" alt="image" />

圖6-1?Client、Server和ServiceManager三者之間的交互關(guān)系

注意:一個(gè)Server進(jìn)程可以注冊(cè)多個(gè)Service,就像即將講解的MediaServer一樣。

根據(jù)圖6-1,可以得出如下結(jié)論:

·? Server進(jìn)程要先注冊(cè)一些Service到ServiceManager中,所以Server是ServiceManager的客戶(hù)端,而ServiceManager就是服務(wù)端了。

·? 如果某個(gè)Client進(jìn)程要使用某個(gè)Service,必須先到ServiceManager中獲取該Service的相關(guān)信息,所以Client是ServiceManager的客戶(hù)端。

·? Client根據(jù)得到的Service信息建立與Service所在的Server進(jìn)程通信的通路,然后就可以直接與Service交互了,所以Client也是Server的客戶(hù)端。

·? 最重要的一點(diǎn)是,三者的交互都是基于Binder通信的,所以通過(guò)任意兩者之間的關(guān)系,都可以揭示Binder的奧秘。

這里,要重點(diǎn)強(qiáng)調(diào)的是Binder通信與C/S架構(gòu)之間的關(guān)系。Binder只是為C/S架構(gòu)提供了一種通信的方式,我們完全可以采用其他IPC方式進(jìn)行通信,例如,系統(tǒng)中有很多其他的程序采用的就是Socket或Pipe的方法進(jìn)行進(jìn)程間通信。很多初學(xué)者可能覺(jué)得Binder較復(fù)雜,尤其是看到諸如BpXXX、BnXXX之類(lèi)的定義便感到頭暈,這很有可能是把Binder通信層結(jié)構(gòu)和應(yīng)用的業(yè)務(wù)層結(jié)構(gòu)搞混了。如果能搞清楚這二者的關(guān)系,完全可以自己實(shí)現(xiàn)一個(gè)不使用BpXXX和BnXXX的Service。須知,ServiceManager可并沒(méi)有使用它們。

6.2 ?庖丁解MediaServer

為了能像“庖丁”那樣解析Binder,我們必須得找一頭“牛”來(lái)做解剖,而MediaServer(簡(jiǎn)稱(chēng)MS)正是一頭比較好的“?!?。它是一個(gè)可執(zhí)行程序,雖然Android的SDK提供Java層的API,但Android系統(tǒng)本身還是一個(gè)完整的基于Linux內(nèi)核的操作系統(tǒng),所以不會(huì)是所有程序都用Java編寫(xiě),這里的MS就是一個(gè)用C++編寫(xiě)的可執(zhí)行程序。

之所以選擇MediaServer作為切入點(diǎn),是因?yàn)檫@個(gè)Server是系統(tǒng)諸多重要Service的棲息地,它們包括:

·? AudioFlinger:音頻系統(tǒng)中的重要核心服務(wù)。

·? AudioPolicyService:音頻系統(tǒng)中關(guān)于音頻策略的重要服務(wù)。

·? MediaPlayerService:多媒體系統(tǒng)中的重要服務(wù)。

·? CameraService:有關(guān)攝像/照相的重要服務(wù)。

可以看到,MS除了不涉及Surface系統(tǒng)外,其他重要的服務(wù)基本上都涉及到了,它不愧是“庖丁”所要的好“?!?。

本章將以其中的MediaPlayerService為主切入點(diǎn)進(jìn)行分析。先來(lái)分析MediaServer本身。

6.2.1 ?MediaServer的入口函數(shù)

MS是一個(gè)可執(zhí)行程序,入口函數(shù)是main,代碼如下所示:

[-->Main_MediaServer.cpp]

int main(int argc, char** argv)

{

? //①獲得一個(gè)ProcessState實(shí)例

?sp<ProcessState>proc(ProcessState::self());

?

?//②MS作為ServiceManager的客戶(hù)端,需要向ServiceManger注冊(cè)服務(wù)

?//調(diào)用defaultServiceManager,得到一個(gè)IServiceManager。

?sp<IServiceManager>sm = defaultServiceManager();

?

?//初始化音頻系統(tǒng)的AudioFlinger服務(wù)

?AudioFlinger::instantiate();

?//③多媒體系統(tǒng)的MediaPlayer服務(wù),我們將以它作為主切入點(diǎn)

?MediaPlayerService::instantiate();

?//CameraService服務(wù)

?CameraService::instantiate();

?//音頻系統(tǒng)的AudioPolicy服務(wù)

?AudioPolicyService::instantiate();

?

?//④根據(jù)名稱(chēng)來(lái)推斷,難道是要?jiǎng)?chuàng)建一個(gè)線(xiàn)程池嗎?

?ProcessState::self()->startThreadPool();

?//⑤下面的操作是要將自己加入到剛才的線(xiàn)程池中嗎?

?IPCThreadState::self()->joinThreadPool();

}

上面的代碼中,確定了5個(gè)關(guān)鍵點(diǎn),讓我們通過(guò)對(duì)這5個(gè)關(guān)鍵點(diǎn)逐一進(jìn)行深入分析,來(lái)認(rèn)識(shí)和理解Binder。

6.2.2 ?獨(dú)一無(wú)二的ProcessState

我們?cè)趍ain函數(shù)的開(kāi)始處便碰見(jiàn)了ProcessState。由于每個(gè)進(jìn)程只有一個(gè)ProcessState,所以它是獨(dú)一無(wú)二的。它的調(diào)用方式如下面的代碼所示:

[-->Main_MediaServer.cpp]

//①獲得一個(gè)ProcessState實(shí)例

sp<ProcessState> proc(ProcessState::self());

下面,來(lái)進(jìn)一步分析這個(gè)獨(dú)一無(wú)二的ProcessState。

1. 單例的ProcessState

ProcessState的代碼如下所示:

[-->ProcessState.cpp]

sp<ProcessState> ProcessState::self()

{

?? //gProcess是在Static.cpp中定義的一個(gè)全局變量

?? //程序剛開(kāi)始執(zhí)行,gProcess一定為空

??? if(gProcess != NULL) return gProcess;

??????? AutoMutex_l(gProcessMutex);

???? //創(chuàng)建一個(gè)ProcessState對(duì)象,并賦值給gProcess

??? if(gProcess == NULL) gProcess = new ProcessState;

?

???? returngProcess;

}

self函數(shù)采用了單例模式,這很明確地告訴了我們一個(gè)信息:每個(gè)進(jìn)程只有一個(gè)ProcessState對(duì)象。這一點(diǎn),從它的命名中也可看出些端倪。

2. ProcessState的構(gòu)造

再來(lái)看ProcessState的構(gòu)造函數(shù)。這個(gè)函數(shù)非常重要,它悄悄地打開(kāi)了Binder設(shè)備。代碼如下所示:

[-->ProcessState.cpp]

ProcessState::ProcessState()

?? // Android的中有很多代碼都是這么寫(xiě)的,稍不留神就容易忽略這里調(diào)用了一個(gè)很重要的函數(shù)

??? :mDriverFD(open_driver())

??? ,mVMStart(MAP_FAILED)//映射內(nèi)存的起始地址

??? ,mManagesContexts(false)

??? ,mBinderContextCheckFunc(NULL)

??? , mBinderContextUserData(NULL)

??? ,mThreadPoolStarted(false)

??? ,mThreadPoolSeq(1)

{

? if(mDriverFD >= 0) {

??/*

BIDNER_VM_SIZE定義為(1*1024*1024) - (4096 *2) = 1M-8K

?? mmap的用法希望讀者man一下,不過(guò)這個(gè)函數(shù)真正的實(shí)現(xiàn)和驅(qū)動(dòng)有關(guān)系,而B(niǎo)inder驅(qū)動(dòng)會(huì)分配一塊

內(nèi)存用來(lái)接收數(shù)據(jù)。

*/

??mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ,MAP_PRIVATE | MAP_NORESERVE,

???????????????????? mDriverFD, 0);

??? }

??? ......

}

3. 打開(kāi)binder設(shè)備

open_driver的作用就是打開(kāi)/dev/binder這個(gè)設(shè)備,它是android在內(nèi)核中專(zhuān)門(mén)用于完成進(jìn)程間通信而設(shè)置的一個(gè)虛擬設(shè)備,具體實(shí)現(xiàn)如下所示:

[-->ProcessState.cpp]

static int open_driver()

{

??? int fd =open("/dev/binder", O_RDWR);//打開(kāi)/dev/binder設(shè)備

??? if (fd>= 0) {

?? ????? ......

???????size_t maxThreads = 15;

?????? //通過(guò)ioctl方式告訴binder驅(qū)動(dòng),這個(gè)fd支持的最大線(xiàn)程數(shù)是15個(gè)

???????result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);??

?? }

return fd;

......

}

至此,Process::self函數(shù)就分析完了。它到底干了什么呢?通過(guò)前面的分析,總結(jié)如下:

·? 打開(kāi)/dev/binder設(shè)備,這就相當(dāng)于與內(nèi)核的Binder驅(qū)動(dòng)有了交互的通道。

·? 對(duì)返回的fd使用mmap,這樣Binder驅(qū)動(dòng)就會(huì)分配一塊內(nèi)存來(lái)接收數(shù)據(jù)。

·? 由于ProcessState的惟一性,因此一個(gè)進(jìn)程只打開(kāi)設(shè)備一次。

分析完P(guān)rocessState,接下來(lái)將要分析第二個(gè)關(guān)鍵函數(shù)defaultServiceManager。

6.2.3 ?時(shí)空穿越魔術(shù)——defaultServiceManager

defaultServiceManager函數(shù)的實(shí)現(xiàn)在IServiceManager.cpp中完成。它會(huì)返回一個(gè)IServiceManager對(duì)象,通過(guò)這個(gè)對(duì)象,我們可以神奇地與另一個(gè)進(jìn)程ServiceManager進(jìn)行交互。是不是有一種觀看時(shí)空穿越魔術(shù)表演的感覺(jué)?

1. 魔術(shù)前的準(zhǔn)備工作

先來(lái)看看defaultServiceManager都調(diào)用了哪些函數(shù)?返回的這個(gè)IServiceManager到底是什么?具體實(shí)現(xiàn)代碼如下所示:

[-->IServiceManager.cpp]

sp<IServiceManager> defaultServiceManager()

{

??? //看樣子又是一個(gè)單例,英文名叫 Singleton,Android是一個(gè)優(yōu)秀的源碼庫(kù),大量使用了

?? //設(shè)計(jì)模式,建議讀者以此為契機(jī)學(xué)習(xí)設(shè)計(jì)模式,首推GOF的《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》

??? if(gDefaultServiceManager != NULL) return gDefaultServiceManager;

???? {

???????AutoMutex _l(gDefaultServiceManagerLock);

??????? if(gDefaultServiceManager == NULL) {

??????? ? //真正的gDefaultServiceManager是在這里創(chuàng)建的。

???????????gDefaultServiceManager = interface_cast<IServiceManager>(

??????????? ?????????????????????? ProcessState::self()->getContextObject(NULL));

??????? }

??? }

?? returngDefaultServiceManager;

}

哦,是調(diào)用了ProcessState的getContextObject函數(shù)!注意:傳給它的參數(shù)是NULL,即0。既然是“庖丁解?!?,就還要一層一層往下切。下面再看getContextObject函數(shù),如下所示:

[-->ProcessState.cpp]

sp<IBinder>ProcessState::getContextObject(const sp<IBinder>& caller)

{

? ?/*

caller的值為0!注意,該函數(shù)返回的是IBinder。它是什么?我們后面再說(shuō)。

??? supportsProcesses函數(shù)根據(jù)openDriver函數(shù)打開(kāi)設(shè)備是否成功來(lái)判斷是否支持process

真實(shí)設(shè)備肯定支持process。

?? */

? if(supportsProcesses()) {

?? //真實(shí)設(shè)備上肯定是支持進(jìn)程的,所以會(huì)調(diào)用下面這個(gè)函數(shù)

???????return getStrongProxyForHandle(0);

??? } else {

???????return getContextObject(String16("default"), caller);

??? }

}

getStrongProxyForHandle這個(gè)函數(shù)名怪怪的,可能會(huì)讓人感到些許困惑。請(qǐng)注意,它的調(diào)用參數(shù)的名字叫handle,Windows編程中經(jīng)常使用這個(gè)名稱(chēng),它是對(duì)資源的一種標(biāo)識(shí)。說(shuō)白了,其實(shí)就是有一個(gè)資源項(xiàng),保存在一個(gè)資源數(shù)組(也可以是別的組織結(jié)構(gòu))中,handle的值正是該資源項(xiàng)在數(shù)組中的索引。

[-->ProcessState.cpp]

sp<IBinder>ProcessState::getStrongProxyForHandle(int32_t handle)

{

???sp<IBinder> result;

?AutoMutex_l(mLock);

/*

根據(jù)索引查找對(duì)應(yīng)資源。如果lookupHandleLocked發(fā)現(xiàn)沒(méi)有對(duì)應(yīng)的資源項(xiàng),則會(huì)創(chuàng)建一個(gè)新的項(xiàng)并返回。

這個(gè)新項(xiàng)的內(nèi)容需要填充。

??? */

???handle_entry* e = lookupHandleLocked(handle);

??? if (e !=NULL) {

???????IBinder* b = e->binder;

??????? if (b== NULL || !e->refs->attemptIncWeak(this)) {

???????????//對(duì)于新創(chuàng)建的資源項(xiàng),它的binder為空,所以走這個(gè)分支。注意,handle的值為0

??????????? b= new BpBinder(handle); //創(chuàng)建一個(gè)BpBinder

???????????e->binder = b; //填充entry的內(nèi)容

???????????if (b) e->refs = b->getWeakRefs();

???????????result = b;

??????? }else {

???????????result.force_set(b);

???????????e->refs->decWeak(this);

??????? }

??? }

??? returnresult; //返回BpBinder(handle),注意,handle的值為0

}

2. 魔術(shù)表演的道具——BpBinder

眾所周知,玩魔術(shù)是必須有道具的。這個(gè)穿越魔術(shù)的道具就是BpBinder。BpBinder是什么呢?有必要先來(lái)介紹它的孿生兄弟BBinder。

BpBinder和BBinder都是Android中與Binder通信相關(guān)的代表,它們都從IBinder類(lèi)中派生而來(lái),如圖6-2所示:

http://wiki.jikexueyuan.com/project/deep-android-v1/images/chapter6/image002.png" alt="image" />

圖6-2 Binder家族圖譜

從上圖中可以看出:

·? BpBinder是客戶(hù)端用來(lái)與Server交互的代理類(lèi),p即Proxy的意思。

·? BBinder則是proxy相對(duì)的一端,它是proxy交互的目的端。如果說(shuō)Proxy代表客戶(hù)端,那么BBinder則代表服務(wù)端。這里的BpBinder和BBinder是一一對(duì)應(yīng)的,即某個(gè)BpBinder只能和對(duì)應(yīng)的BBinder交互。我們當(dāng)然不希望通過(guò)BpBinderA發(fā)送的請(qǐng)求,卻由BBinderB來(lái)處理。

剛才我們?cè)赿efaultServiceManager()函數(shù)中創(chuàng)建了這個(gè)BpBinder。這里有兩個(gè)問(wèn)題:

·? 為什么創(chuàng)建的不是BBinder?

因?yàn)槲覀兪荢erviceManager的客戶(hù)端,當(dāng)然得使用代理端以與ServiceManager交互了。

·? 前面說(shuō)了,BpBinder和BBinder是一一對(duì)應(yīng)的,那么BpBinder如何標(biāo)識(shí)它所對(duì)應(yīng)的BBinder端呢?

答案是Binder系統(tǒng)通過(guò)handler來(lái)對(duì)應(yīng)BBinder。以后我們會(huì)確認(rèn)這個(gè)Handle值的作用。

注意:我們給BpBinder構(gòu)造函數(shù)傳的參數(shù)handle的值是0。這個(gè)0在整個(gè)Binder系統(tǒng)中有重要含義—因?yàn)?代表的就是ServiceManager所對(duì)應(yīng)的BBinder。

BpBinder是如此重要,必須對(duì)它進(jìn)行深入分析,其代碼如下所示:

[-->BpBinder.cpp]

BpBinder::BpBinder(int32_t handle)

??? :mHandle(handle)//handle是0

??? ,mAlive(1)

??? ,mObitsSent(0)

??? ,mObituaries(NULL)

{

?? extendObjectLifetime(OBJECT_LIFETIME_WEAK);

?? //另一個(gè)重要對(duì)象是IPCThreadState,我們稍后會(huì)詳細(xì)講解。

???IPCThreadState::self()->incWeakHandle(handle);

}

看上面的代碼,會(huì)覺(jué)得BpBinder確實(shí)簡(jiǎn)單,不過(guò)再仔細(xì)查看,你或許會(huì)發(fā)現(xiàn),BpBinder、BBinder這兩個(gè)類(lèi)沒(méi)有任何地方操作ProcessState打開(kāi)的那個(gè)/dev/binder設(shè)備,換言之,這兩個(gè)Binder類(lèi)沒(méi)有和binder設(shè)備直接交互。那為什么說(shuō)BpBinder會(huì)與通信相關(guān)呢?注意本小節(jié)的標(biāo)題,BpBinder只是道具嘛!所以它后面一定還另有機(jī)關(guān)。不必急著揭秘,還是先回顧一下道具出場(chǎng)的歷程。

我們是從下面這個(gè)函數(shù)開(kāi)始分析的:

gDefaultServiceManager =interface_cast<IServiceManager>(

???????????????????????????????????????????ProcessState::self()->getContextObject(NULL));

現(xiàn)在這個(gè)函數(shù)調(diào)用將變成如下所示:

gDefaultServiceManager =interface_cast<IServiceManager>(new BpBinder(0));

這里出現(xiàn)了一個(gè)interface_cast。它是什么?其實(shí)是一個(gè)障眼法!下面就來(lái)具體分析它。

3. 障眼法——interface_cast

interface_cast、dynamic_cast和static_cast看起來(lái)是否非常眼熟?它們是指針類(lèi)型轉(zhuǎn)換的意思嗎?如果是,那又是如何將BpBinder*類(lèi)型強(qiáng)制轉(zhuǎn)化成IServiceManager*類(lèi)型的?BpBinder的家譜我們剛才也看了,它的“爸爸的爸爸的爸爸”這條線(xiàn)上沒(méi)有任何一個(gè)與IServiceManager有任何關(guān)系。

問(wèn)題談到這里,我們得去看看interface_cast的具體實(shí)現(xiàn),其代碼如下所示:

[-->IInterface.h]

template<typename INTERFACE>

inline sp<INTERFACE> interface_cast(constsp<IBinder>& obj)

{

??? returnINTERFACE::asInterface(obj);

}

哦,僅僅是一個(gè)模板函數(shù),所以interface_cast<IServiceManager>()等價(jià)于:

inline sp<IServiceManager>interface_cast(const sp<IBinder>& obj)

{

??? return IServiceManager::asInterface(obj);

}

又轉(zhuǎn)移到IServiceManager對(duì)象中去了,這難道不是障眼法嗎?既然找到了“真身”,不妨就來(lái)見(jiàn)識(shí)見(jiàn)識(shí)它吧。

4. 撥開(kāi)浮云見(jiàn)月明——IServiceManager

剛才提到,IBinder家族的BpBinder和BBinder是與通信業(yè)務(wù)相關(guān)的,那么業(yè)務(wù)層的邏輯又是如何巧妙地架構(gòu)在Binder機(jī)制上的呢?關(guān)于這些問(wèn)題,可以用一個(gè)絕好的例子來(lái)解釋?zhuān)褪荌ServiceManager。

(1)定義業(yè)務(wù)邏輯

先回答第一個(gè)問(wèn)題:如何表述應(yīng)用的業(yè)務(wù)層邏輯??梢韵确治鲆幌翴ServiceManager是怎么做的。IServiceManager定義了ServiceManager所提供的服務(wù),看它的定義可知,其中有很多有趣的內(nèi)容。IServiceManager定義在IServiceManager.h中,代碼如下所示:

[-->IServiceManager.h]

class IServiceManager : public IInterface

{

?public:

?? //關(guān)鍵無(wú)比的宏!

?? DECLARE_META_INTERFACE(ServiceManager);

?

??? //下面是ServiceManager所提供的業(yè)務(wù)函數(shù)

??? virtualsp<IBinder>??? getService( constString16& name) const = 0;

??? virtualsp<IBinder>??? checkService( constString16& name) const = 0;

??? virtualstatus_t????? ??addService( const String16& name,

??????????????????????????? ???????????????????const sp<IBinder>&service) = 0;

?? ?virtual Vector<String16>??? listServices() = 0;

??? ......

};

(2)業(yè)務(wù)與通信的掛鉤

Android巧妙地通過(guò)DECLARE_META_INTERFACE和IMPLENT宏,將業(yè)務(wù)和通信牢牢地鉤在了一起。DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE這兩個(gè)宏都定義在剛才的IInterface.h中。先看DECLARE_META_INTERFACE這個(gè)宏,如下所示:

[-->IInterface.h::DECLARE_META_INTERFACE]

#define DECLARE_META_INTERFACE(INTERFACE)?????????????????????????????? \

??? staticconst android::String16 descriptor;????????????????????????? \

??? staticandroid::sp<I##INTERFACE> asInterface(?????????????????????? \

???????????const android::sp<android::IBinder>& obj);???????????????? ?\

??? virtualconst android::String16& getInterfaceDescriptor() const;??? \

???I##INTERFACE();????????????????????????????????????????????????????\

??? virtual~I##INTERFACE();????

將IServiceManager的DELCARE宏進(jìn)行相應(yīng)的替換后得到的代碼如下所示:

[--->DECLARE_META_INTERFACE(IServiceManager)]

//定義一個(gè)描述字符串

static const android::String16 descriptor;

?

//定義一個(gè)asInterface函數(shù)

static android::sp< IServiceManager >

asInterface(constandroid::sp<android::IBinder>& obj)

?

//定義一個(gè)getInterfaceDescriptor函數(shù),估計(jì)就是返回descriptor字符串

virtual const android::String16&getInterfaceDescriptor() const;

?

//定義IServiceManager的構(gòu)造函數(shù)和析構(gòu)函數(shù)

IServiceManager ();???????????????????????????????????????????????????

virtual ~IServiceManager();

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

IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager");

很簡(jiǎn)單,可直接將IServiceManager中的IMPLEMENT宏的定義展開(kāi),如下所示:

const android::String16

IServiceManager::descriptor(“android.os.IServiceManager”);

//實(shí)現(xiàn)getInterfaceDescriptor函數(shù)

const android::String16& IServiceManager::getInterfaceDescriptor()const

?{?

??? //返回字符串descriptor,值是“android.os.IServiceManager”

????? return IServiceManager::descriptor;

? }????

//實(shí)現(xiàn)asInterface函數(shù)

?android::sp<IServiceManager>

?????????????IServiceManager::asInterface(constandroid::sp<android::IBinder>& obj)

{

???????android::sp<IServiceManager> intr;

??????? if(obj != NULL) {??????????? ??????????????????????????????????

???????????intr = static_cast<IServiceManager *>(?????????????????????????

???????????????obj->queryLocalInterface(IServiceManager::descriptor).get());??

???????????if (intr == NULL) {

?????????????//obj是我們剛才創(chuàng)建的那個(gè)BpBinder(0)

???????????????intr = new BpServiceManager(obj);

??????????? }

??????? }

???????return intr;

}

//實(shí)現(xiàn)構(gòu)造函數(shù)和析構(gòu)函數(shù)

IServiceManager::IServiceManager () { }

IServiceManager::~ IServiceManager() { }

我們?cè)岢鲞^(guò)疑問(wèn):interface_cast是如何把BpBinder指針轉(zhuǎn)換成一個(gè)IServiceManager指針的呢?答案就在asInterface函數(shù)的一行代碼中,如下所示:

intr = new BpServiceManager(obj);

明白了!interface_cast不是指針的轉(zhuǎn)換,而是利用BpBinder對(duì)象作為參數(shù)新建了一個(gè)BpServiceManager對(duì)象。我們已經(jīng)知道BpBinder和BBinder與通信有關(guān)系,這里怎么突然冒出來(lái)一個(gè)BpServiceManager?它們之間又有什么關(guān)系呢?

(3)IServiceManager家族

要搞清這個(gè)問(wèn)題,必須先了解IServiceManager家族之間的關(guān)系,先來(lái)看圖6-3,它展示了IServiceManager的家族圖譜。

http://wiki.jikexueyuan.com/project/deep-android-v1/images/chapter6/image003.png" alt="image" />

圖6-3 IServiceManager的家族圖譜

根據(jù)圖6-3和相關(guān)的代碼可知,這里有以下幾個(gè)重要的點(diǎn)值得注意:

·? IServiceManager、BpServiceManager和BnServiceManager都與業(yè)務(wù)邏輯相關(guān)。

·? BnServiceManager同時(shí)從BBinder派生,表示它可以直接參與Binder通信。

·? BpServiceManager雖然從BpInterface中派生,但是這條分支似乎與BpBinder沒(méi)有關(guān)系。

·? BnServiceManager是一個(gè)虛類(lèi),它的業(yè)務(wù)函數(shù)最終需要子類(lèi)來(lái)實(shí)現(xiàn)。

重要說(shuō)明:以上這些關(guān)系很復(fù)雜,但ServiceManager并沒(méi)有使用錯(cuò)綜復(fù)雜的派生關(guān)系,它直接打開(kāi)Binder設(shè)備并與之交互。后文,還會(huì)詳細(xì)分析它的實(shí)現(xiàn)代碼。

圖6-3中的BpServiceManager,既然不像它的兄弟BnServiceManager那樣直接與Binder有血緣關(guān)系,那么它又是如何與Binder交互的呢?簡(jiǎn)言之,BpRefBase中的mRemote的值就是BpBinder。如果你不相信,仔細(xì)看BpServiceManager左邊的派生分支樹(shù)上的一系列代碼,它們都在IServiceManager.cpp中,如下所示:

[-->IServiceManager.cpp::BpServiceManager類(lèi)]

//通過(guò)它的參數(shù)可得知,impl是IBinder類(lèi)型,看來(lái)與Binder有間接關(guān)系,它實(shí)際上是BpBinder對(duì)象

BpServiceManager(const sp<IBinder>& impl)

?? //調(diào)用基類(lèi)BpInterface的構(gòu)造函數(shù)

?? : BpInterface<IServiceManager>(impl)

{

}

BpInterface的實(shí)現(xiàn)代碼如下所示:

[-->IInterface.h::BpInterface類(lèi)]

template<typename INTERFACE>

inlineBpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)

??? :BpRefBase(remote)//基類(lèi)構(gòu)造函數(shù)

{

}

BpRefBase()的實(shí)現(xiàn)代碼如下所示:

[-->Binder.cpp::BpRefBase類(lèi)]

BpRefBase::BpRefBase(const sp<IBinder>&o)

? //mRemote最終等于那個(gè)new 出來(lái)的BpBinder(0)

??? :mRemote(o.get()), mRefs(NULL), mState(0)

{

???extendObjectLifetime(OBJECT_LIFETIME_WEAK);

?

??? if(mRemote) {

???????mRemote->incStrong(this);??????????

??????? mRefs= mRemote->createWeak(this);

??? }

}

原來(lái),BpServiceManager的一個(gè)變量mRemote是指向了BpBinder。至此,我們的魔術(shù)表演完了,回想一下defaultServiceManager函數(shù),可以得到以下兩個(gè)關(guān)鍵對(duì)象:

·? 有一個(gè)BpBinder對(duì)象,它的handle值是0。

·? 有一個(gè)BpServiceManager對(duì)象,它的mRemote值是BpBinder。

BpServiceManager對(duì)象實(shí)現(xiàn)了IServiceManager的業(yè)務(wù)函數(shù),現(xiàn)在又有BpBinder作為通信的代表,接下來(lái)的工作就簡(jiǎn)單了。下面,要通過(guò)分析MediaPlayerService的注冊(cè)過(guò)程,進(jìn)一步分析業(yè)務(wù)函數(shù)的內(nèi)部是如何工作的。

6.2.4 ?注冊(cè)MediaPlayerService

1. 業(yè)務(wù)層的工作

再回到MS的main函數(shù),下一個(gè)要分析的是MediaPlayerService,它的代碼如下所示:

[-->MediaPlayerService.cpp]

void MediaPlayerService::instantiate() {

??? defaultServiceManager()->addService(

???????????String16("media.player"), new MediaPlayerService());

}

根據(jù)前面的分析,defaultServiceManager()實(shí)際返回的對(duì)象是BpServiceManager,它是IServiceManager的后代,代碼如下所示:

[-->IServiceManager.cpp::BpServiceManager的addService()函數(shù)]

virtual status_t addService(const String16&name, const sp<IBinder>& service)

{

??? //Parcel:就把它當(dāng)作是一個(gè)數(shù)據(jù)包。

??? Parceldata, reply;

?? ?data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());

??? data.writeString16(name);

??? data.writeStrongBinder(service);

??? //remote返回的是mRemote,也就是BpBinder對(duì)象

??? status_terr = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

??? returnerr == NO_ERROR ? reply.readInt32() : err;

}

別急著往下走,應(yīng)先思考以下兩個(gè)問(wèn)題:

·? 調(diào)用BpServiceManager的addService是不是一個(gè)業(yè)務(wù)層的函數(shù)?

·? addService函數(shù)中把請(qǐng)求數(shù)據(jù)打包成data后,傳給了BpBinder的transact函數(shù),這是不是把通信的工作交給了BpBinder?

兩個(gè)問(wèn)題的答案都是肯定的。至此,業(yè)務(wù)層的工作原理應(yīng)該是很清晰了,它的作用就是將請(qǐng)求信息打包后,再交給通信層去處理。

2. 通信層的工作

下面分析BpBinder的transact函數(shù)。前面說(shuō)過(guò),在BpBinder中確實(shí)找不到任何與Binder設(shè)備交互的地方嗎?那它是如何參與通信的呢?原來(lái),秘密就在這個(gè)transact函數(shù)中,它的實(shí)現(xiàn)代碼如下所示:

[-->BpBinder.cpp]

status_t BpBinder::transact(uint32_t code, constParcel& data, Parcel* reply,

???????????????????????????????? uint32_tflags)

{

??? if(mAlive) {

?????//BpBinder果然是道具,它把transact工作交給了IPCThreadState

???????status_t status = IPCThreadState::self()->transact(

????? ???????????????????? mHandle,code, data, reply, flags);//mHandle也是參數(shù)

??????? if(status == DEAD_OBJECT) mAlive = 0;

???????return status;

??? }

?

??? returnDEAD_OBJECT;

}

這里又遇見(jiàn)了IPCThreadState,之前也見(jiàn)過(guò)一次??磥?lái),它確實(shí)與Binder通信有關(guān),所以必須對(duì)其進(jìn)行深入分析!

(1)“勞者一份”的IPCThreadState

誰(shuí)是“勞者”?線(xiàn)程,是進(jìn)程中真正干活的伙計(jì),所以它正是勞者。而“勞者一份”,就是每個(gè)伙計(jì)一份的意思。IPCThreadState的實(shí)現(xiàn)代碼在IPCThreadState.cpp中,如下所示:

[-->IPCThreadState.cpp]

IPCThreadState* IPCThreadState::self()

{

??? if(gHaveTLS) {//第一次進(jìn)來(lái)為false

restart:

??????? constpthread_key_t k = gTLS;

?/*

?? TLS是Thread Local Storage(線(xiàn)程本地存儲(chǔ)空間)的簡(jiǎn)稱(chēng)。

?? 這里只需知曉:這種空間每個(gè)線(xiàn)程都有,而且線(xiàn)程間不共享這些空間。

? ?通過(guò)pthread_getspecific/pthread_setspecific函數(shù)可以獲取/設(shè)置這些空間中的內(nèi)容。

? ?從線(xiàn)程本地存儲(chǔ)空間中獲得保存在其中的IPCThreadState對(duì)象。

?? 有調(diào)用pthread_getspecific的地方,肯定也有調(diào)用pthread_setspecific的地方

?*/

???????IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);

??????? if(st) return st;

// new一個(gè)對(duì)象,構(gòu)造函數(shù)中會(huì)調(diào)用pthread_setspecific

???????return new IPCThreadState;

??? }

???

??? if(gShutdown) return NULL;

????pthread_mutex_lock(&gTLSMutex);

??? if(!gHaveTLS) {

??????? if(pthread_key_create(&gTLS, threadDestructor) != 0) {

???????????pthread_mutex_unlock(&gTLSMutex);

???????????return NULL;

??????? }

???????gHaveTLS = true;

??? }

? pthread_mutex_unlock(&gTLSMutex);

//其實(shí)goto沒(méi)有我們說(shuō)的那么不好,匯編代碼也有很多跳轉(zhuǎn)語(yǔ)句(沒(méi)辦法,太低級(jí)的語(yǔ)言了),關(guān)鍵是要用好

? goto restart;

}

接下來(lái),有必要轉(zhuǎn)向分析它的構(gòu)造函數(shù)IPCThreadState(),如下所示:

[-->IPCThreadState.cpp]

IPCThreadState::IPCThreadState()

??? :mProcess(ProcessState::self()), mMyThreadId(androidGetTid())

{

? //在構(gòu)造函數(shù)中,把自己設(shè)置到線(xiàn)程本地存儲(chǔ)中去。

???pthread_setspecific(gTLS, this);

??? clearCaller();

???//mIn和mOut是兩個(gè)Parcel。把它看成是發(fā)送和接收命令的緩沖區(qū)即可。

mIn.setDataCapacity(256);

??? ?mOut.setDataCapacity(256);

}

每個(gè)線(xiàn)程都有一個(gè)IPCThreadState,每個(gè)IPCThreadState中都有一個(gè)mIn、一個(gè)mOut,其中mIn是用來(lái)接收來(lái)自Binder設(shè)備的數(shù)據(jù)的,而mOut則是用來(lái)存儲(chǔ)發(fā)往Binder設(shè)備的數(shù)據(jù)的。

(2)勤勞的transact

傳輸工作是很辛苦的。我們剛才看到BpBinder的transact調(diào)用了IPCThreadState的transact函數(shù),這個(gè)函數(shù)實(shí)際完成了與Binder通信的工作,如下面的代碼所示:

[-->IPCThreadState.cpp]

//注意,handle的值為0,代表了通信的目的端

status_t IPCThreadState::transact(int32_t handle,

????????????????????????????????? uint32_tcode, const Parcel& data,

?????????????????????? ???????????Parcel* reply, uint32_t flags)

{

??? status_terr = data.errorCheck();

?

??? flags |=TF_ACCEPT_FDS;

?

??? ......

/*

?注意這里的第一個(gè)參數(shù)BC_TRANSACTION,它是應(yīng)用程序向binder設(shè)備發(fā)送消息的消息碼,

而binder設(shè)備向應(yīng)用程序回復(fù)消息的消息碼以BR_開(kāi)頭。消息碼的定義在binder_module.h中,

?請(qǐng)求消息碼和回應(yīng)消息碼的對(duì)應(yīng)關(guān)系,需要查看Binder驅(qū)動(dòng)的實(shí)現(xiàn)才能將其理清楚,我們這里暫時(shí)用不上。

*/

???? err =writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);

??? ?......

?? ??err = waitForResponse(reply);

???? ......

???

??? returnerr;

}

多熟悉的流程:先發(fā)數(shù)據(jù),然后等結(jié)果。再簡(jiǎn)單不過(guò)了!不過(guò),我們有必要確認(rèn)一下handle這個(gè)參數(shù)到底起了什么作用。先來(lái)看writeTransactionData函數(shù),它的實(shí)現(xiàn)如下所示:

[-->IPCThreadState.cpp]

status_tIPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,

??? int32_thandle, uint32_t code, const Parcel& data, status_t* statusBuffer)

{

? ?//binder_transaction_data 是和binder設(shè)備通信的數(shù)據(jù)結(jié)構(gòu)。???

? ?binder_transaction_data tr;

?

? ?//果然,handle的值傳遞給了target,用來(lái)標(biāo)識(shí)目的端,其中0是ServiceManager的標(biāo)志。

?? tr.target.handle= handle;

?? //code是消息碼,用來(lái)switch/case的!

??? tr.code =code;

??? tr.flags= binderFlags;

???

??? conststatus_t err = data.errorCheck();

??? if (err== NO_ERROR) {

???????tr.data_size = data.ipcDataSize();

???????tr.data.ptr.buffer = data.ipcData();

???????tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);

???????tr.data.ptr.offsets = data.ipcObjects();

??? } else if(statusBuffer) {

???????tr.flags |= TF_STATUS_CODE;

???????*statusBuffer = err;

???????tr.data_size = sizeof(status_t);

???????tr.data.ptr.buffer = statusBuffer;

???????tr.offsets_size = 0;

???????tr.data.ptr.offsets = NULL;

??? } else {

???????return (mLastError = err);

??? }

?? //把命令寫(xiě)到mOut中, 而不是直接發(fā)出去,可見(jiàn)這個(gè)函數(shù)有點(diǎn)名不副實(shí)。

???mOut.writeInt32(cmd);

???mOut.write(&tr, sizeof(tr));

??? returnNO_ERROR;

}

現(xiàn)在,已經(jīng)把a(bǔ)ddService的請(qǐng)求信息寫(xiě)到mOut中了。接下來(lái)再看發(fā)送請(qǐng)求和接收回復(fù)部分的實(shí)現(xiàn),代碼在waitForResponse函數(shù)中,如下所示:

[-->IPCThreadState.cpp]

status_t IPCThreadState::waitForResponse(Parcel*reply, status_t *acquireResult)

{

??? int32_tcmd;

??? int32_terr;

?

while (1) {

??????? //好家伙,talkWithDriver!

??????? if((err=talkWithDriver()) < NO_ERROR) break;

??????? err =mIn.errorCheck();

??????? if(err < NO_ERROR) break;

??????? if(mIn.dataAvail() == 0) continue;

???????

??????? cmd =mIn.readInt32();

?????? switch(cmd) {

??????? caseBR_TRANSACTION_COMPLETE:

???????????if (!reply && !acquireResult) goto finish;

???????????break;

??????? ......

??????? default:

???????????err = executeCommand(cmd);//看這個(gè)!

???????????if (err != NO_ERROR) goto finish;

???????????break;

??????? }

??? }

?

finish:

??? if (err!= NO_ERROR) {

??????? if(acquireResult) *acquireResult = err;

??????? if(reply) reply->setError(err);

???????mLastError = err;

??? }

???

??? returnerr;

}

OK,我們已發(fā)送了請(qǐng)求數(shù)據(jù),假設(shè)馬上就收到了回復(fù),后續(xù)該怎么處理呢?來(lái)看executeCommand函數(shù),如下所示:

[-->IPCThreadState.cpp]

status_t IPCThreadState::executeCommand(int32_tcmd)

{

??? BBinder*obj;

???RefBase::weakref_type* refs;

??? status_tresult = NO_ERROR;

???

??? switch(cmd) {

??? caseBR_ERROR:

???????result = mIn.readInt32();

???????break;

??????? ......

???? caseBR_TRANSACTION:

??????? {

???????????binder_transaction_data tr;

???????????result = mIn.read(&tr, sizeof(tr));

???????????if (result != NO_ERROR) break;

??? ????????Parcel buffer;

???????????Parcel reply;

???????????if (tr.target.ptr) {

????????? ?/*

?? ??????????看到了BBinder,想起圖6-3了嗎?BnServiceXXX從BBinder派生,

?? ??????????這里的b實(shí)際上就是實(shí)現(xiàn)BnServiceXXX的那個(gè)對(duì)象,關(guān)于它的作用,我們要在6.5節(jié)中講解。

??????????? */

???????????? ???sp<BBinder> b((BBinder*)tr.cookie);

???????????????const status_t error = b->transact(tr.code, buffer, &reply, 0);

?? ?????????????if (error < NO_ERROR)reply.setError(error);

?????????????} else {

?? ???????/*

? ?????????the_context_object是IPCThreadState.cpp中定義的一個(gè)全局變量,

??? ?????可通過(guò)setTheContextObject函數(shù)設(shè)置

?? ????????*/

???????????????const status_t error =

??????????? ?????????????????the_context_object->transact(tr.code,buffer, &reply, 0);

???????????????if (error < NO_ERROR) reply.setError(error);

???????? }

???????break;

??? ......

??? caseBR_DEAD_BINDER:

??????? {

???????? /*

?????????? 收到binder驅(qū)動(dòng)發(fā)來(lái)的service死掉的消息,看來(lái)只有Bp端能收到了,

?????????? 后面,我們將會(huì)對(duì)此進(jìn)行分析。

*/

???????????BpBinder *proxy = (BpBinder*)mIn.readInt32();

???????????proxy->sendObituary();

???????????mOut.writeInt32(BC_DEAD_BINDER_DONE);

???????????mOut.writeInt32((int32_t)proxy);

??????? }break;

??????? ......

case BR_SPAWN_LOOPER:

? //特別注意,這里將收到來(lái)自驅(qū)動(dòng)的指示以創(chuàng)建一個(gè)新線(xiàn)程,用于和Binder通信。

???????mProcess->spawnPooledThread(false);

???????break;

??????default:

????????result = UNKNOWN_ERROR;

???????break;

??? }

?? ......

??? if(result != NO_ERROR) {

???????mLastError = result;

??? }

??? returnresult;

}

(3)打破砂鍋問(wèn)到底

你一定想知道如何和Binder設(shè)備交互的吧?是通過(guò)write和read函數(shù)來(lái)發(fā)送和接收請(qǐng)求的嗎?來(lái)看talkwithDriver函數(shù),如下所示:

[-->IPCThreadState.cpp]

status_t IPCThreadState::talkWithDriver(booldoReceive)

{

? // binder_write_read是用來(lái)與Binder設(shè)備交換數(shù)據(jù)的結(jié)構(gòu)

? ??binder_write_read bwr;

??? constbool needRead = mIn.dataPosition() >= mIn.dataSize();

??? constsize_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;

???

??? //請(qǐng)求命令的填充

???bwr.write_size = outAvail;

???bwr.write_buffer = (long unsigned int)mOut.data();

?

? if(doReceive && needRead) {

?????? //接收數(shù)據(jù)緩沖區(qū)信息的填充。如果以后收到數(shù)據(jù),就直接填在mIn中了。

???????bwr.read_size = mIn.dataCapacity();

???????bwr.read_buffer = (long unsigned int)mIn.data();

??? } else {

???????bwr.read_size = 0;

??? }

???

??? if((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;

???

???bwr.write_consumed = 0;

???bwr.read_consumed = 0;

??? status_terr;

??? do {

? #ifdefined(HAVE_ANDROID_OS)

?? ?????//看來(lái)不是read/write調(diào)用,而是ioctl方式。

??????? if(ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)

???????????err = NO_ERROR;

??????? else

???????????err = -errno;

#else

??????? err =INVALID_OPERATION;

#endif

?????? }while (err == -EINTR);

???

???? if (err>= NO_ERROR) {

??????? if(bwr.write_consumed > 0) {

???????????if (bwr.write_consumed < (ssize_t)mOut.dataSize())

???????????????mOut.remove(0, bwr.write_consumed);

???????????else

???????????????mOut.setDataSize(0);

??????? }

??????? if(bwr.read_consumed > 0) {

???????????mIn.setDataSize(bwr.read_consumed);

???????????mIn.setDataPosition(0);