02.03 Android-ServiceManager管理

ServiceManager在init進程啟動之後啟動,用來管理系統中的service,那麼首先理解一下在init進程啟動之後啟動這句話類:

一般開機過程分為三個階段:

  1. OS級別,由bootloader載入linux內核後,內核開始初始化,並載入built-in的驅動程序,內核完成開機後,載入init process,切換至user-space後,結束內核的循序過程,進入排成模式。
  2. Android-level,由init process開始,讀取init.rc,Mative服務啟動,並啟動重要的外部程序,例如servicemanager、zygote以及system service。
  3. Zygote-Mode,Zygote啟動完System Service後,進入Zygote Mode,在Socket等候命令,隨後,使用者將看到一個桌面環境,桌面環境由一個名為Launcher的應用程序負責提供。
Android-ServiceManager管理

在ServiceManager中有兩個比較重要的方法:add_service和check_service,系統的service需要通過add_service把自己的信息註冊到servicemanager中,當需要使用時,通過check_service檢查該service是否存在。看它的main函數的源碼:

Android-ServiceManager管理

三件事:

  1. 打開Binder設備,並在內存中映射128k的空間

首先看一下struct binder_state這個結構體

<code>struct binder_state{
int fd; //文件描述符,打開/dev/binder設備
void* mapped; //把設備文件/dev/binder映射到進程空間的起始地址
unsigned mapsize; //映射內存空間的大小
}
/<code>
  1. 告訴Binder驅動程序,自己是Binder上下文管理者
  1. 進入循環,不停去讀Binder設備,看是否有對service的請求,如果有的話就去調用svcmgr_handller函數回調處理請求。

下面就來看一下servicemanager是怎麼循環等待客戶端的請求,並進行註冊服務、服務獲取這一系列活動的。

等待客戶端請求

ServiceManager進程通過binder_loop方法進入循環等待客戶端的請求中,當有客戶端請求時,進程ServiceManager被喚醒並調用svcmgr_handler來處理客戶端的請求。

Android-ServiceManager管理

  1. ServiceManager進程在進入循環前,調用binder_write()方法,通過ioctl系統調用設置Binder線程的運行狀態為BINDER_LOOPER_STATE_ENTERED,看下binder_write()方法的源碼:
Android-ServiceManager管理

首先設置binder_write_read結構體變量的值,然後通過ioctl傳遞到Binder驅動程序中,此時控制命令為BINDER_WRITE_READ,binder_ioctl函數中對BINDER_WRITE_READ命令的處理過程為:

Android-ServiceManager管理

在binder_thread_write方法中,對BC_ENTER_LOOPER Binder協議的處理如下:

Android-ServiceManager管理

此處僅僅設置了binder_thread結構體變量中的線程運行狀態looper為BINDER_LOOPER_STATE_ENTERED,表示當前的binder線程進入循環狀態。

2. 睡眠等待客戶端請求

在沒有客戶端請求時,當前進程就進入休眠狀態,等待請求到來再喚醒。

總結一哈?

ServiceManager進程的啟動首先打開binder驅動並開闢內核緩存區,同時將緩存區的物理頁面同時映射到內核虛擬地址空間及進程虛擬地址空間中,然後在內核中創建屬於servicemanager進程的binder_node實體節點,接著設置處理客戶端請求的binder線程運行狀態,由於此時沒有客戶端的請求,servicemanager進程進入睡眠等待中,直到客戶端請求的到來時,喚醒servicemanager進程,再繼續往下執行。

服務註冊

直接來看,當有service請求時,調用的回到函數svcmgr_handler函數。

Android-ServiceManager管理

如果請求註冊,就執行紅色框中的代碼,我們再來看一下具體實現do_add_service()方法是怎麼實現的:

Android-ServiceManager管理

Android-ServiceManager管理

看代碼中的三個紅框,首先會檢查是否有權限註冊service,如果沒有權限就直接返回不能註冊;然後去檢查該service是否已經註冊過了,如果已經註冊過,那就不能再註冊;再判斷內存是否夠用。如果都沒有問題,就會註冊該service,加入到svcList中來,(在servicemanager中維護service信息的地方就是svcList,裡面存了service的name和handler)。通過以上幾步,service就算註冊成功了。

服務獲取

如果是服務獲取,就會執行代碼中的黃色框,並將返回的數據寫入reply,返回給客戶端,do_find_service函數中主要執行service的查找,看源碼:

Android-ServiceManager管理


分享到:


相關文章: