天天看點

Binder驅動是如何維護本地Binder和Binder代理的映射關系

Binder驅動是如何維護本地Binder和Binder代理的映射關系

通信過程:

binder裝置驅動會為每個程序配置設定一個資料結構binder_proc,每程序中的每個用到了binder通信的線程配置設定資料結構binder_thread。

binder裝置驅動會為服務程序中的每個服務對象配置設定資料結構binder_node,它隸屬于服務程序的binder_proc,即binder_node是binder_proc的子結構,binder_node中記錄了服務對象在服務程序中的位址;會為客戶程序中每個引用配置設定binder_ref,binder_ref會指向客戶程序引用的服務對象的binder_node。

binder驅動為客戶程序每個引用都會維護一個handle,它存在于binder_ref中(binder_ref.desc),它就像程序打開某個檔案産生的檔案描述符一樣,程序每引用一個服務,就會配置設定一個最小未使用的整數作為handle。handle是客戶程序相關的,多個程序引用同一個服務得到的handle并不是一樣的。

當服務程序向ServiceManager注冊服務時,會帶上服務的名稱字元串,驅動會為服務程序中的服務對象增加一個binder_node,歸屬于服務程序的binder_proc。

當把注冊服務的請求發給ServiceManager時,ServiceManager也是服務對象的一個引用者,驅動會為ServiceManager增加一個binder_ref,指向服務對象的binder_node。驅動把binder_ref.desc(ServiceManager)作為handle傳回給ServiceManager,ServiceManager儲存此handle和服務名稱字元串。

當客戶程序向ServiceManager擷取服務時,ServiceManager根據服務名稱字元串找到服務對象在ServiceManager程序中的handle。在ServiceManager的應答的過程中,驅動根據此handle在ServiceManager程序的binder_proc找到對應的binder_ref,并根據它找到服務對象的binder_node。然後,驅動會為客戶程序增加一個binder_ref,指向服務對象的binder_node,最後把binder_ref.desc(客戶程序)作為handle傳回給客戶程序。

客戶程序使用得到的handle向服務程序發起請求,驅動會在根據此handle在客戶程序的binder_proc查找對應的binder_ref,并找到它指向的binder_node,并找到binder_node所屬的binder_proc,最終驅動把請求放入服務程序的接收隊列中。

服務程序收到請求後,從binder_node中找到服務對象的位址,然後調用該服務對象。是以,對于服務對象,在客戶程序中表現出來的是handle,在服務程序中表現出來的是位址,驅動會對它們進行映射。

繼續閱讀