RFC-0200:支持用于硬件测试的 adb 协议和接口

RFC-0200:支持用于硬件测试的 adb 协议和接口
状态已接受
领域
  • 开发者
  • 测试
说明

添加了 adb 协议和接口支持,以便针对硬件测试用例实现 Fuchsia 设备与原生 adb 客户端的交互。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2022-08-24
审核日期(年-月-日)2022-11-17

摘要

此 RFC 建议将 Android 调试桥 (adb) 协议和接口支持添加到 用于硬件测试的 Fuchsia。这将启用 Fuchsia 设备与库存 adb 的交互 客户端,该客户端在当前硬件测试工作流中具有多个应用。adb 支持 我们还可以通过 Windows 主机(目前 Fuchsia 工具不支持。此外,添加对 adb 的支持将使我们能够重复使用大部分 围绕 adb shell 构建的用于硬件验证和制造的测试、工具和流程。 为了添加 adb 接口支持,Fuchsia 的 USB 外围设备配置将更新为使用 新的 adb 接口,用于替换(或与)Google 上的现有 USB CDC 以太网接口 启用了 adb 的 build。adb 协议支持仅限于认定为 满足硬件验证和制造用例的要求。支持的 adb 服务将是 Fuchsia 特定版本,不会尝试模拟 Android adb 服务。

设计初衷

adb 支持在硬件验证和制造测试场景中非常有用:

  • 有几个工具、库和框架是围绕 adb 构建的 (123 等等)。
  • 适用于各种平台的 adb 客户端的预构建二进制发行版广泛提供,并且 易于设置。
  • 依赖 adb 提供设备发现、连接和命令的现有测试框架 无需进行任何更改即可运行
  • adb 广受欢迎,开发者也熟悉 adb,开源社区也支持 范围很广。
  • 它还可以通过在 Cloud Storage 中建立隧道 overnet 连接,进一步扩展 ffx 的用例。 目前不支持在 Windows 等环境下运行。适用于 Windows 的 adb 经过充分测试,应用广泛 而 adb Windows 驱动程序也可从 Google 随时获得安装。
  • adb 支持基于 USB 外设的发现和通信,与 adb 相比, 目前用于 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

社交化:与利益相关方一起制定并讨论了概念验证。

设计

关键字“必须”“不得”“必需”“会”“不会”“应”“不应” “RECOMMENDED”(推荐)、“MAY”(可以)和“OPTIONAL”(可选)定义,具体说明请参阅 IETF RFC 2119

概览

Android 调试桥 (adb) 由三个主要部分组成:客户端、服务器和守护程序。通过 客户端和服务器在主机上运行,并使用套接字相互通信。adb 守护程序 (adbd) 在设备上运行,并且通常通过 USB 连接到 adb 服务器。通过 adb 守护程序与服务器之间的通信是在 adb 协议中定义的。

为了让 adb 能够发现 Fuchsia 设备,我们将必须公开一个新的 USB adb 接口。为此,您必须更新 USB 外围设备配置 必须写入新的 USB adb 函数驱动程序。在主机上运行的 adb 服务器 通过该接口连接到设备。建立连接后,adb 服务器将发送/接收 adb 由 USB adb 函数驱动程序支持的 USB adb 接口上的协议消息。编码/解码 这些 adb 协议消息,我们需要编写一个 adb 守护程序组件。具体取决于服务 请求后,adb 守护程序会将请求转发给相应的组件。我们可能不得不 编写新的 adb 服务组件,以将现有组件与 adb 建立连接 守护进程我们打算仅支持部分 adb 命令(请参阅 adb 服务)。 下图展示了所提议的 adb 软件堆栈:

替代文本:显示的 USB adb 堆栈:在设备上 - 在顶部添加了新的驱动程序 usb-adb-function 驱动程序
USB 外围设备驱动程序。在 usb-adb-function 驱动程序的基础之上添加了新组件 adb.cm。新服务
adb.cm 之上可以存在 adb-shell.cm、adb-ffx.cm 等诸多内容。在主机上 - 库存 adb 客户端
且 adb 服务器通过 USB 主机堆栈与设备交互

以下各部分将详细介绍每个部分。

adb 接口和设备发现

adb 仅在支持 USB 外围设备模式的 Fuchsia 板上可用。为了包含 为 Fuchsia 产品提供 adb 支持,产品配置必须包含 adb 软件包并配置 boot args 以指定 USB adb 接口。默认情况下,系统会在硬件测试中启用 adb 接口 产品。不得在用户 build 或正式版 build 中启用 adb,以限制 这些构建。

Fuchsia 的 USB 外围设备配置将更新为使用新的 adb 接口,该接口将 在启用了 adb 的 build 上替换(或协同工作)现有的 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 服务器发送命令时,服务器可能会使用 请求连接到设备上的某项服务,例如 shell 或日志记录器服务。adb 守护程序 搜索已注册的服务提供商列表以找到匹配项。如果匹配,注册的 服务提供商请求 Zircon 套接字。adb 守护程序转发来自 adb 的所有通信 将与服务相关的客户端连接到此套接字请求的服务示例包括 shell、logcat、端口 转发和文件同步这样做的目的是为这些服务提供单独的组件 。例如,我们可以创建一个 adb-shell 组件,用于打开 Dash shell 并管理 adb transport 与 Dash shell 之间基于 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 shell 服务。adb shell 组件将负责提供 adb shell 服务, 将 adb shell I/O 桥接到 Dash shell I/O 短划线 启动器 服务。默认情况下,adb-shell.cm 将提供一个类似于通过 sshd-host.cm 使用 ffx component explore 的 shell,或者具有更受限的功能。如果我们迁移到 不同界面,那么也可以将 adb-shell 迁移到该界面中。要限制 针对特定产品配置的功能;对于特定的应用场景,可使用自定义 shell 提供程序 可以替代这一组件。这与使用 ffx component explore <specific-moniker> 类似。

adb 守护程序每次都会请求新的 adb shell 会话(因此也会请求新的 Dash 会话) 用户请求新的 adb shell 实例。从 adb 客户端或 Dash 断开连接 将关闭整个会话。互动顺序如下所示 图表:

替代文本:所显示的 adb shell 序列图:在主机上,adb 客户端发送“adb shell”消息发送至
adb 服务器。然后,adb 服务器会向设备上的 adb.cm 发送 OPEN(&quot;shell&quot;) 协议消息。adb.cm
根据预配置的服务组件映射启动 adb-shell.cm,然后调用
adb-shell.cm 的 ConnectToService() API 来实现。adb-shell.cm 进而调用提供的 LaunchWIthSocket 协议
由 debug-dash-launcher.cm 生成,后者会生成 dash shell 和 pty 设备。adb.cm 返回
READY() 消息发送到 adb 服务器。adb 客户端与 Dash 之间的 adb 传输通道现在为
。

身份验证和加密

adb 协议支持使用 RSA 密钥对进行身份验证。它还支持 TLS 加密。 这两项功能都是可选的。在最初的实现中,这些功能 只有在开发者 build 或测试 build 中以受限模式运行,才能实现预期用途 环境另外,由于 USB 是唯一支持的传输类型,因此攻击方式仅限于 在某种程度上。将来,如果这些受支持,必须对 adb 进行更新 守护进程

维护

将支持当前的 adb 协议版本 0x01000000。未来对该协议的更新将 视具体情况而定。adb 协议不会经常更改,并且一直是 向后兼容性。

实现

实现可分为三个部分。

  • 在不同的开发板和 build 中添加支持。
  • adb 守护程序 <ph type="x-smartling-placeholder">
      </ph>
    • 在获得批准后,其中部分代码将从 Android 代码库导入 OSRB
  • adb 服务 <ph type="x-smartling-placeholder">
      </ph>
    • 目前的方案是支持 adb-shelladb-ffx
    • 如果必须支持其他命令,此阶段可能会扩展。

目前已经存在概念验证,可作为实施的参考。

性能

计算影响:添加 adb 支持应该不会产生任何显著的计算开销。adb 将使用 SSH 守护程序和/或 overnetstack,后两者均依赖于 驱动程序和组件,因此系统的整体 CPU 使用率应保持不变。

对大小的影响:添加 adb 守护程序和服务后,映像大小将增加大约 1 MB。请注意,这仅适用于使用 adb 组装的开发和测试 build 联系。对运行时内存占用量不会产生重大影响,因为将使用 adb 而无需使用现有工具

延迟时间:adb 中命令处理的延迟时间略优于 ssh 或其他 而无需使用额外的网络堆栈。设备发现延迟时间 预计会更小,并且它基于 USB 枚举,而不是定期广播 就像在 mDNS 中一样

向后兼容性

这涉及到三个部分,第一部分是 adb 协议本身的向后兼容性, 不在 Fuchsia 项目的控制范围内。尽管如此,已知 adb 协议 始终保持向后兼容性其次,支持 adb 服务 - 弃用 服务会影响依赖于它们的主机端命令/脚本。正确的迁移策略 。第三,是 shell 命令。例如,弃用 假设的 CLI xyz-tool 表示运行 adb shell xyz-tool 的脚本将不再有效。 此问题在 Fuchsia 工具的范围内,并非特定于 adb,因此不会 。

安全注意事项

关于 adb 传输的安全注意事项,我们提供了针对 身份验证和加密。但在最初的实现中,系统不会启用这些功能。开始时间 adb 仅在特定 build(例如开发者 build 或测试 build)中提供,不适用于 user build 这应该不是主要问题

就通过 adb 公开的服务的安全注意事项而言,这些与 Fuchsia 上的现有服务。该 adb-shell / adb-ffx 显示的交互面是 等于或小于 dash-shell /ffx 的值。对于特定的应用场景,一个严格限定范围的 shell 通过将 Shell 提供程序从 adb-shell 替换为 custom-shell。

初始实现仅支持 USB 传输。这会限制可能的攻击方式 (与基于网络连接的连接相比)。此外,adb 守护程序本身就是一个组件,因此 其中的漏洞会针对该特定进程采用沙盒机制,并且只会影响 adb 操作。

隐私注意事项

adb 服务公开的数据与 ffx component explore 或 SSH 服务公开的数据相同 其中 7 个网站已经过审核,存在隐私问题。此外,该技术将仅限于 开发者 build 或测试 build,不会部署在用户/正式版 build 中。USB adb 接口 会公开设备序列号,这与用于其他 USB 接口的序列号相同 如 CDC 以太网接口这主要由引导加载程序配置(如果未派生) 来自该 MAC 地址在产品配置过程中必须小心,不得使用 非常重要。

测试

adb 堆栈的所有部分都将进行单元测试。最终,adb 守护程序之间的集成测试 并且将添加 adb 服务。由于 adb 子系统之间的协定基于 FIDL (USB adb 驱动程序除外),这些测试可以是封闭的。将添加设备枚举测试 (针对 USB adb 接口)。如果需要,将添加针对 adb 的主机端 E2E 测试。对于端到端测试 可能需要在测试主机上安装 adb。可以使用端到端测试 / 集成测试 性能 和命令延迟时间测试频繁对 adb 连接进行定期压力测试 系统将考虑是否插上/拔下 USB 进行可靠性测试。对 adb 守护程序进行模糊测试 也会考虑实施

文档

您需要添加以下文件:

  • 支持的 adb 功能列表
  • adb 服务扩展指南
  • 用户指南

缺点、替代方案和未知问题

支持 adb 需要支付维护费用。使用两套工具会产生开销 用于通信和设备控制 - 即 ffx 和 adb。虽然这两种模式 重叠的特征,每个特征的用例是可区分的,并且它们将共用同一个后端 实施。ffx 适合多种开发者工作流,但目前存在局限性 并介绍主机端脚本和各种平台支持。adb 可用于填补这些空白, 硬件测试。通过共享设备上的服务,可以进一步降低维护费用 介于 ffx 和 adb 之间。例如,Dash 启动器、overnetstack 和日志接收器等都可与 adb 搭配使用 。

替代方案:将 ffx 端口传输到 Windows

目前的障碍是获得对 Windows 的 Rust 工具链支持并添加 USB 链接 发送至 ffx。此外,必须更改依赖于 adb 的现有测试框架才能使用 ffx,或者必须在 adb 和 ffx 之间提供转换 shim。此策略 以供日后再次访问在开发适用于 Windows 的 ffx 时,adb 提供了一种便捷的解决方案 正在进行中。

替代方案:在 Linux 虚拟机中运行主机端 ffx

使用在 Windows 上运行的 Linux 虚拟机(VM),并通过设备 USB 连接。包含 此设置,现有的 ffx 工作流程将同时适用于设备发现和互动。但是 设置虚拟机所耗费的时间可能相当长,而且可能不稳定/可靠。 此外,一些组织会限制在受管理的 Windows 计算机上使用虚拟机。使用 Docker 容器 是另一种替代方案,但 USB 转发可能不起作用,具体取决于 Windows 版本。

替代方案:USB 串行端口

向 Fuchsia 添加了对 USB CDC ACM 外围设备的支持。Windows 包含一个 USB 串行 驱动程序,适用于任何 USB CDC ACM 接口。这样,我们就可以将 USB 端口用作 串行通信设备这种方法的缺点是缺少丰富的命令集(只有 shell 将可用)、不分离日志和 shell,并支持单一实例。此外, 基于 adb 的现有测试框架必须进行更新。

先验技术和参考资料