| RFC-0200:支援 adb 通訊協定和介面,用於硬體測試 | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 新增 adb 通訊協定和介面支援,讓 Fuchsia 裝置能與標準 adb 用戶端互動,用於硬體測試用途。 |
| 問題 | |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2022-08-24 |
| 審查日期 (年-月-日) | 2022-11-17 |
摘要
這項 RFC 建議在 Fuchsia 中新增 Android Debug Bridge (adb) 通訊協定和介面支援,以利進行硬體測試。這項功能可讓 Fuchsia 裝置與標準 ADB 用戶端互動,在目前的硬體測試工作流程中有多種應用程式。此外,ADB 支援功能也能讓我們從 Windows 主機探索 Fuchsia 裝置並與之互動,而 Fuchsia 工具目前不支援這項功能。此外,新增 adb 支援後,我們就能重複使用大部分的測試、工具和程序,這些都是圍繞 adb shell 所建構,用於硬體驗證和製造。如要新增 adb 介面支援,Fuchsia 的 USB 周邊裝置設定會更新為使用新的 adb 介面,取代 (或搭配使用) 啟用 adb 的建構版本中現有的 USB CDC 乙太網路介面。adb 通訊協定支援功能僅限於硬體驗證和製造用途中視為必要的功能。支援的 adb 服務將專屬於 Fuchsia,不會嘗試模擬 Android adb 服務。
提振精神
在硬體驗證和製造測試情境中,adb 支援功能非常實用:
- adb 周邊有許多工具、程式庫和架構 (1、2、3 等),可供重複使用。
- ADB 用戶端的預先建構二進位發布版本適用於各種平台,而且設定簡單。
- 現有的測試架構依賴 adb 提供裝置探索、連線和指令執行服務,因此無須進行任何變更即可運作。
- 由於 adb 廣受歡迎,開發人員對此工具並不陌生,且開放原始碼社群也提供廣泛支援。
- 透過在目前不支援的環境 (例如 Windows) 中建立 overnet 連線通道,進一步擴展
ffx的用途。Windows 適用的 adb 經過充分測試,且廣為使用,而 adb Windows 驅動程式庫可從 Google 輕鬆取得並安裝。 - adb 支援以 USB 周邊裝置為基礎的探索和通訊,與 Fuchsia 目前使用的以 mDNS 為基礎的探索相比,延遲時間較短。縮短延遲時間對於製造業應用情境非常重要。
考量到 adb 是一種輕量且通常穩定的工具,因此很適合加入 Fuchsia 工具組。
利害關係人
協助人員:
leannogasawara@google.com
審查者:
- curtisgalloway@google.com
- rdzhuang@google.com
- gkalsi@google.com
- prashanthsw@google.com
- jeremymason@google.com
- surajmalhotra@google.com
已諮詢:
- palmer@google.com
社交化:開發概念驗證,並與相關利害關係人討論。
設計
本文中的「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「MAY」和「OPTIONAL」等關鍵字,應按照 IETF RFC 2119 的說明解讀。
總覽
Android Debug Bridge (adb) 主要由三部分組成:用戶端、伺服器和精靈。用戶端和伺服器會在主體機器上執行,並透過通訊端互相通訊。adb Daemon (adbd) 會在裝置上執行,並通常透過 USB 連線至 adb 伺服器。adb Daemon 與伺服器之間的通訊是在 adb 通訊協定中定義。
如要讓 adb 探索 Fuchsia 裝置,我們必須公開新的 USB adb 介面。如要達成這個目標,必須更新 USB 周邊裝置設定,並編寫新的 USB ADB 函式驅動程式庫。主機上執行的 ADB 伺服器會透過這個介面連線至裝置。連線後,adb 伺服器會在 USB adb 介面上傳送/接收 adb 通訊協定訊息,並由 USB adb 函式驅動程式庫提供支援。如要編碼/解碼這些 ADB 通訊協定訊息,我們需要編寫 ADB Daemon 元件。視要求服務而定,ADB Daemon 會將要求轉送至適當的元件。我們可能必須編寫新的 ADB 服務元件,才能在現有元件和 ADB Daemon 之間建立連線。我們只打算支援部分 adb 指令 (請參閱 adb 服務)。 下圖說明建議的 ADB 軟體堆疊:

以下各節將詳細說明每個部分。
ADB 介面和裝置探索
adb 僅適用於支援 USB 周邊裝置模式的 Fuchsia 開發板。如要將 adb 支援功能納入 Fuchsia 產品,產品設定必須包含 adb 封裝,並設定啟動引數來指定 USB adb 介面。根據預設,adb 介面只會在硬體測試產品中啟用。使用者或正式版建構作業不應啟用 adb,以限制這些建構作業的攻擊面。
Fuchsia 的 USB 周邊裝置設定將更新為使用新的 adb 介面,取代 (或搭配使用) 啟用 adb 的建構版本中現有的 USB CDC 乙太網路介面。新介面將遵循 adb 介面規定:
- USB 類別:
vendor - USB 子類別:
0x42 - 通訊協定:
1
主機上執行的 adb 伺服器會不斷輪詢新的 USB 裝置,尋找符合上述屬性的介面描述元。如果找到,就會記下 USB 裝置描述元中提及的 USB 序號,並用來識別裝置。ADB 用戶端會使用這個序號將要求傳送至裝置。在 Fuchsia 上,這個序號是由開機載入程式傳遞,或是從 MAC 位址衍生而來,或是硬式編碼的回溯序號,視可用的順序而定。
USB adb 函式驅動程式庫
這個驅動程式庫負責處理 ADB 介面的 USB 要求。這個驅動程式庫只會負責計算 USB 封包和回呼。
adb 元件
這個元件會解讀 adb 通訊協定,並負責剖析訊息,然後將訊息轉送至適當的服務。
adb 服務
當 ADB 用戶端將指令傳送至 ADB 伺服器時,伺服器可能會向 Daemon 發出要求,連線至裝置上的服務,例如殼層或記錄器服務。adb Daemon 會查看已註冊的服務供應商清單,找出相符項目。如果相符,註冊的服務供應商會要求使用 Zircon 通訊端。adb 精靈會將 adb 用戶端與服務相關的所有通訊內容轉送至這個通訊端。要求的服務範例包括殼層、Logcat、通訊埠轉送和同步處理檔案。這個概念是為每項服務提供獨立元件,藉此支援這些服務。舉例來說,我們可以建立 adb-shell 元件,開啟 Dash 殼層並管理 adb 傳輸和 Dash 殼層之間的 pty 裝置通訊;我們也可以建立 adb-ffx 元件,協助連結 adb 傳輸和 overnet。服務清單
服務和 adb 元件之間的介面可能位於下列程式碼行:
// Max length of arguments passed in adb OPEN message.
const MAX_ARGS_LENGTH uint64 = 1024
/// A Provider is a provider for one service.
/// The interaction between the adb daemon and Provider is as follows:
/// - adb daemon is started eagerly by core.cml
/// - When an request for a service comes in, adb daemon starts up a lazy component serving
/// Provider and calls ConnectToService, handing it a socket.
/// - If the service has already been started, it opens that service and hands it a socket.
/// - adb daemon and Provider communicate over the socket.
@discoverable
protocol Provider {
/// Connect `socket` to the service (called in response to adb OPEN message).
/// `args` provides additional arguments passed by the client if any.
ConnectToService(resource struct {
socket zx.handle:SOCKET;
args string:<MAX_ARGS_LENGTH, optional>;
}) -> (struct {}) error zx.status;
};
adb 通訊協定指定了多項服務,但我們只打算支援其中一部分,包括 shell、logcat、sync (適用於 adb push/pull)。這些服務可能無法模擬其他平台上的 adb 所有行為,且會針對 Fuchsia 進行調整,例如 Shell 指令必須符合 Fuchsia 支援的指令,而記錄檔可能採用 Fuchsia 系統記錄檔格式。下一節將詳細說明 adb shell 服務。日後是否支援更多服務,將視個別情況而定。
ADB 服務範例:adb shell
本節將以 ADB 殼層服務為例,說明 ADB 服務與 ADB Daemon 之間的互動。adb shell 元件會透過 dash
launcher
服務,將 adb shell I/O 橋接至 dash shell I/O,藉此提供 adb shell 服務。根據預設,adb-shell.cm 會提供類似於透過 sshd-host.cm 使用 ffx component
explore 的殼層,或是功能更受限的殼層。如果我們在 Fuchsia 中遷移至不同的使用者介面,adb-shell 也可以遷移至該介面。如要限制特定產品設定和用途的功能,可以使用功能受限的自訂殼層供應器取代這個元件。這與使用 ffx component
explore <specific-moniker> 類似。
每當使用者要求新的 adb shell 例項時,adb daemon 就會要求新的 adb shell 工作階段 (因此也會要求新的 dash 工作階段)。從 adb 用戶端或 Dash 關閉連線會終止整個工作階段。互動順序如下列順序圖所示:

驗證和加密
adb 通訊協定支援使用 RSA 金鑰組進行驗證。此外,還支援 TLS 加密。 這兩項功能都是選用項目。在初始實作階段,這些功能不會實作,因為預期用途僅限於在受限環境中執行的開發人員或測試版本。此外,由於系統只支援 USB 傳輸,因此在某種程度上會限制攻擊方法。如果日後支援這些功能,則必須單獨更新 ADB Daemon。
維護
系統將支援目前的 adb 通訊協定版本 0x01000000。日後對通訊協定的更新將視情況而定。adb 通訊協定不會經常變更,而且一向具備回溯相容性。
實作
導入作業可分為三個部分。
- 在不同開發板和建構版本中新增支援。
- adb daemon
- 部分內容會在 OSRB 核准後,從 Android 程式碼集匯入。
- adb 服務
- 目前計畫支援
adb-shell和adb-ffx。 - 如果必須支援其他指令,這個階段可能會延長。
- 目前計畫支援
目前已有概念驗證,可做為實作參考。
效能
運算影響:新增 ADB 支援功能後,應該不會造成顯著的運算負荷。ADB 會取代 SSH 精靈和/或 overnetstack,兩者都依賴類似的驅動程式和元件,因此系統的整體 CPU 使用率應該會維持不變。
對大小的影響:加入 ADB Daemon 和服務後,圖片大小會增加約 1 MB。請注意,這僅適用於使用 ADB 支援組裝的開發和測試版本。由於系統會使用 adb,而非現有工具,因此執行階段記憶體用量應該不會受到重大影響。
延遲時間:由於沒有額外的網路堆疊,adb 的指令處理延遲時間會比 ssh 或其他網路服務稍短。裝置探索延遲時間預計也會縮短,因為這是以 USB 列舉為基礎,而不是像 mDNS 一樣定期廣播。
回溯相容性
這項問題有三個部分,其中一個是 adb 通訊協定本身的向後相容性,這超出 Fuchsia 專案的控制範圍。不過,adb 通訊協定目前仍維持回溯相容性。其次,支援的 adb 服務 - 服務淘汰會影響依附這些服務的主機端指令/指令碼。進行這類變更時,必須採用適當的遷移策略。第三個是殼層指令。舉例來說,假設 CLI xyz-tool 已淘汰,執行 adb shell xyz-tool 的指令碼將無法運作。這項問題屬於 Fuchsia 工具的範圍,並非 adb 專屬,因此不會解決。
安全性考量
至於 adb 傳輸的安全性考量,則有啟用驗證和加密的規定。但這些功能不會在初步實作階段啟用。由於 adb 僅適用於特定版本 (例如開發人員版本或測試版本),不適用於使用者版本,因此這應該不是主要問題。
透過 adb 公開的服務在安全性方面與 Fuchsia 現有服務並無不同。該 adb-shell / adb-ffx 公開的互動介面與 dash-shell /ffx 相同或較小。在特定用途中,您可以從 adb-shell 替換為 custom-shell,使用針對該用途量身打造的緊密範圍殼層。
初始實作僅支援 USB 傳輸。與網路連線相比,這會限制可能的攻擊方法。此外,adb Daemon 本身就是一個元件,因此其中的任何安全漏洞都會受到沙箱限制,只會影響 adb 作業。
隱私權注意事項
adb 服務公開的資料與 ffx component explore 或 SSH 相同,兩者都經過隱私權疑慮審查。此外,這項技術僅限於開發人員或測試版本,不會部署在使用者/正式版中。不過,USB ADB 介面會公開裝置序號,而這個序號與其他 USB 介面 (例如 CDC 乙太網路介面) 使用的序號相同。如果不是從 MAC 位址衍生而來,這項設定大多是由開機載入程式設定。設定產品時,請務必謹慎,不要直接使用具有重大重要性的裝置 ID。
測試
adb 堆疊的所有部分都會經過單元測試。最終會加入 adb 精靈和 adb 服務之間的整合測試。由於 adb 子系統之間的合約是以 FIDL 為基礎 (USB adb 驅動程式庫除外),因此測試可以密封。裝置列舉測試將新增至 USB adb 介面。如有需要,系統會新增 adb 的主機端 E2E 測試。如果是端對端測試,我們可能需要在測試主機上安裝 adb。E2E 測試 / 整合測試可用於效能測試和指令延遲測試。頻繁插拔 USB 進行 ADB 連線的週期性壓力測試,將納入可靠性測試。也會考慮對 adb 精靈實作項目進行模糊測試。
說明文件
需要新增的文件如下:
- 支援的 adb 功能清單
- 擴充 adb 服務的指南
- 使用手冊
缺點、替代方案和未知事項
支援 adb 需要維護成本,如果同時使用 ffx 和 adb 這兩組工具進行通訊和裝置控制,會造成額外負擔。雖然這兩項產品的功能會重疊,但用途不同,且會共用相同的後端實作項目。ffx 適用於各種開發人員工作流程,但目前在主機端指令碼和多樣化平台支援方面有限制。adb 可用於填補這些硬體測試的缺口。在 ffx 和 adb 之間共用裝置上的服務,可進一步降低維護成本。舉例來說,您也可以搭配 adb 使用 dash 啟動器、overnetstack、記錄檔接收器等。
替代方案:將 ffx 移植到 Windows
目前這項功能面臨的阻礙是取得 Windows 的 Rust 工具鍊支援,以及將 USB 連結新增至 ffx。此外,依賴 adb 的現有測試架構必須改用 ffx,或在 adb 和 ffx 之間提供轉譯墊片。這項策略日後可能會重新檢討。在開發 Windows 版 ffx 的過程中,adb 提供便利的解決方案。
替代方案:在 Linux 虛擬機器中執行主機端 ffx
在 Windows 上執行 Linux 虛擬機器(VM),並傳遞裝置 USB 連線。完成這項設定後,現有的 ffx 工作流程就能用於裝置探索和互動。但設定 VM 所需的時間可能很長,而且設定過程可能不穩定/不可靠。此外,部分機構會限制在受管理 Windows 電腦上使用 VM。使用 Docker 容器也是一種替代方案,但 USB 轉送功能可能無法運作,具體情況取決於 Windows 版本。
替代方案:USB 序列埠
在 Fuchsia 中新增對 USB CDC ACM 周邊裝置的支援。Windows 內含 USB 序列驅動程式庫程式,適用於任何 USB CDC ACM 介面。這可讓我們將 USB 連接埠當做序列通訊裝置使用。這種方法的缺點是缺乏豐富的指令集 (只有 shell 可用)、沒有記錄檔和 shell 分隔,以及支援單一執行個體。此外,您也必須更新以 adb 為基礎的現有測試架構。
既有技術和參考資料
- ADB 總覽 - ADB 用戶端、伺服器和 Daemon 總覽
- adb 通訊協定 - adb 訊息類型和欄位
- Android 上的 adb - Android adb 實作