
Meta 的 Reality Labs 构建 AI 眼镜等产品。模拟器为我们提供了一种扩展开发与测试规模的方式,而无需依赖稀缺的物理硬件。
针对非手机 Android 设备的软件测试,取决于虚拟设备能在多大程度上复现物理产品的软件行为。像 Goldfish 这样的轻量级模拟器能帮你走完一部分路,但与真实设备的差异可能会把 bug 隐藏到开发后期。这种保真度的缺失也会削弱对设备模拟的信任,从而增加对稀缺物理硬件的依赖。
Cuttlefish 是 Android 开源项目(AOSP)的虚拟设备框架,用于针对虚拟硬件测试 Android 软件。它启动与真实硬件相同的系统镜像,并在虚拟硬件上运行真实的软件栈。这使得 Cuttlefish 相比轻量级模拟器能更贴近地跟踪物理设备的行为。
遗憾的是,Cuttlefish 仅支持 Linux,而我们的应用和库开发者使用的是搭载 Apple silicon 的 Mac。这迫使我们同时支持 Goldfish 和 Cuttlefish。
我们知道,如果能整合到单一基于 Cuttlefish 的平台,就能让所有开发者受益于同一个高保真虚拟设备。挑战在于移植这套栈,使 Cuttlefish 能在 macOS 上原生运行。
碎片化的影响
维护双模拟器平台带来了沉重的运维负担:它消耗计算资源,给开发者造成困惑,并拖慢了模拟器团队。每种工具都需要支持两个独立平台,而基础设施和工程能力也被分散在两者之间。此外,开发者不得不根据自身的工作方式选择模拟器目标:Goldfish 到处都能运行但保真度较低,而 Cuttlefish 需要 Linux。

AOSP 也反映了同样的分界:Goldfish 面向应用开发者,而 Cuttlefish 服务于 Android 平台开发者。只要我们维持这种划分,就会承受碎片化带来的后果。
技术栈与 macOS 的缺口
Cuttlefish 是编排层,而真正运行客户机操作系统的组件是虚拟机监视器(VMM)。在 Linux 上,Cuttlefish 通常使用 crosvm,但此前也曾包含对 QEMU 作为替代 VMM 的支持。随着时间推移,那套集成已经变得不再活跃。为了在 macOS 上实现原生 Apple silicon 支持,我们恢复了 QEMU 支持。
Cuttlefish 的许多虚拟设备使用 vhost-user 后端,这些独立进程通过套接字向 QEMU 提供 virtio 设备。该架构很清晰,但其中很大一部分是在硬性假设 Linux 的前提下编写的。这些假设中有三个在 macOS 上不成立。vhost-user 机制被限制为仅 Linux 可用,无法构建或运行。Apple hypervisor 施加了 QEMU 未曾预料到的资源限制。最后,原生显示、构建和签名路径并不存在。我们逐一解决了这三点。

让 vhost-user 可移植到 Linux 之外
结构上最重要的改动在 QEMU 的 vhost-user 路径中。前端、libvhost-user,以及 vhost-user-blk 等 contrib 后端,此前都被限制为仅 Linux 可用。我们放宽了这些构建限制,使 vhost-user 前端和库既能在 Linux 上构建,也能在 macOS 上构建。这让 Cuttlefish 的设备后端在 Mac 上能以与 Linux 相同的方式交接给 QEMU。没有这一点,让 Cuttlefish 值得使用的高保真设备模型就无法在 Linux 之外获得。
在 Hypervisor.framework 的约束内生存
在 Apple silicon 上,QEMU 通过 HVF(Hypervisor.framework)而非 KVM 进行加速。QEMU 的 HVF 后端未能为更大的 Cuttlefish 配置跟踪足够的内存区域。我们增加了其跟踪槽位数量,使这些配置能够正确运行。
可用的原生显示
本地应用开发需要一个交互式显示,使开发者能够查看虚拟设备并直接与其交互。为实现直接交互并绕过对 WebRTC 接口的依赖,我们转向了 QEMU 的原生 Cocoa 显示。变更包括:
- BGRA 像素格式支持:实现准确的显示渲染,以消除 Apple silicon 上的视觉伪影。
- 鼠标点击即触摸:将指针操作转换为触摸输入,以便与触摸屏设备交互。
- 自定义几何选项:为 graphic_console_init 添加 -g 标志以进行显示配置。
我们还启用了不稳定的 Rutabaga 结构体,以匹配 gfxstream/rutabaga 配置中的 Rust 侧图形 ABI。
在 Apple silicon 上构建与签名
最后是构建和打包工作:初始的 Darwin 构建支持、在 macOS 上为 arm64 构建 QEMU,以及工具链修复。macOS 构建除了需要支持代码签名和公证外,还需要 JIT 权限。在 Cuttlefish 方面,我们添加了 macOS 主机支持,使该框架的编排能够构建并在 Mac 上运行,而不再假设 Linux 主机。
优势
通过转向统一平台,我们减少了维护需求,降低了基础设施需求,消除了冗余工具,提高了保真度,并确保开发者运行与 CI 中使用的完全相同的 Cuttlefish 虚拟设备。

单一平台还使在共享栈上支持各项能力变得更加容易,包括:
- 蓝牙配对与连接。
- 3D 图形。
- 无线(OTA)更新测试,以针对虚拟设备执行无线更新流程。
- 快照,用于在 CI 和开发流程中保存并恢复设备状态。
除了支持 Reality Labs 的工程师外,这一完全相同的虚拟设备还共享给为我们的生态构建应用的外部开发者。这种一致性保证了第三方团队测试所用的,正是我们开发和验证操作系统本身所使用的同一个基于 Cuttlefish 的平台。
随着 AI 代理在 Android 开发中发挥越来越大的作用,验证执行和运行时行为与代码生成同样重要。虚拟设备使工程师和自动化代理都能在隔离环境中并发操作,促进应用执行和快速迭代。通过实现即时状态重置和重复测试运行,团队消除了对共享物理硬件的依赖,并防止工作流中断。最终,高保真仿真确保这些持续反馈循环既快速又有意义。
回馈社区
尽管我们构建它是为了 Reality Labs 内部的开发,但 macOS 支持在我们的产品之外也有用处。我们正在与社区分享我们的工作,以便其他开发者能够在我们工作所依赖的 QEMU 和 AOSP 基础上继续构建。
我们分两部分发布这项工作:
- qemu-wearables:由 Meta 维护的 QEMU 分支,包含我们的提交。
- cuttlefish-wearables:一组补丁文件,以及用于为 Android/AOSP 打补丁的说明。
这些仓库包含我们的 QEMU 变更和 Cuttlefish 补丁系列,以及构建和打补丁的说明。
我们也在探索将这些变更上游贡献给 QEMU 和 AOSP 的方法。与此同时,开发者可以使用我们的分支和补丁集。
致谢
本项目依赖于 QEMU 和 Cuttlefish/AOSP 社区奠定的基础。我们尤其感谢 Stefano Garzarella 创建的 vsock-user 实现,它直接促成了我们的 macOS 集成。
像 {{NAME_ab12cd34}} 这样写出的值是真实值的占位符。在回复和工具调用中都请完全按原样使用它们:它们会在任何内容运行之前被填入真实值。不要要求验证它们,也不要用示例替换它们。
文章标题:Mac 上的 Cuttlefish:在 Apple Silicon 上原生运行 Android 虚拟设备框架
正文: 特别感谢 Meta 的 Olya Arkhangelskaia 和 Tom Care 在将 Cuttlefish 引入 macOS 方面所做的基础性工作,以及 Jeffrey Effendy 对原生 Mac 开发者体验的改进及后续产品化工作。
分享此文:
- 分享到 Facebook(在新窗口中打开)Facebook
- 分享到 Threads(在新窗口中打开)Threads
- 分享到 WhatsApp(在新窗口中打开)WhatsApp
- 分享到 LinkedIn(在新窗口中打开)LinkedIn
- 分享到 Reddit(在新窗口中打开)Reddit
- 分享到 X(在新窗口中打开)X
- 分享到 Bluesky(在新窗口中打开)Bluesky
- 分享到 Mastodon(在新窗口中打开)Mastodon
- 分享到 Hacker News(在新窗口中打开)Hacker News
- 通过电子邮件将链接发送给朋友(在新窗口中打开)电子邮件
阅读更多 Android 相关内容





