使用繫結器處理序間通訊 (IPC)

本頁說明 Android 8 中繫結器驅動程式的異動,並提供 並列出必要的 SELinux 政策。

繫結器驅動程式的變更

從 Android 8 開始,Android 架構和 HAL 現在能夠與 透過繫結器互相連線因為這種通訊方式大幅增加了繫結機制 則 Android 8 提供多項改善以保留繫結器處理序間通訊 (IPC) 快速SoC 供應商和原始設備製造商 (OEM) 應直接從以下位置的相關分支機構併用: android-4.4、android-4.9 以上版本 corenel/common 專案。

多個繫結器網域 (情境)

Common-4.4 以上,包括上游

為了在架構之間正確拆分繫結器流量 (獨立於不同裝置),並 供應商 (裝置專屬) 程式碼,Android 8 導入了「繫結器」這個繫結器的概念 背景資訊。每個繫結器結構定義都有專屬的裝置節點和背景資訊 (服務) 管理員。您只能透過裝置存取 Context Manager 自身所屬節點,且當透過特定 Pod 傳遞繫結器節點時 內容,只能由另一個程序從相同的內容存取,因此 將網域完全區隔開來如要進一步瞭解如何使用 vndbinder 和 「vndservicemanager」

散佈圖

Common-4.4 以上,包括上游

在先前的 Android 版本中,系統會複製繫結器呼叫中的所有資料 三次:

  • 將其序列化為 Parcel 能在通話流程中
  • 進入核心驅動程式後,將 Parcel 複製到目標 處理程序
  • 一次在目標程序中將 Parcel 取消序列化後。

Android 8 用途 散集散播者 最佳化,將副本數量從 3 個減少為 1 個。而不是 首先在 Parcel 中將資料序列化,則資料會保持原始狀態 結構和記憶體配置,以及驅動程式立即將其複製到目標 上傳資料集之後,您可以運用 AutoML 自動完成部分資料準備工作資料進入目標程序後,結構和記憶體就會 兩者相同,而且不需另一份複製即可讀取資料。

精細鎖定

Common-4.4 以上,包括上游

在先前的 Android 版本中,繫結器驅動程式使用全域鎖定來保護 並行存取重要資料結構儘管 AI 確實進行了 鎖定爭用到,主要問題在於,如果執行緒優先順序低的執行緒 取得門鎖然後又遭到先佔,它就可能嚴重延遲 需要取得相同鎖定的高優先順序執行緒。這導致 平台。

剛開始嘗試解決此問題涉及停用先佔功能,而 但保留通用鎖定然而,這並非真正的解決方案, 但最終遭到上游拒絕並遭到捨棄後續嘗試次數 重點是確保鎖定功能更精細, 。儘管這些變化大部分 我們已在後續版本中公開做出大幅改善的措施。

在發現精細鎖定實作方式中的小問題後,我們 設計了採用不同鎖定架構的改良版解決方案,並提交 所有常見核心分支版本的變更我們會繼續測試 並在大量不同裝置上實作因為我們不知道 待處理的問題,這是建議在裝置出貨時採用的實作方式 。

即時優先繼承

Common-4.4 和 Common-4.9 (即將推出上游程式庫)

繫結器驅動程式一律支援良好的優先順序繼承。身為 有越來越多的 Android 程序能即時優先執行,某些情況下 如果即時執行緒發出 Binder 呼叫,情況會很合理 處理該呼叫的執行緒也會在即時優先執行。目的地: 支援這些用途,Android 8 現在導入了即時優先順序繼承 放入繫結器驅動程式中

除了交易層級的優先順序繼承之外,節點優先順序還有 繼承可讓節點 (繫結器服務物件) 指定 呼叫此節點的優先順序。舊版本 Android 已支援節點優先順序繼承和好值,但 Android 8 新增對即時排程政策節點繼承的支援。

使用者空間變更

Android 8 包含與現行版本相容的所有使用者空間變更 共用核心中的繫結機制驅動程式,但有一個例外狀況:原始版本 ,以便停用 /dev/binder使用 ioctl。後續的開發工作切換到了優先順序的控制 更加精密的方法會沿用至於繫結器模式 內容)。因此,ioctl 不在 Android 通用分支版本中,而是 透過常見核心提交

這項變更的作用是停用即時優先順序沿用機制, 「每個」節點的預設值。Android 效能團隊發現 以便為 Pod 中的所有節點啟用即時優先順序繼承 hwbinder 網域。如要達到相同的效果,可以選擇使用 Cherry 這項變更

常用核心的 SHA

如要取得繫結器驅動程式所需的變更,請與適當的 SHA 同步處理:

  • 一般- 3.18
    cc8b90c121de ANDROID:繫結器:在還原時不檢查 Prio 權限。
  • Common-4.4
    76b376eac7a2 ANDROID:繫結器:在還原時不檢查 Prio 權限。
  • Common-4.9
    ecd972d4f9b5 ANDROID:繫結器:在還原時不檢查 Prio 權限。

使用繫結器處理序間通訊 (IPC)

過往廠商流程過去都使用繫結器處理序間通訊 (IPC) 通訊。在 Android 8 中,/dev/binder 裝置節點 成為架構流程獨有的,也就是說,供應商流程 就能存取該資源供應商程序可存取 /dev/hwbinder,但 必須轉換為 AIDL 介面才能使用 HIDL。適合想繼續進行的供應商 採用 AIDL 介面,因此 Android 支援繫結器處理序間通訊 (IPC) 。在 Android 10 中,穩定版 AIDL 允許所有 使用 /dev/binder,同時也解決穩定性問題 保證已解決 HIDL 和 /dev/hwbinder。如何使用穩定版 AIDL,請參閱 HAL 適用的 AIDL

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 (新的 使用 /dev/vndbinderservicemanager 執行個體 而不是 /dev/binder,而且這類建構的來源與 servicemanager 架構供應商程序不需要 變更為與「vndservicemanager」交談;供應商程序開啟時 /dev/vndbinder,服務查詢會自動導向 vndservicemanager

Android 預設值包含 vndservicemanager 二進位檔 裝置 makefile

SELinux 政策

想要使用繫結器功能通訊的供應商程序 彼此都需要下列項目:

  1. 使用 /dev/vndbinder
  2. 繫結機制 {transfer, call} 掛鉤 vndservicemanager
  3. 針對要呼叫的供應商網域 A 提供 binder_call(A, B) 透過供應商繫結器介面傳遞至供應商網域 B。
  4. 在以下位置授予 {add, find} 項服務的權限: vndservicemanager

如要符合第 1 和第 2 項規定,請使用 vndbinder_use() 巨集:

vndbinder_use(some_vendor_process_domain);

如要達成規定 3,供應商的 binder_call(A, B) 需要透過繫結器通訊的 A 和 B 程序可保持原樣,且 需要重新命名

為符合要求 4,您必須變更服務名稱、 服務標籤和規則

如要進一步瞭解 SELinux,請參閱 Security-Enhanced Android 中的 Linux。如要進一步瞭解 Android 8.0 中的 SELinux,請參閱 適用於 Android 的 SELinux 8.0。

服務名稱

過去,供應商會在 service_contexts 個檔案並新增對應的存取規則 該檔案service_contexts 範例檔案來源 device/google/marlin/sepolicy:

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 檔案。

服務標籤

過去,服務標籤,例如 u:object_r:atfwd_service:s0 是在 service.te 檔案中定義。例子:

type atfwd_service,      service_manager_type;

在 Android 8 中,您必須將類型變更為 vndservice_manager_type,並將規則移至 vndservice.te 檔案。例子:

type atfwd_service,      vndservice_manager_type;

servicemanager 規則

先前規則授予網域新增或尋找服務的權限 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;