Files
Obsidian/项目文档/重汽/PX3 地图资源拷贝业务流程.md
2026-11-05 14:35:04 +08:00

470 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PX3 地图资源拷贝业务流程
## 1. 文档定位
| 项目 | 内容 |
| ---- | -------------------------- |
| 项目 | 重汽 PX3 地图数据管理 |
| 适用工程 | `YX_MainInterface_ZhongQi` |
| 适用平台 | Android 4.4 PX3 车机 |
| 当前阶段 | ZIP64 方案已编码,等待 PX3 真机联调 |
| 更新日期 | 2026-08-12 |
本文档描述当前有效的 ZIP 压缩包方案。旧的“U盘展开目录复制到Map”“Map展开目录复制到sdcard”方案已废弃,不再作为开发和验收依据。
## 2. 背景和目标
PX3 存在两代地图存储方案:
| 设备类型 | 硬件能力 | 地图方案 |
|---|---|---|
| 新 PX3 32G 设备 | 不再预留外置 TF 卡接口 | Map 分区保存地图 ZIP,首次使用时解压到内部共享存储 |
| 旧 PX3 设备 | 可以插入外置 TF 卡 | 保留原有 TF 卡导航流程 |
已确认所有无 TF 卡接口的新 PX3 设备均为 32G,当前代码以“PX3 + eMMC 32G”作为新流程开关。
本次改为 ZIP 的主要目标:
1. Map 分区只保存约 8.39GB 的压缩包,不再保存约 13.12GiB 的展开目录。
2. 地图初始化时只解压高德需要的地图和语音资源。
3. 不在 sdcard 创建完整临时地图副本。
4. 保留后台执行、进度恢复、取消重试和差异补齐能力。
5. 旧设备 TF 卡流程保持不变。
## 3. 固定路径和数据范围
### 3.1 路径表
| 用途 | 路径 |
|---|---|
| 旧设备 TF 卡地图 | `/mnt/external_sd0/amapauto9` |
| U盘挂载点 | `/mnt/usb_storage` |
| U盘地图压缩包 | `/mnt/usb_storage/amapauto9.zip` |
| Map地图根目录 | `/mnt/map/amapauto9` |
| Map地图压缩包 | `/mnt/map/amapauto9/amapauto9.zip` |
| Map导入临时文件 | `/mnt/map/amapauto9/amapauto9.zip.part` |
| 内部高德根目录 | `/mnt/sdcard/amapauto9` |
| 内部地图目录 | `/mnt/sdcard/amapauto9/data/navi/compile_v2/chn` |
| 内部语音目录 | `/mnt/sdcard/amapauto9/data/voice` |
| 解压中标记 | `/mnt/sdcard/amapauto9/.yaxon_map_copying` |
| 解压完成标记 | `/mnt/sdcard/amapauto9/.yaxon_map_complete` |
`/mnt/sdcard` 与 `/sdcard` 在当前设备上指向同一内部共享存储。本模块代码统一使用 `/mnt/sdcard`。
### 3.2 ZIP 内部结构
压缩包必须包含:
```text
amapauto9/data/navi/compile_v2/chn/...
amapauto9/data/voice/...
```
只解压以下两个白名单前缀:
```text
amapauto9/data/navi/compile_v2/chn/
amapauto9/data/voice/
```
解压时去掉首层 `amapauto9/`,最终写入:
```text
/mnt/sdcard/amapauto9/data/navi/compile_v2/chn
/mnt/sdcard/amapauto9/data/voice
```
本期不解压:
- `amapauto9/detail_list`
- `amapauto9/res/global.db`
- ZIP 中除 `chn` 和 `voice` 外的其他内容
### 3.3 当前压缩包基线
| 项目 | 数值 |
|---|---|
| ZIP文件大小 | `8,387,521,520 bytes`,约 `7.81GiB` |
| SHA-256 | `69B1448C2FB6BA981F14C7D4A0B5DCFF6F6A3130020DB1D52D47202D14BFF1CC` |
| ZIP总条目 | 2245 |
| 白名单文件 | 1866 |
| 白名单解压后大小 | `14,088,198,086 bytes`,约 `13.12GiB` |
| 最大单文件 | 约 121MB |
该文件中央目录使用 ZIP64,不能依赖 Android 4.4 自带 `java.util.zip.ZipFile`。代码使用 Apache Commons Compress 1.9 读取 ZIP64。
## 4. 新旧设备分流
```text
用户点击导航
-> 判断是否为 PX3 + eMMC 32G
|
+-- 否:保留历史TF卡流程
| -> /mnt/external_sd0/amapauto9存在:启动高德
| -> 不存在:提示插入含离线地图的TF卡
|
+-- 是:执行内部地图流程
-> 内部地图检查通过:启动高德
-> 检查不通过:进入地图初始化页面
-> Map压缩包存在:自动解压到sdcard
-> Map压缩包不存在:提示联系服务人员
```
32G新设备不检查TF卡,也不在Map异常时回退TF流程。
## 5. 两个页面入口
### 5.1 普通导航入口
页面标题:`地图初始化`。
页面只显示:
- 当前初始化提示
- 水平进度条
- 一位小数进度值
进入页面后自动执行“Map ZIP 解压到 sdcard”,不显示U盘、删除和路径等工程操作。成功后只提示初始化完成,不自动启动导航;用户再次点击导航后进入高德。
### 5.2 工程模式入口
入口:工程菜单 -> `地图数据管理`。
三个独立操作:
1. `删除Map分区地图`
2. `从U盘导入到Map分区`
3. `复制地图到sdcard目录`
推荐恢复顺序:
```text
删除Map分区地图
-> 从U盘导入到Map分区
-> 复制地图到sdcard目录
```
三个操作不会自动串联。
## 6. 地图状态判断
### 6.1 U盘地图状态
同时满足以下条件时认为U盘地图存在:
1. `/mnt/usb_storage` 状态为 `MEDIA_MOUNTED`。
2. `/mnt/usb_storage/amapauto9.zip` 是非空普通文件。
真正导入前还会读取 ZIP64 中央目录,确认地图、语音和核心文件存在。
### 6.2 Map源状态
`/mnt/map/amapauto9/amapauto9.zip` 是非空普通文件时,认为Map压缩包存在。
该快速状态只用于页面和入口判断。真正解压前仍会完整读取中央目录并执行白名单结构校验。
### 6.3 内部地图状态
快速检查顺序:
1. `.yaxon_map_copying` 存在时判定未完成。
2. `chn/a0/m1.ans` 必须是非空文件。
3. `chn` 至少有一个 `a+数字` 区域目录。
4. `voice` 至少有一个非空文件。
5. Map中存在ZIP时,`.yaxon_map_complete` 必须与当前ZIP的“文件大小 + 修改时间”一致。
6. Map中没有ZIP时,允许兼容升级前已经存在的内部地图。
完成标记用于识别“内部地图是否由当前Map ZIP解压完成”,不替代解压过程中的逐文件校验。
## 7. 工程操作一:删除Map分区地图
删除范围:
```text
清空 /mnt/map/amapauto9 内全部内容
保留 /mnt/map/amapauto9 根目录
```
流程:
```text
检查32G设备
-> 检查Map目录中是否有数据
-> 显示确认弹框
-> 检查根目录可写
-> 清空目录内容
-> 确认根目录存在且为空
```
不会删除 `/mnt/sdcard/amapauto9`。删除没有回滚能力,权限失败时可能留下部分数据。
## 8. 工程操作二:从U盘导入到Map分区
### 8.1 固定路径
```text
源:/mnt/usb_storage/amapauto9.zip
临时:/mnt/map/amapauto9/amapauto9.zip.part
正式:/mnt/map/amapauto9/amapauto9.zip
```
### 8.2 U盘要求
ZIP单文件约8.39GB,FAT32不支持超过4GB的单文件。内部工程U盘统一使用NTFS,`amapauto9.zip`固定放在U盘根目录。
当前固件存在 `ntfs-3g` 和 `mkntfs`,但仍必须用真实U盘验证能够自动挂载到 `/mnt/usb_storage`。
### 8.3 前置条件
1. 设备为PX3+32G。
2. U盘已挂载且根目录存在非空 `amapauto9.zip`。
3. `/mnt/map/amapauto9` 已由系统预先创建并可写。
4. Map目录中没有正式ZIP或旧展开地图数据。
5. Map可用空间不少于ZIP大小加300MiB安全余量。
6. ZIP中央目录能够读取,并包含 `chn`、`voice` 和 `chn/a0/m1.ans`。
当前真机Map分区约13.3G,旧地图仍占约8.0G时只剩5.3G,无法同时放入8.39GB ZIP,必须先执行删除操作。
### 8.4 执行流程
```text
校验U盘ZIP64结构
-> 清理上次残留的amapauto9.zip.part
-> 检查Map空间
-> 流式复制到amapauto9.zip.part
-> fsync
-> 校验源目标文件大小
-> 再次校验目标ZIP64结构
-> 同目录重命名为amapauto9.zip
```
`.part`是当前正在复制的同一份数据,完成后直接重命名,不会同时占用两份8.39GB空间。
取消、U盘拔出或复制失败时清理`.part`。正式ZIP只有在完整校验成功后才生成。
## 9. 工程操作三及普通初始化:Map解压到sdcard
### 9.1 解压计划
使用ZIP64中央目录生成白名单文件计划:
- 目标不存在:解压。
- 目标存在但大小不同:重新解压并覆盖。
- 目标存在且大小相同:跳过。
- 目标端白名单目录中的多余文件暂不删除。
计划同时统计:
- 地图、语音和核心文件是否齐全
- 本次需要解压的文件数和字节数
- 解压期间的峰值新增空间
- 跳过文件数
### 9.2 路径安全
只接受两个固定白名单前缀。每个条目的规范化目标路径必须仍位于对应的 `chn` 或 `voice` 目录内,拒绝反斜杠、`../`和重复目标路径,防止ZIP路径穿越覆盖其他系统或高德文件。
### 9.3 空间检查
允许解压的条件:
```text
sdcard可用空间 >= 解压过程峰值新增空间 + 300MiB
```
覆盖文件时不会直接写正式文件。当前单个文件先写同目录临时文件,校验后再替换,因此空间计算包含当前临时文件的峰值占用。
### 9.4 单文件处理
```text
从ZIP流式读取条目
-> 写入同目录“文件名.yaxon_part”
-> 更新真实解压字节进度
-> fsync
-> 校验解压后大小
-> 校验CRC32
-> 删除旧目标文件
-> 重命名临时文件为正式文件
```
最大临时文件约121MB,不创建完整13GB临时地图目录。
### 9.5 完整流程
```text
打开Map中的amapauto9.zip
-> 生成白名单差异计划
-> 清理计划内残留.yaxon_part
-> 检查空间 + 300MiB
-> 创建或复用/sdcard/amapauto9
-> 写入.yaxon_map_copying并fsync
-> 逐个解压变化文件
-> 校验全部白名单目标文件存在且大小一致
-> 写入.yaxon_map_complete并fsync
-> 删除.yaxon_map_copying
-> 返回成功
```
成功后Service仅在高德主进程已经运行时发送现有退出通知,让下次启动重新加载地图;高德未运行时不发送,不自动启动导航。
### 9.6 失败和恢复
- 不删除 `/mnt/sdcard/amapauto9` 根目录。
- 不创建完整地图临时副本。
- 已完成并校验的文件保留。
- 当前失败文件的`.yaxon_part`会尽量清理。
- `.yaxon_map_copying`在失败或中断后保留,导航判定未完成。
- 下次进入重新读取ZIP目录并生成差异计划,大小一致文件跳过。
- 全部成功后才更新完成标记和显示100%。
## 10. Service、进度和页面生命周期
- 三个地图操作统一由同进程 `MapDataCopyService` 持有。
- 同一时间只允许一个地图任务。
- Home后Activity解绑,Service继续执行。
- 重新进入页面恢复任务类型、累计字节和进度,不重新启动任务。
- 返回时可选择“后台运行”“停止任务”“继续等待”。
- Service为 `START_NOT_STICKY`,Launcher进程被杀或断电时任务终止,依靠标记和差异计划恢复。
- ZIP检查和计划生成阶段显示准备状态。
- U盘导入进度按压缩包复制字节计算。
- 内部初始化进度按本次实际解压字节计算。
- 进度回调最多每500ms一次,页面显示一位小数。
- 完整校验成功前最高显示99.9%,最终成功才显示100%。
## 11. 结果码和提示
| 结果码 | 典型原因 | 页面处理 |
|---|---|---|
| `SUCCESS` | 导入、解压及校验成功 | 显示成功提示 |
| `SOURCE_NOT_FOUND` | U盘ZIP或Map ZIP不存在 | 提示源数据不可用 |
| `TARGET_ALREADY_EXISTS` | Map目录已有正式数据 | 提示先删除Map数据 |
| `TARGET_PARENT_NOT_FOUND` | sdcard父目录不存在 | 提示目标准备失败 |
| `STORAGE_NOT_WRITABLE` | 目标不可写 | 提示检查存储或权限 |
| `NO_ENOUGH_SPACE` | 可用空间不足 | 提示空间不足 |
| `CREATE_TARGET_FAILED` | 目标目录无法创建 | 提示目标准备失败 |
| `INVALID_ARCHIVE` | ZIP64打不开、结构错误或缺少必要条目 | 提示压缩包无效或不完整 |
| `COPY_FAILED` | ZIP复制或解压读写异常 | 提示重新操作 |
| `VERIFY_FAILED` | 文件大小、CRC或完成标记异常 | 提示校验失败 |
| `DELETE_FAILED` | Map内容没有完全删除 | 提示删除失败 |
| `CANCELLED` | 用户停止任务 | 不显示失败弹框 |
普通导航入口仍将“Map ZIP缺失或不可访问”统一提示为:
```text
地图数据不可用,请联系服务人员
```
## 12. 权限前提
应用是平台签名system UID,但仍受Linux文件权限约束。最低要求:
1. `/mnt/map` 对system UID可读、可执行。
2. `/mnt/map/amapauto9` 对system UID可读、可写、可执行。
3. 权限在每次开机挂载完成后稳定生效。
4. `/mnt/sdcard/amapauto9`及其目标子目录可写。
历史真机曾出现重启后 `/mnt/map` 模式为`000`。该问题会导致ZIP被误判为不存在,仍是量产前P0验证项。临时验证命令:
```bash
adb shell chmod 0755 /mnt/map
```
永久方案应由底层在Map分区挂载完成后设置正确权限。
## 13. 已验证结论
### 13.1 已通过
- eMMC容量判断可将真机识别为32G。
- 新旧设备导航分流代码已保留。
- PC端真实ZIP64中央目录读取成功:2245个条目。
- 白名单识别成功:1866个文件,解压后`14,088,198,086 bytes`。
- ZIP中地图、语音和核心文件路径均存在。
- JDK 8执行Java编译成功。
- JDK 8执行Debug APK完整构建成功,新增库已通过重复类检查、DEX和打包。
### 13.2 尚未验证
- NTFS U盘能否在当前PX3固件自动挂载。
- PX3 Android 4.4运行时能否使用Commons Compress完整读取该ZIP64。
- 1866个文件的真机完整解压、CRC和耗时。
- U盘中途拔出、取消、杀进程和断电恢复。
- 解压时高德已经运行是否稳定。
- 重启后Map权限是否持续正确。
- 实际空间只剩边界余量时的处理。
## 14. 真机验收步骤
### 14.1 U盘和Map导入
1. 将U盘格式化为NTFS。
2. 将`amapauto9.zip`放在U盘根目录。
3. 插入PX3,确认`/mnt/usb_storage`状态为mounted。
4. 确认ZIP文件大小为`8,387,521,520`。
5. 先删除Map中的旧展开数据,确认Map剩余空间足够。
6. 执行“从U盘导入到Map分区”。
7. 确认正式ZIP生成且`.part`不存在。
8. 拔U盘、取消任务各验证一次,确认不会生成残缺正式ZIP。
建议检查命令:
```bash
adb shell "cat /proc/mounts | grep usb_storage"
adb shell "ls -l /mnt/usb_storage/amapauto9.zip"
adb shell "ls -l /mnt/map/amapauto9"
adb shell df
```
### 14.2 Map解压到sdcard
1. 清理内部`chn`和`voice`测试数据,不删除高德根目录其他数据。
2. 从导航入口进入,确认自动开始初始化。
3. 检查进度连续刷新且Home后任务继续。
4. 中途停止后重新进入,确认已完成文件被跳过。
5. 完成后确认`.yaxon_map_copying`消失、`.yaxon_map_complete`存在。
6. 抽查文件数量、大小和语音文件。
7. 再次点击导航,确认高德能加载离线地图和语音。
8. 分别验证高德未运行和已运行两种情况。
### 14.3 旧设备兼容
1. 带TF卡旧设备仍检查`/mnt/external_sd0/amapauto9`。
2. 有目录时启动高德。
3. 无目录时仍提示插入离线地图TF卡。
4. 不进入32G地图初始化页面。
## 15. 代码位置
以下路径均位于 `YX_MainInterface_ZhongQi/src/main/`:
| 职责 | 文件 |
|---|---|
| eMMC容量识别 | `java/com/yaxon/base/system/mapdata/EmmcSizeDetector.java` |
| PX3+32G策略 | `java/com/yaxon/base/system/mapdata/MapDataDevicePolicy.java` |
| ZIP校验、导入、白名单解压和删除 | `java/com/yaxon/base/system/mapdata/MapDataCopyManager.java` |
| 后台任务和高德重载 | `java/com/yaxon/base/system/mapdata/MapDataCopyService.java` |
| 页面状态和交互 | `java/com/yaxon/base/system/mapdata/MapDataCopyActivity.java` |
| 新旧导航分流 | `java/com/yaxon/until/ProgramLoader.java` |
| 页面文案 | `res/values/strings.xml` |
| ZIP64依赖 | `libs/commons-compress-1.9.jar` |
## 16. 当前优先级
| 优先级 | 工作项 | 完成标准 |
|---|---|---|
| P0 | PX3真机ZIP64只读验证 | 能打开ZIP、遍历2245个条目并读取末尾条目 |
| P0 | 修复/确认Map重启权限 | 连续重启后system UID均可读取和写入Map目录 |
| P1 | NTFS U盘挂载与8.39GB导入 | 自动挂载、完整复制、校验、重命名成功 |
| P1 | 13.12GiB完整解压 | 1866个文件完成大小和CRC校验,高德可加载 |
| P1 | 取消、拔盘、断电恢复 | 不产生残缺正式ZIP,可继续补齐内部地图 |
| P1 | 高德运行态验证 | 解压过程不损坏地图,完成后能重新加载 |
| P2 | 恢复工程模式10次点击门槛 | 功能验收完成后恢复正式入口限制 |
## 17. 本次更新记录
- 2026-08-12:按用户确认直接修改、不新增备份。
- 将U盘展开目录导入改为根目录单个`amapauto9.zip`导入。
- 将Map展开目录差异复制改为ZIP64白名单差异解压。
- 增加ZIP路径安全、单文件临时写入、大小和CRC校验、解压完成标记。
- 增加NTFS U盘约束、真实压缩包基线和真机验收矩阵。