由代碼來補充部分:
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()),這一行代碼會建立ProcessState對象,一個進程只有唯一的一個ProcessState對象,而ProcessState類的作用是來打開/dev/binder設備。這也就說明了一個問題,一個進程只不可能同時存在多個對/dev/binder的操作。
sp<IServiceManager> sm = defaultServiceManager(),這一行代碼要做的事情參見上圖。1、創建一個BpBinder。2、由BpBinder對象創建BpServiceManger對象。(為什么要采取如此不自然的方式,可以看一下這兩個對象繼承的基類)。完成這一步驟的最重要的作用在于以后對于IServiceManager對象的方法的調用,都將會由其子類BpServiceManger的方法來實現(這樣做的意義何在?這樣的作用僅僅在于我們可以重用IServiceManager的代碼,別忘了我們還有一個類似的繼承自IServiceManager的類,它叫做BnServiceManger)。這樣說起來似乎過于抽象,好在我們可以舉一個例子,接下去的代碼就會有例子出現。
CameraService::instantiate(),這一行的代碼(前面還有兩行?相信我,他們絕對是幾乎一樣的實現,當然我是指從Binder層來說,而不是指與硬件相關的交互)。我們仍然先畫出結構圖:
我們需要一點代碼來輔助我們的分析,CameraService::instantiate的代碼如下:
void CameraService::instantiate() {
defaultServiceManager()->addService(
String16("media.camera"), new CameraService());
}。
仍然是由defaultServiceManager函數開始,但是我們此時已經擁有了對象,而這樣做的目的僅僅在于我們調用的會是BpServiceManger類中的addService方法,而不是IServiceManager基類的addService方法。我們試著去尋找BpServiceManger類中的addService函數。在此之前有個需要我們注意的地方new CameraService,這里實例化了一個CameraService對象,他的基類們是我們要注意的,因為之后我們將不得不關注于整套虛函數調用的機制。CameraService類的繼承關系我在圖中已經畫出:IBinder->BBinder(ICmaerService兩個基類)->BnInterface->BnCamerService->CamerService,看起來足夠復雜,不幸的是這個繼承模式是有意義的。
我們將思路再拉回來,接著看BpServiceManger類中addService的實現:
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這兩行我們無需關注,因為它們完成一些接口命名之類的事情。來看看data.writeStrongBinder會做些什么:
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);
}
我們先來關注IBinder *local = binder->localBinder()這一行代碼,binder變量是一個IBinder類的指針,那么是否是說我們要調用的是IBinder類的localBinder函數呢?我去查看代碼,發現它是一個虛函數,說明我們將會調用的是指針指向的對象的localBinder函數。還沒忘記我們剛才特別提到的地方吧?defaultServiceManager()->addService(String16("media.camera"), new CameraService());它是一個CamerService對象,理論上來說我們應該是按照沿基類向上的方式查找實現,CamerService-> BnCamerService->BnInterface->ICmaerService,BBinder兩個基類-> IBinder這樣的查找順序。我們在BBinder類的實現中找到了這個localBinder這個函數,那么這里將會調用的就是BBinder對象的實現:
BBinder* BBinder::localBinder()
{
return this;
}很明顯代碼接著會走到橙色部分。
那么finish_flatten_binder又會做些什么呢?代碼我就不貼了,它的作用是更新相應的數據偏移量指針。但是寫到這里,我們似乎越看越糊涂,這些步驟有什么意義?Parcel類為什么又突然出現了?我們來做一下補充,首先是Parcel類的作用,它是用來完成數據的序列化的,也就是完成數據投遞之前的準備工作的。投遞的數據都會放在這個類的一個實例中。我去查找Parcel類的定義的時候發現它沒有虛函數,也就是說關于投遞數據序列化的操作都會在這個類及其實現中完成。我們終于可以暫時的擺脫那些虛函數們了。
我們的工作還遠沒有結束,我們還沒有看到數據是如何投遞的?那么我們接著來看addService函數中的最后一個函數調用remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply),它明顯是用來投遞數據的,如何投遞?這里我們要弄清楚兩個問題:1、remote函數返回的是什么?也就是transcat是哪個對象的方法。2、transcat如何與底層交互。
我們先來看看第一個問題。先前已經討論過,addService方法的調用是來自BpServiceManager對象,我們忘了給出另一套類繼承的機制:RefBase->IServiceManager,BpRefBase兩個基類->BpInterface->BpServiceManager。 那么這里的remote方法(與addService一樣均屬于BpServiceManager),將會調用BpServiceManager的基類BpRefBase的remote方法。其實現時:inline IBinder* remote() { return mRemote; }。問題在于這里的mRemote會是BBinder呢還是BpBinder?這個討論使得我們不得不又再次回到之前的代碼中去(確實復雜,但還不至于會使人疑惑。)答案在很早以前的defaultServiceManager函數中,之前我們并沒有分析過這個函數,是因為我們之前并不需要知道這個函數太多的細節,我們只用知道它是為了完成BpServiceManger對象的建立,但實際上,它還完成了另一個功能,將BpRefBased對象的mRemote成員初始化為BpBinder對象。來看代碼:
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 此函數返回一個BpBinder對象,當然這個對象的指針是其基類指針IBander。然后由interface_cast再次調用,而為mRemote成員的賦值也同樣發生在BpServiceManger對象的建立之時,調用BpServiceManger類的構造函數: BpServiceManager(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl),再次調用BpInterface類的構造函數
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
就在綠色的代碼部分了,具體的分析請看另一篇文檔,這里只是補充。
第一個問題,為我們指明了方向,也就是通訊的時候會采用BpBinder對象的transact函數。這樣我們來繼續看一下第二個問題,現在我們直奔BpBinder類中的transact函數的實現:
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機制的路還很長很長!
http://wsqhs.spaces.live.com/blog/cns!94F639580F58209C!642.entry