View on GitHub

scrcpy-gui

👻 A simple & beautiful GUI application for scrcpy.

Scrcpy GUI 产品与技术功能规格

状态:M0–M4 软件范围已实施(Implemented)

文档版本:1.0

调研基线:2026-08-15

适用代码基线:v2.4.0 及之后版本

维护者:Simon Ma 与 Scrcpy GUI contributors

实施进度(2026-08-15):M1 的 OptionDescriptor、CapabilityRegistry、命令预览、SessionManager、DeviceTracker、结构化事件/错误、Sessions 页面和 Config V3 已落地;M2 的设备工作区、文件推送、APK 安装、应用列表/启动、ArtifactService、脱敏诊断包、Issue helper 和 Profile 导入导出已落地;M3 的六类场景领域模型、官方 argv 序列化、场景冲突矩阵、Profile 往返、设备级编码器/显示/相机探测、响应式场景向导、输出预检和独立无 ADB OTG 流程已落地;M4 的设备组、场景/组预设、批量预检、逐设备结果、Automation V2 编辑/导入预览/取消、并发控制、确认门槛和产物化 run report 已落地,并已通过 fake ADB、迁移、安全验证与 880/1120/1440 视口检查。v2.4.0 Stable 已正式发布:三平台 Release workflow、包内 scrcpy/ADB 执行烟测、15 个发布资产及 14 个包的 SHA-256 清单核对均通过;随后真实发布资产的 macOS DMG、Windows NSIS 与 Ubuntu Debian 安装 → 升级 → 安装后 Renderer 启动 → 卸载工作流也全部通过。真实 Android/Camera/Virtual display/V4L2/OTG 硬件矩阵、签名/公证、人工交互式安装体验与 Chocolatey 社区审核仍是明确未验证项,必须保留在 Release notes,不能由 CI 推断为已完成。

逐项验收状态与缺失证据见 M0–M4 completion audit

0. 文档目的

本文不是宣传页,也不是把所有可能的功能罗列成愿望清单。它用于回答以下工程问题:

  1. Scrcpy GUI 要服务哪些用户,解决哪些真实问题;
  2. 哪些能力属于产品核心,哪些能力明确不做;
  3. 功能如何映射到 scrcpy 4.1、ADB 与当前 Electron 架构;
  4. 每个模块的交互、状态、数据、权限、错误和验收条件是什么;
  5. 如何按可交付里程碑实施,而不通过制造无意义提交来营造活跃度;
  6. 如何让 issue、PR、测试、Release 和用户反馈形成可审计的真实维护记录。

本文是后续功能 issue、设计评审、PR 拆分与版本验收的共同依据。实现与本文冲突时,应先更新本文或在 PR 中记录经过评审的偏差。

1. 执行摘要

Scrcpy GUI 的产品定位是:

官方 scrcpy 的可信桌面控制面:让普通用户无需记忆命令,让专业用户保留完整控制,让多设备任务可复现、可诊断、可审计。

产品继续直接启动未经修改的官方 scrcpy 客户端,而不是重新实现视频编解码、控制协议或嵌入式镜像内核。这样可以继承 scrcpy 的低延迟、设备兼容性和快速迭代,并把有限维护资源集中在 scrcpy 原生不负责的部分:

下一阶段不应以“覆盖全部约 100 个 scrcpy 长参数”为目标。正确模型是四层能力:

  1. 场景向导:将屏幕镜像、相机、虚拟显示、录制、OTG 等互斥参数组合成可靠流程;
  2. 常用可视化设置:为高频且稳定的参数提供有校验的控件;
  3. 专家参数:逐行 argv 透传,同时给出冲突、风险和版本提示;
  4. 能力注册表:以 scrcpy 版本和平台为条件,决定哪些控件、默认值与组合可用。

2. 设计原则

2.1 上游优先

2.2 渐进式复杂度

2.3 离线与本地优先

2.4 安全默认值

2.5 可恢复、可解释

2.6 真实维护

3. 目标与非目标

3.1 产品目标

编号 目标 衡量方式
G-01 新用户在不了解 scrcpy CLI 的情况下完成首次 USB 投屏 首次成功任务中位数不超过 3 分钟
G-02 Android 11+ 用户完成无线配对与重连 有引导时一次成功率不低于 85%
G-03 专业用户能够构造并复用复杂配置 每个启动会话可预览、复制、保存完整 argv
G-04 多设备任务不会漏开、重复打开或丢失结果 每个请求产生唯一 session,并逐项返回结果
G-05 用户能够自行生成高质量 issue 证据 一键诊断包包含版本、状态、命令、脱敏日志与检查结果
G-06 新 scrcpy 稳定版可以低风险接入 能力清单、参数测试、资产校验和跨平台烟测全部通过
G-07 安装包无需用户另行配置 PATH 正式 Release 内置经过校验的 scrcpy 与 ADB

3.2 工程目标

3.3 明确非目标

4. 调研范围与证据

4.1 上游基线

scrcpy 4.1 相比 4.0 的直接相关变化包括 VP8/VP9、编码器尺寸约束修复、--ignore-video-encoder-constraints、媒体扫描与依赖升级。当前 GUI 已把 VP8/VP9 作为一等视频编码选项;新增但尚未可视化的标志可通过专家参数使用。

4.2 竞品样本

调研只用于识别成熟交互与风险,不代表复制其实现或商业功能。统计是 2026-08-15 的快照,会自然变化。

产品 快照规模 公开定位与优势 对本项目的启示
QtScrcpy 约 31.4k stars C++/Qt/OpenGL;多设备、分组控制、按键映射、文件/APK、ADB 快捷动作 多设备需要“组”和逐设备结果;按键映射必须独立建模,不能只存字符串
Escrcpy 约 10.7k stars Electron/Vue;嵌入镜像、集成控制栏、LAN 发现、多设备编排、自动化;部分高级能力来自私有扩展 控制入口应贴近设备上下文;开源核心与私有能力边界必须透明
Scrcpy-GUI (Flutter) 约 449 stars 可视命令构建、相机、虚拟显示、收藏、命令预览、脚本导出、App Drawer 模式化面板与命令预览价值高;全部参数平铺会增加认知负担
guiscrcpy 约 3.1k stars,已归档 Python/PyQt;侧边控制、网络管理、设备信息、多设备与桌面快捷方式 独立控制面板有价值;长期维护成本和界面拥挤是明确风险
本项目 约 3.9k stars 官方 scrcpy launcher;安全 IPC、内置运行时、配置、多设备、控制、自动化、跨平台 Release 应以可信、简洁、可诊断为差异点,而不是重新造镜像内核

4.3 可学习但不直接复制的模式

  1. 设备上下文操作栏:来自 Escrcpy/QtScrcpy;适合截图、旋转、文件、应用与自动化入口;
  2. 命令预览:来自 Flutter Scrcpy-GUI;能帮助专家验证,也能让 issue 可复现;
  3. 配置收藏与使用频率:适合在配置很多时排序,但不应默认收集或上传使用数据;
  4. 设备分组:适合测试机房、展陈和批量演示;必须有 preflight 与部分失败语义;
  5. App Drawer:适合 --start-app,但应用清单获取慢,应按设备缓存并显式刷新;
  6. 可调整控制栏:入口可以排序,底层动作仍必须是固定结构化类型;
  7. LAN 自动发现:优先使用 ADB mDNS 服务,而不是无边界端口扫描;
  8. 脚本导出:可以导出可读命令,但导入时不得自动信任任意 shell 文件。

4.4 明确不采用的竞品模式

5. 当前产品审计

5.1 已具备能力

v2.0.0-beta.3 已经具备以下基础:

5.2 当前架构

Vue Renderer
  └─ window.scrcpy typed API
       └─ sandboxed preload / contextBridge
            └─ ipcMain handlers
                 ├─ processes.ts: ADB、截图、控制、自动化、scrcpy 进程
                 ├─ scrcpy.ts: 参数构建与纯校验
                 └─ Electron: dialog、tray、shortcut、external URL

现有边界是正确的,但职责开始集中:Renderer 单文件同时拥有持久化、业务状态和所有页面;processes.ts 同时负责 binary 解析、ADB、会话、控制、截图与自动化;IPC 依赖编译期类型,缺少统一运行时 schema 和 sender 校验。

5.3 当前参数覆盖

当前提供一等 UI/构建支持的参数约 30 个,包括:

仍缺少场景化 UI 的主要上游能力包括:相机、虚拟显示、OTG、应用启动、音频源/编码器、视频编码器、V4L2、time limit、TCP/IP 向导、列表查询和编码器约束。它们不应逐个变成孤立 checkbox,而应归入后文定义的模式与能力系统。

5.4 历史 issue 主题

历史 issue 提供了比竞品列表更可靠的需求证据:

主题 代表 issue 产品要求
scrcpy/ADB 路径与启动失败 #8、#10、#26、#53、#101、#116 内置运行时、分阶段诊断、实际 stderr
设备兼容与黑屏/无窗口 #1、#9、#14、#22、#31、#44、#48、#120 会话状态机、超时、设备/编码器诊断
无线连接 #15、#23、#42、#45、#61、#93、#127、#132、#147 pairing、mDNS、保存目标、清晰地址状态
多设备 #64、#72、#75、#80、#92、#114、#138 唯一 session、逐设备配置、部分失败结果
输入与快捷键 #6、#13、#27、#41、#81、#83、#85、#155、#158 输入模式解释、剪贴板诊断、映射研究
音频 #7、#34、#52、#58、#125、#129 以原生 scrcpy 音频替代历史 sndcpy 路径
文件与剪贴板 #27、#68、#104、#111、#122 push 目标、安装 APK、传输结果和剪贴板指导
控制与截图 #17、#84、#105、#131 点击控制栏、双向状态、截图产物
录制 #46、#55、#103、#126 文件名、目录、无预览录制、缓冲配置
打包与安装 #32、#36、#40、#66、#73、#90 完整平台资产、便携包、可复现构建
UI 与安全 #4、#25、#49、#57、#71、#119、#140 当前 Electron、安全 CSP、响应式布局、图标资产

5.5 主要缺口

  1. 设备刷新是定时轮询,没有持久 track-devices 事件源;
  2. 会话以 serial 为键,不能自然表达同设备的屏幕、相机、录制等并行模式;
  3. 配置仍在 Renderer localStorage,缺少原子写入、备份、迁移报告和导入导出;
  4. 没有最终命令预览和“为什么产生这个参数”的解释;
  5. 日志是文本流,没有阶段、命令、退出码、耗时和环境快照;
  6. 缺少应用、文件、录像与截图的统一产物视图;
  7. 自动化动作范围安全但很窄,缺少条件、坐标、逐设备执行与取消;
  8. 没有运行时能力探测,UI 主要依赖固定 scrcpy 4.x 假设;
  9. IPC 未统一做 sender 与 payload 运行时校验;
  10. Release 已自动化,但应用内还没有清晰、安全的更新提示策略。

6. 用户与任务模型

6.1 用户角色

P1:临时投屏用户

P2:日常无线用户

P3:开发与测试人员

P4:演示、展陈与内容生产人员

P5:小规模设备管理人员

6.2 核心 Jobs to Be Done

  1. 当我第一次连接 Android 设备时,我想知道缺少哪一步,从而无需查命令行文档;
  2. 当我再次使用固定设备时,我想直接恢复别名、配置和无线目标;
  3. 当我配置画质、音频或窗口时,我想看到最终命令并知道冲突;
  4. 当我同时启动多台设备时,我想知道每台设备的独立结果;
  5. 当镜像未出现时,我想导出足够证据,而不是只看到“启动成功”;
  6. 当我录制或截图时,我想从应用内找到文件和其来源设备;
  7. 当我运行自动化时,我想先预览目标和动作,并能中途停止;
  8. 当上游升级时,我想知道当前 GUI、二进制和参数是否兼容。

6.3 关键成功路径

首次启动
  → 运行时自检
  → USB/无线设备发现
  → 设备授权状态解释
  → 使用推荐配置启动
  → 收到 first-running 或明确 error
  → 可选保存设备别名/配置
重复使用
  → 识别已知设备
  → 恢复设备默认场景
  → 预览差异
  → 启动并跟踪 session
  → 从设备工作区执行截图/控制/产物操作
批量任务
  → 选择设备组
  → preflight(在线、授权、能力、冲突)
  → 确认动作与并发数
  → 执行
  → 逐设备结果
  → 重试失败项或导出报告

7. 信息架构与导航

7.1 一级导航

页面 目的 默认可见内容
设备 发现设备并进入单设备/多设备工作区 运行时健康、设备列表、无线入口、最近场景
会话 查看所有正在启动、运行、停止或失败的 scrcpy 实例 状态、模式、设备、启动时间、命令摘要、停止
产物 统一查看截图、录像、诊断包和传输记录 设备、类型、时间、路径、打开/定位/删除
自动化 编辑、预览和执行结构化工作流 宏列表、步骤、目标、最近运行
设置 管理应用、运行时、默认值、安全和更新 分组设置,支持搜索与恢复默认
日志 查看结构化事件和导出诊断 过滤器、时间线、命令、stderr、环境信息

“设备”仍是默认页。当前 Logs 页保留,但未来日志与诊断共享同一事件模型。设置页不承担设备状态和运行任务。

7.2 设备页布局

设备页按稳定层级组织:

  1. 环境状态条:scrcpy、ADB、版本、来源、检查按钮;仅异常时展开说明;
  2. 设备列表:每个设备显示别名、型号、连接方式、授权状态、默认场景和运行状态;
  3. 选择操作:启动、批量动作、加入组;无选择时禁用并解释;
  4. 无线设备区域:已保存目标、mDNS 建议、pairing/连接向导;
  5. 最近使用:最近设备与场景组合,不在首版保存行为频率到云端。

7.3 设备详情/工作区

选择一台设备进入右侧详情或独立页面,包含:

不把实时镜像嵌入该工作区;Mirror 页管理的是官方 scrcpy 外部窗口的生命周期。

7.4 设置分组

分组 内容
General 语言、启动页、托盘、提示、退出行为
Runtime 内置/自定义 scrcpy、ADB 来源、版本兼容、更新策略
Defaults 新设备默认场景、录像/截图目录、窗口规则
Devices 已知设备、别名、默认场景、自动连接/自动启动
Automation 默认并发、超时、危险动作确认、历史保留
Privacy 日志保留、脱敏、诊断导出、更新网络访问
Shortcuts Boss 键与应用级快捷键冲突检测
Advanced 专家参数策略、ADB server 所有权、调试输出

7.5 响应式规则

8. 领域对象模型

8.1 对象关系

flowchart LR
  Runtime[Runtime Installation] --> Capability[Capability Snapshot]
  Device[Known Device] --> Profile[Launch Profile]
  Device --> Group[Device Group]
  Profile --> Scene[Launch Scene]
  Capability --> Scene
  Device --> Session[Scrcpy Session]
  Scene --> Session
  Group --> BatchRun[Batch Run]
  Automation[Automation] --> BatchRun
  BatchRun --> Session
  Session --> Artifact[Artifact]
  Session --> Event[Structured Event]
  BatchRun --> Event
  Event --> Diagnostic[Diagnostic Bundle]

8.2 RuntimeInstallation

表示实际使用的 scrcpy/ADB 组合,而不是只有一个 scrcpyPath

interface RuntimeInstallation {
  id: string
  source: 'bundled' | 'custom'
  scrcpyPath: string
  adbPath: string
  scrcpyVersion: string
  adbVersion: string
  platform: 'darwin' | 'win32' | 'linux'
  arch: 'arm64' | 'x64' | 'ia32'
  verified: boolean
  verifiedAt: string
  capabilitySnapshotId: string
}

规则:

8.3 CapabilitySnapshot

能力快照来自版本、平台和只读探测命令。

interface CapabilitySnapshot {
  id: string
  scrcpyVersion: string
  capturedAt: string
  flags: string[]
  videoEncoders: EncoderInfo[]
  audioEncoders: EncoderInfo[]
  displays: DisplayInfo[]
  cameras: CameraInfo[]
  supports: {
    audio: boolean
    camera: boolean
    virtualDisplay: boolean
    otg: boolean
    v4l2: boolean
    vp8: boolean
    vp9: boolean
  }
}

8.4 KnownDevice

interface KnownDevice {
  id: string                 // 本地稳定 id,不直接用显示名称
  lastSerial: string
  fingerprint?: string       // 可获得时使用只读设备属性组合
  alias: string
  model: string
  lastConnection: 'usb' | 'wireless'
  defaultProfileId?: string
  groupIds: string[]
  autoConnect: boolean
  autoLaunch: boolean
  firstSeenAt: string
  lastSeenAt: string
}

8.5 LaunchProfile 与 LaunchScene

Profile 是可复用参数;Scene 是模式化入口。

type SceneKind =
  | 'screen'
  | 'camera'
  | 'virtual-display'
  | 'record-only'
  | 'control-only'
  | 'otg'

interface LaunchProfile {
  id: string
  name: string
  scene: SceneKind
  schemaVersion: number
  options: LaunchOptions
  expertArgs: string[]
  createdAt: string
  updatedAt: string
}

Profile 必须可导出为 JSON 和平台无关 argv。绝对输出路径在导出时替换为变量或标记为本地字段。Scene 负责互斥参数和默认值,Profile 不允许制造逻辑上不可能的组合。

8.6 ScrcpySession

type SessionState =
  | 'queued'
  | 'preflighting'
  | 'launching'
  | 'running'
  | 'stopping'
  | 'stopped'
  | 'failed'

interface ScrcpySession {
  id: string
  deviceId: string
  serialAtLaunch: string
  profileId?: string
  scene: SceneKind
  state: SessionState
  pid?: number
  args: string[]
  startedAt?: string
  endedAt?: string
  exitCode?: number
  stopReason?: 'user' | 'boss-key' | 'app-quit' | 'process-exit' | 'launch-error'
  error?: StructuredError
}

Session 使用独立 id,不再只以 serial 为 key。默认仍限制同设备同 scene 一个活动 session;若未来允许屏幕与相机并行,由冲突矩阵决定并分配独立 tunnel port。

8.7 Artifact

type ArtifactKind = 'screenshot' | 'recording' | 'diagnostic' | 'transfer-report'

interface Artifact {
  id: string
  kind: ArtifactKind
  deviceId?: string
  sessionId?: string
  path: string
  createdAt: string
  sizeBytes?: number
  metadata: Record<string, string | number | boolean>
}

索引只记录本地文件元数据。用户移动或删除文件时标记 missing,不自动复制到应用目录。

9. 场景与参数能力模型

9.1 参数描述符

参数定义从 UI 组件移入共享注册表:

interface OptionDescriptor<T> {
  key: string
  flag: string
  category: string
  valueType: 'boolean' | 'number' | 'string' | 'enum' | 'path'
  defaultValue: T
  minScrcpyVersion?: string
  platforms?: Array<'darwin' | 'win32' | 'linux'>
  scenes: SceneKind[]
  conflictsWith?: string[]
  requires?: string[]
  validate(value: unknown, context: ValidationContext): ValidationResult<T>
  serialize(value: T): string[]
}

要求:

9.2 Screen scene

目标:标准屏幕镜像与控制。

默认:

高级能力:编码器、bitrate、size、fps、orientation、crop、display、输入模式、窗口、缓冲、音频源与录制。

9.3 Camera scene

目标:将 Android 12+ 摄像头作为视频源,支持预览或录制。

向导步骤:

  1. 选择设备;
  2. 探测 --list-cameras 和可用尺寸;
  3. 选择前/后摄、尺寸、fps、朝向、torch、zoom;
  4. 选择音频源(设备输出/麦克风/无);
  5. 选择预览、录制或 Linux V4L2;
  6. preflight 并预览命令。

互斥/限制:

9.4 Virtual display scene

目标:创建独立 Android 虚拟显示并启动应用,而非镜像物理屏幕。

字段:size、dpi、系统装饰、销毁内容策略、flex display、start-app、keep-active、display IME policy。

规则:

9.5 Record-only scene

目标:后台录制,不显示播放窗口。

9.6 Control-only / OTG scene

Control-only 用于无需视频的 ADB 控制;OTG 使用 scrcpy 原生 OTG 能力且可不启用 USB debugging。

9.7 Expert args

编辑器特性:

10. 详细功能规格

F-01 运行时健康与兼容性

优先级:P0

用户界面:

检查顺序:

  1. 文件存在且为普通文件;
  2. 平台可执行权限/扩展名满足要求;
  3. scrcpy --version 在 5 秒内返回;
  4. 版本满足当前应用兼容区间;
  5. 找到 ADB 与 scrcpy-server 等依赖;
  6. adb version 返回;
  7. 基础 adb devices -l 可执行;
  8. 建立 CapabilitySnapshot。

验收:

F-02 设备追踪与状态解释

优先级:P0

实现:

设备状态:

验收:

F-03 无线配对、发现与重连

优先级:P0/P1

Android 11+ pairing:

mDNS:

旧 TCP/IP:

F-04 命令预览与配置差异

优先级:P0

F-05 Profile、设备覆盖与导入导出

优先级:P0/P1

F-06 会话生命周期

优先级:P0

状态转换:

queued → preflighting → launching → running → stopping → stopped
                    ↘ failed     ↗       ↘ failed

preflight:

launching → running 判定:

停止:

F-07 会话中心与窗口编排

优先级:P1

F-08 设备控制栏

优先级:P0/P1

基础动作:Back、Home、Recent、Menu、音量、Power、Screen on/off、Rotate、Auto rotate、Show touches、Screenshot。

扩展动作:通知栏展开/收起、锁屏、粘贴文本、打开设置(需逐项验证平台/Android 行为)。

规则:

F-09 文件传输与 APK 安装

优先级:P1

文件传输:

APK:

F-10 应用列表与启动

优先级:P1

F-11 剪贴板与文本输入

优先级:P1

F-12 截图、录像与产物库

优先级:P0/P1

F-13 设备组与批量操作

优先级:P1/P2

DeviceGroup:名称、设备 id 列表、默认 Profile、并发上限与说明。

支持的首批批量动作:

preflight 表:

| 设备 | 在线 | 授权 | 能力 | 会话冲突 | 预计动作 | | — | — | — | — | — | — |

用户可选择“仅执行通过项”或取消。运行结果永远不折叠成单个成功布尔值。

F-14 安全自动化

优先级:P1/P2

步骤类型:

type AutomationStep =
  | { type: 'delay'; durationMs: number }
  | { type: 'control'; action: DeviceControlAction }
  | { type: 'tap'; x: number; y: number; coordinateSpace: 'normalized' }
  | { type: 'swipe'; from: Point; to: Point; durationMs: number }
  | { type: 'text'; value: string; sensitive: boolean }
  | { type: 'start-app'; packageId: string }
  | { type: 'screenshot'; label?: string }
  | { type: 'assert-device'; condition: DeviceCondition }

首版不包括循环、任意条件表达式、shell 或网络请求。后续条件分支只能建立在受控设备状态上。

运行语义:

安全边界:

F-15 按键映射研究轨

优先级:P2 research,不承诺交付日期

目标不是直接复制 QtScrcpy 游戏映射。需比较三条路线:

  1. ADB input/低层事件:实现简单但延迟和权限不稳定;
  2. scrcpy 控制协议:低延迟但意味着实现并维护协议客户端;
  3. 外部 scrcpy 窗口快捷键/全局 hook:平台差异与安全风险高。

研究验收:

F-16 更新提示与发布渠道

优先级:P1

F-17 国际化与无障碍

优先级:P1

11. 目标技术架构

11.1 组件图

flowchart TB
  UI[Vue Renderer]
  VM[View Models / Stores]
  Bridge[Typed Preload API]
  Guard[IPC Sender + Payload Guards]
  Main[Electron Main]
  Runtime[RuntimeService]
  Device[DeviceTracker / AdbService]
  Session[ScrcpySessionManager]
  Auto[AutomationRunner]
  Artifact[ArtifactService]
  Config[ConfigRepository]
  Update[UpdateService]
  Scrcpy[scrcpy process]
  Adb[adb process]
  Disk[Atomic JSON + user files]

  UI --> VM --> Bridge --> Guard --> Main
  Main --> Runtime
  Main --> Device
  Main --> Session
  Main --> Auto
  Main --> Artifact
  Main --> Config
  Main --> Update
  Runtime --> Scrcpy
  Runtime --> Adb
  Device --> Adb
  Session --> Scrcpy
  Auto --> Adb
  Artifact --> Adb
  Config --> Disk
  Artifact --> Disk

11.2 Renderer

职责:

拆分建议:

src/renderer/
├─ pages/
│  ├─ DevicesPage.vue
│  ├─ SessionsPage.vue
│  ├─ ArtifactsPage.vue
│  ├─ AutomationsPage.vue
│  ├─ SettingsPage.vue
│  └─ LogsPage.vue
├─ components/
│  ├─ runtime/
│  ├─ device/
│  ├─ profile/
│  ├─ session/
│  └─ common/
├─ stores/
│  ├─ devices.ts
│  ├─ sessions.ts
│  ├─ config.ts
│  └─ events.ts
├─ composables/
└─ i18n/

不要求为拆分而引入重量级全局状态库;可以先以 Vue reactive modules/composables 实现。只有状态依赖和调试证据支持时才引入额外依赖。

11.3 Preload

Preload 只暴露逐能力函数,禁止暴露通用 sendinvokeon 或整个 ipcRenderer

interface DesktopApi {
  runtime: RuntimeApi
  devices: DeviceApi
  profiles: ProfileApi
  sessions: SessionApi
  artifacts: ArtifactApi
  automations: AutomationApi
  settings: SettingsApi
  diagnostics: DiagnosticsApi
  app: AppApi
}

事件订阅必须:

11.4 主进程服务

RuntimeService

AdbService

DeviceTracker

ScrcpySessionManager

AutomationRunner

ArtifactService

ConfigRepository

UpdateService

11.5 纯领域模块

以下模块不导入 Electron/Vue,便于快速单元测试:

12. IPC 合约与安全边界

12.1 命名

采用 domain:verb

runtime:get
runtime:choose-custom
runtime:reset-bundled
runtime:probe
devices:list
devices:pair
devices:connect
devices:disconnect
profiles:list
profiles:save
sessions:start
sessions:stop
sessions:list
artifacts:list
artifacts:reveal
automations:validate
automations:start
automations:cancel
diagnostics:export
settings:get
settings:update

事件使用过去式或状态名:devices:changedsessions:eventautomations:event

12.2 Envelope

interface IpcSuccess<T> {
  ok: true
  data: T
  requestId: string
}

interface IpcFailure {
  ok: false
  error: StructuredError
  requestId: string
}

interface StructuredError {
  code: string
  stage: string
  message: string
  detail?: string
  exitCode?: number
  retryable: boolean
  suggestedActions: string[]
}

异常不能把 stack、环境变量或完整本地路径默认暴露给 Renderer;开发模式可在日志保留 stack。

12.3 Runtime validation

所有 handler 执行:

  1. 验证 sender frame URL 属于本地应用;
  2. 检查 payload 是 plain serializable data;
  3. 按 schema 限制字符串长度、数组长度、枚举、数字范围;
  4. 重新验证 device/session/profile 是否真实存在;
  5. 执行业务操作;
  6. 输出前再次构造成已知 DTO。

建议先用显式 validators,不把依赖选择绑定进本文。若 validators 重复度证明需要 schema library,再以独立 ADR 决定。

12.4 输入上限

输入 上限
别名/Profile/Group 名称 80 Unicode code points
expert arg 单行 4096 bytes
expert args 总数 200
Automation steps 200
text step 2000 code points
日志单事件 16 KiB,超出截断并标记
screenshot buffer 64 MiB
命令输出 buffer 默认 4 MiB,能力探测可单独配置
诊断包 默认 20 MiB,超限要求用户缩小范围

12.5 URL、导航和窗口

13. 持久化与迁移

13.1 存储位置

主配置目录使用 Electron app.getPath('userData'),不污染 home 根目录。建议:

userData/
├─ config.json
├─ config.backup.json
├─ profiles.json
├─ automations.json
├─ artifacts.json
├─ logs/                 # opt-in file logging
└─ diagnostics/          # 用户明确导出或临时生成

可根据实际体积合并小文件;服务边界不依赖文件数量。

13.2 Config schema

interface AppConfigV3 {
  schemaVersion: 3
  revision: number
  locale: Locale
  appearance: AppearanceSettings
  runtime: RuntimeSelection
  defaults: DefaultSettings
  privacy: PrivacySettings
  shortcuts: ShortcutSettings
  knownDevices: KnownDevice[]
  wirelessTargets: WirelessTarget[]
  groups: DeviceGroup[]
}

不持久化:

13.3 原子写入

  1. 对内存对象做完整 schema 校验;
  2. 写到同目录临时文件;
  3. flush/close;
  4. 当前文件复制/轮换为 backup;
  5. 同文件系统 rename 临时文件到正式文件;
  6. 更新内存 revision;
  7. 失败时保留旧正式文件并记录事件。

13.4 beta.3 → V3 migration

来源是 localStoragescrcpy-gui:config:v2

迁移流程:

13.5 导入导出

14. 进程、并发与资源管理

14.1 Child process policy

14.2 PortAllocator

scrcpy tunnel 默认端口范围可能被并发 session 使用。PortAllocator:

14.3 并发限制

操作 默认并发
scrcpy launch 3
screenshot 4
ADB lightweight action 每设备串行,全局 8
file push/APK install 2
capability probe 1/设备
Automation 3 个设备,单设备步骤串行

这些值是默认值,不是未经测量的硬性性能承诺;后续依据基准调整。

14.4 ADB server ownership

15. 结构化日志与诊断

15.1 Event schema

interface AppEvent {
  id: string
  timestamp: string
  level: 'debug' | 'info' | 'warn' | 'error'
  domain: 'runtime' | 'device' | 'session' | 'automation' | 'artifact' | 'update'
  action: string
  requestId?: string
  deviceId?: string
  sessionId?: string
  stage?: string
  message: string
  data?: Record<string, unknown>
}

15.2 日志保留

15.3 脱敏

默认替换:

用户导出前看到将包含的字段和预览。可选择“包含完整设备地址/路径”,但必须显式勾选。

15.4 诊断包

包含:

不包含:录像、截图、用户传输文件、剪贴板、账户信息、完整应用清单(除非用户选择)。

15.5 Issue helper

诊断导出后可生成 Markdown 模板:

### Environment
- Scrcpy GUI: ...
- scrcpy: ...
- OS/arch: ...

### Steps
1.
2.

### Expected / actual

### Diagnostic bundle
Attach manually after reviewing its contents.

应用只打开 GitHub issue 页面,不自动上传附件或代表用户提交。

16. 安全与威胁模型

16.1 受保护资产

16.2 主要威胁

威胁 场景 控制
shell injection expert arg、文件名或地址进入命令 始终 argv;禁止 shell syntax import
IPC privilege abuse Renderer/XSS 调用任意主进程能力 CSP、sandbox、sender 校验、narrow APIs、payload schema
malicious profile 导入配置携带命令或危险路径 declarative schema、dry-run、受管 flag、无 hooks
automation mis-targeting 对错误设备广播 tap/text/install 目标预览、preflight、别名/model、二次确认、逐设备结果
binary substitution 下载或 custom scrcpy 被替换 bundled 固定 SHA-256;custom 明确未验证;不静默下载
diagnostic leakage issue 附件暴露 IP/serial/path 默认脱敏、导出预览、最小字段
path overwrite 录像/截图覆盖任意文件 安全默认目录、冲突策略、原子写、显式选择
resource exhaustion 无限日志/步骤/输出/并发 size、time、step、buffer、concurrency limits

16.3 Electron hardening backlog

P0 hardening:

17. 性能与可靠性要求

17.1 参考目标

这些是产品目标,需要在参考机器上测量,不是宣传保证。

指标 目标
冷启动到 UI 可交互 ≤ 2 s(不含首次系统安全检查)
已启动后设备插拔显示 ≤ 2 s
点击启动到 session launching ≤ 200 ms
基础 preflight ≤ 2 s
日志新增到 UI ≤ 250 ms
5000 条日志过滤 ≤ 100 ms
配置保存 ≤ 200 ms
UI idle CPU 接近 0,不固定高频轮询

17.2 可靠性

18. 测试策略

18.1 单元测试

必须覆盖:

18.2 服务集成测试

使用受控 fake adb/scrcpy 可执行程序模拟:

测试不依赖真实用户 ADB server,也不 kill 全局进程。

18.3 IPC contract tests

18.4 UI/E2E

至少覆盖:

18.5 硬件烟测矩阵

每个稳定版至少人工验证:

维度 最低覆盖
Android 8/10/11/当前稳定版(按可用设备调整并记录缺口)
厂商 Pixel/AOSP、Samsung、小米系、华为系中可获得样本
连接 USB、旧 TCP/IP、Android 11+ pairing/mDNS
主机 Windows x64、macOS arm64、Linux x64
场景 screen、audio、record、multi-device;新模式按版本加入

不能获得的矩阵项必须在 Release notes 标为未验证,不凭推断宣称支持。

18.6 Release 验收

  1. unit/integration/typecheck/build 三平台通过;
  2. scrcpy 官方资产下载与 SHA-256 通过;
  3. 每个安装资产存在且命名稳定;
  4. 解包后实际运行 bundled scrcpy --version / adb version
  5. 基础 GUI 启动无 console error/overflow;
  6. 安装、升级、卸载路径按平台烟测;
  7. GitHub Release asset 数和 checksum manifest 校验;
  8. 相关 issue 回复版本与验证方法。

19. 实施路线图

路线图以交付物为单位,不规定每月提交数量。每个阶段可以拆成多个可独立评审 PR。

M0:v2.0 稳定化(当前 → Stable)

目标:把 beta 变成可信稳定基线。

退出条件:

M1:v2.1 能力与会话基础

退出条件:所有当前场景功能迁移到新基础且行为不回退;重复/漏开问题有集成测试。

M2:v2.2 设备工作区与产物

退出条件:文件/APK/应用/产物有逐设备结果和诊断,导入配置不能执行任意命令。

M3:v2.3 scrcpy 4.x 场景完整性

退出条件:每个模式有独立向导、命令预览、至少一平台硬件烟测和失败路径。

M4:v2.4 多设备与安全自动化

退出条件:批量失败不会误报整体成功;危险动作有确认;无 raw shell。

Research:v3 候选

任何研究项只有在有原型、跨平台数据、安全评审和维护者承诺后进入版本路线。

19.1 真实维护节奏建议

该节奏用于组织真实工作,不用于回填 2019—2026 的虚假 commit。

20. 优先级与验收总表

能力 优先级 目标版本 关键验收
Runtime health P0 v2.0 Stable 分阶段错误、bundled 回退
IPC hardening P0 v2.0 Stable sender/payload/navigation 测试
Command preview P0 v2.1 argv 与来源可解释
Session state machine P0 v2.1 不以 spawn 等同 running
DeviceTracker P0 v2.1 插拔 ≤2s、崩溃恢复
Config V3 migration P0 v2.1 原子写、备份、migration report
Files/APK P1 v2.2 安全 argv、逐设备结果
Apps/start-app P1 v2.2 缓存、刷新、失败解释
Artifacts P1 v2.2 路径、索引、missing 状态
Diagnostics P1 v2.2 默认脱敏、导出预览
Camera P1 v2.3 探测、互斥、硬件烟测
Virtual display P1 v2.3 lifecycle 与 app start
OTG P1 v2.3 与 ADB workflow 分离
Device groups P1 v2.4 preflight、partial result
Automation V2 P1 v2.4 cancel、limits、无 shell
Key mapping Research v3 候选 延迟/权限/维护成本证据
Embedded mirror Research v3 候选 不 fork 上游的可行性

21. 产品指标与维护指标

21.1 产品指标(本地可测,不默认上传)

这些指标首先用于本地测试和用户主动提交的诊断。若未来讨论匿名遥测,必须单独设计 opt-in、数据字典、保留期限和隐私说明,本文不预先授权。

21.2 OSS 维护指标

不使用“随机提交数”或“绿点连续性”作为维护质量指标。

22. 决策记录

D-01 保留官方外部 scrcpy 窗口

D-02 不允许任意 shell 自动化

D-03 bundled runtime 随应用发布

D-04 真实里程碑,不伪造历史

23. 待决问题

  1. Stable 最低 OS 版本与 Electron 43 官方范围如何写入兼容矩阵;
  2. 是否在 v2.1 引入第三方 runtime schema library,还是保留手写 validators;
  3. 同一设备是否允许 screen + camera 并行 session;
  4. App list 优先使用 scrcpy --list-apps 还是 ADB package manager;
  5. 文件传输是否需要可取消进度,ADB 输出是否足够稳定;
  6. 产物索引采用 JSON 还是在规模证据出现后采用 SQLite;
  7. Beta/Stable 更新检查是否需要 ETag cache;
  8. Windows/macOS 完成签名之前,Stable Release 的用户预期如何表达;
  9. 设备 fingerprint 哪些只读属性足够稳定且不侵犯隐私;
  10. 自动化 normalized 坐标在折叠屏、旋转与虚拟显示上的适配策略。

每个待决问题应以 issue/ADR 记录证据和结论,不能由实现者在代码中静默决定。

24. 参考资料

上游与平台

竞品

本项目

25. 文档完成定义

本文达到“可实施”需要满足:

后续第一个实施 PR 应从 M0 或 M1 选择一个垂直切片,同时更新本文对应状态;不应一次性重写全部架构。