RFC-0200:支援 ADB 通訊協定與硬體測試介面

RFC-0200:支援用於硬體測試的 ADB 通訊協定和介面
狀態已接受
區域
  • 開發人員
  • 測試
說明

新增 ADB 通訊協定和介面支援,讓 Fuchsia 裝置與 ADB 用戶端互動,以便進行硬體測試。

問題
變更
作者
審查人員
提交日期 (年/月)2022-08-24
審查日期 (年/月)2022-11-17

摘要

這個 RFC 建議在 Fuchsia 中新增 Android Debug Bridge (ADB) 通訊協定和介面支援,以便進行硬體測試。這會讓 Fuchsia 裝置與庫存 ADB 用戶端 (在目前的硬體測試工作流程中具有數個應用程式) 互動。ADchsia 支援也可以讓我們探索 Windows 主機的 Fuchsia 裝置,但 Fuchsia 工具目前不支援這類裝置。此外,新增對 ADB 的支援,讓我們可重複使用以 adb shell 為中心建構的大多數測試、工具和程序,以進行硬體驗證和製造作業。為了新增 ADB 介面支援,Fuchsia 的 USB 週邊裝置設定將更新為使用新的 ADB 介面,在啟用 ADB 的版本中取代 (或搭配使用) 現有的 USB CDC 乙太網路介面。ADB 通訊協定支援僅限於硬體驗證和製造用途所需的功能。ADchsia 支援的功能將限定在 Fuchsia 產品,不會嘗試模仿 Android ADB 服務。

提振精神

在硬體驗證和製造測試情境中,ADB 支援非常有用:

  • 有許多以 ADB (123 等) 為建構基礎的工具、程式庫和架構可以重複使用。
  • 各種平台的 ADB 用戶端預先建構的二進位檔發布已廣泛提供且容易設定。
  • 目前使用 ADB 提供裝置探索、連線和指令執行服務的測試架構仍可運作,而無需進行任何變更。
  • 由於 ADB 廣受開發人員歡迎,而且支援開放原始碼社群,因此開發人員相當熟悉。
  • 在 Windows 等目前不支援的環境中,通道可建立 overnet 連線,藉此進一步擴充 ffx 的用途。ADB 版 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

社交化:我們向相關利害關係人開發並討論概念,

設計

本文件中的重要字詞「必須」、「不得」、「必要」、「應」、「不應」、「應該」、「不應該」、「建議」、「可能」和「選用」均適用 IETF RFC 2119 描述。

總覽

Android Debug Bridge (ADB) 由三個主要部分組成:用戶端、伺服器和 Daemon。用戶端和伺服器會在主機機器上執行,並透過通訊端彼此通訊。ADB Daemon (ADBd) 會在裝置上執行,通常會透過 USB 連線至 ADB 伺服器。ADB Daemon 與伺服器之間的通訊是在 ADB 通訊協定中定義。

為了讓 ADB 探索 Fuchsia 裝置,我們必須公開新的 USB ADB 介面。為此,USB 週邊裝置設定必須更新,並且必須編寫新的 USB ADB 函式驅動程式庫。在主機上執行的 ADB 伺服器會透過這個介面連線到裝置。連線後,ADB 伺服器將在由 usb ADB 函式驅動程式庫支援的 USB ADB 介面上傳送/接收 ADB 通訊協定訊息。如要對這些 ADB 通訊協定訊息進行編碼/解碼,我們必須編寫 ADB Daemon 元件。視所要求的服務而定,ADB Daemon 會將要求轉送至適當的元件。我們可能必須編寫新的 ADB 服務元件,以橋接現有元件與 ADB Daemon 之間的連線。我們打算僅支援部分 ADB 指令 (請參閱 ADB 服務)。下圖說明我們提議的 ADB 軟體堆疊:

替代文字:顯示裝置上的 USB ADB 堆疊:裝置上 - 新驅動程式庫 usb-adb 功能驅動程式庫,已新增至 usb-peripheral 驅動程式庫。新增一個 adb.cm 元件是 usb-adb-function 驅動程式庫。出現 ADB.cm 上面還有許多新服務,包括 ADB-shell.cm、adb-ffx.cm 等。在主機上 - Stock ADB 用戶端和 ADB 伺服器透過 USB 主機堆疊與裝置互動

以下各節將詳細說明各個部分。

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 Daemon 會將與服務相關的所有通訊從 ADB 用戶端轉送至這個通訊端。系統要求的服務包括殼層、logcat、通訊埠轉送和檔案同步處理。我們希望藉由支援這些服務的不同元件來支援這些服務。舉例來說,我們可以提供 adb-shell 元件,用來開啟破折號殼層,並管理 ADB 傳輸與 Dash shell 之間的 Pty 裝置通訊;我們也可以提供 ADB-ffx 元件來連結 ADB 傳輸和超網路。服務清單

服務和 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 通訊協定會指定數個服務,不過我們只支援部分方法,包括殼層、Logcat、sync (用於 ADB 推送/提取)。這些服務可能無法模擬其他平台上的 ADB 所有行為,因此會針對 Fuchsia 加以自訂,例如,殼層指令必須和 Fuchsia 支援的指令相符,而記錄則可能是 Fuchsia 系統記錄格式。下一節將詳細說明 ADB 殼層服務。我們日後會考慮為更多服務新增支援情況。

ADB 服務範例:adb shell

本節將考慮 ADB 殼層服務的範例,說明 ADB 服務與 ADB Daemon 之間的互動。ADB 殼層元件將負責提供 ADB 殼層服務,方法是透過破折號啟動器服務,將 ADB 殼層 I/O 連結到 dash shell I/O。根據預設,adb-shell.cm 會提供一個殼層,類似於透過 sshd-host.cm 使用 ffx component explore 或功能較多的殼層。如果我們在 Fuchsia 中遷移至其他使用者介面,也可以將 ADB 殼層遷移至該介面。如要限制特定產品設定和特定用途的功能,功能有限的自訂殼層供應商可以替換這個元件。與使用 ffx component explore <specific-moniker> 類似。

每當使用者要求新的 ADB 殼層執行個體時,ADB Daemon 就會要求新的 ADB 殼層工作階段,進而建立新的破折號工作階段。如果關閉 ADB 用戶端或破折號的連線,都會關閉整個工作階段。互動順序如以下序列圖表所示:

替代文字:顯示 ADB 殼層序列圖表:在主機上,ADB 用戶端會透過 adb 伺服器傳送「adb shell」訊息到 adb 伺服器。接著,adb 伺服器會將 OPEN (shell) 通訊協定訊息傳送至裝置上的 adb.cm。adb.cm 會根據預先設定的 service-元件重建,在 adb-shell.cm 啟動 adb-shell.cm,透過 adb-turn.cm.

驗證與加密

ADB 通訊協定支援使用 RSA 金鑰組進行驗證。此外,這項產品也支援 TLS 加密。這兩項功能皆為選用。初始實作項目不會實作這些功能,因為只有在受限制環境中執行的開發人員或測試版本才會實作這些功能。此外,由於 USB 是唯一支援的傳輸方式,因此會限制攻擊方式的一些程度。日後如要獲得支援,就必須只對 ADB Daemon 進行更新。

維護

支援目前的 ADB 通訊協定版本 0x01000000。日後的通訊協定更新將視個案情況而定。已知 ADB 通訊協定不常變更,且始終回溯相容。

實作

實作可分為三個部分。

  • 新增不同主面板和版本的支援。
  • ADB Daemon
    • OSRB 核准之後,系統會從 Android 程式碼集匯入部分的部分內容。
  • ADB 服務
    • 目前的方案將支援「adb-shell」和「adb-ffx」。
    • 如果裝置必須支援其他指令,可能會延長這個階段。

目前已有概念驗證,日後會做為實作的參考資料。

效能

運算影響:新增 ADB 支援應該不會對運算負擔造成大量的運算負擔。將使用 ADB 取代 SSH Daemon 和/或 overnetstack,兩者皆依賴類似的驅動程式和元件類型,因此系統的整體 CPU 用量應維持不變。

對大小的影響 - 加入 ADB Daemon 和服務,大小約為 1 MB。請注意,這僅適用於與 ADB 支援組合的開發和測試版本。由於系統會使用 ADB (而非現有工具),因此不會對執行階段記憶體用量造成任何重大影響。

延遲:由於沒有額外的網路堆疊,ADB 中的指令處理延遲時間會比 SSH 或其他網路型服務的延遲時間稍長。裝置探索延遲時間預期會比以 USB 列舉為基礎的更小,而不是像 mDNS 中的定期廣播訊息一樣。

回溯相容性

其分為三個部分:一個是 ADB 通訊協定本身的回溯相容性,超出 Fuchsia 專案的控管範圍。無庸置疑的是,ADB 通訊協定仍具回溯相容性。其次,支援 ADB 服務 (淘汰服務) 會影響依賴這些元件的主機端指令/指令碼。進行這類變更時,必須使用適當的遷移策略。第三是殼層指令舉例來說,淘汰假設的 CLI xyz-tool,執行 ADB 殼層 xyz-tool 的指令碼將無法運作。這個問題位於 Fuchsia 工具的涵蓋範圍內,且不屬於 ADB,因此不會處理。

安全性考量

針對 ADB 傳輸的安全性考量,我們有啟用驗證和加密功能的相關條款。但是在初始實作期間不會啟用這些功能。由於 ADB 只能在特定版本 (例如開發人員版本或測試版本) 中提供,因此使用者版本不應如此。

對於透過 ADB 公開的服務的安全性考量,這些內容與 Fuchsia 上的現有服務並無不同。該 adb-shell / adb-ffx 公開的互動介面與 dash-shell /ffx 的途徑相同,或較小。對於特定用途,您可以將殼層提供者從 adb-shell 替換為自訂殼層,藉此使用限定範圍的殼層。

初始實作僅支援 USB 傳輸。相較於以網路為基礎的連線,這種做法會限制可能的攻擊方法。此外,ADB Daemon 本身是元件,因此會受制於特定程序的沙箱機制,只會影響 ADB 作業。

隱私權注意事項

ADB 服務公開的資料與 ffx component explore 或 SSH 資料相同,兩者都會經過審查以滿足隱私權疑慮。此外,這項技術將僅限於開發人員或測試版本,而且不會部署在使用者/正式版中。USB ADB 介面會公開裝置序號,而這與用於 CDC 乙太網路介面等其他 USB 介面的序號相同。這主要由系統啟動載入程式設定 (如果不是從 MAC 位址衍生),設定產品時,請務必小心,以免直接使用重要性高的裝置 ID。

測試

ADB 堆疊的所有部分都會經過單元測試。最後,系統將新增 ADB Daemon 和 ADB 服務之間的整合測試。由於 ADB 子系統之間的合約是以 FIDL 為基礎 (USB ADB 驅動程式庫除外),因此測試可能十分密封。即將新增 USB ADB 介面的裝置列舉測試。如有需要,系統會新增 ADB 的主機端 E2E 測試。針對 E2E 測試,我們可能需要在測試主機機器上安裝 ADB。E2E 測試 / 整合測試可用來進行效能測試和指令延遲測試。經常插頭/拔除 USB 傳輸線的 ADB 連線效能測試將視為可靠性測試。系統也會考慮 ADB Daemon 實作的模糊作業。

說明文件

您必須新增這些文件:

  • 支援的 ADB 功能清單
  • 擴充 ADB 服務指南
  • 使用手冊

缺點、替代方案和未知

支援 ADB 需要維護。擁有兩組通訊與裝置控制的工具組合 (也就是 ffx 和 ADB) 會產生負擔。雖然這兩項功能具有重疊的功能,但兩者的用途不同,且共用相同的後端實作。ffx 支援各種開發人員工作流程,但目前在主機端指令碼和各種平台支援方面有限。ADB 可用於填補這些缺漏的硬體測試空間。在 ffx 和 ADB 之間共用裝置上的服務,可以進一步降低維護成本。例如破折號啟動器、超網路堆疊、記錄接收器等,也可與 ADB 搭配使用。

替代方法:從 ffx 通訊埠轉移至 Windows

目前,這些障礙會取得 Windows 的 Rust 工具鍊支援,並將 USB 連結新增至 ffx。此外,仰賴 ADB 的現有測試架構將必須更改為使用 ffx,或者必須在 ADB 和 ffx 之間提供翻譯填充碼。這項策略日後可以再回頭審視。ADB 提供了便利的解決方案,同時針對 Windows 開發 ffx

替代方法:在 Linux 虛擬機器中執行主機端 ffx

使用在 Windows 上執行的 Linux 虛擬機器(VM),並通過裝置 USB 連線。使用此設定時,現有的 ffx 工作流程將適用於裝置探索和互動操作。不過,設定 VM 所需的時間可能相當龐大,因此可能不穩定/可靠。此外,有些機構會限制在代管 Windows 機器上使用 VM。您也可以使用 Docker 容器,但 USB 轉送可能視 Windows 版本而定。

替代方法:USB 序列

為 Fuchsia 新增 USB CDC ACM 週邊裝置支援。Windows 隨附一個 USB 序列驅動程式庫程式,適用於任何 USB CDC ACM 介面。這可讓我們使用 USB 連接埠做為序列通訊裝置。使用這種方法的缺點,缺少豐富指令集 (只能使用殼層)、沒有將記錄與殼層分隔,也不支援單一執行個體。此外,現有的測試架構也必須更新以 ADB 為基礎的。

先前的圖片和參考資料