本章主要內(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
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)有使用它們。
為了能像“庖丁”那樣解析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本身。
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。
我們?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。
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),從它的命名中也可看出些端倪。
再來(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);
??? }
??? ......
}
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。
defaultServiceManager函數(shù)的實(shí)現(xiàn)在IServiceManager.cpp中完成。它會(huì)返回一個(gè)IServiceManager對(duì)象,通過(guò)這個(gè)對(duì)象,我們可以神奇地與另一個(gè)進(jìn)程ServiceManager進(jìn)行交互。是不是有一種觀看時(shí)空穿越魔術(shù)表演的感覺(jué)?
先來(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
}
眾所周知,玩魔術(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)具體分析它。
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í)它吧。
剛才提到,IBinder家族的BpBinder和BBinder是與通信業(yè)務(wù)相關(guān)的,那么業(yè)務(wù)層的邏輯又是如何巧妙地架構(gòu)在Binder機(jī)制上的呢?關(guān)于這些問(wèn)題,可以用一個(gè)絕好的例子來(lái)解釋?zhuān)褪荌ServiceManager。
先回答第一個(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;
??? ......
};
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)系呢?
要搞清這個(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)部是如何工作的。
再回到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)求信息打包后,再交給通信層去處理。
下面分析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)行深入分析!
誰(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ù)的。
傳輸工作是很辛苦的。我們剛才看到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;
}
你一定想知道如何和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);