Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

使用活頁夾IPC

此頁面描述了對Android 8中的活頁夾驅動程序的更改,提供了有關使用活頁夾IPC的詳細信息,並列出了所需的SELinux策略。

對活頁夾驅動程序的更改

從Android 8開始,Android框架和HAL現在使用活頁夾彼此通信。由於這種通信方式大大增加了活頁夾流量,因此Android 8進行了多項改進,旨在保持活頁夾IPC快速。 SoC供應商和OEM應該直接從內核/通用項目的android-4.4,android-4.9和更高版本的相關分支合併。

多個活頁夾域(上下文)

通用4.4及更高版本,包括上游

為了在框架(獨立於設備)代碼和供應商(特定於設備)代碼之間明確劃分綁定程序流量,Android 8引入了綁定程序上下文的概念。每個綁定程序上下文都有其自己的設備節點和其上下文(服務)管理器。您只能通過上下文管理器所屬的設備節點來訪問上下文管理器,並且當綁定程序節點通過某個上下文時,只能通過另一個進程從同一上下文訪問上下文管理器,從而將域彼此完全隔離。有關使用的詳細信息,請參見vndbindervndservicemanager

散佈聚集

通用4.4及更高版本,包括上游

在以前的Android版本中,活頁夾調用中的每個數據都被複製了3次:

  • 一次在調用過程中將其序列化為Parcel
  • 一旦在內核驅動程序中將Parcel複製到目標進程
  • 一次在目標流程中反序列化Parcel

Android 8使用分散收集優化功能將副本數從3減少到1。 Parcel先在Parcel中序列化數據,數據保留了其原始結構和內存佈局,並且驅動程序立即將其複製到目標進程。數據進入目標進程後,其結構和內存佈局相同,並且可以讀取數據而無需其他副本。

細粒度鎖定

通用4.4及更高版本,包括上游

在以前的Android版本中,綁定程序驅動程序使用全局鎖來防止對關鍵數據結構的並發訪問。儘管鎖的爭用最少,但是主要問題是,如果低優先級線程獲得了鎖然後被搶占,則可能嚴重延遲需要獲得同一鎖的高優先級線程。這在平台中造成了麻煩。

解決此問題的最初嘗試包括在持有全局鎖的同時禁用搶占。但是,這更多的不是真正的解決方案,而是最終被上游拒絕並丟棄。隨後的嘗試著重於使鎖定更細粒度,自2017年1月以來,該版本已在Pixel設備上運行。儘管大多數更改已公開,但後續版本進行了實質性改進。

在確定細粒度的鎖定實現中的小問題之後,我們設計了一種具有不同鎖定架構的改進解決方案,並在所有通用內核分支中提交了更改。我們將繼續在大量不同的設備上測試該實現;由於我們不知道有任何未解決的問題,因此這是Android 8隨附設備的推薦實現。

實時優先級繼承

Common-4.4和Common-4.9(即將推出)

綁定程序驅動程序始終支持良好的優先級繼承。隨著Android中越來越多的進程以實時優先級運行,在某些情況下,現在有意義的是,如果實時線程進行綁定程序調用,則處理該調用的進程中的線程也將以實時優先級運行。為了支持這些用例,Android 8現在在活頁夾驅動程序中實現了實時優先級繼承。

除了事務級優先級繼承外, 節點優先級繼承還允許節點(活頁夾服務對象)指定最低優先級,在該最低優先級上應執行對該節點的調用。早期版本的Android已經支持具有良好值的節點優先級繼承,但是Android 8增加了對實時調度策略節點繼承的支持。

用戶空間變更

Android的8包含了所有用戶空間的變化需要工作在有一個例外的通用內核當前綁定驅動:原來實施禁用實時優先繼承權/dev/binder使用的IOCTL 。隨後的開發將優先級繼承的控制切換為每個綁定器模式(而不是每個上下文)的更細粒度的方法。因此,ioctl不在Android通用分支中,而是在我們的通用內核中提交

此更改的結果是默認情況下每個節點都禁用實時優先級繼承。 Android性能團隊發現,為hwbinder域中的所有節點啟用實時優先級繼承是hwbinder 。為了達到相同的效果,請在用戶空間中選擇此更改

通用內核的SHA

要對綁定程序驅動程序進行必要的更改,請同步至相應的SHA:

  • 普通3.18
    cc8b90c121de ANDROID:活頁夾:不檢查恢復時的prio權限。
  • 通用4.4
    76b376eac7a2 ANDROID:活頁夾:不檢查恢復時的prio權限。
  • 普通4.9
    ecd972d4f9b5 ANDROID:活頁夾:不檢查恢復時的prio權限。

使用活頁夾IPC

從歷史上看,供應商流程使用活頁夾進程間通信(IPC)進行通信。在Android 8中, /dev/binder設備節點變為框架進程專有的,這意味著供應商進程不再有權訪問它。供應商進程可以訪問/dev/hwbinder ,但是必須將其AIDL接口轉換為使用HIDL。對於希望繼續在供應商流程之間使用AIDL接口的供應商,Android支持如下所述的活頁夾IPC。

vndbinder

Android 8支持供供應商服務使用的新的綁定器域,可使用/dev/vndbinder而不是/dev/binder 。通過添加/dev/vndbinder ,Android現在具有以下三個IPC域:

IPC域描述
/dev/binder 具有AIDL接口的框架/應用程序流程之間的IPC
/dev/hwbinder 具有HIDL接口的框架/供應商流程之間的IPC
具有HIDL接口的供應商流程之間的IPC
/dev/vndbinder 使用AIDL接口的供應商/供應商流程之間的IPC

對於/dev/vndbinder出現,確保內核配置項CONFIG_ANDROID_BINDER_DEVICES設置為"binder,hwbinder,vndbinder"這是Android的通用內核樹默認值)。

通常,供應商進程不會直接打開活頁夾驅動程序,而是鏈接到libbinder用戶空間庫,後者會打開活頁夾驅動程序。為::android::ProcessState()添加方法為libbinder選擇活頁夾驅動程序。供應商進程應調用ProcessState, IPCThreadState或進行任何綁定程序調用之前先調用此方法。若要使用,請將以下調用放在供應商進程(客戶端和服務器)的main()之後:

ProcessState::initWithDriver("/dev/vndbinder");

vndservicemanager

以前,活頁夾服務已在servicemanager中註冊,可以在​​其他進程中檢索它們。在Android 8中, servicemanager現在僅由框架和應用程序進程使用,並且供應商進程無法再訪問它。

但是,供應商服務現在可以使用vndservicemanager ,這是servicemanager的新實例,它使用/dev/vndbinder而不是/dev/binder ,並且與框架servicemanager具有相同的來源。供應商流程無需進行更改即可與vndservicemanager ;當供應商進程打開/ dev/vndbinder ,服務查找將自動轉到vndservicemanager

vndservicemanager二進製文件包含在Android的默認設備makefile中。

SELinux政策

想要使用活頁夾功能相互通信的供應商流程需要以下條件:

  1. 訪問/dev/vndbinder
  2. 活頁夾{transfer, call}掛接到vndservicemanager
  3. 要通過供應商資料夾接口調用供應商域B的任何供應商域A的binder_call(A, B)
  4. vndservicemanager {add, find}服務的vndservicemanager

要滿足要求1和2,請使用vndbinder_use()宏:

vndbinder_use(some_vendor_process_domain);

為了滿足要求3,需要通過綁定器進行對話的供應商進程A和B的binder_call(A, B)可以保留在原位,並且不需要重命名。

為了滿足要求4,您必須更改服務名稱,服務標籤和規則的處理方式。

有關SELinux的詳細信息,請參見Android中的安全性增強的Linux 。有關Android 8.0中的SELinux的詳細信息,請參見適用於Android 8.0的SELinux

服務名稱

以前,供應商在service_contexts文件中處理註冊的服務名稱,並添加了訪問該文件的相​​應規則。來自device/google/marlin/sepolicy示例service_contexts文件:

AtCmdFwd                              u:object_r:atfwd_service:s0
cneservice                            u:object_r:cne_service:s0
qti.ims.connectionmanagerservice      u:object_r:imscm_service:s0
rcs                                   u:object_r:radio_service:s0
uce                                   u:object_r:uce_service:s0
vendor.qcom.PeripheralManager         u:object_r:per_mgr_service:s0

在Android 8中, vndservicemanager會改為加載vndservice_contexts文件。遷移到vndservicemanager供應商服務(已經在舊的service_contexts文件中)應該添加到新的vndservice_contexts文件中。

服務標籤

以前,在service.te文件中定義了諸如u:object_r:atfwd_service:s0類的服務標籤。例:

type atfwd_service,      service_manager_type;

在Android 8中,您必須將類型更改為vndservice_manager_type並將規則移至vndservice.te文件。例:

type atfwd_service,      vndservice_manager_type;

服務經理規則

以前,規則授予域訪問權限以從servicemanager添加或查找服務。例:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;

在Android 8中,此類規則可以保留並使用相同的類。例:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;