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,因為 ADB 廣受歡迎,且開放原始碼社群也提供廣泛的支援。
- 它可以透過在目前不支援的環境 (例如 Windows) 中建立 overnet 通道,進一步擴展
ffx
的用途。Windows 版 ADB 經過充分測試且廣泛使用,而且您可以從 Google 安裝 ADB Windows 驅動程式庫。 - 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) 由三個主要部分組成:用戶端、伺服器和 Daemon。用戶端和伺服器會在主機上執行,並透過 Socket 彼此通訊。ADB 守護程序 (adbd) 會在裝置上執行,通常會透過 USB 連線至 ADB 伺服器。ADB Daemon 與伺服器之間的通訊是在 adb 通訊協定中定義。
為了讓 ADB 偵測 Fuchsia 裝置,我們必須公開新的 USB ADB 介面。為此,您必須更新 USB 周邊裝置設定,並編寫新的 USB ADB 函式驅動程式庫。在主機上執行的 ADB 伺服器會透過這個介面連線至裝置。連線後,ADB 伺服器會在 USB ADB 函式驅動程式支援的 USB ADB 介面上傳送/接收 ADB 通訊協定訊息。如要對這些 ADB 通訊協定訊息進行編碼/解碼,我們需要編寫 ADB 守護程式元件。視要求的服務而定,adb 守護程序會將要求轉送至適當的元件。我們可能必須編寫新的 ADB 服務元件,以便在現有元件和 ADB 守護程序之間建立連線。我們只打算支援部分 ADB 指令 (請參閱「ADB 服務」)。下圖說明建議的 ADB 軟體堆疊:
下列各節將詳細說明各個部分。
ADB 介面和裝置探索
adb 僅適用於支援 USB 周邊裝置模式的 Fuchsia 主機板。為了在 Fuchsia 產品中加入 ADB 支援,產品設定必須包含 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 提出要求,要求連線至裝置上的服務,例如 Shell 或記錄器服務。ADB 守護程序會查看已註冊的服務供應者清單,找出符合條件的供應者。如果相符,已註冊的服務供應器會要求 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 通訊協定指定了幾項服務,但我們只打算支援其中的一部分,包括殼層、Logcat 和同步處理 (針對 ADB 推送/拉取)。這些服務可能無法模擬其他平台上的所有 ADB 行為,且會針對 Fuchsia 進行調整,例如殼層指令必須與 Fuchsia 支援的指令相符,而記錄可能會採用 Fuchsia 系統記錄格式。下一節將詳細討論 ADB 殼層服務。我們會視情況考慮日後新增更多服務的支援功能。
ADB 服務範例:ADB 殼層
本節將以 ADB 殼層服務為例,說明 ADB 服務與 ADB 守護程序之間的互動情形。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 殼層例項時,ADB 守護程序就會要求新的 ADB 殼層工作階段 (因此也會要求新的 Dash 工作階段)。從 ADB 用戶端或 Dash 關閉連線,會關閉整個工作階段。下圖顯示互動順序:
驗證和加密
adb 通訊協定支援使用 RSA 金鑰組進行驗證。也支援 TLS 加密。這兩項功能皆為選用功能。在初始導入階段,我們不會導入這些功能,因為這些功能的預期用途僅限於在受限環境中執行的開發人員或測試版本。此外,由於 USB 是唯一支援的傳輸方式,因此可在某種程度上限制攻擊方法。日後,如果這些功能獲得支援,則必須只對 ADB 守護程序進行更新。
維護
系統將支援目前的 ADB 通訊協定版本 0x01000000
。我們會視個別情況更新這份通訊協定。ADB 通訊協定不會經常變更,且一向向後相容。
實作
實作方式可分為三個部分。
- 在不同電路板和版本中新增支援功能。
- ADB Daemon
- 在 OSRB 核准後,部分內容會從 Android 程式碼庫匯入。
- ADB 服務
- 目前的計畫是支援
adb-shell
和adb-ffx
。 - 如果需要支援其他指令,這個階段可能會延長。
- 目前的計畫是支援
目前已完成概念驗證,可做為導入作業的參考依據。
成效
運算影響:新增 ADB 支援後,不應有任何重大的運算額外負擔。系統將使用 ADB 取代 ssh 守護程式和/或 overnetstack,因為這兩者都依賴類似類型的驅動程式和元件,因此系統的整體 CPU 用量應保持不變。
對大小的影響:由於新增 ADB 守護程序和服務,圖片大小會增加約 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 殼層替換為自訂殼層,藉此使用為該用途量身打造的殼層。
初始實作僅支援 USB 傳輸。與網路連線相比,這可限制可能的攻擊方法。此外,adb 守護程序本身就是一個元件,因此其中的任何漏洞都會被隔離到該特定程序,並只影響 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 測試 / 整合測試可用於效能測試和指令延遲時間測試。我們會定期進行 adb 連線能力的壓力測試,方法是經常插入/拔除 USB 裝置,以便進行可靠性測試。我們也會考慮對 ADB 守護程式實作內容進行模糊測試。
說明文件
您需要新增下列文件:
- 支援的 ADB 功能清單
- 擴充 ADB 服務的指南
- 使用手冊
缺點、替代方案和未知事項
支援 ADB 需要支付維護費用。使用兩組工具進行通訊和裝置控制 (即 ffx
和 ADB) 會產生額外負擔。雖然這兩者會有重疊的功能,但各自的用途不同,且會共用相同的後端實作。ffx
可滿足各種開發人員工作流程的需求,但目前在主機端指令碼和各種平台支援方面有限制。adb 可用於填補硬體測試的這些缺口。您可以將裝置上的服務共用於 ffx
和 ADB 之間,進一步降低維護成本。舉例來說,Dash Launcher、overnetstack、記錄匯入器等也可以與 ADB 搭配使用。
替代方案:將 ffx 移植至 Windows
目前的障礙是讓 Rust 工具鍊支援 Windows,並將 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 連接埠用作序列通訊裝置。這種方法的缺點是缺乏豐富的指令集 (僅提供殼層)、不分割記錄和殼層,且不支援單一例項。此外,您也必須更新現有的 ADB 測試架構。
既有技術與參考資料
- adb 總覽 - ADB 用戶端、伺服器和 Daemon 的總覽
- ADB 通訊協定:ADB 訊息類型和欄位
- Android 上的 adb - Android adb 實作