由代碼來補(bǔ)充部分:
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
sp<ProcessState> proc(ProcessState::self()),這一行代碼會(huì)建立ProcessState對(duì)象,一個(gè)進(jìn)程只有唯一的一個(gè)ProcessState對(duì)象,而ProcessState類的作用是來打開/dev/binder設(shè)備。這也就說明了一個(gè)問題,一個(gè)進(jìn)程只不可能同時(shí)存在多個(gè)對(duì)/dev/binder的操作。
sp<IServiceManager> sm = defaultServiceManager(),這一行代碼要做的事情參見上圖。1、創(chuàng)建一個(gè)BpBinder。2、由BpBinder對(duì)象創(chuàng)建BpServiceManger對(duì)象。(為什么要采取如此不自然的方式,可以看一下這兩個(gè)對(duì)象繼承的基類)。完成這一步驟的最重要的作用在于以后對(duì)于IServiceManager對(duì)象的方法的調(diào)用,都將會(huì)由其子類BpServiceManger的方法來實(shí)現(xiàn)(這樣做的意義何在?這樣的作用僅僅在于我們可以重用IServiceManager的代碼,別忘了我們還有一個(gè)類似的繼承自IServiceManager的類,它叫做BnServiceManger)。這樣說起來似乎過于抽象,好在我們可以舉一個(gè)例子,接下去的代碼就會(huì)有例子出現(xiàn)。
CameraService::instantiate(),這一行的代碼(前面還有兩行?相信我,他們絕對(duì)是幾乎一樣的實(shí)現(xiàn),當(dāng)然我是指從Binder層來說,而不是指與硬件相關(guān)的交互)。我們?nèi)匀幌犬嫵鼋Y(jié)構(gòu)圖:
我們需要一點(diǎn)代碼來輔助我們的分析,CameraService::instantiate的代碼如下:
void CameraService::instantiate() {
defaultServiceManager()->addService(
String16("media.camera"), new CameraService());
}。
仍然是由defaultServiceManager函數(shù)開始,但是我們此時(shí)已經(jīng)擁有了對(duì)象,而這樣做的目的僅僅在于我們調(diào)用的會(huì)是BpServiceManger類中的addService方法,而不是IServiceManager基類的addService方法。我們?cè)囍ふ?/span>BpServiceManger類中的addService函數(shù)。在此之前有個(gè)需要我們注意的地方new CameraService,這里實(shí)例化了一個(gè)CameraService對(duì)象,他的基類們是我們要注意的,因?yàn)橹笪覀儗⒉坏貌魂P(guān)注于整套虛函數(shù)調(diào)用的機(jī)制。CameraService類的繼承關(guān)系我在圖中已經(jīng)畫出:IBinder->BBinder(ICmaerService兩個(gè)基類)->BnInterface->BnCamerService->CamerService,看起來足夠復(fù)雜,不幸的是這個(gè)繼承模式是有意義的。
我們將思路再拉回來,接著看BpServiceManger類中addService的實(shí)現(xiàn):
virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readInt32() : err;
}
Data.writeInterfaceToken與data.writeString這兩行我們無需關(guān)注,因?yàn)樗鼈兺瓿梢恍┙涌诿惖氖虑?。來看?/span>data.writeStrongBinder會(huì)做些什么:
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
而flatten_binder代碼如下:
status_t flatten_binder(const sp<ProcessState>& proc,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == NULL) {
LOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_HANDLE;
obj.handle = handle;
obj.cookie = NULL;
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = local->getWeakRefs();
obj.cookie = local;
}
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = NULL;
obj.cookie = NULL;
}
return finish_flatten_binder(binder, obj, out);
}
我們先來關(guān)注IBinder *local = binder->localBinder()這一行代碼,binder變量是一個(gè)IBinder類的指針,那么是否是說我們要調(diào)用的是IBinder類的localBinder函數(shù)呢?我去查看代碼,發(fā)現(xiàn)它是一個(gè)虛函數(shù),說明我們將會(huì)調(diào)用的是指針指向的對(duì)象的localBinder函數(shù)。還沒忘記我們剛才特別提到的地方吧?defaultServiceManager()->addService(String16("media.camera"), new CameraService());它是一個(gè)CamerService對(duì)象,理論上來說我們應(yīng)該是按照沿基類向上的方式查找實(shí)現(xiàn),CamerService-> BnCamerService->BnInterface->ICmaerService,BBinder兩個(gè)基類-> IBinder這樣的查找順序。我們?cè)?/span>BBinder類的實(shí)現(xiàn)中找到了這個(gè)localBinder這個(gè)函數(shù),那么這里將會(huì)調(diào)用的就是BBinder對(duì)象的實(shí)現(xiàn):
BBinder* BBinder::localBinder()
{
return this;
}很明顯代碼接著會(huì)走到橙色部分。
那么finish_flatten_binder又會(huì)做些什么呢?代碼我就不貼了,它的作用是更新相應(yīng)的數(shù)據(jù)偏移量指針。但是寫到這里,我們似乎越看越糊涂,這些步驟有什么意義?Parcel類為什么又突然出現(xiàn)了?我們來做一下補(bǔ)充,首先是Parcel類的作用,它是用來完成數(shù)據(jù)的序列化的,也就是完成數(shù)據(jù)投遞之前的準(zhǔn)備工作的。投遞的數(shù)據(jù)都會(huì)放在這個(gè)類的一個(gè)實(shí)例中。我去查找Parcel類的定義的時(shí)候發(fā)現(xiàn)它沒有虛函數(shù),也就是說關(guān)于投遞數(shù)據(jù)序列化的操作都會(huì)在這個(gè)類及其實(shí)現(xiàn)中完成。我們終于可以暫時(shí)的擺脫那些虛函數(shù)們了。
我們的工作還遠(yuǎn)沒有結(jié)束,我們還沒有看到數(shù)據(jù)是如何投遞的?那么我們接著來看addService函數(shù)中的最后一個(gè)函數(shù)調(diào)用remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply),它明顯是用來投遞數(shù)據(jù)的,如何投遞?這里我們要弄清楚兩個(gè)問題:1、remote函數(shù)返回的是什么?也就是transcat是哪個(gè)對(duì)象的方法。2、transcat如何與底層交互。
我們先來看看第一個(gè)問題。先前已經(jīng)討論過,addService方法的調(diào)用是來自BpServiceManager對(duì)象,我們忘了給出另一套類繼承的機(jī)制:RefBase->IServiceManager,BpRefBase兩個(gè)基類->BpInterface->BpServiceManager。 那么這里的remote方法(與addService一樣均屬于BpServiceManager),將會(huì)調(diào)用BpServiceManager的基類BpRefBase的remote方法。其實(shí)現(xiàn)時(shí):inline IBinder* remote() { return mRemote; }。問題在于這里的mRemote會(huì)是BBinder呢還是BpBinder?這個(gè)討論使得我們不得不又再次回到之前的代碼中去(確實(shí)復(fù)雜,但還不至于會(huì)使人疑惑。)答案在很早以前的defaultServiceManager函數(shù)中,之前我們并沒有分析過這個(gè)函數(shù),是因?yàn)槲覀冎安⒉恍枰肋@個(gè)函數(shù)太多的細(xì)節(jié),我們只用知道它是為了完成BpServiceManger對(duì)象的建立,但實(shí)際上,它還完成了另一個(gè)功能,將BpRefBased對(duì)象的mRemote成員初始化為BpBinder對(duì)象。來看代碼:
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
ProcessState::self()->getContextObject 此函數(shù)返回一個(gè)BpBinder對(duì)象,當(dāng)然這個(gè)對(duì)象的指針是其基類指針IBander。然后由interface_cast再次調(diào)用,而為mRemote成員的賦值也同樣發(fā)生在BpServiceManger對(duì)象的建立之時(shí),調(diào)用BpServiceManger類的構(gòu)造函數(shù): BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl),再次調(diào)用BpInterface類的構(gòu)造函數(shù)
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
就在綠色的代碼部分了,具體的分析請(qǐng)看另一篇文檔,這里只是補(bǔ)充。
第一個(gè)問題,為我們指明了方向,也就是通訊的時(shí)候會(huì)采用BpBinder對(duì)象的transact函數(shù)。這樣我們來繼續(xù)看一下第二個(gè)問題,現(xiàn)在我們直奔BpBinder類中的transact函數(shù)的實(shí)現(xiàn):
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
今天只能寫這么多,binder機(jī)制的路還很長(zhǎng)很長(zhǎng)!
聯(lián)系客服