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 构建的 (1、2、3 等等)。
- 适用于各种平台的 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 软件堆栈:
以下各部分将详细介绍每个部分。
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 协议支持使用 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-shell
和adb-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 的现有测试框架必须进行更新。
先验技术和参考资料
- adb 概览 - adb 客户端、服务器和守护程序概览
- adb 协议 - adb 消息类型和字段
- Android 上的 adb - Android adb 实现