feat(harmony): add folder transfers and HDC device management
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
# Harmony Connector 手机管理能力调研
|
||||
|
||||
调研日期:2026-09-10。承接 [USB 文件传输调研](harmony-connector.md),评估 Harmony Connector 从文件工具扩展为手机助手。以调研时的最新官方文档设计能力,不以 HarmonyOS 6 为硬上限;HUAWEI Pura 70 Ultra 是待验收设备,不能凭系统名称或文档命令表宣称真机已支持。
|
||||
|
||||
本文只做资料核查和本机工具定位,没有连接手机、安装应用、读取手机数据或改变设备状态。华为商业 HarmonyOS 文档与 OpenHarmony 开源资料分别标注。后者能证明对应源码/命令契约,不能直接证明商业固件的编译选项、授权策略与运行行为。
|
||||
|
||||
## 结论与实现优先级
|
||||
|
||||
建议保留 MTP 用户文件通道,并增加可选的本机官方 HDC 通道。HDC 支持 Mac,适合应用管理、调试文件和诊断;华为要求先开启并授权 USB/无线调试。普通文件传输不应因为新增管理能力而强制进入开发者模式。[华为 HDC](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)、[华为开发者选项](https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/ide-developer-mode)、[华为 USB 文件传输](https://consumer.huawei.com/cn/support/content/zh-cn16090699/)
|
||||
|
||||
以下优先级是本项目的工程建议,表示可实现范围,尚非真机验收结果:
|
||||
|
||||
| 优先级 | 功能 | 启用条件与产品表达 |
|
||||
| --- | --- | --- |
|
||||
| P0 | HDC 工具选择、版本和连接状态;设备基本信息 | 找到可运行工具,用户选择目标,授权成功;失败分清工具缺失、未授权、离线、命令不支持。 |
|
||||
| P0 | 应用列表、应用详情、签名 HAP 安装、单应用卸载 | 包管理命令可用;安装预览包信息和覆盖影响;卸载显示具体包和数据损失。 |
|
||||
| P0 | 日志快照、系统报告导出 | 用户触发,限时/限量,保存到用户选择的位置。 |
|
||||
| P1 | 截图、应用启动、强制停止 | 先探测设备工具和真实组件;动作只针对用户选定对象。 |
|
||||
| P1 | 调试应用数据导出;导出本机已有的安装包 | 沙箱导出逐应用检查调试签名与权限;安装包归档只处理用户拥有的原包,不等同从设备提取所有应用。 |
|
||||
| P1 | 用户文件备份任务 | 明确选择范围、清单、校验和、失败项;仅称“所选文件备份”。 |
|
||||
| P2 | 调试应用数据恢复、无线调试、实时日志/进程、UI 控制 | 探测成功后开放;恢复/控制/无线切换属于改变设备状态的动作。 |
|
||||
| 暂不承诺 | 全机镜像、所有第三方应用数据备份、联系人/短信数据库直接读写、任意已安装应用导出并可恢复 | 未找到面向普通第三方 macOS 助手的官方公共接口;不能由 MTP 或 HDC shell 推导得到。 |
|
||||
|
||||
## 工具获取、发现和授权
|
||||
|
||||
华为官方获取路径为 DevEco Studio 所带 SDK,或 Command Line Tools 的 SDK;macOS 下典型位置为 `DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc`。独立运行还需保留相邻 `libusb_shared` 依赖。这说明可以使用已安装的官方工具,不能据此推断可以重新打包分发华为整个 SDK。[华为 HDC 环境准备](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)、[官方工具下载入口](https://developer.huawei.com/consumer/cn/download/)
|
||||
|
||||
实现建议:先读用户保存的绝对路径,再查应用自身继承的 `PATH`,最后检查 `/Applications`、`~/Applications` 的 DevEco Studio 应用包及用户选定的 Command Line Tools 目录。解析软链接,验证是文件且可执行,显示最终路径。不要全盘扫描、执行下载来的未知工具或自动修改 shell 配置;GUI 的 PATH 不一定与交互终端相同。
|
||||
|
||||
本次本机只读发现:`PATH` 中无 `hdc`;在 `/Applications`、`~/Applications` 和存在的 `~/Library/OpenHarmony`、`~/Library/Huawei`、`~/Library/DevEcoStudio`、`~/ohos-sdk` 范围未找到候选工具。这不是“整台电脑绝无 HDC”的结论。没有安装 SDK,也没有执行设备命令。
|
||||
|
||||
首次开启开发者选项与随后打开调试开关是不同步骤:华为手机/平板指引要求在设备名称页连续点击软件版本七次,确认并按需输入 PIN,首次开启可能触发重启。之后 USB/无线调试需在手机确认计算机授权。插件应引导用户操作设备,不绕过锁屏、信任弹窗、企业调试管控。[华为开发者选项](https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/ide-developer-mode)
|
||||
|
||||
OpenHarmony HDC 仓库采用 Apache-2.0。若未来需要随插件交付 HDC,可评估从确切开源提交自行构建并保留许可证、版权与依赖声明;商业 Huawei 下载包的分发权需核对其实际许可,本次未确认该授权。不能把仓库许可扩展至 SDK 的其他组件或使用华为商标暗示官方产品。[OpenHarmony HDC LICENSE](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/LICENSE)
|
||||
|
||||
## CLI 调用契约
|
||||
|
||||
以下表格中 `key` 是用户选定的 `connect-key`,`bundle`/`ability`/`module` 来自设备已返回且验证过的数据;`local` 是用户选择的绝对本地路径。数组是传给 `Command::new(hdc).args(...)` 的 argv,省略可执行文件本身。带尖括号的值只作占位,不能原样执行。
|
||||
|
||||
宿主不要使用 `sh -c` 拼接 HDC 命令。`hdc shell` 的最后一个参数仍会由设备 shell 解释,必须用固定模板与严格参数验证/单引号转义;宿主 argv 安全不等于远端 shell 安全。文件名、应用名和设备返回内容都不是可信 shell 代码。
|
||||
|
||||
### 只读探测与设备信息
|
||||
|
||||
| 功能 | argv | 证据与处理 |
|
||||
| --- | --- | --- |
|
||||
| 客户端版本 | `["-v"]` | 解析 `Ver:` 字段,保留未知版本原文。 |
|
||||
| 客户端/服务端版本 | `["checkserver"]` | 记录两端版本,不能认为刚选择的二进制已经替换后台旧服务。 |
|
||||
| 设备状态 | `["list", "targets", "-v"]` | 识别 `USB/TCP` 和 `Unknown/Ready/Connected/Offline/Unauthorized`;`[Empty]` 表示没有目标。 |
|
||||
| HDC 帮助 | `["-h", "verbose"]` | 作为本机命令存在性的证据。 |
|
||||
| 包管理能力 | `["-t", key, "shell", "bm help"]` | 成功识别帮助内容后再开放相关操作。 |
|
||||
| 组件管理能力 | `["-t", key, "shell", "aa help"]` | 不通过实际启动/停止应用来探测。 |
|
||||
| 截图工具能力 | `["-t", key, "shell", "uitest help"]` | 要求返回可识别 `screenCap` 帮助。 |
|
||||
| 日志工具能力 | `["-t", key, "shell", "hilog -h"]` | 确认 `-x` 可用。 |
|
||||
| 基本设备信息 | `["-t", key, "shell", "hidumper -c base"]` | 华为文档展示 BuildId、ReleaseType、OsVersion、DeviceType 等字段。 |
|
||||
| 参数读取 | `["-t", key, "shell", "param get <name>"]` | 单项读取,键需要固件实际返回/探测;未知键不应显示成空字符串的正常值。 |
|
||||
|
||||
HDC 命令和状态依据 [华为 HDC](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc);设备信息依据 [华为 HiDumper](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/hidumper);`param get` 语法依据 [OpenHarmony param 文档](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/tools/param-tool.md)。`hdc -t key shell hdcd -v` 是守护程序版本探测,不能当作手机完整系统版本。
|
||||
|
||||
实现应把“工具不存在”“没有授权”“权限不足”“输出无法识别”“版本不支持”与“数据为空”区分开。每个能力使用 `unknown / available / unavailable` 加原因;仅凭全局 HDC 连接成功不能一次性点亮所有管理功能。连接阶段不要执行 `kill -r`、`reconnect`、`tmode`、重启或任何包管理写操作。
|
||||
|
||||
### 应用列表、安装、卸载与运行
|
||||
|
||||
| 功能 | argv | 条件 |
|
||||
| --- | --- | --- |
|
||||
| 包名列表 | `["-t", key, "shell", "bm dump -a"]` | 华为官方 FAQ 直接采用该命令查询已安装应用。 |
|
||||
| 包详情 | `["-t", key, "shell", "bm dump -n <bundle>"]` | 华为 HiDumper 指引用详情中的 `appProvisionType` 判断 debug。 |
|
||||
| 调试包列表 | `["-t", key, "shell", "bm dump -g"]` | OpenHarmony 最新文档支持;需以本机帮助/实际输出确认。 |
|
||||
| 应用显示名 | `["-t", key, "shell", "bm dump -n <bundle> -l"]` | OpenHarmony 文档标注 API 20 起;失败仍可显示包名。 |
|
||||
| 安装签名 HAP | `["-t", key, "install", local]` | 本地绝对路径,成功后重新查询包版本。 |
|
||||
| 单应用卸载 | `["-t", key, "uninstall", bundle]` | 指定包名;拒绝自动级联卸载依赖。 |
|
||||
| 启动组件 | `["-t", key, "shell", "aa start -b <bundle> -a <ability> -m <module>"]` | 从详情找可启动、已导出的真实组件;不能硬编码所有应用都有 `EntryAbility`。 |
|
||||
| 强制停止 | `["-t", key, "shell", "aa force-stop <bundle>"]` | 与正常退出不同,可能丢失尚未保存的工作。 |
|
||||
|
||||
查询依据:[华为应用市场错误排查](https://developer.huawei.com/consumer/en/doc/harmonyos-references/errorcode-appgallery)、[华为 HiDumper](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/hidumper)。`bm` 详细参数与 user/root 限制依据 [OpenHarmony bm 文档](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/tools/bm-tool.md)。`aa` 的显式启动、exported 限制、强停和响应依据 [OpenHarmony aa 文档](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/tools/aa-tool.md);商业华为 HDC 将 aa 列为配套工具,但本次华为 aa 独立页面未成功抓取,故实际能力仍需设备探测。
|
||||
|
||||
安装不是“有 HAP 就能装”:华为要求真实设备使用签名包,自动签名会绑定调试设备信息。debug/release 签名、应用标识、版本和多模块一致性受安装器校验;不能把 OpenHarmony 的公开测试证书当作商业设备通用签名,也不能从 HDC 命令存在推导任意 release 包均可安装。[华为开发入门](https://developer.huawei.com/consumer/cn/develop-novice-guide/)、[华为自动签名](https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/ide-signing-auto)、[华为安装与更新一致性校验](https://developer.huawei.com/consumer/cn/doc/doccenter-getting-started/install-and-update-consistency-verification)
|
||||
|
||||
华为 HDC 说明 `install` 默认就是覆盖安装,省略 `-r` 不能防止覆盖;安装路径支持 HAP/应用内 HSP,APP 包从 API 22 起。`-w` 等组合参数有特殊解析约定,初版建议先只用必要参数。用户操作之前展示即将安装的应用与已装版本;签名冲突或系统拒绝时保留错误码,不能自动先卸载再安装。卸载共享库可能因其他应用依赖而被拒绝。[华为 HDC 安装说明](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)、[华为共享包依赖错误 9568312](https://developer.huawei.com/consumer/cn/doc/doccenter-dev-faq/faqs-technology-32)
|
||||
|
||||
包名清单是行文本,详情可能有标签/前缀加 JSON 内容,不能将所有 `bm` 命令输出当作同一个稳定 JSON API。建议仅接受明确命令对应的格式:列表验证包名,详情解析完整 JSON 对象并校验预期字段与查询包名;无法解析则显示原始诊断并禁用依赖该字段的操作。显示名不能作为包名、权限或可卸载性的替代。安装和卸载需同时判断进程结果、工具成功/失败信息及操作后的目标状态,不能只看是否含 `AppMod finish`。
|
||||
|
||||
### 截图、日志和系统报告
|
||||
|
||||
1. 探测 `uitest help` 后,为每次截图生成不可预测且只含安全字符的文件名。
|
||||
2. 调用 `["-t", key, "shell", "uitest screenCap -p /data/local/tmp/curios-<nonce>.png"]`。
|
||||
3. 调用 `["-t", key, "file", "recv", "/data/local/tmp/curios-<nonce>.png", localTemp]`。
|
||||
4. 校验下载文件确实是可解码 PNG,再提交到用户目标位置。只删除本次创建的远端文件;失败时不要清理整个临时目录。
|
||||
|
||||
`uitest screenCap -p`、只能存到 `/data/local/tmp/` 的限制,以及 `-d` 多屏参数从 API 20 开始,均来自 [OpenHarmony UITest 官方文档](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/application-test/uitest-guidelines.md)。华为官方也提供 HiSmartPerf 的截图采集/文件导出流程,但本次没有将 `snapshot_display` 的商业固件可用性或任何投屏帧率作为已确认能力。[华为 HiSmartPerf](https://developer.huawei.com/consumer/cn/doc/doccenter-testing/smartperf-guidelines)
|
||||
|
||||
| 导出 | argv | 实现建议 |
|
||||
| --- | --- | --- |
|
||||
| 日志快照 | `["-t", key, "shell", "hilog -x"]` | `-x` 非阻塞读完退出,宿主将 stdout 写到独立临时文件。 |
|
||||
| 实时日志 | `["-t", key, "shell", "hilog"]` | 持续读取,提供停止按钮和大小限制;不要视为普通短请求。 |
|
||||
| 系统报告 | `["-t", key, "bugreport", localTemp]` | FILE 是本地路径;内容可能较多,预留更长但有限的超时。 |
|
||||
| 已有落盘日志 | `["-t", key, "file", "recv", "/data/log/hilog", localDir]` | 只有权限与路径确认后才能导出,不需先开启新的落盘任务。 |
|
||||
|
||||
`hilog -x` 语义依据 [OpenHarmony HiLog](https://github.com/openharmony/docs/blob/f41b9345badd47c7ab0c263344cd7f4b5a549afb/zh-cn/application-dev/dfx/hilog.md);`bugreport` 与现有落盘日志路径依据 [华为 HDC](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)。日志与系统报告可能包含应用活动和设备标识;默认只本地保存,不自动上传。不要为普通日志导出自动执行清日志、关闭隐私过滤或开启持续日志落盘。
|
||||
|
||||
## 备份和恢复:需要分别命名的三种能力
|
||||
|
||||
### 用户文件副本
|
||||
|
||||
MTP 面向设备公开的存储对象。选择文件夹后递归复制、生成大小/校验和清单、记录失败项,是可以实现的“所选文件备份”;没有通过 MTP 暴露的沙箱、系统设置、账号和数据库不在范围内。图库模式限制沿用原调研,不能把普通文件夹可写推导为可任意恢复图库数据库。[libmtp 对象/存储 API](https://github.com/libmtp/libmtp/blob/v1.1.23/src/libmtp.h.in)、[华为 USB 文件传输](https://consumer.huawei.com/cn/support/content/zh-cn16090699/)
|
||||
|
||||
### 调试应用数据导出与导入
|
||||
|
||||
华为明确 `shell -b`、`file send/recv -b` 只用于“调试证书签名且已经在设备上启动”的应用;不是任意应用的沙箱读取入口。`-b` 从 API 15 引入。先查询 `appProvisionType`,再对具体目录进行只读访问探测,不应单凭包名出现在应用列表就启用备份。[华为 HDC 沙箱条件](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)、[华为 HiDumper 调试类型判定](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/hidumper)
|
||||
|
||||
```text
|
||||
查询指定调试应用目录:
|
||||
["-t", key, "shell", "-b", bundle, "ls data/storage/el2/base/"]
|
||||
|
||||
导出用户选择的沙箱文件或目录:
|
||||
["-t", key, "file", "recv", "-b", bundle, "<verified-remote-path>", "<new-local-directory>"]
|
||||
|
||||
向同一调试应用导入已选择的数据:
|
||||
["-t", key, "file", "send", "-b", bundle, "<local-file>", "<verified-remote-path>"]
|
||||
```
|
||||
|
||||
这些是官方 `-b` 文件操作语法,remote path 应在该应用实际可见的根目录内,不使用 `/data/app/...` 猜测另一个应用的路径,不接受越界 `..`。导出清单应记录设备/系统、包名、版本、签名类型、所选路径、时间、实际复制文件及校验结果。正在运行的应用可能继续写入数据库;原始文件副本不自动获得事务一致性,也不保证跨设备的密钥、登录状态或应用版本可恢复。建议界面名称为“导出调试应用数据”,完整备份成功必须有明确的范围与验证。
|
||||
|
||||
恢复是覆盖写入,不应在枚举或探测时尝试。只允许用户选择明确的备份和目标应用,核对包名/版本/范围,展示将修改的文件后执行。未经该应用可恢复性验证,不提供一键“全部应用恢复”。不要通过重新签名现有商业应用或卸载重装来制造沙箱访问权限。
|
||||
|
||||
### 官方系统备份
|
||||
|
||||
华为应用备份框架允许应用接入 `BackupExtensionAbility` 并声明可备份范围,但普通应用自身不能触发系统备份;触发功能面向系统应用。官方最新验证指引使用数据克隆,由新旧设备配对触发。应用可不接入,也可限制备份内容。因此额外装一个普通手机伴随应用,并不自然获得其他应用全部数据的备份权。[华为备份概述](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V13/app-file-backup-overview-V13)、[华为应用接入](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/app-file-backup-extension)、[华为数据克隆验证](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/app-file-backup-dataclone)
|
||||
|
||||
特别检查了 OpenHarmony `filemanagement_app_file_service` 提交 `589be5d84d3c23967be62ca7f0317690237a0041`:
|
||||
|
||||
- `backup_tool/BUILD.gn` 仅在 `build_variant == "root"` 编入真实操作,且 `install_enable = false`。
|
||||
- 未定义 `BACKUP_TOOL_ENABLE` 时,`main()` 直接返回 0,不执行备份。
|
||||
- 备份服务检查 BACKUP 权限;HAP 调用还检查系统应用身份,shell 调用亦受 UID 条件限制。
|
||||
|
||||
这是开源实现证据,不能证明商业设备使用完全相同实现;却直接说明“找到 backup_tool 且退出码为 0”不是备份成功证据。本轮不将该工具作为商业设备备份后端,也不自动尝试备份/恢复命令。[OpenHarmony 构建约束](https://github.com/openharmony/filemanagement_app_file_service/blob/589be5d84d3c23967be62ca7f0317690237a0041/tools/backup_tool/BUILD.gn)、[无操作入口](https://github.com/openharmony/filemanagement_app_file_service/blob/589be5d84d3c23967be62ca7f0317690237a0041/tools/backup_tool/src/main.cpp)、[服务权限检查](https://github.com/openharmony/filemanagement_app_file_service/blob/589be5d84d3c23967be62ca7f0317690237a0041/services/backup_sa/src/module_ipc/service.cpp)
|
||||
|
||||
## 与官方助手的能力对照
|
||||
|
||||
| 官方路线 | 已确认范围 | 对本插件的结论 |
|
||||
| --- | --- | --- |
|
||||
| HiSuite / 华为手机助手 | 当前官网针对 HarmonyOS 5+ 列出基础数据、部分第三方应用及数据、部分设置备份;受系统/应用兼容性限制。明确 5+ 暂不支持 macOS 连接。 | Windows 官方能力不等于 macOS 第三方插件可调用的协议/API。不能用旧 Android/HDB 教程保证原生鸿蒙兼容。 |
|
||||
| 手机“备份和恢复 → 外部存储” | 官方 5+ 指引支持第三方应用和部分应用数据等,并需备份密码;范围以实际设备为准。 | 可以提供官方操作指引,或归档用户已经生成的备份文件;尚无公开证据支持插件在 Mac 直接触发/解密其备份。 |
|
||||
| 数据克隆 | 最新开发者指引通过两台设备触发已接入应用的数据迁移验证。 | 是系统侧迁移流程,不是通用电脑备份 CLI。 |
|
||||
| 华为分享 + 鸿蒙星河互联 | 官方提供与 Mac 的图片、视频、文档无线互传流程。 | 可链接官方方案;没有据此获得可嵌入分享 SDK、应用安装或全机备份能力。 |
|
||||
|
||||
分别依据:[华为 HiSuite 当前支持范围](https://consumer.huawei.com/cn/support/hisuite/)、[华为外部存储备份](https://consumer.huawei.com/cn/support/content/zh-cn16024725/)、[华为数据克隆验证](https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/app-file-backup-dataclone)、[华为与 Mac 互传](https://consumer.huawei.com/cn/support/content/zh-cn16093657/)。产品可以覆盖“文件、应用、设备、诊断、备份”模块;不同模块应展示实际通道与数据范围,不把官方系统级功能画成已经可执行的按钮。
|
||||
|
||||
## 无线与其他能力
|
||||
|
||||
用户先在手机开启无线调试,输入手机显示的 IP 和端口,然后调用 `["tconn", "<ip>:<port>"]`;断开用 `["tconn", "<ip>:<port>", "-remove"]`。官方仍将 TCP 调试标为测试场景。`tmode port` 会重启设备守护进程并断开会话,连接探测不应使用它。端口转发、重启、UI 输入可以作为后续显式操作,不默认启用。[华为 HDC 无线和连接管理](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)
|
||||
|
||||
最新文档版本提示用于解释能力差异,不作为 HarmonyOS 大版本硬编码:`-b` 与 API 15/HDC 3.1.0e 配套;API 20/HDC 3.2.0b 增加部分网络能力;APP 安装 API 22;安装自动授权 `-g` API 24;沙箱无命令交互式 shell、reconnect、子服务器等 API 26 新能力仍需两端支持。实现按本机帮助和设备实际结果逐项判定,不自动调用新命令来“修复”连接。[华为 HDC 版本表](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/hdc)
|
||||
|
||||
## 输出解析、操作风险与验收
|
||||
|
||||
建议为 HDC 建立独立执行适配器:固定可执行路径、每次携带目标、有限并发、逐设备串行写入、进程组取消、stdout/stderr 大小上限、操作超时。长日志和文件任务走流式输出,UI 接收结构化事件,不在前端解释 shell 字符串。不要为了隔离无条件另开 USB server,也不要在退出插件时杀掉用户 DevEco Studio 的共享 HDC 服务。
|
||||
|
||||
最小验收应覆盖可观察行为:
|
||||
|
||||
- 无工具、工具依赖缺失、未连接、拒绝授权、多设备、未知输出格式、版本不匹配,都不得显示假空列表或操作成功。
|
||||
- 应用列表中中文显示名与包名分离;详情解析失败不影响其他条目;安装拒绝/签名冲突/包格式错误保留真实结果;成功安装/卸载后刷新验证。
|
||||
- 签名 HAP 安装只能使用用户专门选取的测试包;卸载只能操作明确选择的应用。验证不得卸载用户日常应用来测试失败路径。
|
||||
- 截图下载后能解码,报告文件非空且包含实际内容,日志导出有限且可取消;中断不会把临时文件报告为完成。
|
||||
- 调试沙箱必须验证 release 应用被限制、debug 未启动的处理、权限失败、部分传输、中文/空格路径;导出实际文件校验和对应清单。恢复只在专门测试应用验证,并检查恢复后的应用行为。
|
||||
- 系统备份无法实现时明确展示边界,不执行空壳 `backup_tool`,不以退出码 0、模拟输出、无设备测试或构建通过替代真机验收。
|
||||
|
||||
本调研最终产物仅为本文。文档命令来自第一方资料,设备兼容性仍需按实际固件验证;本机未找到 HDC 的范围见上文,未对手机执行任何命令。
|
||||
|
||||
## 补充:应用输出解析与真实入口选择
|
||||
|
||||
这一节按 2026-09-10 获取的 OpenHarmony 源码追踪输出生产链:Bundle Framework `e0b9be9be36186e040385895f7f764e6e111a809` 与 bm CLI `6b9b9ad316b764f472194a962081c0fb99c32fdf`。下面是**由源码生成规则还原、省略无关字段的代表样例**,不是 HUAWEI Pura 70 Ultra 的实测输出。商业设备返回新结构时应报告格式未知,不能假装已经得到相同数据。
|
||||
|
||||
### `bm dump -a` / `bm dump -g`
|
||||
|
||||
成功输出是按用户分组的纯文本,不是 JSON;当前 CLI 直接转发服务结果,没有额外 `all bundle names:` 标题。样例中的应用名是占位数据,缩进实际为制表符。服务支持多个用户段;CLI 默认查询当前用户,指定不活跃 `-u` 可能产生前置警告并退回当前用户。[BMS 列表生成](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/bundle_mgr_host_impl.cpp#L2999)、[bm CLI 查询和转发](https://github.com/openharmony/bundlemanager_bundle_tool/blob/6b9b9ad316b764f472194a962081c0fb99c32fdf/frameworks/src/bundle_command.cpp#L1153)
|
||||
|
||||
```text
|
||||
ID: 100:
|
||||
com.example.notes
|
||||
com.example.reader
|
||||
```
|
||||
|
||||
解析建议:保留 userId 分组;只在已识别 `ID: <integer>:` 段内读取并验证包名;允许空段和空行;未知诊断行不能被当作应用。不要把任意含点字符串提取成包名,也不要把错误文本归一化成零应用。空结果或查询失败时,当前 CLI 会输出下面的错误,且 dump 分支仍可能返回成功退出码。[bm 空结果处理](https://github.com/openharmony/bundlemanager_bundle_tool/blob/6b9b9ad316b764f472194a962081c0fb99c32fdf/frameworks/src/bundle_command.cpp#L1246)、[缺包查询官方系统测试](https://github.com/openharmony/bundlemanager_bundle_tool/blob/6b9b9ad316b764f472194a962081c0fb99c32fdf/test/systemtest/bm/bm_command_dump_system_test.cpp#L106)
|
||||
|
||||
```text
|
||||
error: failed to get information and the parameters may be wrong.
|
||||
```
|
||||
|
||||
### `bm dump -n <bundle>` 的字段
|
||||
|
||||
服务先输出包名和冒号,再输出完整 JSON 对象。它显式移除顶层 `abilityInfos`,组件应从 `hapModuleInfos[].abilityInfos[]` 读取;不能把 manifest 的 `abilities` 字段直接当作 dump 格式。[BMS 详情组装](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/bundle_mgr_host_impl.cpp#L3094)、[模块序列化](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/src/hap_module_info.cpp#L927)
|
||||
|
||||
```text
|
||||
com.example.notes:
|
||||
{
|
||||
"name": "com.example.notes",
|
||||
"versionCode": 1000000,
|
||||
"versionName": "1.0.0",
|
||||
"entryModuleName": "entry",
|
||||
"applicationInfo": {
|
||||
"bundleName": "com.example.notes",
|
||||
"appProvisionType": "debug"
|
||||
},
|
||||
"hapModuleInfos": [
|
||||
{
|
||||
"moduleName": "entry",
|
||||
"mainAbility": "NotesAbility",
|
||||
"mainElementName": "NotesAbility",
|
||||
"isStageBasedModel": true,
|
||||
"abilityInfos": [
|
||||
{
|
||||
"bundleName": "com.example.notes",
|
||||
"moduleName": "entry",
|
||||
"name": "NotesAbility",
|
||||
"type": 1,
|
||||
"visible": true,
|
||||
"enabled": true,
|
||||
"isStageBasedModel": true,
|
||||
"isLauncherAbility": false,
|
||||
"skills": [
|
||||
{
|
||||
"actions": ["ohos.want.action.home"],
|
||||
"entities": ["entity.system.home"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
准确映射与限制:
|
||||
|
||||
| 需要的信息 | dump 字段与解释 |
|
||||
| --- | --- |
|
||||
| 应用身份/版本 | 顶层 `name`、`versionCode`、`versionName`;并校验 `applicationInfo.bundleName` 与查询目标一致。 |
|
||||
| 调试签名 | `applicationInfo.appProvisionType`;调试值 `debug`,缺失是未知。 |
|
||||
| 入口模块 | 顶层 `entryModuleName`;模块使用 `moduleName`,不是模块显示用的 `name`。 |
|
||||
| 模块主组件 | `hapModuleInfos[].mainElementName`、`mainAbility`;当前 Stage 解析都来源于 manifest 的 `mainElement`。 |
|
||||
| 实际组件 | `hapModuleInfos[].abilityInfos[]`,每项携带 `bundleName`、`moduleName`、`name`。 |
|
||||
| 可见/导出状态 | dump 使用布尔 `visible`。Stage manifest 的 `exported` 写入内部 `visible`,且比旧 `visible` 配置优先;dump 不使用 `exported` 字段。 |
|
||||
| UI 组件类型 | `type` 是数字枚举:`UNKNOWN=0`、`PAGE=1`、`SERVICE=2`、`DATA=3`、`FORM=4`、`EXTENSION=5`;Stage UIAbility 解析为 PAGE。 |
|
||||
| 是否可用 | `enabled` 是布尔;显式 false 时不能作为启动候选。缺字段不应凭空生成 true。 |
|
||||
| 桌面入口 skill | 同一项 `skills[]` 中,`actions` 含 `ohos.want.action.home` 或 `action.system.home`,且 `entities` 含 `entity.system.home`。 |
|
||||
| `isLauncherAbility` | 不是普通应用“可从桌面启动”的通用标志。当前实现只在特殊 launcher entity、预装且系统应用等条件下设置。不能要求普通入口它必须为 true。 |
|
||||
|
||||
这些映射依据:[BundleInfo 序列化](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/src/bundle_info.cpp#L898)、[ApplicationInfo 序列化](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/src/application_info.cpp#L1064)、[组件 JSON 字段](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/include/common_json_converter.h#L669)、[组件类型枚举](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/include/ability_info.h#L57)、[exported 解析](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/module_profile.cpp#L636)、[Stage 类型赋值](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/module_profile.cpp#L2702)、[模块入口赋值](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/inner_bundle_info.cpp#L1800)、[HOME skill 与 launcher 判定](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/services/bundlemgr/src/module_profile.cpp#L3005)、[HOME 字符串常量](https://github.com/openharmony/bundlemanager_bundle_framework/blob/e0b9be9be36186e040385895f7f764e6e111a809/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h#L174)。
|
||||
|
||||
实现建议:从合法详情中选择 `type == 1 && visible == true`,排除明确禁用项,并校验组件包名/模块名;优先具有 HOME skill 的组件,再用入口模块和主组件字段消除歧义。没有唯一可确定入口时展示实际组件选择,不自动启动任意 exported 页面。`visible`、`type` 缺失时不能直接宣称可启动;旧格式适配应增加明确来源与 fixture。权限仍由系统决定,元数据筛选通过不保证启动一定成功。以上代表样例对应 argv 为 `["-t", key, "shell", "aa start -b com.example.notes -a NotesAbility -m entry"]`。
|
||||
|
||||
解析 JSON 时应先识别查询包名的前缀,再对完整对象解析;校验身份和字段类型,限制输入大小/嵌套深度。不要从错误文本中随意截取第一个到最后一个花括号,或在详情中递归搜同名 `name` 来猜应用身份。没有完整有效详情时保留应用条目和错误,禁用依赖组件/调试状态的操作。
|
||||
|
||||
## 补充:`hdc file recv -b` 目录层级
|
||||
|
||||
OpenHarmony HDC `e93f663afa159d3e601cad1e1869d70326731af6` 的收件端根据**传输开始时本地目标是否存在**决定是否保留源目录 basename;`-b` 在设备端解析沙箱路径,本地主机仍走同一文件接收逻辑。以下以已确认可读的 `data/storage/el2/base` 目录中存在 `files/a.txt` 为例。[HDC 源目录任务生成及沙箱处理](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/file.cpp#L266)、[接收端目标目录和文件名处理](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/transfer.cpp#L724)
|
||||
|
||||
| 调用前本地状态 | 接收目标 argv 最后一个参数 | 最终文件位置 |
|
||||
| --- | --- | --- |
|
||||
| `/exports/job` 已存在且为目录 | `/exports/job` | `/exports/job/base/files/a.txt` |
|
||||
| `/exports/job` 不存在 | `/exports/job` | `/exports/job/files/a.txt` |
|
||||
| `/exports/job` 已存在且为普通文件 | `/exports/job` | 目录模式报错,不能作为合法备份目标。 |
|
||||
|
||||
源路径加尾部 `/` 不构成“只复制内容”的开关;源 basename 提取前会去除尾部分隔符。目标不存在时接收器先建目标,再从相对任务路径剥掉第一层;目标已经存在则保留第一层。不要用 rsync 的尾斜杠规则推断 HDC。[basename 实现](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/base.cpp#L1823)、[CheckFilename 首层处理](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/transfer.cpp#L801)
|
||||
|
||||
建议先创建唯一、空的 staging 父目录,例如 `/exports/.curios-job-<nonce>`,再传 `["-t", key, "file", "recv", "-b", bundle, "data/storage/el2/base", "/exports/.curios-job-<nonce>"]`;验收期望位于 `staging/base/...` 的输出,记录 `remoteRoot` 与 `localRelativeRoot: "base"`。完成后按清单提交用户目标。恢复必须依清单映射,不能将整个 `base` 再送入设备已经存在的 `base`,制造 `base/base`。若想把目录内容直接放入目标,可使用尚不存在的目标路径,但实现必须控制初始状态,并在对应本机 HDC 版本做行为验收。
|
||||
|
||||
该源码递归任务以文件为单位,纯空源目录直接报 `Operation failed, because the source folder is empty.`;空子目录也不能按文件任务数量证明完整保留。不能把这类报错改写为完整备份成功。若产品承诺保留空目录,应另行枚举并记录空目录、处理权限失败,或将“不保留空目录”列入导出范围。源码不替代当前华为 SDK 二进制的行为测试。[目录遍历实现](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/src/common/transfer.cpp#L658)、[空目录官方测试](https://github.com/openharmony/developtools_hdc/blob/e93f663afa159d3e601cad1e1869d70326731af6/test/scripts/testModule/test_hdc_file.py#L502)
|
||||
Reference in New Issue
Block a user