IssueNo:#9876

Description:add doc
Sig:SIG_ApplicaitonFramework
Feature or Bugfix:Bugfix
Binary Source:No
Signed-off-by: wangtiantian <wangtiantian19@huawei.com>
Co-Authored-By: Agent

Signed-off-by: wangtiantian <wangtiantian19@huawei.com>

AI[0%] Human Fixed[0%] Human[100%] AI Adopted[0%]
This commit is contained in:
wangtiantian
2026-08-18 19:05:39 +08:00
parent ad6705293d
commit 221949011a
6 changed files with 73 additions and 26 deletions
@@ -19,7 +19,7 @@
| 概念 | 含义 |
|------|------|
| 双模式设备 | `persist.sceneboard.ispcmode``persist.sceneboard.mainmode` 均为合法值 ∈{0,1}0=tablet, 1=2in1 |
| 双模式设备 | `persist.sceneboard.ispcmode``const.sceneboard.mainmode` 均为合法值 ∈{0,1}0=tablet, 1=2in1 |
| 主模式 | `ispcmode == mainmode`(当前模式即主模式) |
| 副模式 | `ispcmode != mainmode`(当前模式为非主模式) |
| 不同包体类别(DiffPackage | `DeviceModeDistributionPolicy` ∈ {`UNIVERSAL_DIFFERENT_PACKAGE`(4), `PARTIAL_COMPATIBLE_DIFFERENT_PACKAGE`(6), `FULL_COMPATIBLE_DIFFERENT_PACKAGE`(8)},同包名不同包体,双模式特殊处理对象(`DualModeHelper::IsDiffPackageCategory` 判定为 true |
@@ -37,7 +37,7 @@
| appIndex 固定 10000 | 不走分身 appIndex 分配(1..5),不触发 `VerifyAndAckCloneAppIndex`;普通安装路径无 `IsValidAppIndex(10000)` 校验 |
| odid 一致性 | `GenerateOdidNoLock` 基于 developerId 的 groupId 派生(非 bundleName),同时遍历 `bundleInfos_` + `tempBundleInfos_`,同应用主/副模式 developerId 相同 → 一致性保持 |
| key 自愈陷阱 | `bundle_data_storage_rdb.cpp``TransResult`/`UpdateDataBase` 会重写 `key != GetBundleName()` 的记录,是前缀方案的核心风险点(ADR-3 处理) |
| 模式判断参数 | `persist.sceneboard.ispcmode`(int 0/1) + `persist.sceneboard.mainmode`(int 0/1);任一缺失/非法(∉{0,1}) → 非双模式设备 |
| 模式判断参数 | `persist.sceneboard.ispcmode`(int 0/1) + `const.sceneboard.mainmode`(int 0/1);任一缺失/非法(∉{0,1}) → 非双模式设备 |
## 上下文和现状
@@ -339,7 +339,7 @@ return bundleInfo.IsDualModeCloneApp()
| 字段 | 内容 |
|------|------|
| 问题 | 双模式逻辑依赖 ispcmode/mainmode 系统参数,非双模式硬件无法触发副模式分支,单测/集成验证难以复现。如何注入? |
| 推荐方案 | `DualModeHelper::IsTestDualMode()`(公开静态,读 `persist.bms.test_dual_mode` 开关)+ 匿名 namespace `GetIspcmodeParamKey()`/`GetMainmodeParamKey()`(选 key+ 常量(dual_mode_helper.cpp:36-38/115-118)。开关 true 时 ispcmode/mainmode `persist.sceneboard.*` `persist.bms.*` 间切换;生产(开关未设/false)读真实 sceneboard 参数,零影响 |
| 推荐方案 | `DualModeHelper::IsTestDualMode()`(公开静态,读 `persist.bms.test_dual_mode` 开关)+ 匿名 namespace `GetIspcmodeParamKey()`/`GetMainmodeParamKey()`(选 key+ 常量(dual_mode_helper.cpp:36-38/115-118)。开关 true 时 ispcmode/mainmode 改读 `persist.bms.*`(默认读 `persist.sceneboard.ispcmode` / `const.sceneboard.mainmode`;生产(开关未设/false)读真实 sceneboard 参数,零影响 |
| 取舍理由 | 生产环境完全不生效,零影响;测试环境可精确注入任意 ispcmode/mainmode 组合。单测另用 `#define private public` 直写缓存成员(不走参数) |
| 影响 | 仅 DualModeHelper cache 初始化路径;生产环境无行为变化 |
@@ -422,6 +422,15 @@ return bundleInfo.IsDualModeCloneApp()
| 取舍理由 | 粘性隔离贴合"隔离不可逆"的安全语义,避免更新翻覆;before+当前两组值让上层一次广播即可判断变更,无需查询历史;持久化闭环是粘性的必要条件,故把 InnerBundleInfo 访问器一并实现。放弃纯现场推导(无法表达粘性);放弃由上层自行比对历史(增加查询与竞态)。before 值用成员变量透传(避免改 FillDualModeEventFields 签名波及 3 个调用点),成员默认值天然覆盖首装/拿不到 oldInfo 的场景 |
| 影响 | `bundle_common_event_mgr.h/cpp`(结构体 5 字段 + Want key + SetParam)、`base_bundle_installer.h/cpp`(before 成员变量 + 捕获点 :1802-1811 + `ComputeCurrentAppSandboxPolicy` helper :5740-5750 + SetDualModeAppInfo 写入 :5795 + FillDualModeEventFields 填充 :5723-5738 + ResetInstallProperties 重置 :7278-7279)、`inner_bundle_info.h`Get/SetAppSandboxPolicy);AC-175 字段)、AC-39(粘性)、AC-40before 值 + 首装默认);**对外契约变更**(Want key `isSharedSandbox``appSandboxPolicy` + 新增 2 个 before key),须同步需求二上层消费者;非双模式设备保持默认值零回归 |
### ADR-30TS 接口 parameters 保留 key 透传设备模式分发策略(2026-08-17/18 增量)
| 字段 | 内容 |
|------|------|
| 问题 | 分发平台需在 TS `install` 调用时刻指定 `deviceModeDistributionPolicy`,但该策略为内部 IPC 字段(InstallParam),TS d.ts 无对应参数字段。扩 d.ts 新增 Public 参数需走 API 评审流程且引入版本兼容负担;如何在不改 TS API 契约的前提下把策略送到服务端? |
| 推荐方案 | 复用 installParam.parameters 既有通用通道(`Array<{key, value}>`d.ts 已有):约定保留 key `Constants::DEVICE_MODE_DISTRIBUTION_POLICY_KEY``ohos.bms.param.deviceModeDistributionPolicy`,对齐 `ohos.bms.param.*` 保留前缀惯例),value 为枚举值十进制字符串(如 "4")。新增 `InstallParam::RefreshDeviceModeDistributionPolicy()`install_param.cpp,对齐 `IsVerifyUninstallRule` 的 parameters 提取模式):key 缺失返回 true 且字段不动(零回归);key 存在做严格十进制解析(拒非数字符/空串/超值域,手工解析防溢出)后刷新字段;非法返回 false 且字段保持刷新前值。适配层接入点 2 处、均在参数解析/校验完成之后:NAPI `Install`installer.cpp:891,对 `callbackPtr->installParam` 调用)+ ANI `AniInstall`ani_bundle_installer.cpp:225`GetInstallParamForInstall` 返回之后对局部 installParam 调用);返回 false 时适配层仅 `APP_LOGW` 告警、继续安装(2026-08-17 需求方裁定:非法值不报 401、静默降级走默认策略)。刷新后的字段经既有 Parcel 链路(AC-1)跨 IPC 持久化。NAPI/ANI `updateBundleForSelf` 两入口均未接入(按代码现状记录,如需生效为后续增量) |
| 取舍理由 | 不改 d.ts:零 API 契约变更、零版本兼容负担,parameters 通道本就面向系统级保留参数透传(`ohos.bms.param.*` 前缀已有 `verifyUninstallForced` 等先例)。静默降级优于报错:安装主流程不应因策略参数笔误被拦截(分发平台脚本容错),非法值仅告警走默认 UNSPECIFIED。手工十进制解析优于 `stoi`:无异常、拒绝空串/正负号/空格/尾随字符,且 `parsed > maxValue` 提前截断防溢出。放弃在共享 helper `GetInstallParamForInstall` 内部刷新(那样可顺带覆盖 `AniUpdateBundleForSelf`,但 helper 返回 bool 语义是"参数解析失败",混入静默降级刷新会污染语义;且自更新入口是否应接受策略指定本身待定) |
| 影响 | `bundle_constants.h`(保留 key 常量)、`install_param.h/cpp``RefreshDeviceModeDistributionPolicy` 声明+实现)、`installer.cpp`NAPI `Install` 接入)、`ani_bundle_installer.cpp``AniInstall` 接入)、`bms_dual_mode_install_test.cpp`(+5 例至 128 例:有效值刷新/缺 key 零回归/边界值 0/8/前导零/非法值集拒收不污染字段/Parcel 往返保真);AC-41、FR-16。初版 installer.cpp 曾误写未声明标识符 `installParam`(编译不过),2026-08-18 工作区已修正为 `callbackPtr->installParam` |
## 双模式 key 规则
> 应用缓存 `bundleInfos_` 的 key 与运行时状态机 `installStates_` 的 key **规则不同**,是双模式最易混淆点。
@@ -613,7 +622,7 @@ enum DeviceModeDistributionPolicy {
| 副模式不同包体类别记录 key | installed_bundle 表 KEY(带前缀) | /bmsdb.db | 持久化 |
| tempBundleInfos_ | 内存 map(不持久化,重启重建) | BundleDataMgr | 进程级 |
| DualModeHelper 模式缓存(cachedIspcmode_/cachedMainmode_int-1=未读取) | 内存静态变量 | DualModeHelper | 进程级(启动 InitializeCache 填充,UpdateModeCache 刷新) |
| persist.sceneboard.ispcmode / mainmode(只读,int 0/1 | 系统参数 | param | 系统级 |
| persist.sceneboard.ispcmode / const.sceneboard.mainmode(只读,int 0/1 | 系统参数 | param | 系统级 |
### 异常场景
@@ -1,6 +1,6 @@
# 执行计划
> 将 Spec 拆成可独立执行、可验证、可审查的 Task。每个 Task 自包含。当前代码基线:`appIndex_dual_mode_07_doc` HEAD `020de12b8`(含代码落地提交 `14eb7f286`2026-08-0613 文件 +349 -47123 例单测)。TASK-1~6 已落地。
> 将 Spec 拆成可独立执行、可验证、可审查的 Task。每个 Task 自包含。当前代码基线:`appIndex_dual_mode_07_doc` HEAD `020de12b8`(含代码落地提交 `14eb7f286`2026-08-0613 文件 +349 -47123 例单测)。TASK-1~6 已落地TASK-7TS 接口 parameters 透传,AC-41)为 2026-08-17 增量,2026-08-18 增补 ANI `install` 入口(接入点共 2 处:NAPI `install` + ANI `install`NAPI/ANI `updateBundleForSelf` 均未接入)
## Plan 元数据
@@ -43,6 +43,7 @@
| AC-36 / AC-37 | TASK-1 | 单测(AppSandboxPolicy Parcel+JSON 序列化往返保真 / 缺字段默认 SHARED_SANDBOX |
| AC-38 | TASK-3 | 单测+集成(副模式不同包体 appIndex=10000 单一数据源、CreateHapInfoParams 直接传播) |
| AC-39 / AC-40 | TASK-6 | 单测+集成(粘性隔离 / before 值更新捕获/首装默认) |
| AC-41 | TASK-7 | 单测+集成(parameters 保留 key 刷新枚举 / 缺 key 零回归 / 非法 value 告警降级) |
## 阶段计划
@@ -62,6 +63,7 @@
| TASK-4 | DB key 前缀适配 + 自愈陷阱修复 | bundle_data_storage_rdb.cpp, inner_bundle_info.cpp | AC-4, AC-11 | TASK-2, TASK-3 | 副模式 key 不被自愈误删 + 查询正确 | 集成 |
| TASK-5 | 重启数据加载分类 + tempBundleInfos_ | bundle_data_mgr.h/cpp | AC-11~AC-16 | TASK-4 | 重启按模式分类加载 + odid 跨模式一致 | 集成 |
| TASK-6 | 安装事件字段扩展(5 双模式字段 + before 值 + 粘性规则) | bundle_common_event_mgr.h/cpp, base_bundle_installer.h/cpp, inner_bundle_info.h | AC-17, AC-39, AC-40 | TASK-1 | 事件含 5 字段(deviceModeDistributionPolicy/currentMode int/appSandboxPolicy/before×2);粘性隔离保持 | 集成 |
| TASK-7 | TS 接口 parameters 保留 key 透传设备模式分发策略 | bundle_constants.h, install_param.h/cpp, installer.cpp, ani_bundle_installer.cpp, common_fun_ani.cpp | AC-41 | TASK-1 | parameters 携带保留 key 时刷新 InstallParam.deviceModeDistributionPolicyNAPI install + ANI install 共 2 入口;NAPI/ANI updateBundleForSelf 均不适配(2026-08-18 裁定));缺 key 零回归;非法 value 仅告警降级;服务端 ReadFromParcel 越界值降级 UNSPECIFIEDNAPI/ANI 重复 key 统一 first-winscodecheck R1 加固,2026-08-18 | `unittest` |
## Task 详情
@@ -115,6 +117,16 @@
- **完成判据**:安装/更新事件含 5 双模式字段;currentMode 为 int0/1/-1);粘性隔离保持(before=ISOLATED 则当前 ISOLATED);before 值更新捕获/首装默认。
- **关联**AC-17/AC-39/AC-40design ADR-29currentMode int + Want key 改名 isSharedSandbox→appSandboxPolicy + 新增 2 before key 属对外契约变更,须同步需求二)。
### TASK-7: TS 接口 parameters 保留 key 透传设备模式分发策略
- **目标**TS 侧经 installParam.parameters 既有通用通道(`Array<{key, value}>`,无需改 d.ts)传入 key `ohos.bms.param.deviceModeDistributionPolicy`、value 为枚举值十进制字符串(如 "4");`InstallParam::RefreshDeviceModeDistributionPolicy()`(新方法,对齐 `IsVerifyUninstallRule` 的 parameters 提取模式)在 parameters 含该 key 时将字符串解析为 int 并校验值域 [0,8]、刷新 `deviceModeDistributionPolicy` 字段;接入点共 2 处(均在参数解析/校验完成之后调用):NAPI `Install`installer.cpp:891,对 `callbackPtr->installParam` 调用;初版曾误写未声明标识符 `installParam` 致编译不过,2026-08-18 工作区修正为 `callbackPtr->installParam`+ ANI `AniInstall`ani_bundle_installer.cpp:225`GetInstallParamForInstall` 返回之后对局部 installParam 调用,2026-08-18 增补 ANI;刷新调用在 `AniInstall` 函数体内、不在共享 helper 内部,故 `AniUpdateBundleForSelf`:311 经同一 helper)不被覆盖);key 缺失保持默认 UNSPECIFIED 零回归,value 非法(非十进制整数/超 0~8)返回 false,适配层 `APP_LOGW` 告警后继续安装、字段不被污染(2026-08-17 需求方裁定:不报 401、静默降级);NAPI `updateBundleForSelf`installer.cpp:1146 `CheckInstallParam` 之后)与 ANI `AniUpdateBundleForSelf` 均不接入,保留 key 在该两入口不生效(**2026-08-18 需求方裁定:updateBundleForSelf 接口不适配,透传范围即 install 入口,非缺口**)。
- **文件**`bundle_constants.h`key 常量 `DEVICE_MODE_DISTRIBUTION_POLICY_KEY``ohos.bms.param.*` 保留前缀区)、`install_param.h/cpp`(方法声明+实现)、`installer.cpp`NAPI `Install` 接入)、`ani_bundle_installer.cpp`ANI `AniInstall` 路径接入)、`bms_dual_mode_install_test.cpp`(单测组)。
- **完成判据**:带 key "4" → 字段刷新为 UNIVERSAL_DIFFERENT_PACKAGE(4);缺 key → 默认 UNSPECIFIED"abc"/"9"/"-1"/"4x" → 返回 false 且字段保持刷新前值(适配层仅告警、继续安装)。
- **codecheck R1 加固(2026-08-18codecheck_report_192a99ab_R1 F-P2-01/F-P2-02,用户裁定方向:越界静默降级 UNSPECIFIED + 双栈重复 key 严格剥离)**:
- **F-P2-01(服务端值域白名单)**:`InstallParam::ReadFromParcel`install_param.cpp)对 policy 字段加值域白名单 `[UNSPECIFIED(0), FULL_COMPATIBLE_DIFFERENT_PACKAGE(8)]`,越界 int32(原生 IPC 调用方绕过 kit 校验场景)`APP_LOGW` 告警后降级 UNSPECIFIED(与 amended AC-41 静默降级口径一致,不阻断 IPC 安装请求),越界值不再可达广播事件字段;单测 `RefreshDeviceModeDistributionPolicy_0600`(越界 999/-5 降级 + 边界 0/8 直通)。
- **F-P2-02(重复 key 跨栈统一 first-wins**NAPI `ParseParameters`installer.cpp)遇重复 key 从 `APP_LOGE + return false`(中断循环、调用方吞错后实际 first-wins 且丢失后续合法 key)改为 `APP_LOGW` 告警 + `continue` 跳过(保留首个、后续重复忽略,循环继续解析其余 key);ANI `ParseInstallParam` parameters 分支(common_fun_ani.cpp)从 `operator[]` last-wins 改为 find 检查 + `continue`——双栈统一为 **first-wins**(保留首个、忽略后续重复、`APP_LOGW` 告警),单次 key 零回归;kit 层解析无本仓单测覆盖(XTS 待集成,同 F-P3-05 遗留口径)。
- **关联**AC-41/FR-16。
## Plan 自审清单
- [x] 每个 P0/P1 AC 至少映射到一个 Task
@@ -125,4 +137,4 @@
- [x] 无 TBD/TODO/占位符
- [x] 无超 3000 行阈值的 Task
**Plan 结论:** Approved — TASK-1~6 已实现落地(`_04` commit `80d089208` 基线 + 增量代码落地提交 `14eb7f286`2026-08-0613 文件 +349 -47123 例单测)。AC-1~35 已编译验证通过(`_04`);AC-36~40 代码已落地、待集成环境编译/单测/运行时回归。运行时全 AC(AC-1~40)集成回归 + 人类 Owner 发布批准仍待(见 [gates/release.md](./gates/release.md))。
**Plan 结论:** Approved — TASK-1~6 已实现落地(`_04` commit `80d089208` 基线 + 增量代码落地提交 `14eb7f286`2026-08-0613 文件 +349 -47123 例单测)。AC-1~35 已编译验证通过(`_04`);AC-36~40 代码已落地、待集成环境编译/单测/运行时回归。TASK-7AC-41TS 接口 parameters 透传)代码已落地(2026-08-17 NAPI `Install` 入口,2026-08-18 增补 ANI `AniInstall` 入口 + 提交 `192a99abb`2026-08-18 codecheck R1 加固 F-P2-01/F-P2-02 落地工作区——服务端 ReadFromParcel 值域白名单 + NAPI/ANI 重复 key 统一剥离语义,单测扩至 129 例,见 TASK-7 详情)待集成环境编译/单测/运行时回归。运行时全 ACAC-1~41)集成回归 + 人类 Owner 发布批准仍待(见 [gates/release.md](./gates/release.md))。
@@ -13,7 +13,7 @@
| 检查项 | 结果 | 证据/理由 |
|--------|------|-----------|
| execution-plan Task 明确、文件范围清晰 | ✅ | [execution-plan.md](../execution-plan.md) TASK-1~6 |
| execution-plan Task 明确、文件范围清晰 | ✅ | [execution-plan.md](../execution-plan.md) TASK-1~7 |
| 每个 Task 有完成判据与验证命令 | ✅ | 同上 |
## Task 实现检查
@@ -21,7 +21,9 @@
| 检查项 | 结果 | 证据/理由 |
|--------|------|-----------|
| TASK-1~6 代码已落地 | ✅ | `_04` commit `80d089208`dual_mode_helper / base_bundle_installer / bundle_data_mgr / bundle_data_storage_rdb / bundle_resource/ / bundle_exception_handler / install_exception_mgr / bundle_permission_mgr / bundle_common_event_mgr / appexecfwk_errors+ 增量 `14eb7f286`2026-08-06AppSandboxPolicy 数据模型 / appIndex 单一数据源 / 广播沙箱粘性 + before 值,13 文件 +349 -47 |
| TASK-7 代码已落地(2026-08-17 增量,2026-08-18 增补 ANI 入口) | ✅ | bundle_constants.h`DEVICE_MODE_DISTRIBUTION_POLICY_KEY` 保留 key+ install_param.h/cpp`RefreshDeviceModeDistributionPolicy`parameters 提取→十进制严格解析→值域 [0,8] 校验→刷新字段)+ installer.cppNAPI `Install`:891 对 `callbackPtr->installParam` 接入——初版曾误写未声明标识符 `installParam`(编译不过),2026-08-18 工作区已修正;非法 value 仅 `APP_LOGW` 告警降级、不报 4012026-08-17 裁定)+ ani_bundle_installer.cpp`AniInstall`:225 在 `GetInstallParamForInstall` 返回之后接入,仅覆盖 install 入口,2026-08-18+ bms_dual_mode_install_test.cpp(单测 +5 例至 128 例) |
| AC-1~40 实现完整 | ✅ | 逐 AC 对照源码静态一致;AC-1~35(`_04`+ AC-36~40`14eb7f286`)静态一致([review.md](../review.md) |
| AC-41 实现完整 | ✅(静态) | `RefreshDeviceModeDistributionPolicy` 覆盖 AC-41 三分支(带 key 刷新 / 缺 key 零回归 / 非法静默降级),NAPI `Install` + ANI `AniInstall` 两入口接入静态对照一致;NAPI/ANI `updateBundleForSelf` 均不适配(2026-08-18 需求方裁定,透传范围即 install 入口,非缺口);codecheck R1 加固(2026-08-18F-P2-01/F-P2-02):ReadFromParcel 值域白名单越界降级 UNSPECIFIED + NAPI/ANI 重复 key 统一 first-winsinstaller.cpp / common_fun_ani.cpp);编译/单测待集成环境 |
## 审查检查
@@ -29,7 +31,7 @@
|--------|------|-----------|
| 规范符合性(不多不少不误解) | ✅ | [review.md](../review.md) |
| 代码质量(分层/线程安全/错误处理/DRY/日志) | ✅ | 同上 |
| 编译(bms_target + 单测编译) | ✅(`_04`/ ⏳(增量) | 用户确认 `_04` 代码与单测编译 OK(112 例);增量代码(`14eb7f286`,单测扩至 123 例)编译/单测待集成环境 |
| 编译(bms_target + 单测编译) | ✅(`_04`/ ⏳(增量) | 用户确认 `_04` 代码与单测编译 OK(112 例);增量代码(`14eb7f286` 123 例 + TASK-7 工作区增量至 128 例 + codecheck R1 加固 `RefreshDeviceModeDistributionPolicy_0600` 至 129 例)编译/单测待集成环境 |
## 出口检查
@@ -38,11 +40,12 @@
| 主体 AC-1~21 运行集成验证 | ✅ | 2026-07-18 集成环境编译 + 单测 + AC-1~21 全回归 PASS |
| 增量 AC-22~35 编译验证 | ✅ | `_04` 编译通过(运行时集成回归待集成环境) |
| 增量 AC-36~40 + AC-17/19 重验 | ⏳ | 代码落地 `14eb7f286`,编译/单测/运行时回归待集成环境(含 AC-17 5 字段、AC-19 appIndex 单一数据源重验) |
| 增量 AC-41TS parameters 透传) | ⏳ | 代码落地工作区(2026-08-17 落地 NAPI 入口、2026-08-18 增补 ani_bundle_installer.cpp `AniInstall` 入口 + codecheck R1 加固 install_param.cpp/installer.cpp/common_fun_ani.cpp 3 文件,TASK-76 源文件 + 单测 6 例至 129 例),编译/单测/运行时回归待集成环境 |
| 无阻塞级 Open Issues | ✅ | review.md 历史 FAIL 均已修;剩余为 follow-up 遗留 |
## 总结论
**Approval(编译验证通过,`_04` 层)** — 代码落地完整(`_04` `80d089208` + 增量 `14eb7f286`)、静态审查 PASS、`_04` 编译验证通过(112 例单测);主体 AC-1~21 运行集成验证 PASS2026-07-18)。未决:① 增量(AC-36~40 + AC-17 5 字段 + AC-19 appIndex 置位,`14eb7f286`,123 例)编译/单测/运行时回归待集成环境;② 运行时全 AC(AC-1~40)集成回归。编译通过 ≠ 运行回归 PASS。
**Approval(编译验证通过,`_04` 层)** — 代码落地完整(`_04` `80d089208` + 增量 `14eb7f286` + TASK-7 工作区增量)、静态审查 PASS、`_04` 编译验证通过(112 例单测);主体 AC-1~21 运行集成验证 PASS2026-07-18)。未决:① 增量(AC-36~40 + AC-17 5 字段 + AC-19 appIndex 置位,`14eb7f286`,123 例)编译/单测/运行时回归待集成环境;② TASK-7 增量(AC-412026-08-17/18 工作区 + codecheck R1 加固,129 例)编译/单测/运行时回归待集成环境;③ 运行时全 ACAC-1~41)集成回归。编译通过 ≠ 运行回归 PASS。
## Approval 记录
@@ -82,7 +82,7 @@
| -1 / 非法(∉{0,1}) | * | false | false | 非双模式(回退正常流程) |
| * | -1 / 非法(∉{0,1}) | false | false | 非双模式(回退正常流程) |
> 参数源:`persist.sceneboard.ispcmode`int0=tablet/1=2in1+ `persist.sceneboard.mainmode`int0=主tablet/1=主2in1)。`GetIntParameter(key, -1)` 用 -1 作"参数不存在/读取失败"sentinel,再校验值域 ∈{0,1}。仅不同包体类别(policy ∈ {4,6,8})应用在**副模式**ispcmode≠mainmode)下安装时做目录/key 前缀特殊处理;主模式及非双模式均不做处理。
> 参数源:`persist.sceneboard.ispcmode`int0=tablet/1=2in1+ `const.sceneboard.mainmode`int0=主tablet/1=主2in1)。`GetIntParameter(key, -1)` 用 -1 作"参数不存在/读取失败"sentinel,再校验值域 ∈{0,1}。仅不同包体类别(policy ∈ {4,6,8})应用在**副模式**ispcmode≠mainmode)下安装时做目录/key 前缀特殊处理;主模式及非双模式均不做处理。
### 目标和成功指标
+24 -14
View File
@@ -8,8 +8,8 @@
|------|------|
| 特性 | FEAT-20260715-001 双模式同包名不同安装包应用安装支持 |
| 审查人 | ClaudeAI 审查) |
| 代码基线 | `appIndex_dual_mode_07_doc` HEAD `020de12b8`(含代码落地 `14eb7f286`123 例单测) |
| 审查范围 | spec AC-1~40 + design ADR-1~29 + 实现代码静态对照 |
| 代码基线 | `appIndex_dual_mode_07_doc` HEAD `020de12b8`(含代码落地 `14eb7f286`123 例单测)+ TASK-7 工作区增量(2026-08-17/18+5 例至 128 例) |
| 审查范围 | spec AC-1~41 + design ADR-1~30 + 实现代码静态对照 |
| 复杂度 | 标准 |
## 审查输入
@@ -17,16 +17,16 @@
| 项 | 内容 |
|----|------|
| Requirement | [proposal.md](./proposal.md) |
| Design | [design.md](./design.md)ADR-1~29 |
| Spec | [spec.md](./spec.md)AC-1~40、FR-1~15 |
| 代码 | `services/bundlemgr/`dual_mode_helper / base_bundle_installer / bundle_data_mgr / bundle_data_storage_rdb / bundle_resource/ / bundle_exception_handler / install_exception_mgr / bundle_common_event_mgr / bundle_permission_mgr 等) |
| 单测 | `services/bundlemgr/test/unittest/bms_dual_mode_install_test/bms_dual_mode_install_test.cpp`123 例 HWTEST_F |
| Design | [design.md](./design.md)ADR-1~30 |
| Spec | [spec.md](./spec.md)AC-1~41、FR-1~16 |
| 代码 | `services/bundlemgr/`dual_mode_helper / base_bundle_installer / bundle_data_mgr / bundle_data_storage_rdb / bundle_resource/ / bundle_exception_handler / install_exception_mgr / bundle_common_event_mgr / bundle_permission_mgr 等)+ `interfaces/`TASK-7install_param.h/cpp / bundle_constants.h / kits/js/installer/installer.cpp / kits/ani/bundle_installer/ani_bundle_installer.cpp |
| 单测 | `services/bundlemgr/test/unittest/bms_dual_mode_install_test/bms_dual_mode_install_test.cpp`128 例 HWTEST_F |
## 规范符合性
| 检查项 | 结果 | 证据 |
|--------|------|------|
| 需求覆盖(AC-1~40 全部由代码实现) | PASS | 逐 AC 对照源码,安装/更新路径与 HEAD `020de12b8` 代码一致;AC-34(不同包体类别仅系统应用准入,不分主副模式)由 `SetDualModeAppInfo`base_bundle_installer.cpp:5766-5802/ AC-35(跨 map 一致性)由 `CheckDualModeCategoryConsistencyInTemp`:5820-5842)实现 |
| 需求覆盖(AC-1~41 全部由代码实现) | PASS | 逐 AC 对照源码,安装/更新路径与 HEAD `020de12b8` 代码一致;AC-34(不同包体类别仅系统应用准入,不分主副模式)由 `SetDualModeAppInfo`base_bundle_installer.cpp:5766-5802/ AC-35(跨 map 一致性)由 `CheckDualModeCategoryConsistencyInTemp`:5820-5842)实现AC-41TS parameters 透传)由 `InstallParam::RefreshDeviceModeDistributionPolicy` + NAPI `Install`/ANI `AniInstall` 两入口接入实现(见下方增量检视记录) |
| 架构合规(特权文件操作经 SA 511;IPC Parcel 序列化) | PASS | 安装目录创建/轮转跨 IPC 到 installddeviceModeDistributionPolicy / appSandboxPolicy 经 Parcel 跨进程 |
| API 契约(DeviceModeDistributionPolicy 9 成员 + AppSandboxPolicy 2 成员枚举 + BundleInfo/InstallParam 字段) | PASS | 与 `bundle_info.h`:159-176/ `install_param.h` 实现一致 |
| 错误码(CATEGORY_CONFLICT 8519943 / NOT_SYSTEM_APP 8519942 | PASS | `appexecfwk_errors.h:213-214` + `status_receiver_proxy.cpp:720-723` 映射 |
@@ -41,14 +41,24 @@
| 错误处理 | PASS | CHECK_RESULT 宏 + ROLLBACK |
| 锁契约/DRY/日志 | PASS | effective name 集中 helper;粘性沙箱 helperComputeCurrentAppSandboxPolicy)单源;日志保持原名 |
## 增量检视记录(TASK-7 / AC-412026-08-17 检视 + 2026-08-18 刷新)
| 项 | 结论 | 证据/说明 |
|----|------|-----------|
| 2026-08-17 检视(NAPI 入口) | PASS | `RefreshDeviceModeDistributionPolicy` 实现健壮(严格十进制解析、值域 [0,8]、防溢出截断、非法值不污染字段),与 amended AC-41(非法值静默降级不报 401)一致 |
| 2026-08-18 刷新(Sync-24 | 2 处修正 | ① 接入点事实修正:spec/plan/gates 曾记"ANI 经共享 helper 覆盖 install/updateBundleForSelf 共 3 入口"——实际刷新调用位于 `AniInstall` 函数体(ani_bundle_installer.cpp:225)而非 helper 内部,`AniUpdateBundleForSelf` 不被覆盖,真实接入点 2 处(NAPI `Install` + ANI `AniInstall`),NAPI/ANI `updateBundleForSelf` 均未接入,全部文档已按代码现状改记;② installer.cpp:891 初版误写未声明标识符 `installParam`(编译不过,静态检视遗漏、本地无编译环境未拦截),用户 2026-08-18 工作区修正为 `callbackPtr->installParam` |
| 2026-08-18 codecheck R1 加固(F-P2-01/F-P2-02 | PASS(静态) | 对 `192a99abb` 的 codecheck R1score 80 / conditional / 无 P0P12 个 P2 落地修复(用户裁定:越界静默降级 UNSPECIFIED + 双栈重复 key 统一 first-wins,初版严格剥离方案因改动过大收敛为最小改动):① F-P2-01 `InstallParam::ReadFromParcel` 加值域白名单 [0,8],越界 int32 降级 UNSPECIFIED + `APP_LOGW`(与 amended AC-41 静默降级口径一致),越界值不可达广播字段,消除 kit 校验被原生通道绕过的校验不对称;② F-P2-02 NAPI `ParseParameters` 重复 key 由 `APP_LOGE + return false`(中断循环、调用方吞错后实际 first-wins 且丢失后续合法 key)改为 `APP_LOGW + continue`ANI `ParseInstallParam` parameters 分支由 `operator[]` last-wins 改为 find 检查 + continue——双栈统一 first-wins(保留首个、忽略后续、告警,单次 key 零回归,净改动 NAPI 1 处 + ANI 4 行)。单测 `RefreshDeviceModeDistributionPolicy_0600`(越界 999/-5 降级 + 边界 0/8 直通),128→129 例;kit 层解析无本仓单测(XTS 待集成,同 F-P3-05 口径)。编译/单测待集成环境 |
| 401 表述统一 | ✅ 已消 | spec 内 4 处提及均为"不报 401"裁定表述,无失实残留;单测注释(bms_dual_mode_install_test.cpp:1295)同口径 |
| 遗留(已裁定关闭) | ✅ 非缺口 | NAPI/ANI `updateBundleForSelf` 不接入刷新(保留 key 在该两入口不生效、字段走默认)——**2026-08-18 需求方裁定:该接口不适配,透传范围即 install 入口**spec AC-41/FR-16 已改记裁定口径;codecheck R2 F-P3-03 同步关闭,资料锚点 F-P3-04 亦裁定资料不适配) |
## 验证证据
| 项 | 结果 | 证据 |
|----|------|------|
| 编译(bms_target + 单测编译) | ✅(`_04`/ ⏳(增量) | 用户确认 `_04` `80d089208` 代码与单测(112 例)编译 OK;增量代码(`14eb7f286`123 例)编译待集成环境 |
| 单测 | 123 例(`14eb7f286` 后) | 覆盖 DualModeHelper 谓词 / IsDiffPackageCategory / GetEffectiveBundleName / Classify / Resource / DeviceModeDistributionPolicy+AppSandboxPolicy 序列化 / FillDualModeEventFields5 字段+粘性+before/ ComputeCurrentAppSandboxPolicy / Router / Skill / FetchTempBundleInfo / GenerateOdid 双 map / UpdateBundleInstallState / SetDualModeAppInfo(系统应用,主+副模式)/ CreateHapInfoParamsappIndex 直接传播)/ CheckDualModeCategoryConsistencyInTemp / DeliveryProfileToCodeSign |
| 编译(bms_target + 单测编译) | ✅(`_04`/ ⏳(增量) | 用户确认 `_04` `80d089208` 代码与单测(112 例)编译 OK;增量代码(`14eb7f286` 123 例 + TASK-7 工作区至 128 例)编译待集成环境 |
| 单测 | 129 例(`14eb7f286` + TASK-7 增量 + codecheck R1 加固 0600 | 覆盖 DualModeHelper 谓词 / IsDiffPackageCategory / GetEffectiveBundleName / Classify / Resource / DeviceModeDistributionPolicy+AppSandboxPolicy 序列化 / FillDualModeEventFields5 字段+粘性+before/ ComputeCurrentAppSandboxPolicy / Router / Skill / FetchTempBundleInfo / GenerateOdid 双 map / UpdateBundleInstallState / SetDualModeAppInfo(系统应用,主+副模式)/ CreateHapInfoParamsappIndex 直接传播)/ CheckDualModeCategoryConsistencyInTemp / DeliveryProfileToCodeSign / RefreshDeviceModeDistributionPolicy(有效刷新/缺 key 零回归/边界 0/8/前导零/非法值拒收不污染/Parcel 往返/Parcel 越界值降级 UNSPECIFIED0600F-P2-01)) |
| 主体集成回归(AC-1~21 | ✅ 运行 PASS | 2026-07-18 集成环境编译 + 单测 + AC-1~21 全回归 PASS |
| 增量 AC-22~40 运行时集成回归 | ⏳ 待集成环境 | 含 AC-36~40 + AC-175 字段重验)+ AC-19appIndex 置位机制重验);编译验证通过 ≠ 运行回归 PASS |
| 增量 AC-22~41 运行时集成回归 | ⏳ 待集成环境 | 含 AC-36~40 + AC-41TS parameters 透传真机验证)+ AC-175 字段重验)+ AC-19appIndex 置位机制重验);编译验证通过 ≠ 运行回归 PASS |
## 关键遗留(不阻塞 Stage 3,影响发布范围)
@@ -70,8 +80,8 @@
| 字段 | 内容 |
|----|------|
| 阶段 | 实现(Stage 3 |
| 决策 | **静态审查 PASS** — spec AC-1~40 / design ADR-1~29 与 HEAD `020de12b8` 代码静态一致;`_04` AC-1~35 编译验证通过 + AC-1~21 运行 PASS;增量代码(`14eb7f286`)核对全命中、编译/单测/运行时回归待集成环境。运行时全 AC 集成回归 + 人类 Owner 发布批准仍待 |
| 下一阶段 | 集成环境全 AC(AC-1~40)运行回归 PASS + 人类 Owner 发布批准 + 复盘 → [gates/release.md](./gates/release.md) 解阻塞 |
| 重检范围 | 全量(`_04` + `14eb7f286` 编译 + 123 例单测运行 + 全 AC 运行时集成回归 + 人工发布批准) |
| 决策 | **静态审查 PASS** — spec AC-1~41 / design ADR-1~30 与 HEAD `020de12b8` + TASK-7 工作区增量代码静态一致;`_04` AC-1~35 编译验证通过 + AC-1~21 运行 PASS;增量代码(`14eb7f286`)核对全命中、TASK-7 增量(2026-08-17/18 检视,见「增量检视记录」)静态一致,编译/单测/运行时回归待集成环境。运行时全 AC 集成回归 + 人类 Owner 发布批准仍待 |
| 下一阶段 | 集成环境全 AC(AC-1~41)运行回归 PASS + 人类 Owner 发布批准 + 复盘 → [gates/release.md](./gates/release.md) 解阻塞 |
| 重检范围 | 全量(`_04` + `14eb7f286` + TASK-7 工作区增量编译 + 128 例单测运行 + 全 AC 运行时集成回归 + 人工发布批准) |
> **编译验证通过的精确含义**:`_04`「代码和用例均编译验证 OK」= bms_target 编译通过 + 单测编译通过(112 例)。按「证据先于声明」,增量代码(`14eb7f286`123 例)编译/单测 + 运行时逐 AC 集成回归(clone app 安装/更新/卸载隔离、副模式目录/key、重启分类、跨模式 odid、粘性沙箱、广播 5 字段等)仍须集成环境运行。编译通过不等于运行时回归 PASS。Stage 4 发布仍需人类 Owner 批准。
> **编译验证通过的精确含义**:`_04`「代码和用例均编译验证 OK」= bms_target 编译通过 + 单测编译通过(112 例)。按「证据先于声明」,增量代码(`14eb7f286` 123 例 + TASK-7 工作区增量至 128 例)编译/单测 + 运行时逐 AC 集成回归(clone app 安装/更新/卸载隔离、副模式目录/key、重启分类、跨模式 odid、粘性沙箱、广播 5 字段、TS parameters 透传等)仍须集成环境运行。编译通过不等于运行时回归 PASS。Stage 4 发布仍需人类 Owner 批准。
+15 -2
View File
@@ -205,9 +205,19 @@
- **AC-39:** WHEN 双模式设备计算当前 `appSandboxPolicy``ComputeCurrentAppSandboxPolicy` 私有 helper`SetDualModeAppInfo` 写入 info 与 `FillDualModeEventFields` 填广播同源)THEN 若 `beforeAppSandboxPolicy==ISOLATED_SANDBOX`(存量已隔离)当前恒为 `ISOLATED_SANDBOX`**粘性**,与新 policy 无关);否则(共沙箱或首装默认 SHARED)当前 = `IsDiffPackageCategory(newPolicy) ? ISOLATED_SANDBOX : SHARED_SANDBOX`。WHEN 存量隔离应用更新为非不同包体类别 THEN 当前仍 ISOLATED(粘性保持)。单测:`FillDualModeEventFields_0100`(首装+不同包体→ISOLATED)、`FillDualModeEventFields_0300`(粘性:before=ISOLATED + 非不同包体→仍 ISOLATED
- **AC-40:** WHEN 更新(存量存在,`isAppExist_=true`THEN `beforeDeviceModeDistributionPolicy`/`beforeAppSandboxPolicy` 从 oldInfo 捕获(`InitTempBundleFromCache` 后 base_bundle_installer.cpp:1802-1811,存入 BaseBundleInstaller 成员);WHEN 首次安装(无存量)THEN before 两字段为默认(UNSPECIFIED/SHARED_SANDBOX);WHEN 非双模式设备 THEN 5 字段全默认、零回归。`appSandboxPolicy``InnerBundleInfo.SetAppSandboxPolicy` 写入并随 baseBundleInfo_ 持久化(粘性闭环,AC-39 下次更新可读);`ResetInstallProperties`:7278-7279)重置 before 成员防实例复用泄漏。单测:`FillDualModeEventFields_0100`(首装 before 默认)、`FillDualModeEventFields_0200`(非双模式保持预置标记)
### US-12: TS 接口透传设备模式分发策略
**作为** 上层分发调用方(经 TS installer 接口),
**需要** 在调用 TS 安装接口时经 installParam.parameters 通用通道传入设备模式分发策略,
**以便** 分发平台在安装时刻指定策略,走既有 IPC 字段链路(AC-1)持久化,无需新增独立 TS 参数字段。
**验收标准:**
- **AC-41:** WHEN TS 侧调用 `install` 接口且 installParam.parameters 携带 key `ohos.bms.param.deviceModeDistributionPolicy`(value 为枚举值的十进制字符串,如 "4") THEN 适配层解析后将 `InstallParam.deviceModeDistributionPolicy` 刷新为对应枚举值(int 0~8),经既有 Parcel 字段(IPC)传至服务端,衔接 AC-1 持久化链路;WHEN parameters 不含该 key THEN 字段保持默认 UNSPECIFIED0),现有调用方零回归;WHEN key 存在但 value 非法(非十进制整数/空串/超出 0~8 值域)THEN 忽略该 key 仅打印 warning 日志(`RefreshDeviceModeDistributionPolicy` 返回 false,适配层 `APP_LOGW` 告警后继续安装流程,字段不被污染、保持刷新前值即默认 UNSPECIFIED),不拦截安装、不返回异常(2026-08-17 需求方裁定:非法值不报 401,静默降级走默认策略)。实现:`InstallParam::RefreshDeviceModeDistributionPolicy()`install_param.cpp,从 parameters map 提取并刷新字段,对齐 `IsVerifyUninstallRule` 的 parameters 提取模式),接入点共 2 处(均在参数解析/校验完成之后调用):NAPI `Install`installer.cpp:891,对 `callbackPtr->installParam` 调用)与 ANI `AniInstall`ani_bundle_installer.cpp:225`GetInstallParamForInstall` 返回之后对局部 `installParam` 调用,2026-08-18 增补 ANI;刷新调用在 `AniInstall` 函数体内、不在共享 helper 内部,故经同一 helper 的 `AniUpdateBundleForSelf` 不被覆盖);NAPI `updateBundleForSelf`installer.cpp:1146 `CheckInstallParam` 之后)与 ANI `AniUpdateBundleForSelf`ani_bundle_installer.cpp:311 helper 调用之后)均不接入刷新,该两入口携带保留 key 不生效、字段走默认(**2026-08-18 需求方裁定:updateBundleForSelf 接口不适配,保留 key 透传范围即 install 入口,非功能覆盖缺口**);key 常量 `Constants::DEVICE_MODE_DISTRIBUTION_POLICY_KEY`bundle_constants.h,对齐 `ohos.bms.param.*` 保留前缀惯例);**codecheck R1 加固(2026-08-18F-P2-01/F-P2-02**:① 服务端 `InstallParam::ReadFromParcel` 对该字段加值域白名单 [0,8],原生 IPC 调用方携越界 int32 时 `APP_LOGW` 告警后降级 UNSPECIFIED(与非法 value 静默降级同口径,不阻断安装请求),越界值不可达广播事件字段;② NAPI `ParseParameters` 与 ANI `ParseInstallParam`common_fun_ani.cpp)对 parameters 重复 key 统一为 **first-wins**——遇重复 key `APP_LOGW` 告警 + 跳过(保留首个、忽略后续,消除原 NAPI 吞错中断 / ANI last-wins 跨栈分歧),单次 key 行为零回归
## 验收追溯
> 全 ACAC-1~40)代码已落地、待集成环境编译/单测验证;AC-17(5 字段)、AC-19instIndex=10000)待集成环境重验;AC-1~35 已编译验证通过(`80d089208`,112 例单测编译 OK);增量代码落地提交 `14eb7f286`2026-08-06)后单测扩至 123 例。运行时集成回归 + 人类 Owner 发布批准为发布 Gate 未决项(见 [gates/release.md](./gates/release.md))。
> 全 ACAC-1~41)代码已落地、待集成环境编译/单测验证;AC-41 为 TS 接口透传增量(2026-08-17 NAPI `install`2026-08-18 增补 ANI `install`,接入点共 2 处;NAPI/ANI `updateBundleForSelf` 均不适配——2026-08-18 需求方裁定,透传范围即 install 入口,非缺口);AC-175 字段)、AC-19instIndex=10000)待集成环境重验;AC-1~35 已编译验证通过(`80d089208`,112 例单测编译 OK);增量代码落地提交 `14eb7f286`2026-08-06)后单测扩至 123 例。运行时集成回归 + 人类 Owner 发布批准为发布 Gate 未决项(见 [gates/release.md](./gates/release.md))。
| AC | 关联规则 | 关联 Task | 验证方式 | 证据 |
|----|----------|-----------|----------|------|
@@ -251,6 +261,7 @@
| AC-38 | — | TASK-3 | 单测+集成(副模式不同包体 appIndex=10000、CreateHapInfoParams 直接传播) | ⏳ 代码已落地,待集成环境编译/单测/运行时回归 |
| AC-39 | — | TASK-6 | 单测+集成(粘性隔离:隔离后更新仍隔离) | ⏳ 代码已落地,待集成环境编译/单测/运行时回归 |
| AC-40 | — | TASK-6 | 单测+集成(before 值更新捕获/首装默认/非双模式零回归) | ⏳ 代码已落地,待集成环境编译/单测/运行时回归 |
| AC-41 | FR-16 | TASK-7 | 单测(parameters key 刷新枚举/缺 key 零回归/非法 value 静默降级/Parcel 越界值降级) | ⏳ 代码已落地(NAPI install + ANI install 共 2 入口;NAPI/ANI updateBundleForSelf 均不适配(2026-08-18 裁定);codecheck R1 加固:服务端值域白名单 + 双栈重复 key first-wins,已随提交 `e148c7a34` 入库、R2 报告 approve/94),待集成环境编译/单测/运行时回归 |
## 业务规则
@@ -279,6 +290,7 @@
| FR-13 | 语言/主题切换时刷新双模式(`bundleInfos_` + `tempBundleInfos_`)同名应用的名称资源,两模式各自 key 不交叉污染 | 语言/主题切换 + 双模式 | BundleResourceManager 刷新路径(GetAllResourceInfo | AC-31 |
| FR-14 | 双模式设备不同包体类别(**不分主副模式**)仅限系统应用,非系统应用安装失败返回 `ERR_APPEXECFWK_INSTALL_DUAL_MODE_NOT_SYSTEM_APP``isDualModeCloneApp` 仅副模式置位 | 双模式 + 不同包体类别 + 安装准入 | SetDualModeAppInfoIsDiffPackageCategory 时校验 IsSystemApp | AC-34 |
| FR-15 | 副模式安装时跨 map`tempBundleInfos_`)校验类别一致性,不同包体类别 互转拦截返回 `ERR_APPEXECFWK_INSTALL_DUAL_MODE_CATEGORY_CONFLICT` | 双模式 + 不同包体类别 + 跨模式 | CheckDualModeCategoryConsistencyInTemp | AC-35 |
| FR-16 | TS 安装接口经 installParam.parameters 保留 key `ohos.bms.param.deviceModeDistributionPolicy`(value 为枚举值十进制字符串)透传设备模式分发策略,适配层解析刷新 `InstallParam.deviceModeDistributionPolicy` 字段后走既有 IPC 链路;NAPI/ANI `updateBundleForSelf` 均不适配(2026-08-18 裁定,保留 key 透传范围即 install 入口,该两入口走默认非缺口);服务端 ReadFromParcel 值域白名单 [0,8] 越界降级 UNSPECIFIEDNAPI/ANI parameters 重复 key 统一 first-winscodecheck R1 加固);保留 key 为内部分发平台契约,不出对外资料(2026-08-18 裁定) | NAPI `install`installer.cpp:893+ ANI `install`ani_bundle_installer.cpp:225+ parameters 携带保留 key | InstallParam::RefreshDeviceModeDistributionPolicy(接入点 2 处,参数校验之后调用)+ ReadFromParcel 值域白名单 + 双栈重复 key first-wins | AC-41 |
## 异常/豁免规则
@@ -313,7 +325,7 @@
|----------|----------|----------|--------|------------|----------|---------|
| DeviceModeDistributionPolicy(枚举) | Public | 9 个枚举成员(值 0~8 | - | N/A | 设备模式分发策略定义,连续 int 值不支持按位或 | AC-1 |
| BundleInfo.deviceModeDistributionPolicy | Public | number(枚举值,0~8 | - | N/A | 应用设备模式分发策略,默认 UNSPECIFIED(值 0 | AC-1/AC-2 |
| InstallParam.deviceModeDistributionPolicy | Public | number(枚举值,0~8 | - | N/A | 安装时指定的设备模式分发策略,默认 UNSPECIFIED(值 0 | AC-1 |
| InstallParam.deviceModeDistributionPolicy | Public | number(枚举值,0~8 | - | N/A | 安装时指定的设备模式分发策略,默认 UNSPECIFIED(值 0TS 侧经 parameters 保留 key 透传(AC-41),native/IPC 侧为字段 | AC-1/AC-41 |
| AppSandboxPolicy(枚举) | Public | 2 个枚举成员(值 0~1 | - | N/A | 应用沙箱策略定义,连续 int 值互斥单值 | AC-36 |
| BundleInfo.appSandboxPolicy | Public | number(枚举值,0~1 | - | N/A | 应用沙箱策略,默认 SHARED_SANDBOX(值 0 | AC-36/37 |
@@ -329,6 +341,7 @@
| API 名称 | 变更类型 | 影响场景 | 迁移指引 | 关联 AC |
|----------|----------|----------|----------|---------|
| InstallParam(结构扩展) | 新增可选字段 | 现有调用方不传 deviceModeDistributionPolicy 时走默认值 | 无需迁移,向后兼容 | AC-1/AC-2 |
| InstallParam.parameters(保留 key 透传) | 新增保留 key 语义 | TS 侧经既有 parameters 数组(`Array<{key, value}>`)传 key `ohos.bms.param.deviceModeDistributionPolicy`、value 为枚举值十进制字符串(如 "4");适配层(NAPI `install`ANI `install`)刷新 `deviceModeDistributionPolicy` 字段 | 无需迁移:不传该 key 走默认 UNSPECIFIED;传非法 value(非十进制整数/超 0~8)仅打 warning 日志、静默降级默认策略,不拦截安装(2026-08-17 裁定不报 401 | AC-41 |
| ApplicationInfo(结构扩展) | 新增可选字段 | 反序列化老数据时字段缺失 | from_json 默认值兜底,无需迁移 | AC-18 |
| BundleInfo(结构扩展) | 新增可选字段 appSandboxPolicy | 反序列化老数据时字段缺失 | from_json 默认值兜底(SHARED_SANDBOX),无需迁移 | AC-37 |