Back to home

kokubunshu

DSH-mobile-sync

No description

Stars
1
Language
JavaScript
Created
Aug 16, 2026
Updated
Aug 16, 2026

Introduction

Harness Sync 三件套整合包

本整合包按 Harness 交接链路拆成三个独立部分:

  1. Harness 桌面插件;
  2. relay 服务器模块和搭建教程;
  3. Android 移动端 APK,以及可复现构建源码。

当前移动端版本为 0.1.0+11,Android 包名为 org.dsh.dsh_mobile,最低 支持 Android 7/API 24。整合包不包含真实配对码、deviceToken、Web UI Cookie、服务器 IP、真实域名、SSH 私钥、签名密钥、Firebase 服务账号或 运行日志。

目录

目录交付内容
01-harness-plugin/桌面端 dsh-mobile-bridge 插件源码、构建脚本和协议验证脚本
02-relay-server/Node relay 源码、Docker/Caddy 配置、环境变量示例和部署教程
03-mobile-apk/开发测试 APK、移动端 Flutter 源码和图标/通知兼容文档
docs/三件套共用的部署、协议、安全脱敏和截图资源

01 · Harness 桌面插件

进入 01-harness-plugin/dsh-mobile-bridge,先执行 npm install,然后按照 该目录 README 和 docs/DEPLOYMENT.md 安装到 Harness 的 web profile。 插件负责 LAN WebSocket、WSS relay 出站连接、移动端配对、HTTP 隧道、 会话事件和通知意图转发。

02 · relay 服务器

进入 02-relay-server/relay,使用其中的 .env.example、Dockerfile、 docker-compose.yml、Caddyfile 和 DEPLOY-STEP.md。先用 example.com 或 部署方自己的域名替换示例地址,再注入服务器环境变量。FCM 凭据是可选的 后续能力,不能放入这个包。

03 · Android 移动端

开发测试 APK:

03-mobile-apk/artifacts/app-release-development-signed.apk

该 APK 使用 debug key 回退签名,因为整合包没有携带任何生产签名密钥。 它可以用于真实设备兼容性测试,但不能作为应用商店生产更新包。

移动端源码:

03-mobile-apk/app-source/

进入 app-source 后执行 flutter pub get、flutter analyze、flutter test, 再执行 flutter build apk --release。生产构建前必须在本机配置未入库的 android/keystore.properties。

截图示例

以下图片由用户提供,作为 README 的界面和通知展示示例;它们不是本次 未连接设备的实时验证证据。

已连接后的任务列表

Harness Sync 已连接任务列表

开始配对页面

Harness Sync 开始配对页面

HyperOS 通知展示示例

Harness Sync HyperOS 通知展示

验收顺序

  1. 服务器先通过 /health 检查;
  2. Harness 插件加载并显示移动端配对面板;
  3. 移动端在同一局域网完成 LAN 配对;
  4. 再使用 WSS relay 完成 WAN 配对;
  5. 验收 Android 13+ 通知权限、Android 14/15 前台服务和 OEM 后台策略;
  6. 在 HyperOS 通知中心以及可穿戴设备通知中心查看一条新通知;
  7. 对 APK 运行 aapt2 资源合同检查;
  8. 发布前阅读 docs/SECURITY-REDACTION-REPORT.md。

安全边界

公共整合包只携带示例配置。真实 relay 域名、DNS、Docker secrets、 FCM service-account、签名密钥、配对码和设备数据必须由部署方在本机或 CI secret 中注入。不要把生成的二维码、adb serial、蓝牙地址、dumpsys 输出或用户会话截图追加到 Git。

详细总项目手册

本目录应作为一个整体交接。三个子模块必须使用同一份协议、同一套配对策略和同一套安全边界;只部署其中一个模块不能形成可工作的系统。

端到端数据流

LAN:
  Android App -- ws://桌面IP:端口/ws --> Harness 桌面插件 --> Harness 本地 API/Web

WAN:
  Android App -- wss://relay/connect --> 自有 relay VPS <-- wss:// -- 桌面插件
                                                        |
                                                        +-- 仅按配对码转发帧
  • 桌面插件负责生成配对码、批准设备、维护桌面侧连接和转发 Harness API;
  • relay 负责让桌面和手机在不同网络中建立可路由的 WebSocket 通道;
  • Android App 负责配对、前台连接、loopback WebView 隧道和本地通知;
  • relay 当前是信任边界,协议 v1 不提供端到端加密;
  • FCM 只是预留的后续能力,不属于本包已完成的 killed-process 推送能力。

推荐部署顺序

严格按照下面顺序操作,出现问题时也按这个顺序定位:

  1. 先部署 relay:域名解析、Caddy 证书、/health 检查全部通过;
  2. 再安装桌面插件:确认 Harness 设置页出现移动端配对,并确认插件能连接 relay;
  3. 再安装 Android App:使用包内开发 APK,或由维护者使用私有签名重新构建;
  4. 先做 LAN 配对:排除 relay、证书和公网网络变量;
  5. 再做 WAN 配对:确认桌面和手机都能连 wss:// relay;
  6. 最后做通知与可穿戴设备验收:通知权限、后台策略、HyperOS 缓存和手环缓存要分别检查。

一、relay 中继服务器

运行要求

  • Linux VPS,具备 root 或 sudo 权限;
  • 一个 DNS 已指向 VPS 的域名,例如 relay.example.com
  • TCP 80/443 可以从公网访问;
  • 推荐 Docker + Docker Compose;
  • 不使用 Docker 时,需要 Node.js 22+、Caddy 和 systemd;
  • FCM 当前不需要配置,默认运行在 echo/无推送凭据模式。

Docker 快速部署

进入 02-relay-server/relay,复制 .env.example 为本机 .env,再把 caddy/Caddyfile 中的示例域名替换为部署方自己的域名。启动后用 HTTPS 健康接口验证,不要把真实域名写回公共示例文件。

完整的 VPS 打包、上传、Caddy、Docker、验证和排障流程见 02-relay-server/relay/DEPLOY-STEP.md

relay 接口

地址用途
GET /health存活检查,不应暴露 secrets
WS /connect?code=...&role=desktop|app桌面和手机按配对码加入房间
POST /pair/info查询房间在线状态
POST /push/registerFCM 后续能力的 token 注册入口

relay 默认只在内存中维护房间和连接,不应持久化会话正文。生产部署仍应把 relay 视为可信基础设施,日志级别要控制在不泄露配对码、Cookie、设备 token 和任务内容的范围内。

relay 安全门禁

  • 对外只提供 HTTPS/WSS,不让手机在公网使用 ws://
  • Node relay 的 8787 端口只绑定本机或受控反向代理;
  • .env、Docker secrets、FCM service account 不进 Git;
  • Caddyfile 中的真实域名只保留在部署机;
  • 服务器日志、Docker 输出、SSH 输出提交前必须脱敏;
  • 更换配对码或执行停止配对后,旧配对凭据必须失效。

二、Harness 桌面插件

安装

在 Harness 的 web profile 中使用 dsh plugin --profile web add link:<本整合包目录>/01-harness-plugin/dsh-mobile-bridge 安装本地插件,安装后重启 Harness,并在设置页确认出现“移动端配对”。

插件 standalone 测试和更完整的安装说明见 01-harness-plugin/README.md

设置页白名单

部分 Harness 版本会过滤第三方设置命名空间。如果插件已经加载但设置表单不显示,按 docs/DEPLOYMENT.md 的说明,将 mobile-bridge 加入 Harness apiproxy 的 WEB_SETTINGS_NAMESPACES。这是 Harness 安装树中的一次性兼容补丁,升级 Harness 后可能需要重新应用;不要把 Harness 的用户目录、绝对路径或私有补丁内容提交到本仓库。

插件功能

  • LAN WebSocket 监听,默认端口为 3088;
  • 出站连接自有 WSS relay;
  • QR/配对码、待批准设备和撤销设备;
  • HTTP tunnel 到 Harness /m 移动界面;
  • session、event、mux、config 和 RPC 转发;
  • 工作中状态、任务结束、等待回答、等待审批等通知意图;
  • 通知开关和安静时段。

插件默认关闭高风险写操作,例如修改敏感 credentials、替换 settings、删除工作区和打开任意本地路径。若部署方确实需要放开,必须在桌面设置中明确启用并重新进行安全审查。

三、Android 移动端

使用现成 APK

APK 位于 03-mobile-apk/artifacts/app-release-development-signed.apk。包名为 org.dsh.dsh_mobile,版本为 0.1.0+11。此 APK 没有使用生产 upload keystore,只适合开发测试和设备兼容性验证。

从源码构建

进入 03-mobile-apk/app-source,依次执行 flutter pub getflutter analyzeflutter testflutter build apk --release。生成文件位于 build/app/outputs/flutter-apk/app-release.apk

如果 android/keystore.properties 不存在,构建脚本会明确回退到 debug key。生产构建时复制 android/keystore.properties.example,填写真实 keystore,但不要把真实文件、keystore 或密码提交到 Git。

当前总项目限制

  • APK 是开发测试签名,不是应用商店生产签名;
  • 本轮没有重新连接物理 Android 设备安装回归;
  • HyperOS 桌面、手环通知图标需要部署方用全新通知补充验证;
  • FCM killed-process 推送尚未启用;
  • Android API 24/25、非小米 OEM 和可穿戴设备矩阵需要交接方补测。

Android 兼容性矩阵

能力API 24–25API 26–32API 33+API 34/35 和 OEM
启动图标五套密度 PNG 回退adaptive iconadaptive icon可能受桌面缓存影响
通知基础通知通知渠道通知渠道 + 运行时权限另受 OEM 后台/渠道策略影响
前台服务基础前台服务基础前台服务通知权限影响可见性dataSync 类型和启动时机更严格
WebViewloopback 隧道loopback 隧道loopback 隧道仅允许当前 127.0.0.1 origin
FCM 强杀推送未启用未启用未启用未启用

Xiaomi/HyperOS、Huawei、OPPO 等 ROM 可能需要用户允许自启动、后台活动、后台联网和不受限制的电池使用。当前实现不能把“系统强杀 App 后仍然收到通知”写成已保证能力。

四、配对和使用流程

LAN

  1. 手机和桌面连接同一个可信局域网;
  2. 在 Harness 的移动端配对面板打开 LAN 监听;
  3. 手机扫描 LAN 二维码,或手动输入 ws://桌面IP:端口/ws 和配对码;
  4. 桌面面板先显示待批准设备,再点击允许;
  5. 手机通过 loopback WebView 隧道打开 Harness /m
  6. 运行一个短任务,确认状态通知和完成通知。

LAN 使用明文 WebSocket,只适合可信网络。不要把 LAN 二维码或配对 URL 发布到公共网络。

WAN

  1. relay /health 已通过 HTTPS 检查;
  2. 桌面插件填入 wss://你的域名
  3. 手机扫描公网二维码,或手动输入同一个 wss:// 地址和配对码;
  4. 桌面点允许;
  5. 关闭手机 Wi-Fi,使用 4G/5G 验证重连;
  6. 在任务完成、等待回答和等待审批场景分别验证通知。

配对码为短期凭据。刷新配对码、停止配对或撤销设备后,旧码/旧设备应失效。不要在日志或截图中保留 dshm://pair?...code=...deviceToken 或 Cookie。

五、图标与通知验收

应用启动图标与 Android 通知 small icon 必须分开处理:

用途资源
启动图标@mipmap/deepseek_launcher
API 26+ adaptive iconmipmap-anydpi-v26/deepseek_launcher.xml
API 24–25 回退mipmap-mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi/deepseek_launcher.png
通知 small icon@drawable/deepseek_notification_v2
前台服务 metadatadsh_notification_icon

通知 small icon 要使用透明背景的单色前景,不能直接拿 adaptive launcher icon 代替。HyperOS 桌面和可穿戴设备可能各自缓存图标,因此 APK 资源正确不等于所有界面立即刷新。

推荐验收顺序:

  1. aapt2 dump resources 确认资源确实进入 APK;
  2. 检查 manifest 的 iconroundIcon 和通知 metadata 没有指向旧资源;
  3. 完全停止并重新打开 App;
  4. 发送一条全新的通知;
  5. 如果手机桌面仍为旧图标,重启 HyperOS 桌面或重启手机;
  6. 如果手环仍为旧通知图标,清理/刷新手环端通知缓存,再发送新通知;
  7. 分别记录手机桌面、手机通知中心和手环通知中心的结果。

根因报告见 docs/ANDROID-ICON-NOTIFICATION-REPORT.md,兼容性细节见 docs/COMPATIBILITY-SECURITY-PACKAGING.md

六、构建和验收

插件和 relay

01-harness-plugin/dsh-mobile-bridge 执行 npm install 后运行 node test/standalone-test.mjs;在 02-relay-server/relay 执行 npm install 后运行 node test/run-mock.js

Android 静态检查

03-mobile-apk/app-source 执行 flutter pub getflutter analyzeflutter testflutter build apk --release。然后对生成 APK 执行:

  • aapt2 dump badging app-release.apk:确认包名、版本和 SDK;
  • aapt2 dump resources app-release.apk:确认 launcher 和 notification 资源;
  • aapt2 dump xmltree app-release.apk --file AndroidManifest.xml:确认 manifest 图标和前台服务 metadata;
  • apksigner verify --verbose app-release.apk:确认签名可验证。

至少确认:包名为 org.dsh.dsh_mobile、最低 API 为 24、manifest 图标为 deepseek_launcher、五套 PNG 回退存在、deepseek_notification_v2 存在、APK 的签名类型与交付标签一致。

设备矩阵

交付方至少补充以下设备验证:

  • Android 7/8:启动图标回退、通知创建、相机扫码;
  • Android 12:前台服务、锁屏通知、loopback WebView;
  • Android 13:首次通知权限、通知渠道、扫码权限;
  • Android 14/15:dataSync 前台服务、切后台、锁屏、应用更新;
  • 一台 Xiaomi/HyperOS:通知渠道、图标缓存和后台策略;
  • 一台非小米 Android 设备:通知 small icon 对照;
  • 一台可穿戴设备:新通知图标和通知正文显示。

没有物理设备时只能报告“未执行”,不能把 aapt2 或 Flutter build 结果写成真机兼容证明。

七、安全脱敏规则

允许提交

  • .env.examplekeystore.properties.example
  • example.comexample.invalid 等示例地址;
  • 不包含用户会话数据的界面截图;
  • 协议样例、mock 测试和静态资源合同;
  • 构建说明和故障排查模板。

禁止提交

  • 真实 relay 域名、服务器 IP、SSH 用户、密码和私钥;
  • 配对码、二维码 payload、deviceTokenmobileCookie
  • Firebase google-services.json 和 FCM service account;
  • Android keystore、keystore.properties 和签名密码;
  • android/local.properties.dart_toolbuildnode_modules
  • adb serial、蓝牙地址、MAC、完整 dumpsys 和运行日志;
  • 含工作区路径、任务内容、内部域名或模型上下文的原始截图。

真实配置只通过部署机器、CI secret、Docker secret 或本机 keystore 注入。公共 Git 中只保留模板,不能把模板当成“可以填写后直接提交”的配置文件。

脱敏结果见 docs/SECURITY-REDACTION-REPORT.md,包内文件边界见 docs/PACKAGE-MANIFEST.md

八、常见故障

现象优先检查
设置页没有移动端配对插件列表、Harness 重启、WEB_SETTINGS_NAMESPACES 白名单
relay 未连接HTTPS /health、DNS、80/443 安全组、Caddy 证书、wss:// 前缀
LAN 配对失败同一可信 Wi-Fi、桌面 IP、端口、防火墙、配对码是否过期
手机页面空白桌面插件在线、loopback 隧道、WebView origin、HTTP tunnel 帧
通知完全不出现Android 13+ 权限、通知渠道、桌面开关、免打扰、OEM 后台策略
手机上的图标正确但手环旧新通知、手环缓存、手环同步设置;不要只重装 App
WAN 强杀后收不到通知当前 FCM 未启用,属于已知能力边界,不是 relay /health 故障
重启 Harness 后需要重新批准当前桌面配对记录以内存为主,属于已知限制

排障日志提交前必须删除真实域名、IP、路径、配对码、token、Cookie、任务正文和设备标识。

九、文档导航

十、交付前清单

  • relay 的真实域名和 secrets 只存在于部署方私有环境;
  • /health、Docker/Caddy 和 WSS 连接检查通过;
  • 插件加载、设置页、配对面板和 standalone 测试通过;
  • relay mock 测试通过;
  • Flutter analyze、test、release build 通过;
  • aapt2 和 apksigner 合同检查通过;
  • 已明确 APK 是 development-signed 还是生产签名;
  • 已完成 LAN 配对、WAN 配对、断线重连和任务通知;
  • 已检查 Android 13+ 权限、Android 14/15 前台服务和 OEM 后台策略;
  • 已在 HyperOS 手机、非小米手机和可穿戴设备发送新通知;
  • 已阅读脱敏报告,没有新增 .env、keystore、二维码或设备数据;
  • 已重新生成并验证 SHA256SUMS.txt
  • Git 工作区干净后再交付 ZIP。

十一、交接结论

本包已经把 Harness 插件、relay 服务器和 Android APK 整合为一个 Git 项目,并保留三张用户提供的 README 展示截图。接手者应把它当作一个端到端系统维护:协议、配对、通知资源、Android 权限和 relay 配置任何一项变更,都要同步专项文档与测试。

当前可交付的是“开发测试整合包”,不是带生产密钥的最终商店包。生产交接时必须由维护者补充私有 relay、生产签名、真实设备矩阵和可穿戴设备验收;如果需要强杀后仍收通知,再单独设计和审查 FCM 方案。

English project guide

Harness Sync is one end-to-end project with three cooperating deliverables:

  1. 01-harness-plugin/ — the desktop Harness bridge;
  2. 02-relay-server/ — the operator-controlled WebSocket relay and deployment tutorial;
  3. 03-mobile-apk/ — the Android APK, Flutter source, and compatibility documents.

The desktop plugin and Android app can pair directly over a trusted LAN using ws://, or both can dial an operator-owned wss:// relay for WAN access. The phone tunnels the Harness /m surface through the desktop, receives session events, and displays local Android notifications.

English quick start

  1. Deploy 02-relay-server/relay behind Caddy and verify https://your-domain/health;
  2. Install 01-harness-plugin/dsh-mobile-bridge in the Harness web profile and restart Harness;
  3. Install the development APK from 03-mobile-apk/artifacts/, or rebuild it with a private production keystore;
  4. Complete LAN pairing first, then WAN pairing;
  5. Grant Android 13+ notification permission and configure OEM background policy;
  6. Validate a new notification on the phone and wearable, not only an old cached notification;
  7. Run the plugin, relay, Flutter, APK resource, and signing checks before handoff.

English security boundary

This repository contains templates and sanitized examples only. Never commit real relay domains, server IPs, SSH keys, pairing codes, device tokens, Web UI cookies, Firebase files, Android keystores, QR payloads, adb serials, Bluetooth addresses, user paths, or task screenshots containing private content. Protocol v1 treats the relay as a trusted boundary and does not provide end-to-end encryption. FCM killed-process delivery is not enabled.

English documentation map

The included APK is version 0.1.0+11, package org.dsh.dsh_mobile, and minimum API 24. It is development-signed and is not an app-store production update.