mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 22:21:36 -04:00
!20071 merge 15383 into master
dfx sdd Created-by: wendel Commit-by: wendel Merged-by: openharmony_ci Description: **IssueNo**: **Description**: **稳定性自检:** | 自检项 | 自检结果 | | ------------------------------------------------------------ | -------- | | 涉及跨进程调用的相关操作需要抛至主线程或加锁防止并发 | | | 成员变量进行赋值或创建需要排查并发 | | | 谨慎在lambda表达式中使用引用捕获 | | | 谨慎在未经拷贝的情况下使用外部传入的string、C字符串 | | | map\vector\list\set等stl模板类使用时需要排查并发 | | | 谨慎考虑加锁范围 | | | 在IPC通信中谨慎使用同步通信方式 | | | 禁止传递this指针至其他模块或线程(特别是eventhandler任务) | | | 禁止将外部传入的裸指针在内部直接构造智能指针 | | | 禁止多个独立创建的智能指针管理同一地址 | | | 禁止在析构函数中抛异步任务 | | | 禁止js对象在非js线程(例如在IPC线程)创建、使用或销毁 | | | 禁止在对外接口中未经判空直接使用外部传入的指针 | | | 禁止接口返回局部变量引用 | | | 禁止在信号函数中加锁 | | | 禁止在关键流程(SA启动、应用启动等主流程)执行耗时的操作 | | | 禁止将同一个cpp编译在不同的so中 | | **安全编码自检:** | 自检项 | 自检结果 | | -------------------------------------------------------------- | -------- | | 裸指针避免通过隐式转换构造为sptr | | | json对象在取值之前必须先判断类型,避免类型不匹配 | | | 序列化时必须对传入的数组大小进行校验,避免出现超大数组 | | | 避免使用未明确位宽的整型,选择使用int8_t、uint8_t等类型 | | | 外部传入的路径要做规范化校验,对路径中的.、..、../等特殊字符严格校验 | | | 指针变量、表示资源描述符的变量、bool变量必须赋初值 | | | readParcelable获取的对象使用前需要判空 | | | 分配和释放内存的函数需要成对出现 | | | 申请内存后异常退出前需要及时进行内存释放 | | | 内存申请前必须对内存大小进行合法性校验 | | | 内存分配后必须判断是否成功 | | | 禁止使用realloc、alloca函数 | | | 禁止打印文件路径、口令等敏感信息,如有需要,使用private修饰 | | | 禁止打印内存地址 | | | 整数之间运算时必须严格检查,确保不会出现溢出、反转、除0 | | | 禁止对有符号整数进行位操作符运算 | | | 禁止对指针进行逻辑或位运算 | | | 循环次数如果收外部数据控制,需要检验其合法性 | | | 禁止使用内存操作类危险函数,需要使用安全函数 | | | 谨慎使用不可重入函数 | | | 必须检查安全函数的返回值,并进行正确处理 | | | 禁止仅通过TokenType类型判断绕过权限校验 | | **TDD Result**: **XTS Result**: ### 是否已执行L0用例 - [ ] 已验证 - [ ] 不涉及。如不涉及,请写明理由 ### AI检视评分(使用本地代码检视skills扫描): See merge request: openharmony/ability_ability_runtime!20071
This commit is contained in:
@@ -0,0 +1,343 @@
|
||||
# 架构设计
|
||||
|
||||
> 本设计承接 `proposal.md`(条件通过)与 `spec.md`(Draft),固化 `execTool` 的架构约束、关键设计决策与模块影响。设计 AC ⊆ spec AC,不发明新行为。
|
||||
|
||||
## 设计元数据
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| Design ID | DESIGN-CLI-001 |
|
||||
| 关联需求 | `proposal.md`(REQ-010) |
|
||||
| 关联 Epic | 无(独立特性) |
|
||||
| 目标 Feature | FEAT-CLI-001 |
|
||||
| 复杂度 | 标准 |
|
||||
| 目标版本 | OpenHarmony-6.0-Release(待确认) |
|
||||
| Owner | 待确认 |
|
||||
| 状态 | Draft |
|
||||
|
||||
## 需求基线
|
||||
|
||||
> 需求基线详见 proposal.md。以下仅列出设计阶段需额外强调的要点。
|
||||
|
||||
| 项 | 补充说明 |
|
||||
|----|----------|
|
||||
| 仅系统应用 + EXEC_CLI_TOOL | 安全边界由 SA 186 入口统一执行,不在 NAPI 层做权限判定 |
|
||||
| HAP 沙箱前置 | 沙箱配置由调用方 Token 生成,非 HAP 直接拒绝(35700003) |
|
||||
| 会话内存态不持久化 | 不涉及 RDB/Preferences,无跨版本数据兼容约束 |
|
||||
|
||||
## 上下文和现状
|
||||
|
||||
### 涉及仓和模块
|
||||
|
||||
| 仓库 | 补充架构说明 |
|
||||
|------|-------------|
|
||||
| foundation/ability/ability_runtime | 服务层(services/)与 SDK 层(interfaces/kits/)解耦;cli_tool_framework 自成子系统,经 IDL 生成 IPC Stub/Proxy;服务侧依赖 `services/common` 的权限/日志/事件上报设施 |
|
||||
|
||||
### 调用链层级分析
|
||||
|
||||
| 层 | 模块 | 职责 | 修改类型 |
|
||||
|----|------|------|----------|
|
||||
| NAPI | `frameworks/js/napi/cli_tool_manager` | JS↔C++ 绑定:参数解析、同步校验、Promise/异步回调派发 | 修改(既有实现,固化契约) |
|
||||
| InnerAPI/IPC | `interfaces/cli_tool`(IDL 生成) | `ICliToolManager` Proxy/Stub、`ICliToolManagerScheduler` 回复回调、Parcelable 数据结构 | 修改(既有实现,固化契约) |
|
||||
| 服务 | `services/climgr` | SA 186 服务端:权限校验、工具查找、参数/schema 校验、沙箱生成、子进程、会话/超时/让出、IO 监控、事件派发 | 修改(既有实现,固化契约) |
|
||||
| 服务/公共 | `services/common`、`cli_tool_framework/services/common` | 权限工具、HiSysEvent 上报、HiLog 标签 | 不变(复用) |
|
||||
| SA 注册 | `services/sa_profile/186.json` | SA 186 注册到 samgr(进程 aimgr,库 libclimgr.z.so,ondemand) | 不变 |
|
||||
|
||||
**检查项:**
|
||||
- [x] 调用链每一层都已覆盖(NAPI→InnerAPI/IPC→服务→SA 注册)
|
||||
- [x] 每层职责边界清晰,无跨层违规(NAPI 不直接调 services 内部;服务不反向依赖 NAPI)
|
||||
- [x] 每层修改类型明确
|
||||
|
||||
### 适用架构规则
|
||||
|
||||
| Rule ID | 适用原因 | 设计结论 | 验证方式 |
|
||||
|---------|----------|----------|----------|
|
||||
| OH-ARCH-LAYERING | NAPI→InnerAPI/IPC→服务 三层调用 | 调用方向自上而下;服务不反向依赖 NAPI;框架层不直接引用 services 内部头文件 | 依赖检查/代码评审 |
|
||||
| OH-ARCH-SUBSYSTEM | 单子系统 ability 内闭环 | 不跨子系统调用 | 代码评审 |
|
||||
| OH-ARCH-IPC-SAF | 跨进程经 SA 186 | oneway `ExecTool` + `SchedulerExecToolReplyEvent` 回复;客户端按需拉起 SA | 集成测试 |
|
||||
| OH-ARCH-API-LEVEL | 新增 System API | System 级、需 `ohos.permission.EXEC_CLI_TOOL`、系统应用限定 | API 评审/XTS |
|
||||
| OH-ARCH-COMPONENT-BUILD | 复用既有 component/parts | 无新增 component;BUILD.gn 无新增源文件(既有实现固化) | 构建验证 |
|
||||
| OH-ARCH-ERROR-LOG | 错误码/HiSysEvent | 错误码 357000xx 区间;失败路径上报 bundleName/toolName/failureReason | 单测/hilog/hisysevent |
|
||||
|
||||
## 不涉及项承接
|
||||
|
||||
| 维度 | 设计结论 |
|
||||
|------|----------|
|
||||
| 安全与权限 | 入口在 SA 做「系统应用 + EXEC_CLI_TOOL」双校验;沙箱由调用方 Token 生成,非 HAP 拒绝;失败经 HiSysEvent 上报。详见「安全基础检查」 |
|
||||
| API/SDK | 新增 System API `execTool`;签名/d.ts/权限见「API 签名、Kit 与权限」 |
|
||||
| IPC/跨进程 | oneway IPC + Scheduler 回复;客户端 Scheduler Stub 接收回复并派发到 NAPI 异步任务。详见「时序设计」「线程与并发模型」 |
|
||||
|
||||
## 关键设计决策
|
||||
|
||||
| 决策 ID | 问题 | 推荐方案 | 探索过的替代方案 | 取舍理由 | 影响 |
|
||||
|---------|------|----------|-----------------|------|------|
|
||||
| ADR-1 | 执行承载位置 | SA 186(aimgr)集中承载 | 备选1:应用进程内 fork+exec(放弃,绕过权限/沙箱/审计);备选2:独立 SA(放弃,复用 aimgr 进程更内聚) | CLI 执行涉及权限/沙箱/超时/审计,集中到 SA 统一安全边界与并发控制 | 服务端实现集中在 climgr |
|
||||
| ADR-2 | 调用回复模型 | oneway `ExecTool` + `SchedulerExecToolReplyEvent` 异步回复 | 备选1:同步 IPC 返回(放弃,子进程执行可能超 timeout,同步阻塞 Binder);备选2:客户端轮询 QuerySession(放弃,延迟与功耗差) | 子进程执行时长不定(最长 1800s),同步 IPC 不可行;oneway+回调让回复时机由服务端决定 | IPC 接口为 oneway;客户端须建 Scheduler Stub |
|
||||
| ADR-3 | 前台长任务返回时机 | yieldMs 让出:定时器到点切后台并派发 reply | 备选1:进程退出才返回(放弃,长任务让调用方长时间无响应);备选2:长轮询(放弃,功耗高) | yield 让调用方在 yieldMs 处拿到 running 会话后可订阅事件,兼顾响应性与长任务 | 引入 yieldMs 参数与 yield 定时器 |
|
||||
| ADR-4 | 超时实现 | ffrt 延时任务(`PostExecToolTask`) | 备选1:独立 watchdog 线程(放弃,ffrt 已提供延时能力更轻量);备选2:alarm 信号(放弃,精度与可组合性差) | 复用 ffrt 延时任务,与既有调度一致 | 超时/让出各一个延时任务 |
|
||||
| ADR-5 | 并发控制 | 全局会话表 + 系统配置上限 | 备选1:按调用方限流(放弃,全局资源更需保护);备选2:无上限(放弃,易资源耗尽) | CLI 子进程消耗系统资源,需全局上限保护 | `ValidateSessionLimit` 在入口校验 |
|
||||
|
||||
## 设计骨架
|
||||
|
||||
### 骨架范围
|
||||
|
||||
| 骨架项 | 目标 | 不包含 | 验证方式 |
|
||||
|--------|------|--------|----------|
|
||||
| API/接口骨架 | `execTool` 签名、ExecOptions/CliSessionInfo/ExecResult 数据模型 | 完整业务逻辑 | 编译 + API 快照 |
|
||||
| 模块骨架 | NAPI 入口、IDL 接口、climgr 服务类 | 复杂策略调优 | 构建通过 |
|
||||
| 测试骨架 | exec_tool_param/exec_options/cli_session_info/process_manager 测试 fixture | 全场景 | 最小用例通过 |
|
||||
|
||||
### 骨架 Spec 拆分
|
||||
|
||||
| Task ID | 目标 | 受影响文件 | AC |
|
||||
|---------|------|------------|-----|
|
||||
| TASK-SKELETON-1 | 建立接口/数据结构骨架 | `interfaces/cli_tool/` | WHEN 编译 THEN IDL/Parcelable 生成通过 |
|
||||
|
||||
## 后续 Task 拆分
|
||||
|
||||
| Task ID | 目标 | 受影响文件 | 依赖 |
|
||||
|---------|------|------------|------|
|
||||
| TASK-CLI-001 | 正常执行链路(权限→查找→校验→沙箱→子进程→会话→回复) | `services/climgr/src/cli_tool_manager_service.cpp` 等 | design + spec Approved |
|
||||
| TASK-CLI-002 | 会话语义(前台/让出/后台)reply 时机 | `cli_tool_manager_service.cpp`、`session_record.cpp` | TASK-CLI-001 |
|
||||
| TASK-CLI-003 | 超时/让出定时器与终态派发 | `cli_tool_manager_service.cpp`、`process_manager.cpp` | TASK-CLI-002 |
|
||||
| TASK-CLI-004 | 权限/非 HAP/SA 不可用异常路径 | `cli_tool_manager_service.cpp`、`cli_tool_mgr_client.cpp` | TASK-CLI-001 |
|
||||
| TASK-CLI-005 | 参数/schema/超时边界校验 | `tool_util.cpp`、`exec_options.cpp` | TASK-CLI-001 |
|
||||
| TASK-CLI-006 | NAPI 参数同步校验 | `js_cli_manager.cpp` | TASK-CLI-001 |
|
||||
| TASK-CLI-007 | 会话上限与并发保护 | `cli_tool_manager_service.cpp` | TASK-CLI-001 |
|
||||
| TASK-CLI-008 | DFX/HiSysEvent 失败上报 | `cli_event_report` | TASK-CLI-004 |
|
||||
|
||||
## API 签名、Kit 与权限
|
||||
|
||||
### 新增 API
|
||||
|
||||
| API 签名 | 类型 | Kit | d.ts 位置 | 权限要求 | SysCap |
|
||||
|----------|------|-----|-----------|----------|--------|
|
||||
| `execTool(toolName: string, subcommand: string, args: object, challenge: string, options?: ExecOptions): Promise<CliSessionInfo>` | System | CliToolKit | `cli_tool_framework/interfaces/.../*.d.ts`(待确认) | `ohos.permission.EXEC_CLI_TOOL` + 系统应用 | 待确认 |
|
||||
|
||||
### 变更/废弃 API
|
||||
|
||||
无。
|
||||
|
||||
## 构建系统影响
|
||||
|
||||
### BUILD.gn 变更
|
||||
|
||||
```
|
||||
文件路径: cli_tool_framework/interfaces/cli_tool/BUILD.gn
|
||||
变更说明: 无新增源文件;IDL 接口与 cli_tool_client 库既有,固化契约不改构建。
|
||||
```
|
||||
```
|
||||
文件路径: cli_tool_framework/services/climgr/BUILD.gn
|
||||
变更说明: 无新增源文件;climgr SA 库既有,固化契约不改构建。
|
||||
```
|
||||
```
|
||||
文件路径: cli_tool_framework/frameworks/js/napi/cli_tool_manager/BUILD.gn
|
||||
变更说明: 无新增源文件;NAPI 模块既有,固化契约不改构建。
|
||||
```
|
||||
|
||||
### bundle.json 变更
|
||||
|
||||
无新增 component;复用既有 `ability_runtime` part。若 `ohos.permission.EXEC_CLI_TOOL` 尚未在权限定义仓声明,需在该仓补登记(不在本仓)。
|
||||
|
||||
---
|
||||
|
||||
## 可选设计扩展
|
||||
|
||||
### 架构图
|
||||
|
||||
```
|
||||
[系统应用/NAPI execTool] → [cli_tool_client Proxy] →(IPC oneway)→ [SA 186 climgr ExecTool]
|
||||
↑ SchedulerExecToolReplyEvent 回复 ↓
|
||||
└── [NapiAsyncTask Resolve/Reject] ← [cli_tool_mgr_scheduler_recipient] [ProcessManager 创建沙箱子进程]
|
||||
↓
|
||||
[IOMonitor 监控 stdout/stderr/stdin]
|
||||
↓
|
||||
[EventDispatcher 派发 IO/Exit/Error 事件]
|
||||
```
|
||||
|
||||
### 数据流/控制流
|
||||
|
||||
| 步骤 | 调用方 | 被调用方 | 数据/接口 | 说明 |
|
||||
|------|--------|----------|-----------|------|
|
||||
| 1 | NAPI | cli_tool_client | `ExecTool(param, callback)` | 解析参数建 ExecToolParam |
|
||||
| 2 | cli_tool_client | SA 186 | `ICliToolManager::ExecTool`(oneway) | 拉起 SA(按需)并 IPC |
|
||||
| 3 | SA 186 | PermissionUtil | VerifyAccessToken | 系统应用 + EXEC_CLI_TOOL |
|
||||
| 4 | SA 186 | CliToolDataManager | GetToolByName | 工具查找 |
|
||||
| 5 | SA 186 | ToolUtil | ValidateProperties/GenerateSandboxConfig | schema 校验 + 沙箱 |
|
||||
| 6 | SA 186 | ProcessManager | CreateChildProcess | fork 沙箱子进程 |
|
||||
| 7 | SA 186 | IOMonitor | RegisterSession | 监控管道 + 调度 yield/timeout 定时器 |
|
||||
| 8 | SA 186 | EventDispatcher | DispatchExecToolReplyEvent | 经 Scheduler 回复 |
|
||||
| 9 | cli_tool_client | NapiAsyncTask | Resolve/Reject | 派发到 JS Promise |
|
||||
|
||||
### 时序设计
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as 系统应用(NAPI)
|
||||
participant Client as cli_tool_client
|
||||
participant SA as SA 186 climgr
|
||||
participant Proc as 子进程
|
||||
App->>Client: execTool(param)
|
||||
Client->>SA: ExecTool(param,eventId,scheduler) [oneway]
|
||||
SA->>SA: 权限+查找+校验+沙箱
|
||||
SA->>Proc: CreateChildProcess(fork)
|
||||
SA->>SA: RegisterSessionWithMonitors(yield/timeout 定时器)
|
||||
alt background=true
|
||||
SA-->>Client: SchedulerExecToolReplyEvent(running)
|
||||
else foreground yieldMs>0
|
||||
SA-->>Client: SchedulerExecToolReplyEvent(running) @yieldMs
|
||||
else foreground no-yield
|
||||
Proc-->>SA: 退出+输出排空
|
||||
SA-->>Client: SchedulerExecToolReplyEvent(completed/failed)
|
||||
end
|
||||
Client-->>App: Promise resolve(CliSessionInfo)
|
||||
```
|
||||
|
||||
### 算法与状态机
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> SPAWNING: CreateChildProcess
|
||||
SPAWNING --> RUNNING: 子进程创建成功+会话登记
|
||||
RUNNING --> CANCELLING: timeout/kill/clear
|
||||
RUNNING --> COMPLETED: 进程退出+输出排空
|
||||
RUNNING --> FAILED: 非零退出/异常
|
||||
CANCELLING --> COMPLETED: 清理完成
|
||||
CANCELLING --> FAILED: 清理完成
|
||||
COMPLETED --> [*]
|
||||
FAILED --> [*]
|
||||
```
|
||||
|
||||
> CliSessionInfo.status 字符串映射:RUNNING→"running"、COMPLETED→"completed"、FAILED→"failed"。
|
||||
|
||||
### 测试性设计
|
||||
|
||||
| 测试层级 | 测试目标 | Mock 策略 | 验证方式 |
|
||||
|----------|----------|-----------|----------|
|
||||
| 单元测试 | Parcelable 编解码、参数/schema 校验、超时边界 | Mock 服务端 | `exec_tool_param_test`/`exec_options_test`/`tool_util_test` |
|
||||
| 单元测试 | 客户端错误码与回复派发 | Mock `ICliToolManager`/`Scheduler` | `cli_tool_mgr_client_test`/`cli_tool_mgr_scheduler_recipient_test` |
|
||||
| 集成测试 | 正常执行链路、会话语义、超时/让出 | 真实 SA + 测试工具 | `process_manager_test`/`cli_tool_mgr_service_test` |
|
||||
| 集成测试 | 子进程创建与管道 | 真实 fork | `process_manager_test` |
|
||||
|
||||
### 异常传播时序图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as 应用层
|
||||
participant FW as cli_tool_client
|
||||
participant SA as SA 186
|
||||
App->>FW: execTool(param)
|
||||
FW->>SA: ExecTool [oneway]
|
||||
alt 权限/非系统/非HAP/上限/工具不存在/参数非法
|
||||
SA-->>FW: SchedulerExecToolReplyEvent(错误码)
|
||||
FW-->>App: Promise reject(错误码)
|
||||
else SA 不可用
|
||||
FW-->>App: Promise reject(35700000)
|
||||
else 超时
|
||||
SA->>SA: HandleProcessTimeout(kill)
|
||||
SA-->>FW: SchedulerExecToolReplyEvent(timeout)
|
||||
SA-->>App: DispatchErrorEvent("session timed out")
|
||||
end
|
||||
```
|
||||
|
||||
| 异常场景 | 触发层 | 传播路径 | 最终处理 |
|
||||
|----------|--------|----------|----------|
|
||||
| 非系统应用/缺权限 | SA 入口 | SA→Scheduler→NAPI | reject 35700008/35700007 |
|
||||
| 非 HAP | SA 沙箱生成 | SA→Scheduler→NAPI | reject 35700003 |
|
||||
| 工具/子命令不存在 | SA 查找 | SA→Scheduler→NAPI | reject 35700005 |
|
||||
| schema/参数非法 | SA 校验 | SA→Scheduler→NAPI | reject 35700002 |
|
||||
| 会话上限 | SA 入口 | SA→Scheduler→NAPI | reject 35700001 |
|
||||
| 超时 | SA 定时器 | SA kill→Scheduler→NAPI + ErrorEvent | reject/终态 + 错误事件 |
|
||||
| SA 不可用 | 客户端 | cli_tool_client→NAPI | reject 35700000 |
|
||||
|
||||
### 资源所有权矩阵
|
||||
|
||||
| 资源 | 创建方 | 持有方 | 销毁触发 | 实际释放 | 异常回收 |
|
||||
|------|--------|--------|----------|----------|----------|
|
||||
| 子进程 | ProcessManager | SessionRecord | 进程退出/超时/clear | Killpg + reap | 超时定时器 kill |
|
||||
| 管道 fd(stdin/stdout/stderr) | ProcessManager | SessionRecord | 输出排空/会话清理 | close | IOMonitor 注销 + close |
|
||||
| 会话记录 | SA | sessions_ 表 | 终态派发后 | RemoveSessionRecord | 超时/清理路径兜底移除 |
|
||||
| Scheduler Stub | cli_tool_client | client 单例 | DeathRecipient | ClearProxy | 进程死亡清代理 |
|
||||
| yield/timeout 定时器 | SA(IOMonitor 注册) | ffrt | 触发或会话清理 | ffrt 任务完成 | 会话清理时不取消(幂等检查 record 存在性) |
|
||||
|
||||
### 接口参数规约
|
||||
|
||||
| 接口 | 参数 | 类型 | 合法范围 | 非法处理 | 边界说明 |
|
||||
|------|------|------|----------|----------|----------|
|
||||
| execTool | toolName | string | 非空 + 已注册 | 空/非串→同步抛错;未注册→reject 35700005 | — |
|
||||
| execTool | subcommand | string | 可空串 + 工具子命令表内 | 非空但工具无子命令/不在表→reject 35700005 | 空串用工具顶层 inputSchema |
|
||||
| execTool | args | object | 键须在 inputSchema.properties 内且类型匹配 | 含未声明键/类型不符→reject 35700002 | 空对象合法;`help` 须单独存在 |
|
||||
| execTool | challenge | string | 非空 | 空/非串→同步抛错 | — |
|
||||
| ExecOptions | background | boolean | true/false | — | 默认 false |
|
||||
| ExecOptions | yieldMs | int64 | ≥0;非后台须 ≤ timeout*1000 | <0 或越界→reject 35700002 | 默认 0;仅前台生效 |
|
||||
| ExecOptions | timeout | int64 | ∈[0,1800] 秒 | <0 或 >1800→reject 35700002 | 默认 0=不启用;timeoutMs=timeout*1000 |
|
||||
|
||||
### 线程与并发模型
|
||||
|
||||
| 操作 | 发起线程 | 回调线程 | 跨进程边界 | 线程安全 | 重入约束 |
|
||||
|------|----------|----------|------------|----------|----------|
|
||||
| execTool(NAPI) | JS 主线程 | NapiAsyncTask(JsCliEventHandlerManager 投递) | 是(IPC) | NAPI 异步任务串行化 | 允许并发调用 |
|
||||
| SA ExecTool | Binder 线程 | ffrt 定时器线程 | 是 | sessions_ 表 ffrt::mutex 保护 | 允许并发会话 |
|
||||
| IOMonitor 回调 | IOMonitor 线程 | 同 | 否(进程内) | SessionRecord 原子状态 + mutex | 幂等:record 不存在即跳过 |
|
||||
|
||||
**并发场景:**
|
||||
|
||||
| 场景 | 竞争对象 | 保护机制 | 预期行为 |
|
||||
|------|----------|----------|----------|
|
||||
| 多调用方并发创建会话 | sessions_ 表 | sessionsMutex_ 互斥 + 上限校验 | 超限拒绝 35700001 |
|
||||
| 超时与正常退出竞争 | SessionRecord 状态 | 原子状态 + BeginCleanup 单次进入 | 仅一方完成终态派发 |
|
||||
| 回调与代理死亡竞争 | Scheduler 代理 | DeathRecipient + mutex | 代理死亡不清会话,仅清代理 |
|
||||
|
||||
### 安全基础检查
|
||||
|
||||
> proposal「安全与权限」= 是,本节必填。
|
||||
|
||||
#### 信任边界交叉分析
|
||||
|
||||
| 边界类型 | 跨越的交互 | 风险 | 约束 |
|
||||
|---|---|---|---|
|
||||
| 用户态/内核态 | fork 子进程、pipe 读写 | 子进程越权 | 子进程运行在调用方 HAP 沙箱;SA 持 caps=KILL 可终止 |
|
||||
| 沙箱内外 | 子进程 vs SA(aimgr) 进程 | 跨沙箱数据泄漏 | 沙箱配置按调用方 Token 生成;stdin/stdout/stderr 经管道受控 |
|
||||
| 本地/远程 | NAPI→IPC→SA 全本地 | 无远程暴露 | 仅本机系统应用可调 |
|
||||
| 不同 SELinux 域 | aimgr 域 vs 子进程域 | 域切换 | SA 域 aimgr;子进程域由沙箱配置决定 |
|
||||
|
||||
#### 基础安全要求
|
||||
|
||||
| 检查项 | 结论 | 说明/措施 |
|
||||
|---|---|---|
|
||||
| 加密算法(OH 推荐) | N/A | execTool 不涉及加密 |
|
||||
| 密钥管理 | N/A | 不涉及密钥 |
|
||||
| 随机数 | sessionId 生成 | 由 ToolUtil::GenerateCliSessionId 生成,不要求密码学随机 |
|
||||
| 输入验证 | 强制 | toolName/subcommand/schema/timeout/yieldMs 全链路校验,非法即拒绝 |
|
||||
| 错误处理 | 错误码化 | 357000xx 区间,不泄漏内部栈 |
|
||||
| 配置 | 系统配置 | 并发上限由系统配置,非调用方可控 |
|
||||
| 敏感数据处理(传输/存储/日志) | 不存储敏感数据 | 会话内存态;日志不打印 args 明文(args 仅 Key 校验) |
|
||||
|
||||
### 深度威胁分析(如需)
|
||||
|
||||
> 命中高风险判据评估:execTool 涉及沙箱/子进程/权限,但无网络暴露、无认证授权(仅本机系统应用+权限)、无敏感数据存储、无合规强约束。判定为不升级独立 threat-model.md。如 Owner 复核认为子进程沙箱逃逸风险需深入,再由 `ohos-security-threat-model` 产出。
|
||||
|
||||
## 风险和开放问题
|
||||
|
||||
| 项 | 类型 | 影响 | 处理方式 | Owner |
|
||||
|----|------|------|----------|-------|
|
||||
| 目标版本/Owner 未确认 | 进度 | 基线无法冻结为「通过」 | 需求方/SIG 确认 | 待确认 |
|
||||
| d.ts 位置/SysCap 未确认 | API | 影响 @since 与 SysCap 声明 | API 评审 | 待确认 |
|
||||
| `ohos.permission.EXEC_CLI_TOOL` 权限登记仓 | 构建 | 权限须在定义仓声明 | 跨仓协调 | 待确认 |
|
||||
| yield/timeout 定时器在会话清理后触发 | 可靠性 | 幂等检查 record 存在性,已缓解 | 代码评审 + 单测 | — |
|
||||
|
||||
## 设计审批
|
||||
|
||||
- [x] 需求基线已确认,设计覆盖 P0/P1 AC(AC-1.1–1.15)
|
||||
- [x] 不涉及项已承接,N/A 和展开项都有结论
|
||||
- [x] 涉及仓和模块职责清楚
|
||||
- [x] 调用链层级分析完整,每层覆盖到位
|
||||
- [x] 适用架构规则已识别并形成设计结论
|
||||
- [x] 分层和子系统边界合规
|
||||
- [x] API 变更有签名、权限、错误码和兼容性说明
|
||||
- [x] BUILD.gn/bundle.json 影响明确(无新增源文件,固化契约)
|
||||
- [x] 设计输出和后续 Task 拆分明确
|
||||
- [x] 关键设计决策有理由和影响说明
|
||||
- [x] 风险和开放问题有 Owner(部分待确认)
|
||||
|
||||
**结论:** 条件通过(待 Owner 复核后转「通过」)
|
||||
@@ -0,0 +1,626 @@
|
||||
# 执行计划
|
||||
|
||||
> 将 Approved Spec 拆成可独立执行、可验证、可审查的 Task。本计划针对 `execTool` 既有实现进行契约固化与测试覆盖验证:实现已存在,Task 聚焦「验证既有链路符合 spec + 补齐测试缺口 + 跨仓协调」。
|
||||
|
||||
## Plan 元数据
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| Plan ID | PLAN-CLI-001 |
|
||||
| 关联 Feature/Bug | FEAT-CLI-001(REQ-010) |
|
||||
| 关联文档 | proposal.md / design.md / spec.md |
|
||||
| 复杂度 | 标准 |
|
||||
| 状态 | Draft |
|
||||
| Owner | 待确认 |
|
||||
|
||||
## 输入状态
|
||||
|
||||
| 输入 | 路径 | 要求状态 |
|
||||
|------|------|----------|
|
||||
| Requirement | `proposal.md` | Approved(条件通过,待 Owner 转正) |
|
||||
| Design | `design.md` | Approved(条件通过,待 Owner 转正) |
|
||||
| Spec | `spec.md` | Approved(Draft→待转 Approved) |
|
||||
|
||||
## 受影响文件全量清单
|
||||
|
||||
| 仓 | 层(来自 design.md) | 文件路径 | 修改类型 | 说明 |
|
||||
|----|---------------------|----------|----------|------|
|
||||
| ability_runtime | NAPI | `cli_tool_framework/frameworks/js/napi/cli_tool_manager/src/js_cli_manager.cpp` | 验证/补测试 | `execTool`/`OnExecTool` 参数解析与回调 |
|
||||
| ability_runtime | NAPI | `cli_tool_framework/frameworks/js/napi/cli_tool_manager/include/js_cli_manager.h` | 只读参考 | 声明 |
|
||||
| ability_runtime | InnerAPI/IPC | `cli_tool_framework/interfaces/cli_tool/ICliToolManager.idl` | 只读参考 | `ExecTool` oneway 声明 |
|
||||
| ability_runtime | InnerAPI/IPC | `cli_tool_framework/interfaces/cli_tool/ICliToolManagerScheduler.idl` | 只读参考 | `SchedulerExecToolReplyEvent` 回复 |
|
||||
| ability_runtime | InnerAPI/IPC | `cli_tool_framework/interfaces/cli_tool/include/exec_tool_param.h` | 验证 | ExecToolParam Parcelable |
|
||||
| ability_runtime | InnerAPI/IPC | `cli_tool_framework/interfaces/cli_tool/include/exec_options.h` | 验证 | ExecOptions |
|
||||
| ability_runtime | InnerAPI/IPC | `cli_tool_framework/interfaces/cli_tool/include/cli_session_info.h` | 验证 | CliSessionInfo |
|
||||
| ability_runtime | InnerAPI/IPC | `cli_tool_framework/interfaces/cli_tool/include/exec_result.h` | 验证 | ExecResult |
|
||||
| ability_runtime | InnerAPI/IPC | `cli_tool_framework/interfaces/cli_tool/include/cli_error_code.h` | 验证 | 错误码 357000xx |
|
||||
| ability_runtime | InnerAPI/IPC | `cli_tool_framework/interfaces/cli_tool/src/cli_tool_mgr_client.cpp` | 验证 | 客户端 ExecTool + SA 拉起 |
|
||||
| ability_runtime | 服务 | `cli_tool_framework/services/climgr/src/cli_tool_manager_service.cpp` | 验证 | 服务端 ExecTool 全链路 |
|
||||
| ability_runtime | 服务 | `cli_tool_framework/services/climgr/src/tool_util.cpp` | 验证 | 参数/schema/沙箱校验 |
|
||||
| ability_runtime | 服务 | `cli_tool_framework/services/climgr/src/process_manager.cpp` | 验证 | 子进程创建 |
|
||||
| ability_runtime | 服务 | `cli_tool_framework/services/climgr/src/session_record.cpp` | 验证 | 会话状态机 |
|
||||
| ability_runtime | 服务 | `cli_tool_framework/services/climgr/src/event_dispatcher.cpp` | 验证 | 事件/回复派发 |
|
||||
| ability_runtime | DFX | `cli_tool_framework/services/common/src/cli_event_report*.cpp` | 验证 | HiSysEvent 上报 |
|
||||
| ability_runtime | SA | `services/sa_profile/186.json` | 只读参考 | SA 186 注册 |
|
||||
| ability_runtime | 配置 | `cli_tool_framework/etc/profile/aimgr.cfg` | 只读参考 | 进程/权限/caps |
|
||||
| 跨仓(权限定义仓) | 权限 | `ohos.permission.EXEC_CLI_TOOL` 定义 | 跨仓协调 | 权限登记(不在本仓) |
|
||||
|
||||
**检查项:**
|
||||
- [x] design.md 调用链每一层都有对应文件列出
|
||||
- [x] 每个文件修改类型和职责说明明确
|
||||
- [x] 无映射行的层缺失
|
||||
|
||||
## AC 到 Task 追溯
|
||||
|
||||
| AC | 来源 | Task | 验证方式 | 覆盖? |
|
||||
|----|------|------|----------|--------|
|
||||
| AC-1.1 | spec.md | TASK-CLI-001 | 集成 | 是 |
|
||||
| AC-1.2 | spec.md | TASK-CLI-002 | 集成 | 是 |
|
||||
| AC-1.3 | spec.md | TASK-CLI-002 | 集成 | 是 |
|
||||
| AC-1.4 | spec.md | TASK-CLI-003 | 集成 | 是 |
|
||||
| AC-1.5 | spec.md | TASK-CLI-004 | 单测 | 是 |
|
||||
| AC-1.6 | spec.md | TASK-CLI-004 | 单测 | 是 |
|
||||
| AC-1.7 | spec.md | TASK-CLI-005 | 单测 | 是 |
|
||||
| AC-1.8 | spec.md | TASK-CLI-005 | 单测 | 是 |
|
||||
| AC-1.9 | spec.md | TASK-CLI-005 | 单测 | 是 |
|
||||
| AC-1.10 | spec.md | TASK-CLI-005 | 单测 | 是 |
|
||||
| AC-1.11 | spec.md | TASK-CLI-005 | 单测 | 是 |
|
||||
| AC-1.12 | spec.md | TASK-CLI-006 | 单测 | 是 |
|
||||
| AC-1.13 | spec.md | TASK-CLI-007 | 集成 | 是 |
|
||||
| AC-1.14 | spec.md | TASK-CLI-004 | 集成 | 是 |
|
||||
| AC-1.15 | spec.md | TASK-CLI-008 | 单测 | 是 |
|
||||
|
||||
## 首批实现边界
|
||||
|
||||
**首批必须实现:** TASK-CLI-001(正常链路)+ TASK-CLI-005(参数/边界校验)+ TASK-CLI-004(权限/非HAP),构成主链与安全边界。
|
||||
**可后置:** TASK-CLI-008(DFX 跨仓协调)。
|
||||
**不建议延后:** TASK-CLI-002/003(会话语义/超时)延后会导致主链行为不闭合。
|
||||
|
||||
## 阶段计划(如适用)
|
||||
|
||||
| 阶段 | 目标 | 关键 Task | 结束门槛 | 最小验证 |
|
||||
|------|------|-----------|----------|----------|
|
||||
| Phase-1 | 主链+安全+参数 | TASK-CLI-001,004,005,006 | 正常执行与异常路径单测通过 | `run -t UT -ts cli_tool_mgr_client_test` |
|
||||
| Phase-2 | 会话语义+超时+并发 | TASK-CLI-002,003,007 | yield/background/timeout/上限验证通过 | `run -t UT -ts process_manager_test` |
|
||||
| Phase-3 | DFX+SA 不可用 | TASK-CLI-008 | 失败上报与 SA 不可用覆盖 | `run -t UT -ts cli_event_report_test` |
|
||||
|
||||
## Task 粒度原则
|
||||
|
||||
- 每个 Task 对应一个可独立验收的最小能力闭环
|
||||
- 文件范围、验证闭环和风险边界足够分离 → 拆分
|
||||
- 简单变更:1-2 张 Task Card;本计划按主链/会话/超时/权限/参数/NAPI/并发/DFX 拆为 8 张
|
||||
- 每个 Task 自包含,不依赖外部文件路径引用
|
||||
|
||||
## 禁止项
|
||||
|
||||
- [x] 没有 TBD / TODO / 占位符(「待确认」为需 Owner 决议项,非规格占位)
|
||||
- [x] 没有"根据需要实现""酌情处理"等模糊指令
|
||||
- [x] 没有跨 Task 隐式依赖(依赖显式声明在前置依赖列)
|
||||
- [x] 没有要求 Agent 自行寻找未列出的上下文文件
|
||||
- [x] 没有无验证方式的 AC
|
||||
- [x] 没有"与 Task-N 类似""参考 Task-N 实现"等引用
|
||||
|
||||
## Task 列表
|
||||
|
||||
| Task ID | 目标 | 文件范围 | AC 映射 | 前置依赖 | 完成判据 | 验证命令 |
|
||||
|---------|------|----------|---------|----------|----------|----------|
|
||||
| TASK-CLI-001 | 正常执行链路契约验证 | climgr/cli_tool_mgr_client | AC-1.1 | 无 | 正常调用返回 completed 会话与退出码 | `run -t UT -ts cli_tool_mgr_service_test` |
|
||||
| TASK-CLI-002 | 前台让出/后台会话语义验证 | cli_tool_manager_service/session_record | AC-1.2,AC-1.3 | TASK-CLI-001 | yieldMs 与 background reply 时机/状态正确 | `run -t UT -ts cli_tool_mgr_service_test` |
|
||||
| TASK-CLI-003 | 超时终止与终态派发验证 | cli_tool_manager_service/process_manager | AC-1.4 | TASK-CLI-002 | timeout 触发 kill+timeout=true+错误事件 | `run -t UT -ts process_manager_test` |
|
||||
| TASK-CLI-004 | 权限/非HAP异常路径验证 | cli_tool_manager_service/cli_tool_mgr_client | AC-1.5,AC-1.6,AC-1.14 | TASK-CLI-001 | 非系统/缺权限/非HAP 返回正确码 | `run -t UT -ts cli_tool_mgr_client_test` |
|
||||
| TASK-CLI-005 | 工具/子命令/schema/超时边界校验验证 | tool_util/exec_options/exec_tool_param | AC-1.7–1.11 | TASK-CLI-001 | 各非法输入返回 35700005/35700002 | `run -t UT -ts tool_util_test` |
|
||||
| TASK-CLI-006 | NAPI 参数同步校验验证 | js_cli_manager | AC-1.12 | TASK-CLI-001 | 必填缺失/类型错/argc<4 同步抛错 | `run -t UT -ts cli_tool_mgr_client_test` |
|
||||
| TASK-CLI-007 | 会话并发上限验证 | cli_tool_manager_service | AC-1.13 | TASK-CLI-001 | 超上限返回 35700001 | `run -t UT -ts cli_tool_mgr_service_test` |
|
||||
| TASK-CLI-008 | DFX 失败上报 + SA 不可用验证 | cli_event_report/cli_tool_mgr_client | AC-1.15 | TASK-CLI-004 | SA 不可用返回 35700000;失败经 HiSysEvent | `run -t UT -ts cli_event_report_test` |
|
||||
|
||||
## Task 详情
|
||||
|
||||
### TASK-CLI-001: 正常执行链路契约验证
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| 任务目标 | 验证既有 execTool 正常链路符合 spec AC-1.1:合法调用返回 completed 会话与退出码 |
|
||||
| AC 映射 | AC-1.1 |
|
||||
| 前置依赖 | 无 |
|
||||
| 非目标 | 不验证 yield/background/timeout(属 TASK-CLI-002/003) |
|
||||
| 完成判据 | 集成测试覆盖:合法 toolName+subcommand+args+challenge→resolve status="completed",result.exitCode=进程退出码 |
|
||||
| 停止条件 | 发现既有实现与 spec 行为不一致且无法在 Task 范围内修复 |
|
||||
|
||||
**Files**
|
||||
|
||||
| 操作 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| Test | `cli_tool_framework/test/unittest/cli_tool_mgr_service_test/` | 正常链路用例 |
|
||||
| Test | `cli_tool_framework/test/unittest/process_manager_test/` | 子进程创建用例 |
|
||||
|
||||
**Spec Context**
|
||||
|
||||
AC-1.1:WHEN 系统应用持 EXEC_CLI_TOOL 调用 execTool,传入已注册 toolName、工具支持 subcommand、符合 inputSchema 的 args、非空 challenge THEN 接口返回 Promise,工具执行结束后 resolve 为 CliSessionInfo(status="completed",result.exitCode 等于子进程退出码)。
|
||||
|
||||
R-1:合法输入→创建会话与受沙箱子进程执行工具,结束后 resolve CliSessionInfo{status="completed", result.exitCode=进程退出码, outputText, errorText, executionTime}。
|
||||
|
||||
**Design Context**
|
||||
|
||||
调用链:NAPI→cli_tool_client Proxy→SA 186 ExecTool(oneway)→权限/查找/校验/沙箱→ProcessManager.CreateChildProcess→IOMonitor.RegisterSession→EventDispatcher.DispatchExecToolReplyEvent→client Scheduler Stub→NapiAsyncTask.Resolve。设计 ADR-1(SA 集中承载)、ADR-2(oneway+回调)。
|
||||
|
||||
**Required Rules**
|
||||
|
||||
| Rule ID | Must / Must Not |
|
||||
|---------|-----------------|
|
||||
| OH-ARCH-LAYERING | Must:NAPI 不直接调 services 内部;经 InnerAPI/IPC |
|
||||
| OH-ARCH-IPC-SAF | Must:ExecTool 为 oneway;回复经 Scheduler |
|
||||
|
||||
**Steps**
|
||||
|
||||
- [ ] 写失败测试:合法调用断言 resolve completed + exitCode
|
||||
- [ ] 运行测试,确认当前结果
|
||||
- [ ] 若不一致,做最小实现修正
|
||||
- [ ] 运行测试,确认通过
|
||||
- [ ] 填写完成证据
|
||||
|
||||
**Completion Evidence**
|
||||
|
||||
| 证据类型 | 命令/路径 | 结果 |
|
||||
|----------|-----------|------|
|
||||
| 测试 | `run -t UT -ts cli_tool_mgr_service_test` | PASS |
|
||||
| 测试 | `run -t UT -ts process_manager_test` | PASS |
|
||||
|
||||
**Handoff Summary**
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| 任务描述 | 验证 execTool 正常链路返回 completed 会话与退出码(AC-1.1) |
|
||||
| 允许修改 | `cli_tool_framework/services/climgr/src/cli_tool_manager_service.cpp`、`cli_tool_framework/test/unittest/cli_tool_mgr_service_test/` |
|
||||
| 允许新建 | 测试用例文件 |
|
||||
| 只读参考 | `spec.md` AC-1.1、`design.md` ADR-1/ADR-2、`ICliToolManager.idl` |
|
||||
| Spec 摘要 | AC-1.1 + R-1:合法输入→completed 会话+exitCode |
|
||||
| Design 摘要 | NAPI→IPC→SA oneway+Scheduler 回复;ProcessManager.CreateChildProcess |
|
||||
| 执行步骤 | 写失败测试→运行→最小修正→运行通过→记录证据 |
|
||||
| 验证命令 | `run -t UT -ts cli_tool_mgr_service_test` / 期望: PASS |
|
||||
| 完成规则 | 不得修改允许范围外文件;如需扩大范围停止并修订 Plan;无 fresh evidence 不得声明完成 |
|
||||
|
||||
### TASK-CLI-002: 前台让出/后台会话语义验证
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| 任务目标 | 验证 yieldMs 让出与 background 立即返回的 reply 时机与 status 符合 AC-1.2/AC-1.3 |
|
||||
| AC 映射 | AC-1.2, AC-1.3 |
|
||||
| 前置依赖 | TASK-CLI-001 |
|
||||
| 非目标 | 不验证超时终止(TASK-CLI-003) |
|
||||
| 完成判据 | background=true 立即 resolve running;foreground+yieldMs>0 在 yieldMs 处 resolve running 且转后台 |
|
||||
| 停止条件 | 定时器或状态机行为与 spec 不一致且超范围 |
|
||||
|
||||
**Files**
|
||||
|
||||
| 操作 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| Test | `cli_tool_framework/test/unittest/cli_tool_mgr_service_test/` | 会话语义用例 |
|
||||
| Test | `cli_tool_framework/test/unittest/session_record_test/` | 状态机用例 |
|
||||
|
||||
**Spec Context**
|
||||
|
||||
AC-1.2:WHEN background=false 且 yieldMs>0 THEN 在 yieldMs 毫秒后 resolve 为 status="running",会话转后台继续运行。
|
||||
AC-1.3:WHEN background=true THEN 立即 resolve 为 status="running"。
|
||||
R-2/R-3:yield 让出、background 立即返回。
|
||||
|
||||
**Design Context**
|
||||
|
||||
RegisterSessionWithMonitors:非 background 且 yieldMs!=0 → PostExecToolTask(yieldMs, isTimeout=false);background → HandleBackgroundSessionReply 立即派发。HandleProcessYieldTimeout 切后台并派发 running。状态机 SPAWNING→RUNNING→CANCELLING/COMPLETED/FAILED。设计 ADR-3。
|
||||
|
||||
**Required Rules**
|
||||
|
||||
| Rule ID | Must / Must Not |
|
||||
|---------|-----------------|
|
||||
| OH-ARCH-IPC-SAF | Must:回复经 SchedulerExecToolReplyEvent |
|
||||
|
||||
**Steps**
|
||||
|
||||
- [ ] 写失败测试:background 立即返回 + yieldMs 让出时机
|
||||
- [ ] 运行测试
|
||||
- [ ] 最小修正
|
||||
- [ ] 运行通过
|
||||
- [ ] 记录证据
|
||||
|
||||
**Completion Evidence**
|
||||
|
||||
| 证据类型 | 命令/路径 | 结果 |
|
||||
|----------|-----------|------|
|
||||
| 测试 | `run -t UT -ts cli_tool_mgr_service_test` | PASS |
|
||||
| 测试 | `run -t UT -ts session_record_test` | PASS |
|
||||
|
||||
**Handoff Summary**
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| 任务描述 | 验证 yield 让出与 background 立即返回语义(AC-1.2/1.3) |
|
||||
| 允许修改 | `cli_tool_manager_service.cpp`、`session_record.cpp`、对应测试 |
|
||||
| 允许新建 | 测试用例 |
|
||||
| 只读参考 | spec AC-1.2/1.3、design ADR-3、`session_record.h` 状态枚举 |
|
||||
| Spec 摘要 | AC-1.2/1.3 + R-2/R-3 |
|
||||
| Design 摘要 | RegisterSessionWithMonitors 调度 yield;HandleBackgroundSessionReply/HandleProcessYieldTimeout |
|
||||
| 执行步骤 | 写失败测试→运行→修正→通过→证据 |
|
||||
| 验证命令 | `run -t UT -ts cli_tool_mgr_service_test` / 期望: PASS |
|
||||
| 完成规则 | 不改范围外文件;无 evidence 不声明完成 |
|
||||
|
||||
### TASK-CLI-003: 超时终止与终态派发验证
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| 任务目标 | 验证 timeout 秒后进程被终止、result.timeout=true、派发超时错误事件(AC-1.4) |
|
||||
| AC 映射 | AC-1.4 |
|
||||
| 前置依赖 | TASK-CLI-002 |
|
||||
| 非目标 | 不验证正常完成路径 |
|
||||
| 完成判据 | 进程达 timeout 被 kill,终态 result.timeout=true,订阅者收到 "session timed out" 错误事件 |
|
||||
| 停止条件 | kill/定时器逻辑与 spec 不一致且超范围 |
|
||||
|
||||
**Files**
|
||||
|
||||
| 操作 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| Test | `cli_tool_framework/test/unittest/process_manager_test/` | 超时/kill 用例 |
|
||||
|
||||
**Spec Context**
|
||||
|
||||
AC-1.4:WHEN 进程运行达 options.timeout 秒 THEN 进程被终止、result.timeout=true,并向订阅者派发超时错误事件。
|
||||
R-4:timeout>0 达阈值→终止、timeout=true、错误事件;未后台则派发终态 reply。
|
||||
|
||||
**Design Context**
|
||||
|
||||
PostExecToolTask(timeoutMs, isTimeout=true) → HandleProcessTimeout:SetTimeout(true)、SetState(CANCELLING)、DispatchExecToolReplyEvent(未后台)、DispatchErrorEvent("session timed out")、ProcessManager.Killpg。设计 ADR-4(ffrt 延时)。
|
||||
|
||||
**Required Rules**
|
||||
|
||||
| Rule ID | Must / Must Not |
|
||||
|---------|-----------------|
|
||||
| OH-ARCH-ERROR-LOG | Must:超时经 HiSysEvent ReportCliTimeout 上报 |
|
||||
|
||||
**Steps**
|
||||
|
||||
- [ ] 写失败测试:timeout 触发 kill + timeout=true + 错误事件
|
||||
- [ ] 运行测试
|
||||
- [ ] 最小修正
|
||||
- [ ] 运行通过
|
||||
- [ ] 记录证据
|
||||
|
||||
**Completion Evidence**
|
||||
|
||||
| 证据类型 | 命令/路径 | 结果 |
|
||||
|----------|-----------|------|
|
||||
| 测试 | `run -t UT -ts process_manager_test` | PASS |
|
||||
|
||||
**Handoff Summary**
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| 任务描述 | 验证超时终止与终态派发(AC-1.4) |
|
||||
| 允许修改 | `cli_tool_manager_service.cpp`、`process_manager.cpp`、对应测试 |
|
||||
| 允许新建 | 测试用例 |
|
||||
| 只读参考 | spec AC-1.4 + R-4、design ADR-4 |
|
||||
| Spec 摘要 | AC-1.4:timeout→kill+timeout=true+错误事件 |
|
||||
| Design 摘要 | HandleProcessTimeout + Killpg + ffrt 延时任务 |
|
||||
| 执行步骤 | 写失败测试→运行→修正→通过→证据 |
|
||||
| 验证命令 | `run -t UT -ts process_manager_test` / 期望: PASS |
|
||||
| 完成规则 | 不改范围外文件;无 evidence 不声明完成 |
|
||||
|
||||
### TASK-CLI-004: 权限/非HAP异常路径验证
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| 任务目标 | 验证非系统应用、缺权限、非 HAP 调用分别返回 35700008/35700007/35700003(AC-1.5/1.6/1.14) |
|
||||
| AC 映射 | AC-1.5, AC-1.6, AC-1.14 |
|
||||
| 前置依赖 | TASK-CLI-001 |
|
||||
| 非目标 | 不验证工具不存在/参数非法(TASK-CLI-005) |
|
||||
| 完成判据 | 三类调用方均被正确拒绝并返回对应错误码,失败经 HiSysEvent 上报 |
|
||||
| 停止条件 | 权限/沙箱判定与 spec 不一致 |
|
||||
|
||||
**Files**
|
||||
|
||||
| 操作 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| Test | `cli_tool_framework/test/unittest/cli_tool_mgr_client_test/` | 权限/非HAP 用例 |
|
||||
|
||||
**Spec Context**
|
||||
|
||||
AC-1.5:非系统应用→reject 35700008。AC-1.6:缺权限→reject 35700007。AC-1.14:非 HAP→reject 35700003。
|
||||
R-5/R-11。
|
||||
|
||||
**Design Context**
|
||||
|
||||
ValidateExecToolPermissions:IsSystemAppByFullTokenID→ERR_NOT_SYSTEM_APP;VerifyAccessToken(EXEC_CLI_TOOL)→ERR_PERMISSION_DENIED。ValidateAndPrepareTool→GenerateSandboxConfig 失败→ERR_NOT_HAP。ReportCliExecuteFailed 上报。设计「安全基础检查」信任边界。
|
||||
|
||||
**Required Rules**
|
||||
|
||||
| Rule ID | Must / Must Not |
|
||||
|---------|-----------------|
|
||||
| OH-ARCH-API-LEVEL | Must:System API + 系统应用 + EXEC_CLI_TOOL |
|
||||
| OH-ARCH-ERROR-LOG | Must:失败经 HiSysEvent |
|
||||
|
||||
**Steps**
|
||||
|
||||
- [ ] 写失败测试:三类调用方断言对应错误码
|
||||
- [ ] 运行测试
|
||||
- [ ] 最小修正
|
||||
- [ ] 运行通过
|
||||
- [ ] 记录证据
|
||||
|
||||
**Completion Evidence**
|
||||
|
||||
| 证据类型 | 命令/路径 | 结果 |
|
||||
|----------|-----------|------|
|
||||
| 测试 | `run -t UT -ts cli_tool_mgr_client_test` | PASS |
|
||||
|
||||
**Handoff Summary**
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| 任务描述 | 验证权限/非HAP 异常路径错误码(AC-1.5/1.6/1.14) |
|
||||
| 允许修改 | `cli_tool_manager_service.cpp`、`cli_tool_mgr_client.cpp`、对应测试 |
|
||||
| 允许新建 | 测试用例 |
|
||||
| 只读参考 | spec AC-1.5/1.6/1.14 + R-5/R-11、design 安全基础检查 |
|
||||
| Spec 摘要 | 非系统→35700008;缺权限→35700007;非HAP→35700003 |
|
||||
| Design 摘要 | ValidateExecToolPermissions + GenerateSandboxConfig + ReportCliExecuteFailed |
|
||||
| 执行步骤 | 写失败测试→运行→修正→通过→证据 |
|
||||
| 验证命令 | `run -t UT -ts cli_tool_mgr_client_test` / 期望: PASS |
|
||||
| 完成规则 | 不改范围外文件;无 evidence 不声明完成 |
|
||||
|
||||
### TASK-CLI-005: 工具/子命令/schema/超时边界校验验证
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| 任务目标 | 验证工具/子命令不存在、schema 不匹配、timeout/yieldMs 越界返回 35700005/35700002(AC-1.7–1.11) |
|
||||
| AC 映射 | AC-1.7, AC-1.8, AC-1.9, AC-1.10, AC-1.11 |
|
||||
| 前置依赖 | TASK-CLI-001 |
|
||||
| 非目标 | 不验证权限路径(TASK-CLI-004) |
|
||||
| 完成判据 | 各非法输入返回正确错误码;空 args 合法;help 特殊键放行 |
|
||||
| 停止条件 | 校验逻辑与 spec 不一致 |
|
||||
|
||||
**Files**
|
||||
|
||||
| 操作 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| Test | `cli_tool_framework/test/unittest/tool_util_test/` | 工具/schema 校验 |
|
||||
| Test | `cli_tool_framework/test/unittest/exec_options_test/` | timeout/yieldMs 边界 |
|
||||
| Test | `cli_tool_framework/test/unittest/exec_tool_param_test/` | Parcelable + schema |
|
||||
|
||||
**Spec Context**
|
||||
|
||||
AC-1.7:toolName 未注册→35700005。AC-1.8:subcommand 非法→35700005。AC-1.9:args 不符 schema→35700002。AC-1.10:timeout<0 或 >1800→35700002。AC-1.11:非后台 yieldMs>timeout*1000→35700002。
|
||||
R-6/R-7/R-8。
|
||||
|
||||
**Design Context**
|
||||
|
||||
ValidateProperties:subcommand 非空但工具无子命令/不在表→ERR_TOOL_NOT_EXIST。ValidateExecOptionsProperties:timeout<0/yieldMs<0/timeout>1800/yieldMs>timeout*1000→ERR_INVALID_PARAM。ValidateInputSchemaProperties:args 键须在 properties 且类型匹配;help 单独放行;空 args 合法。接口参数规约表。
|
||||
|
||||
**Required Rules**
|
||||
|
||||
| Rule ID | Must / Must Not |
|
||||
|---------|-----------------|
|
||||
| OH-ARCH-ERROR-LOG | Must:错误码 35700005/35700002 |
|
||||
|
||||
**Steps**
|
||||
|
||||
- [ ] 写失败测试:各非法输入断言错误码
|
||||
- [ ] 运行测试
|
||||
- [ ] 最小修正
|
||||
- [ ] 运行通过
|
||||
- [ ] 记录证据
|
||||
|
||||
**Completion Evidence**
|
||||
|
||||
| 证据类型 | 命令/路径 | 结果 |
|
||||
|----------|-----------|------|
|
||||
| 测试 | `run -t UT -ts tool_util_test` | PASS |
|
||||
| 测试 | `run -t UT -ts exec_options_test` | PASS |
|
||||
| 测试 | `run -t UT -ts exec_tool_param_test` | PASS |
|
||||
|
||||
**Handoff Summary**
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| 任务描述 | 验证工具/子命令/schema/超时边界校验(AC-1.7–1.11) |
|
||||
| 允许修改 | `tool_util.cpp`、`exec_options.cpp`、`exec_tool_param.cpp`、对应测试 |
|
||||
| 允许新建 | 测试用例 |
|
||||
| 只读参考 | spec AC-1.7–1.11 + R-6/R-7/R-8、design 接口参数规约 |
|
||||
| Spec 摘要 | 工具/子命令→35700005;schema/超时边界→35700002 |
|
||||
| Design 摘要 | ValidateProperties + ValidateExecOptionsProperties + ValidateInputSchemaProperties |
|
||||
| 执行步骤 | 写失败测试→运行→修正→通过→证据 |
|
||||
| 验证命令 | `run -t UT -ts tool_util_test` / 期望: PASS |
|
||||
| 完成规则 | 不改范围外文件;无 evidence 不声明完成 |
|
||||
|
||||
### TASK-CLI-006: NAPI 参数同步校验验证
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| 任务目标 | 验证必填缺失/类型错/argc<4 同步抛 invalid parameter 异常(AC-1.12) |
|
||||
| AC 映射 | AC-1.12 |
|
||||
| 前置依赖 | TASK-CLI-001 |
|
||||
| 非目标 | 不验证服务端校验(TASK-CLI-005) |
|
||||
| 完成判据 | toolName/challenge 空或非串、args 非对象、argc<4 均同步抛错,不进入异步 |
|
||||
| 停止条件 | NAPI 校验与 spec 不一致 |
|
||||
|
||||
**Files**
|
||||
|
||||
| 操作 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| Test | `cli_tool_framework/test/unittest/cli_tool_mgr_client_test/` | NAPI 校验用例 |
|
||||
|
||||
**Spec Context**
|
||||
|
||||
AC-1.12:toolName 空/非串、challenge 空/非串、args 非对象、实参<4 → 同步抛 invalid parameter 异常。
|
||||
R-9:NAPI 层校验先于服务端。
|
||||
|
||||
**Design Context**
|
||||
|
||||
OnExecTool:argc<INDEX_FOUR→ThrowTooFewParametersError;UnwrapStringFromJS2(toolName) 失败或空→ThrowInvalidParamError("Tool toolName is required");subcommand 非串→抛错;UnwrapWantParams(args) 失败→抛错;challenge 空或非串→抛错;UnwrapExecOptions 失败→抛错。BindNativeFunction("execTool")。调用链层级 NAPI 层。
|
||||
|
||||
**Required Rules**
|
||||
|
||||
| Rule ID | Must / Must Not |
|
||||
|---------|-----------------|
|
||||
| OH-ARCH-LAYERING | Must:NAPI 层做同步参数校验先于 IPC |
|
||||
|
||||
**Steps**
|
||||
|
||||
- [ ] 写失败测试:各缺失/类型错/argc<4 断言同步抛错
|
||||
- [ ] 运行测试
|
||||
- [ ] 最小修正
|
||||
- [ ] 运行通过
|
||||
- [ ] 记录证据
|
||||
|
||||
**Completion Evidence**
|
||||
|
||||
| 证据类型 | 命令/路径 | 结果 |
|
||||
|----------|-----------|------|
|
||||
| 测试 | `run -t UT -ts cli_tool_mgr_client_test` | PASS |
|
||||
|
||||
**Handoff Summary**
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| 任务描述 | 验证 NAPI 参数同步校验(AC-1.12) |
|
||||
| 允许修改 | `js_cli_manager.cpp`、对应测试 |
|
||||
| 允许新建 | 测试用例 |
|
||||
| 只读参考 | spec AC-1.12 + R-9、design 调用链 NAPI 层 |
|
||||
| Spec 摘要 | 必填缺失/类型错/argc<4→同步抛错 |
|
||||
| Design 摘要 | OnExecTool 参数解析与 ThrowInvalidParamError |
|
||||
| 执行步骤 | 写失败测试→运行→修正→通过→证据 |
|
||||
| 验证命令 | `run -t UT -ts cli_tool_mgr_client_test` / 期望: PASS |
|
||||
| 完成规则 | 不改范围外文件;无 evidence 不声明完成 |
|
||||
|
||||
### TASK-CLI-007: 会话并发上限验证
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| 任务目标 | 验证活动会话数达系统上限时返回 35700001(AC-1.13) |
|
||||
| AC 映射 | AC-1.13 |
|
||||
| 前置依赖 | TASK-CLI-001 |
|
||||
| 非目标 | 不验证单会话内部行为 |
|
||||
| 完成判据 | 会话数≥上限→reject 35700001,不排队 |
|
||||
| 停止条件 | 并发保护与 spec 不一致 |
|
||||
|
||||
**Files**
|
||||
|
||||
| 操作 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| Test | `cli_tool_framework/test/unittest/cli_tool_mgr_service_test/` | 上限用例 |
|
||||
|
||||
**Spec Context**
|
||||
|
||||
AC-1.13:会话数达上限→reject 35700001。
|
||||
R-10:全局会话表 + 系统配置上限。
|
||||
|
||||
**Design Context**
|
||||
|
||||
ValidateSessionLimit:GetCliConcurrencyLimit→sessions_ 表 size≥上限→ERR_SESSION_LIMIT_EXCEEDED。sessionsMutex_ 互斥保护。设计 ADR-5。
|
||||
|
||||
**Required Rules**
|
||||
|
||||
| Rule ID | Must / Must Not |
|
||||
|---------|-----------------|
|
||||
| OH-ARCH-ERROR-LOG | Must:错误码 35700001 |
|
||||
|
||||
**Steps**
|
||||
|
||||
- [ ] 写失败测试:填满会话后调用断言 35700001
|
||||
- [ ] 运行测试
|
||||
- [ ] 最小修正
|
||||
- [ ] 运行通过
|
||||
- [ ] 记录证据
|
||||
|
||||
**Completion Evidence**
|
||||
|
||||
| 证据类型 | 命令/路径 | 结果 |
|
||||
|----------|-----------|------|
|
||||
| 测试 | `run -t UT -ts cli_tool_mgr_service_test` | PASS |
|
||||
|
||||
**Handoff Summary**
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| 任务描述 | 验证会话并发上限(AC-1.13) |
|
||||
| 允许修改 | `cli_tool_manager_service.cpp`、对应测试 |
|
||||
| 允许新建 | 测试用例 |
|
||||
| 只读参考 | spec AC-1.13 + R-10、design ADR-5 |
|
||||
| Spec 摘要 | 超上限→35700001 |
|
||||
| Design 摘要 | ValidateSessionLimit + sessions_ mutex |
|
||||
| 执行步骤 | 写失败测试→运行→修正→通过→证据 |
|
||||
| 验证命令 | `run -t UT -ts cli_tool_mgr_service_test` / 期望: PASS |
|
||||
| 完成规则 | 不改范围外文件;无 evidence 不声明完成 |
|
||||
|
||||
### TASK-CLI-008: DFX 失败上报 + SA 不可用验证
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| 任务目标 | 验证 SA 不可用返回 35700000(AC-1.15);失败路径经 HiSysEvent 上报 bundleName/toolName/failureReason |
|
||||
| AC 映射 | AC-1.15 |
|
||||
| 前置依赖 | TASK-CLI-004 |
|
||||
| 非目标 | 不验证正常路径 DFX |
|
||||
| 完成判据 | SA 拉起失败/代理空→reject 35700000;失败路径 HiSysEvent 字段完整 |
|
||||
| 停止条件 | DFX 事件与 hisysevent.yaml 定义冲突 |
|
||||
|
||||
**Files**
|
||||
|
||||
| 操作 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| Test | `cli_tool_framework/test/unittest/cli_event_report_test/` | DFX 上报用例 |
|
||||
| Test | `cli_tool_framework/test/unittest/cli_tool_mgr_client_test/` | SA 不可用用例 |
|
||||
|
||||
**Spec Context**
|
||||
|
||||
AC-1.15:CliToolManager SA 未就绪/代理获取失败→reject 35700000。
|
||||
R-12:SA 未加载/代理空→35700000。
|
||||
|
||||
**Design Context**
|
||||
|
||||
cli_tool_client LoadCliToolMgrService 失败→GET_CLI_TOOL_MGR_SERVICE_FAILED。ReportCliExecuteFailed/ReportCliTimeout 上报 bundleName/toolName/failureReason/duration。hisysevent.yaml 为硬性合约。设计异常传播时序图。
|
||||
|
||||
**Required Rules**
|
||||
|
||||
| Rule ID | Must / Must Not |
|
||||
|---------|-----------------|
|
||||
| OH-ARCH-ERROR-LOG | Must:不破坏 hisysevent.yaml 已发布事件;不为通过测试删事件 |
|
||||
| OH-ARCH-IPC-SAF | Must:SA 按需拉起,失败回 35700000 |
|
||||
|
||||
**Steps**
|
||||
|
||||
- [ ] 写失败测试:SA 不可用断言 35700000;失败上报断言 HiSysEvent 字段
|
||||
- [ ] 运行测试
|
||||
- [ ] 最小修正
|
||||
- [ ] 校验 hisysevent.yaml 未被破坏
|
||||
- [ ] 运行通过
|
||||
- [ ] 记录证据
|
||||
|
||||
**Completion Evidence**
|
||||
|
||||
| 证据类型 | 命令/路径 | 结果 |
|
||||
|----------|-----------|------|
|
||||
| 测试 | `run -t UT -ts cli_event_report_test` | PASS |
|
||||
| 测试 | `run -t UT -ts cli_tool_mgr_client_test` | PASS |
|
||||
| 静态检查 | `hisysevent.yaml` 事件定义未被破坏 | PASS |
|
||||
|
||||
**Handoff Summary**
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| 任务描述 | 验证 SA 不可用 35700000 + 失败 HiSysEvent 上报(AC-1.15) |
|
||||
| 允许修改 | `cli_event_report*.cpp`、`cli_tool_mgr_client.cpp`、对应测试 |
|
||||
| 允许新建 | 测试用例 |
|
||||
| 只读参考 | spec AC-1.15 + R-12、design 异常传播时序图、`hisysevent.yaml` |
|
||||
| Spec 摘要 | SA 不可用→35700000;失败经 HiSysEvent |
|
||||
| Design 摘要 | LoadCliToolMgrService + ReportCliExecuteFailed/ReportCliTimeout |
|
||||
| 执行步骤 | 写失败测试→运行→修正→校验 yaml→通过→证据 |
|
||||
| 验证命令 | `run -t UT -ts cli_event_report_test` / 期望: PASS |
|
||||
| 完成规则 | 不改 hisysevent.yaml 已发布事件;不改范围外文件;无 evidence 不声明完成 |
|
||||
|
||||
## Plan 自审清单
|
||||
|
||||
- [x] 每个 P0/P1 AC 至少映射到一个 Task(AC-1.1–1.15 全覆盖)
|
||||
- [x] 每个 Task 文件范围明确
|
||||
- [x] 每个 Task 明确前置依赖、非目标、完成判据和停止条件
|
||||
- [x] 每个 Task 有验证命令
|
||||
- [x] Task 粒度形成能力闭环
|
||||
- [x] 没有 TBD/TODO/占位符(「待确认」为 Owner 决议项)
|
||||
- [x] 没有要求 Agent 自行寻找未列出的上下文
|
||||
- [x] 交接信息自包含(Handoff Summary 完整)
|
||||
- [x] 每个 Task 验证在完成时立即执行并记录证据
|
||||
- [x] 超 3000 行阈值的 Task 已说明不拆分理由(本计划 Task 均聚焦验证+补测试,上下文未超阈值)
|
||||
@@ -0,0 +1,301 @@
|
||||
---
|
||||
target_release:
|
||||
id: OpenHarmony-6.0-Release
|
||||
status: proposed
|
||||
---
|
||||
|
||||
# 需求文档
|
||||
|
||||
> 一份文档,从原始需求到基线结论。本需求 `REQ-010` 原始条目未在工作区检索到,以下内容依据 `cli_tool_framework` 中 `execTool` 既有实现反推并固化,待需求方/Owner 确认后基线。
|
||||
|
||||
## 一、原始需求
|
||||
|
||||
### 基本信息
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|------|
|
||||
| 需求ID | REQ-010 |
|
||||
| 需求名称 | 执行 CLI 工具(execTool)System API |
|
||||
| 来源 | 待确认(实现已存在于 cli_tool_framework,2026 版权) |
|
||||
| 提出人 | 待确认 |
|
||||
| 目标发行版本 | OpenHarmony-6.0-Release(待确认) |
|
||||
| 候选 Profile | none |
|
||||
| 优先级 | P1 |
|
||||
| 状态 | Clarifying |
|
||||
|
||||
### 原始描述
|
||||
|
||||
**原始问题:** 系统应用需要一种受控、受沙箱约束的方式按名称执行系统中已注册的命令行工具(CLI Tool),并获取执行会话的状态与结果,而不应直接 fork 任意命令或绕过权限审计。
|
||||
|
||||
**痛点:**
|
||||
|
||||
| 用户类型 | 当前痛点 | 影响 |
|
||||
|----------|----------|------|
|
||||
| 系统应用开发者 | 无统一受控入口执行已注册 CLI 工具,需自建子进程与权限处理 | 集成成本高、安全风险大 |
|
||||
| 系统安全/审计方 | 缺少统一的权限校验、沙箱隔离与失败上报 | 故障归因与合规审计困难 |
|
||||
| 平台方 | 工具执行无并发上限与超时控制 | 易被滥用导致资源耗尽 |
|
||||
|
||||
**期望结果:** 系统应用通过一个 System API(`execTool`)执行已注册 CLI 工具,系统统一完成权限校验、沙箱子进程创建、超时/让出/后台会话管理与结果回传,并在失败路径经 HiSysEvent 上报。
|
||||
|
||||
### 背景证据
|
||||
|
||||
| 证据类型 | 链接/路径 | 说明 |
|
||||
|----------|-----------|------|
|
||||
| 源码实现 | `cli_tool_framework/frameworks/js/napi/cli_tool_manager/src/js_cli_manager.cpp` | NAPI 入口 `execTool`/`OnExecTool` 已实现 |
|
||||
| 源码实现 | `cli_tool_framework/services/climgr/src/cli_tool_manager_service.cpp` | 服务端 `ExecTool`、超时/让出/会话管理已实现 |
|
||||
| SA 注册 | `services/sa_profile/186.json` | SA 186(进程 aimgr,库 libclimgr.z.so) |
|
||||
| 进程配置 | `cli_tool_framework/etc/profile/aimgr.cfg` | ondemand、uid=aimgr、caps=KILL、SELinux 域 aimgr |
|
||||
|
||||
### 初始范围
|
||||
|
||||
**可能包含:**
|
||||
- `execTool` System API 的参数契约(toolName/subcommand/args/challenge/options)
|
||||
- 前台/让出(yieldMs)/后台/超时 四种会话语义
|
||||
- 权限校验(系统应用 + `ohos.permission.EXEC_CLI_TOOL`)、HAP 沙箱校验
|
||||
- 错误码 35700000–35700008、35700020
|
||||
|
||||
**明确不包含:**
|
||||
- `execCmd`(shell 命令执行)、`SubscribeSession`/`SendMessage`/`RegisterFunction` 等同模块其他接口
|
||||
- 工具注册/数据管理(`CliToolDataManager`/`RegisterFunction`)的内部实现
|
||||
- 跨设备会话同步
|
||||
|
||||
### 初始假设
|
||||
|
||||
| 假设 | 类型 | 验证方式 | 状态 |
|
||||
|------|------|----------|------|
|
||||
| 调用方须为系统应用 HAP | 技术/安全 | 源码 `ValidateExecToolPermissions` | 已验证 |
|
||||
| 沙箱由系统按调用方 Token 生成 | 技术 | 源码 `ToolUtil::GenerateSandboxConfig` | 已验证 |
|
||||
| 会话为运行态内存对象,不持久化 | 兼容性 | 源码 `SessionRecord` 生命周期 | 已验证 |
|
||||
| 并发上限由系统配置决定 | 技术 | 源码 `CcmUtil::GetCliConcurrencyLimit` | 已验证 |
|
||||
|
||||
### 初始分级判断
|
||||
|
||||
| 判断项 | 结果 | 依据 |
|
||||
|--------|------|------|
|
||||
| 复杂度 | 标准 | 单 System API,行为分支有限但涉及沙箱/IPC/会话生命周期 |
|
||||
| 涉及仓数量 | 1 | `foundation/ability/ability_runtime` |
|
||||
| 是否涉及 Public/System API | 是 | 新增 System API `execTool` |
|
||||
| 是否涉及安全/性能关键路径 | 是 | 权限校验、沙箱、子进程、超时 |
|
||||
| 是否跨 SIG | 否 | 全部在 Sig-Ability 内 |
|
||||
|
||||
### 进入澄清条件
|
||||
|
||||
- [x] 原始问题和期望结果已记录
|
||||
- [ ] 需求来源和责任人已明确(待确认)
|
||||
- [x] 初始范围和不包含项已记录
|
||||
- [x] 关键假设和待澄清问题已列出
|
||||
- [x] 复杂度有判断或明确为待定
|
||||
|
||||
---
|
||||
|
||||
## 二、澄清记录
|
||||
|
||||
> 本需求无原始对话记录,澄清项依据实现反推。标记「已澄清(实现反推)」的项需 Owner 复核确认。
|
||||
|
||||
### 待澄清问题
|
||||
|
||||
| 编号 | 问题 | 为什么需要澄清 | 状态 |
|
||||
|------|------|----------------|------|
|
||||
| Q-1 | `execTool` 是否仅限系统应用? | 决定 API 开放范围与权限模型 | 已澄清(实现反推:仅系统应用) |
|
||||
| Q-2 | 是否允许非 HAP 调用? | 决定沙箱生成可行性 | 已澄清(实现反推:须 HAP) |
|
||||
| Q-3 | 让出(yieldMs)与后台(background)是否互斥? | 决定会话语义模型 | 已澄清(实现反推:yieldMs 仅前台生效) |
|
||||
| Q-4 | 超时上限是否固定 1800 秒? | 决定边界约束 | 已澄清(实现反推:MAX_TIMEOUT=1800) |
|
||||
| Q-5 | 目标发行版本? | 基线必需 | 待确认 |
|
||||
|
||||
### 讨论记录
|
||||
|
||||
| 日期 | 参与人 | 讨论主题 | 结论 | 后续动作 |
|
||||
|------|--------|----------|------|----------|
|
||||
| 2026-08-05 | AI 反推 | 会话语义 | 前台/让出/后台/超时四态 | Owner 复核 |
|
||||
|
||||
### 功能范围确认
|
||||
|
||||
| 问题 | 回答 | 确认人 | 状态 |
|
||||
|------|------|--------|------|
|
||||
| 核心功能包含哪些? | execTool 执行已注册 CLI 工具;前台/让出/后台/超时会话;错误码 | 待确认 | 已确认(反推)/待确认 |
|
||||
| 明确不包含哪些? | execCmd、订阅、注册函数、跨设备同步 | 待确认 | 已确认(反推)/待确认 |
|
||||
| 是否有分期策略? | 否 | 待确认 | 已确认(反推) |
|
||||
|
||||
### 方案探索
|
||||
|
||||
| 编号 | 方案概述 | 优势 | 风险/代价 | 选择结论 |
|
||||
|------|----------|------|-----------|----------|
|
||||
| A-1 | SA(186/aimgr)统一承载:NAPI→IPC→服务端做权限/沙箱/子进程/会话管理 | 集中权限审计、统一沙箱、可并发控制、失败可上报 | 跨进程 IPC 开销、SA 须按需拉起 | 推荐 |
|
||||
| A-2 | 应用进程内直接 fork+exec 工具 | 无 IPC 开销、延迟低 | 绕过权限审计、沙箱不可控、无并发上限、难审计 | 放弃 |
|
||||
|
||||
**取舍理由:** CLI 工具执行涉及权限/沙箱/超时/审计,集中到 SA 可统一安全边界与并发控制,IPC 开销可接受;A-2 安全风险不可接受。
|
||||
|
||||
### 上下文与知识源检索日志
|
||||
|
||||
| 编号 | 来源 | 查询/读取内容 | 关键发现 | 可信度 | 用于 | 命中/原因 |
|
||||
|------|------|---------------|----------|--------|------|-----------|
|
||||
| K-1 | 源码 `js_cli_manager.cpp` | `OnExecTool` 参数解析与回调派发 | 必填:toolName/subcommand/args/challenge,options 可选;argc<4 同步抛错 | 高 | 范围/API | 命中 |
|
||||
| K-2 | 源码 `cli_tool_manager_service.cpp` | `ExecTool`/`ValidateExecToolPermissions`/`ValidateAndPrepareTool`/`SetupAndStartSession`/超时与让出处理 | 权限链、会话生命周期、超时=1800、yieldMs 仅前台、后台立即返回 | 高 | 设计/测试 | 命中 |
|
||||
| K-3 | 源码 `tool_util.cpp` | `ValidateProperties`/`ValidateExecOptionsProperties`/`ValidateInputSchemaProperties` | subcommand 与 inputSchema 校验规则、help 特殊键 | 高 | 设计/测试 | 命中 |
|
||||
| K-4 | `cli_error_code.h` | 错误码枚举 | 35700000–35700020 区间 | 高 | API | 命中 |
|
||||
| K-5 | `ICliToolManager.idl` | IPC 接口签名 | `ExecTool(param, eventId, scheduler)` oneway 回复经 Scheduler | 高 | 设计 | 命中 |
|
||||
| K-6 | `services/sa_profile/186.json`、`aimgr.cfg` | SA 注册与进程配置 | SA 186、进程 aimgr、ondemand、caps=KILL | 高 | 设计/构建 | 命中 |
|
||||
| K-7 | `AGENTS.md` | 目标仓 Agent 指南 | 服务层与 SDK 层解耦、PermissionVerification、hisysevent 硬约束 | 高 | 设计约束 | 命中 |
|
||||
|
||||
**上下文结论:**
|
||||
- 高可信结论:execTool 行为链路、参数契约、错误码、SA/进程模型均已由源码固化,可直接进入基线与设计。
|
||||
- 待确认结论:目标发行版本、需求来源与责任人、并发上限具体数值(由产品配置)。
|
||||
- 未使用来源及原因:未使用多仓知识库(本需求单仓内闭环)。
|
||||
|
||||
### 子系统影响
|
||||
|
||||
| 问题 | 回答 | 确认人 | 状态 |
|
||||
|------|------|--------|------|
|
||||
| 涉及哪些子系统? | ability(ability_runtime) | 待确认 | 已确认(反推) |
|
||||
| 是否需要新增子系统或部件? | 否 | 待确认 | 已确认(反推) |
|
||||
|
||||
### API 变更评估
|
||||
|
||||
| 问题 | 回答 | 确认人 | 状态 |
|
||||
|------|------|--------|------|
|
||||
| 是否需要新增/修改 Public API? | 否 | 待确认 | 已确认(反推) |
|
||||
| 是否需要新增 System API? | 是,1 个(`execTool`) | 待确认 | 已确认(反推) |
|
||||
| 是否会废弃已有 API? | 否 | 待确认 | 已确认(反推) |
|
||||
| 是否需要新增权限声明? | 是,`ohos.permission.EXEC_CLI_TOOL` | 待确认 | 已确认(反推) |
|
||||
|
||||
### 兼容性与非功能需求
|
||||
|
||||
| 类别 | 核心问题 | 结论 | 确认人 | 状态 |
|
||||
|------|----------|------|--------|------|
|
||||
| 兼容性 | 向前/向后兼容要求?破坏性变更? | 新增 API,无破坏性;会话内存态无持久化迁移 | 待确认 | 已确认(反推) |
|
||||
| 性能 | 响应时间/内存/并发要求? | 并发受系统上限约束;无公开 P 指标 | 待确认 | 已确认(反推) |
|
||||
| 安全 | 权限/隐私/加密/审计要求? | 系统应用+权限+HAP 沙箱;失败经 HiSysEvent | 待确认 | 已确认(反推) |
|
||||
| 可靠性 | 崩溃率/容错/恢复要求? | SA 不可用回 35700000;单次调用不应致 SA 崩溃 | 待确认 | 已确认(反推) |
|
||||
|
||||
### 依赖与风险
|
||||
|
||||
| 依赖项 | 类型 | 说明 | 状态 |
|
||||
|--------|------|------|------|
|
||||
| `safwk`/`samgr` | 编译/运行 | SA 186 按需注册与拉起 | 已确认 |
|
||||
| `access_token` | 运行 | 系统应用判定与权限校验 | 已确认 |
|
||||
| `bundle_framework` | 运行 | HAP 判定与 bundleName 获取 | 已确认 |
|
||||
| `kv_store` | 运行 | 工具/函数元数据存储(不影响 execTool 行为契约) | 已确认 |
|
||||
|
||||
| 风险 | 类型 | 影响 | 缓解措施 | 状态 |
|
||||
|------|------|------|----------|------|
|
||||
| 需求来源/Owner 未确认 | 进度 | 基线无法冻结 | 需求方/SIG 确认 | 待确认 |
|
||||
| 目标版本未确认 | 进度 | 影响 @since 与发布 | proposal.target_release 确认 | 待确认 |
|
||||
| 并发上限随产品配置 | 技术 | 行为语义不变但数值差异 | spec 标注「由系统配置决定」 | 已确认 |
|
||||
|
||||
### AC 完整性
|
||||
|
||||
- [x] 每个用户故事有验收标准
|
||||
- [x] AC 全部使用 WHEN/THEN 格式
|
||||
- [x] 覆盖正常流程、异常流程、边界条件
|
||||
- [x] AC 可测试、可度量
|
||||
|
||||
### 澄清结论
|
||||
|
||||
- [x] 功能范围已完全明确
|
||||
- [x] 子系统影响已识别
|
||||
- [x] API 变更已评估
|
||||
- [x] 兼容性和非功能需求已确认
|
||||
- [x] 依赖和风险已识别且有缓解方案
|
||||
- [x] AC 完整可测试
|
||||
- [x] 标准及以上复杂度已完成方案探索(A-1/A-2 + 取舍理由)
|
||||
|
||||
**结论:** 条件通过(实现反推完整,待 Owner/需求方确认后转「通过」)
|
||||
|
||||
---
|
||||
|
||||
## 三、需求基线
|
||||
|
||||
> 澄清完成后固化。manifest.md 是事实源,此处为审批结论。
|
||||
|
||||
### 基线信息
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|-----|
|
||||
| 基线版本 | v1.0 |
|
||||
| 基线日期 | 2026-08-05 |
|
||||
| Owner | 待确认 |
|
||||
| 确认人 | 需求方/模块Owner/SIG代表(待确认) |
|
||||
| 复杂度 | 标准 |
|
||||
| Profile | none |
|
||||
| 目标发行版本 | OpenHarmony-6.0-Release(待确认) |
|
||||
| 版本状态 | proposed |
|
||||
|
||||
### 问题陈述
|
||||
|
||||
系统应用缺少受控、可审计、受沙箱约束的 CLI 工具执行入口。本需求新增 `execTool` System API,由 SA 186(aimgr)统一承载权限校验、沙箱子进程创建、会话生命周期(前台/让出/后台/超时)与结果回传,并在失败路径经 HiSysEvent 上报。
|
||||
|
||||
### 目标和成功指标
|
||||
|
||||
| 目标 | 成功指标 | 验证方式 |
|
||||
|------|----------|----------|
|
||||
| 受控执行已注册 CLI 工具 | 合法调用返回 completed 会话与退出码 | 集成测试 |
|
||||
| 权限/沙箱边界生效 | 非系统应用/缺权限/非 HAP 均被拒绝并返回正确错误码 | 单测 |
|
||||
| 会话语义正确 | 前台/让出/后台/超时各态 reply 时机与 status 正确 | 集成测试 |
|
||||
| 失败可归因 | 失败路径经 HiSysEvent 上报 bundleName/toolName/failureReason | hisysevent 校验 |
|
||||
|
||||
### 用户故事与 AC
|
||||
|
||||
| Story ID | 用户故事 | 优先级 |
|
||||
|----------|----------|--------|
|
||||
| US-1 | 作为系统应用开发者,我想要通过 execTool 按名称执行已注册 CLI 工具并获取会话信息,以便在系统应用内集成受沙箱约束的命令行工具能力 | P1 |
|
||||
|
||||
> AC 共 15 条(AC-1.1–AC-1.15),详见 `spec.md`。此处不重复摘录,避免与 spec 不一致。
|
||||
|
||||
### 范围边界
|
||||
|
||||
**包含:** `execTool` System API 行为契约、参数校验、会话生命周期(前台/让出/后台/超时)、错误码、权限/沙箱前置校验。
|
||||
**不包含:** `execCmd`、`SubscribeSession`/`SendMessage`、`RegisterFunction`、工具注册数据管理、跨设备同步。
|
||||
|
||||
### 影响范围
|
||||
|
||||
| 子系统 | 仓库 | 模块/路径 | 当前职责 | 影响类型 | Owner |
|
||||
|--------|------|-----------|----------|----------|-------|
|
||||
| ability | foundation/ability/ability_runtime | cli_tool_framework/frameworks/js/napi/cli_tool_manager | NAPI 绑定 | 新增 API(既有实现固化契约) | 待确认 |
|
||||
| ability | foundation/ability/ability_runtime | cli_tool_framework/services/climgr | 服务端实现 | 新增(既有实现固化契约) | 待确认 |
|
||||
| ability | foundation/ability/ability_runtime | cli_tool_framework/interfaces/cli_tool | IPC 接口与数据结构 | 新增(既有实现固化契约) | 待确认 |
|
||||
| ability | foundation/ability/ability_runtime | services/sa_profile/186.json | SA 注册 | 不变(已注册) | — |
|
||||
|
||||
### API 变更项清单
|
||||
|
||||
| API 名称 | 变更类型 | 开放范围 | 概要说明 |
|
||||
|----------|----------|----------|----------|
|
||||
| `cliTool.execTool` | 新增 | System | 按名称执行已注册 CLI 工具,返回 Promise<CliSessionInfo> |
|
||||
|
||||
### 不涉及项确认
|
||||
|
||||
| 维度 | 涉及? | 依据 | 若涉及,进入哪个下游文档 |
|
||||
|------|--------|------|--------------------------|
|
||||
| 性能 | 否 | 无公开 P 指标;并发上限由系统配置,非本 API 行为契约 | — |
|
||||
| 安全与权限 | 是 | 系统应用+EXEC_CLI_TOOL 权限、HAP 沙箱、失败上报 | design.md / spec.md |
|
||||
| 兼容性 | 否 | 新增 API,无破坏性;会话内存态无迁移 | spec.md |
|
||||
| API/SDK | 是 | 新增 System API | design.md / spec.md |
|
||||
| IPC/跨进程 | 是 | NAPI→IPC→SA 186 | design.md |
|
||||
| 构建与部件 | 否 | 复用既有 component/parts,无新增部件 | — |
|
||||
| 国际化/无障碍 | 否 | 无界面 System API | — |
|
||||
| 数据迁移 | 否 | 无持久化 | — |
|
||||
|
||||
### 变更控制
|
||||
|
||||
| 变更类型 | 触发条件 | 处理规则 |
|
||||
|----------|----------|----------|
|
||||
| 范围新增 | 新增用户故事或仓/模块 | 重新评估复杂度和设计影响 |
|
||||
| AC 变更 | 修改可观察行为或错误码 | 重新审批基线和 Spec |
|
||||
| API 变更 | 新增/修改 Public/System API | 触发设计审批 |
|
||||
| 非功能指标变更 | 性能/安全/兼容性阈值变化 | 重新确认测试计划 |
|
||||
| 目标版本变更 | 交付版本调整 | 更新 proposal.target_release |
|
||||
|
||||
### 进入设计/Spec 条件
|
||||
|
||||
- [x] 所有 P0/P1 用户故事有 AC
|
||||
- [x] 每条 AC 可测试、可度量
|
||||
- [x] 范围内/外已确认
|
||||
- [ ] `proposal.target_release` 已确认或明确 TBD(待确认)
|
||||
- [x] `manifest.profile` 已确认或明确 none
|
||||
- [x] 涉及仓、模块、SIG 已识别
|
||||
- [x] 不涉及项已标记 N/A
|
||||
- [x] 变更控制规则已确认
|
||||
- [x] 标准及以上复杂度的澄清问题已逐项关闭,且讨论记录包含需求方/Owner/SIG 明确确认(实现反推,待 Owner 复核)
|
||||
- [x] 上下文与知识源检索日志已填写;未查询关键来源的原因已记录
|
||||
- [x] 目标仓 Agent 指南已检查并记录关键约束(AGENTS.md 服务/SDK 解耦、PermissionVerification、hisysevent 硬约束)
|
||||
|
||||
**基线结论:** 条件通过
|
||||
@@ -0,0 +1,278 @@
|
||||
# 特性规格
|
||||
|
||||
> 本规格仅覆盖 `execTool` 接口行为。范围限定:`execTool` 的用户可见行为、参数契约、错误码、会话生命周期与超时/让出/后台语义。`execCmd`、`SubscribeSession`、`SendMessage`、`RegisterFunction` 等同模块其他接口不在本规格范围内。
|
||||
>
|
||||
> **输入文档说明:** 工作区未检索到 `REQ-010` 需求条目与已批准的 `proposal.md`。本规格依据 `cli_tool_framework` 中 `execTool` 的既有实现(`frameworks/js/napi/cli_tool_manager/src/js_cli_manager.cpp`、`services/climgr/src/cli_tool_manager_service.cpp`、`interfaces/cli_tool/`)反推固化。待 `proposal.md` 基线化后,以下「优先级/目标版本/SIG 归属」字段应回填 proposal 值。
|
||||
|
||||
## 概述
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|-----|
|
||||
| 特性名称 | 执行 CLI 工具(execTool) |
|
||||
| 特性编号 | FEAT-CLI-001 |
|
||||
| 所属 Epic | REQ-010 |
|
||||
| 优先级 | P1 |
|
||||
| 目标版本 | 参见 proposal.md(待基线) |
|
||||
| SIG 彾属 | Sig-Ability |
|
||||
| 状态 | Draft |
|
||||
| 复杂度 | 标准 |
|
||||
|
||||
## 本次变更范围(Delta)
|
||||
|
||||
本特性为新增能力(lineage: new)。`execTool` 为 `cli_tool_framework` 对外暴露的 System API,此前不存在对外契约。
|
||||
|
||||
| 类型 | 内容 | 说明 |
|
||||
|------|------|------|
|
||||
| ADDED | `execTool` System API(JS) | 系统应用按名称执行已注册 CLI 工具,返回会话信息 |
|
||||
| ADDED | 错误码 35700000–35700008、35700020 | 见 cli_error_code.h,本规格仅声明 execTool 链路涉及项 |
|
||||
| ADDED | 权限 `ohos.permission.EXEC_CLI_TOOL` | execTool 调用前置权限 |
|
||||
| ADDED | 数据结构 `ExecOptions`/`CliSessionInfo`/`ExecResult` | 对外行为契约,非内部实现 |
|
||||
|
||||
## 输入文档
|
||||
|
||||
| 文档 | 路径 | 状态 |
|
||||
|------|------|------|
|
||||
| Requirement | `REQ-010`(未在工作区检索到) | Pending |
|
||||
| Proposal | `proposal.md`(未提供) | Pending |
|
||||
|
||||
> 需求基线、不涉及项、受影响子系统与仓库详见 proposal.md,本文档不重复摘录。design.md 与本文档并行产出,互不依赖。
|
||||
|
||||
## 用户故事
|
||||
|
||||
### US-1: 系统应用执行已注册的 CLI 工具
|
||||
|
||||
**作为** 系统应用开发者,
|
||||
**我想要** 通过 `execTool` 接口按名称执行已注册的 CLI 工具并获取执行会话信息,
|
||||
**以便** 在系统应用内集成受沙箱约束的命令行工具能力。
|
||||
|
||||
**验收标准(AC, Acceptance Criteria):**
|
||||
|
||||
| AC编号 | 验收标准 | 类型 |
|
||||
|--------|----------|------|
|
||||
| AC-1.1 | WHEN 系统应用持 `ohos.permission.EXEC_CLI_TOOL` 调用 `execTool`,传入已注册的 `toolName`、工具支持的 `subcommand`、符合工具 `inputSchema` 的 `args`、非空 `challenge` THEN 接口返回 Promise,工具执行结束后 resolve 为 `CliSessionInfo`(`status="completed"`,`result.exitCode` 等于子进程退出码) | 正常 |
|
||||
| AC-1.2 | WHEN `options.background=false` 且 `options.yieldMs>0` THEN 在 `yieldMs` 毫秒后 resolve 为 `status="running"` 的 `CliSessionInfo`,会话转入后台继续运行 | 行为 |
|
||||
| AC-1.3 | WHEN `options.background=true` THEN 接口立即 resolve 为 `status="running"` 的 `CliSessionInfo`,不等待执行结束 | 行为 |
|
||||
| AC-1.4 | WHEN 进程持续运行至 `options.timeout` 秒 THEN 进程被终止、最终会话 `result.timeout=true`,并向会话订阅者派发超时错误事件 | 边界 |
|
||||
| AC-1.5 | WHEN 非系统应用调用 `execTool` THEN Promise reject 错误码 `35700008`(ERR_NOT_SYSTEM_APP) | 异常 |
|
||||
| AC-1.6 | WHEN 系统应用未持有 `ohos.permission.EXEC_CLI_TOOL` THEN Promise reject 错误码 `35700007`(ERR_PERMISSION_DENIED) | 异常 |
|
||||
| AC-1.7 | WHEN `toolName` 未在系统中注册 THEN Promise reject 错误码 `35700005`(ERR_TOOL_NOT_EXIST) | 异常 |
|
||||
| AC-1.8 | WHEN 传入非空 `subcommand` 但工具未声明子命令,或 `subcommand` 不在工具子命令列表中 THEN Promise reject 错误码 `35700005`(ERR_TOOL_NOT_EXIST) | 异常 |
|
||||
| AC-1.9 | WHEN `args` 含工具 `inputSchema` 未定义的键,或某键值类型与 schema 声明不符 THEN Promise reject 错误码 `35700002`(ERR_INVALID_PARAM) | 异常 |
|
||||
| AC-1.10 | WHEN `options.timeout<0` 或 `options.timeout>1800` THEN Promise reject 错误码 `35700002`(ERR_INVALID_PARAM) | 边界 |
|
||||
| AC-1.11 | WHEN `options.background=false` 且 `options.yieldMs>options.timeout*1000` THEN Promise reject 错误码 `35700002`(ERR_INVALID_PARAM) | 边界 |
|
||||
| AC-1.12 | WHEN `toolName` 为空字符串/非字符串、`challenge` 为空字符串/非字符串、`args` 非对象,或实参个数小于 4 THEN 同步抛出 invalid parameter 异常,不进入异步链路 | 边界 |
|
||||
| AC-1.13 | WHEN 调用时系统并发会话数已达上限 THEN Promise reject 错误码 `35700001`(ERR_SESSION_LIMIT_EXCEEDED) | 边界 |
|
||||
| AC-1.14 | WHEN 调用方进程非 HAP THEN Promise reject 错误码 `35700003`(ERR_NOT_HAP) | 异常 |
|
||||
| AC-1.15 | WHEN CliToolManager 系统能力未就绪或代理获取失败 THEN Promise reject 错误码 `35700000`(GET_CLI_TOOL_MGR_SERVICE_FAILED) | 恢复 |
|
||||
|
||||
## 验收追溯
|
||||
|
||||
| AC | 关联规则 | 关联 Task | 验证方式 | 证据 |
|
||||
|----|----------|-----------|----------|------|
|
||||
| AC-1.1 | R-1 | TASK-CLI-001 | 集成 + 单测 | `cli_tool_framework/test/unittest/process_manager_test/` |
|
||||
| AC-1.2 | R-2 | TASK-CLI-002 | 集成 | `cli_tool_framework/test/` |
|
||||
| AC-1.3 | R-3 | TASK-CLI-002 | 集成 | `cli_tool_framework/test/` |
|
||||
| AC-1.4 | R-4 | TASK-CLI-003 | 集成 | `cli_tool_framework/test/` |
|
||||
| AC-1.5 | R-5 | TASK-CLI-004 | 单测 | `cli_tool_mgr_client_test/` |
|
||||
| AC-1.6 | R-5 | TASK-CLI-004 | 单测 | `cli_tool_mgr_client_test/` |
|
||||
| AC-1.7 | R-6 | TASK-CLI-005 | 单测 | `cli_tool_mgr_client_test/` |
|
||||
| AC-1.8 | R-6 | TASK-CLI-005 | 单测 | `cli_tool_mgr_client_test/` |
|
||||
| AC-1.9 | R-7 | TASK-CLI-005 | 单测 | `exec_tool_param_test/` |
|
||||
| AC-1.10 | R-8 | TASK-CLI-005 | 单测 | `exec_options_test/` |
|
||||
| AC-1.11 | R-8 | TASK-CLI-005 | 单测 | `exec_options_test/` |
|
||||
| AC-1.12 | R-9 | TASK-CLI-006 | 单测 | `js_cli_manager` NAPI 单测 |
|
||||
| AC-1.13 | R-10 | TASK-CLI-007 | 集成 | `cli_tool_framework/test/` |
|
||||
| AC-1.14 | R-11 | TASK-CLI-004 | 集成 | `cli_tool_framework/test/` |
|
||||
| AC-1.15 | R-12 | TASK-CLI-008 | 集成 | `cli_tool_mgr_client_test/` |
|
||||
|
||||
## 规则定义
|
||||
|
||||
| 规则ID | 类型 | 触发条件 | 预期行为 | 边界/约束 | 关联AC |
|
||||
|--------|------|----------|----------|-----------|--------|
|
||||
| R-1 | 行为 | 系统应用 + 持 EXEC_CLI_TOOL + toolName 已注册 + subcommand 合法 + args 匹配 inputSchema + challenge 非空 + options 合法 | 创建会话与受沙箱子进程执行工具,结束后 resolve `CliSessionInfo{status="completed", result.exitCode=进程退出码, outputText, errorText, executionTime}` | 退出码为 int32;executionTime 为 int64 毫秒 | AC-1.1 |
|
||||
| R-2 | 行为 | foreground(yieldMs>0) 模式 | 会话在 `yieldMs` 毫秒处派发 reply,resolve 为 `status="running"` 的会话;会话切后台继续运行;后续结束通过会话事件(订阅)派发 | yieldMs 单位毫秒,int64 | AC-1.2 |
|
||||
| R-3 | 行为 | background=true 模式 | 立即 resolve 为 `status="running"` 的会话;不调度 yield 任务;结束时向订阅者派发退出事件 | — | AC-1.3 |
|
||||
| R-4 | 边界 | 进程运行时间 = options.timeout 秒(timeout>0) | 终止进程、`result.timeout=true`、向订阅者派发 "session timed out" 错误事件;若此前未后台则派发终态 reply | timeout 单位秒,上限 1800(=30 分钟);=0 表示不启用超时 | AC-1.4 |
|
||||
| R-5 | 异常 | 调用方 Token 非系统应用,或未持 EXEC_CLI_TOOL 权限 | reject:非系统应用→35700008;缺权限→35700007 | 校验在入口执行 | AC-1.5, AC-1.6 |
|
||||
| R-6 | 异常 | toolName 未注册;或 subcommand 非空但工具无子命令/不在子命令表 | reject 35700005(ERR_TOOL_NOT_EXIST) | subcommand 为空串时使用工具顶层 inputSchema | AC-1.7, AC-1.8 |
|
||||
| R-7 | 异常 | args 含 inputSchema 未声明的键,或键值类型与 schema.type 不符 | reject 35700002(ERR_INVALID_PARAM);特殊键 `help` 单独存在时放行 | args 为空对象视为合法 | AC-1.9 |
|
||||
| R-8 | 边界 | options.timeout<0 或 >1800;或非后台且 yieldMs>timeout*1000;或 yieldMs<0 | reject 35700002(ERR_INVALID_PARAM) | timeout∈[0,1800] 秒;yieldMs∈[0, timeout*1000] 毫秒(非后台) | AC-1.10, AC-1.11 |
|
||||
| R-9 | 边界 | 实参个数<4;或 toolName/challenge 为空串或非字符串;或 args 非对象 | 同步抛出 invalid parameter 异常(不进入异步 Promise) | NAPI 层校验先于服务端 | AC-1.12 |
|
||||
| R-10 | 边界 | 调用时活动会话数 ≥ 系统并发上限 | reject 35700001(ERR_SESSION_LIMIT_EXCEEDED) | 上限由系统配置 CcmUtil.GetCliConcurrencyLimit 决定 | AC-1.13 |
|
||||
| R-11 | 异常 | 调用方 Token 非 HAP(无法生成沙箱配置) | reject 35700003(ERR_NOT_HAP) | 沙箱配置生成失败前置 | AC-1.14 |
|
||||
| R-12 | 恢复 | CliToolManager SA 未加载或代理为空 | reject 35700000(GET_CLI_TOOL_MGR_SERVICE_FAILED) | 客户端按需拉起 SA;拉起失败即此码 | AC-1.15 |
|
||||
|
||||
## 验证映射
|
||||
|
||||
| 编号 | 对应规格项 | 验证方式 | 验证重点 |
|
||||
|------|------------|----------|----------|
|
||||
| VM-1 | R-1 / AC-1.1 | 集成 + 单测 | 正常执行返回 completed 会话与退出码 |
|
||||
| VM-2 | R-2,R-3 / AC-1.2,AC-1.3 | 集成 | yield/background 模式 reply 时机与 status |
|
||||
| VM-3 | R-4 / AC-1.4 | 集成 | 超时终止、result.timeout、错误事件派发 |
|
||||
| VM-4 | R-5 / AC-1.5,AC-1.6 | 单测 | 系统应用判定与权限校验路径 |
|
||||
| VM-5 | R-6,R-7,R-8 / AC-1.7–AC-1.11 | 单测 | 工具/子命令/schema/超时参数校验 |
|
||||
| VM-6 | R-9 / AC-1.12 | 单测 | NAPI 参数校验同步抛错 |
|
||||
| VM-7 | R-10,R-11,R-12 / AC-1.13–AC-1.15 | 集成 + 单测 | 会话上限、非 HAP、SA 不可用 |
|
||||
|
||||
## API 变更分析
|
||||
|
||||
### 新增 API
|
||||
|
||||
| API 名称 | 开放范围 | 入参概要 | 返回值 | 错误码范围 | 功能描述 | 关联 AC |
|
||||
|----------|----------|----------|--------|------------|----------|---------|
|
||||
| `cliTool.execTool` | System | `(toolName: string, subcommand: string, args: object, challenge: string, options?: ExecOptions)` | `Promise<CliSessionInfo>` | 35700000–35700008, 35700020 | 按名称执行已注册 CLI 工具,返回会话信息 | AC-1.1–1.15 |
|
||||
|
||||
> API 签名、d.ts 位置、权限要求等实现细节见 design.md。ExecOptions/CliSessionInfo/ExecResult 的字段语义见下「接口规格」。
|
||||
|
||||
### 变更/废弃 API
|
||||
|
||||
无变更或废弃项。
|
||||
|
||||
## 接口规格
|
||||
|
||||
### 接口定义
|
||||
|
||||
**execTool**
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|-----|
|
||||
| 函数签名 | `execTool(toolName: string, subcommand: string, args: object, challenge: string, options?: ExecOptions): Promise<CliSessionInfo>` |
|
||||
| 返回值 | `Promise<CliSessionInfo>` — resolve 为会话信息;reject 为错误码 |
|
||||
| 开放范围 | System |
|
||||
| 权限 | `ohos.permission.EXEC_CLI_TOOL`,且调用方须为系统应用 |
|
||||
| 错误码 | 35700000, 35700001, 35700002, 35700003, 35700004, 35700005, 35700007, 35700008 |
|
||||
| 关联 AC | AC-1.1–1.15 |
|
||||
|
||||
**参数约束**
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认值 | 约束条件 |
|
||||
|------|------|------|--------|---------|
|
||||
| toolName | string | 是 | — | 非空;须为已注册工具名,否则 35700005 |
|
||||
| subcommand | string | 是 | — | 可为空串(工具无子命令时);非空时须在工具子命令表内,否则 35700005 |
|
||||
| args | object(WantParams 键值对) | 是 | — | 键须在工具 inputSchema.properties 内且类型匹配;空对象合法;特殊键 `help` 须单独存在 |
|
||||
| challenge | string | 是 | — | 非空 |
|
||||
| options | ExecOptions | 否 | `{background:false, yieldMs:0, timeout:0}` | 见 ExecOptions 约束 |
|
||||
|
||||
**ExecOptions 约束**
|
||||
|
||||
| 字段 | 类型 | 默认 | 约束 |
|
||||
|------|------|------|------|
|
||||
| background | boolean | false | true=后台立即返回;false=前台,可由 yieldMs 触发让出 |
|
||||
| yieldMs | number(int64) | 0 | ≥0,单位毫秒;仅 foreground 生效;foreground 下须 ≤ timeout*1000 |
|
||||
| timeout | number(int64) | 0 | ∈[0,1800],单位秒;0=不启用超时;timeoutMs=timeout*1000 |
|
||||
|
||||
**CliSessionInfo(resolve 值)**
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| sessionId | string | 会话唯一标识 |
|
||||
| toolName | string | 工具名 |
|
||||
| status | string | `"running"` / `"completed"` / `"failed"` |
|
||||
| result | ExecResult \| undefined | 仅 completed/failed 时存在 |
|
||||
|
||||
**ExecResult**
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| exitCode | number(int32) | 子进程退出码,默认 1 |
|
||||
| outputText | string | 标准输出累计 |
|
||||
| errorText | string | 标准错误累计 |
|
||||
| signalNumber | number(int32) | 终止信号,0 表示正常 |
|
||||
| timeout | boolean | 是否因超时终止 |
|
||||
| executionTime | number(int64) | 执行耗时(毫秒) |
|
||||
|
||||
**行为场景**
|
||||
|
||||
| # | 触发条件 | 预期行为 | 关联 AC |
|
||||
|---|----------|----------|---------|
|
||||
| 1 | 前台 + timeout=0 + yieldMs=0 + 进程正常退出 | 进程退出且输出排空后 resolve `status="completed"`,含 exitCode/outputText | AC-1.1 |
|
||||
| 2 | 前台 + yieldMs>0 | yieldMs 毫秒处 resolve `status="running"`,会话转后台;后续结束经订阅事件通知 | AC-1.2 |
|
||||
| 3 | background=true | 立即 resolve `status="running"`;结束时向订阅者派发退出事件,不再二次 resolve | AC-1.3 |
|
||||
| 4 | timeout>0 且进程未在 timeout 秒内退出 | 终止进程、`result.timeout=true`、派发 "session timed out" 事件;未后台则派发终态 reply | AC-1.4 |
|
||||
| 5 | 非系统应用调用 | reject 35700008 | AC-1.5 |
|
||||
| 6 | 系统应用缺权限 | reject 35700007 | AC-1.6 |
|
||||
| 7 | toolName 未注册 / subcommand 非法 | reject 35700005 | AC-1.7, AC-1.8 |
|
||||
| 8 | args 不符 inputSchema | reject 35700002 | AC-1.9 |
|
||||
| 9 | options.timeout/yieldMs 越界 | reject 35700002 | AC-1.10, AC-1.11 |
|
||||
| 10 | 必填参数缺失/类型错/实参<4 | 同步抛 invalid parameter 异常 | AC-1.12 |
|
||||
| 11 | 会话数达上限 | reject 35700001 | AC-1.13 |
|
||||
| 12 | 非 HAP 调用 | reject 35700003 | AC-1.14 |
|
||||
| 13 | SA 不可用 | reject 35700000 | AC-1.15 |
|
||||
|
||||
## 兼容性声明
|
||||
|
||||
- **已有 API 行为变更:** 否。本特性为新增 System API,不改变既有公共 API 行为。
|
||||
- **配置文件格式变更:** 否(沙箱配置为内部生成,非对外配置文件)。
|
||||
- **数据存储格式变更:** 否。会话为运行态内存对象,不持久化。
|
||||
- **最低支持版本:** 参见 proposal.md(待基线)。
|
||||
- **API 版本号策略:** 新增 API 自首个引入版本起标注 `@since`;错误码 357000xx 为本特性专属区间,不可被其他特性复用数值。
|
||||
|
||||
## 架构约束
|
||||
|
||||
| 关键约束 | 约束说明 | 影响 AC |
|
||||
|----------|----------|---------|
|
||||
| 仅系统应用 + `ohos.permission.EXEC_CLI_TOOL` 可调用 | 入口须做系统应用判定与权限校验 | AC-1.5, AC-1.6 |
|
||||
| 执行须在受限沙箱子进程中进行 | 调用方须为 HAP 以生成沙箱配置 | AC-1.14 |
|
||||
| 回复经 IPC Scheduler 异步派发 | 回调不在调用线程同步执行 | AC-1.1–1.4 |
|
||||
| 并发会话受系统上限约束 | 超限拒绝,不排队 | AC-1.13 |
|
||||
|
||||
> 架构规则适用性及设计方案(SA 注册、IPC Stub/Proxy、沙箱生成、IOMonitor 调度等)见 design.md。
|
||||
|
||||
## 非功能性需求
|
||||
|
||||
| 类型 | 指标/阈值 | 验证方式 | 证据 |
|
||||
|------|-----------|----------|------|
|
||||
| 可靠性 | 单次 execTool 调用不应导致 CliToolManager SA 崩溃 | 压力测试 | `cli_tool_framework/test/` |
|
||||
| 安全 | 非系统应用/无权限/非 HAP 调用均被拒绝 | 单测 | `cli_tool_mgr_client_test/` |
|
||||
| 可测试性 | execTool 行为可经 mock 服务端校验错误码与回复时机 | 单测 | `cli_tool_mgr_client_test/`、`exec_options_test/` |
|
||||
| 定界定位 | 失败路径经 HiSysEvent 上报(bundleName、toolName、failureReason/duration) | hisysevent | `hisysevent.yaml` |
|
||||
|
||||
## 多设备适配声明
|
||||
|
||||
| 设备类型 | 行为差异 | 规格/约束 | 验证方式 | 证据 |
|
||||
|----------|----------|-----------|----------|------|
|
||||
| 手机 | 无差异 | — | 集成 | `cli_tool_framework/test/` |
|
||||
| 平板 | 无差异 | — | 集成 | `cli_tool_framework/test/` |
|
||||
| 折叠屏 | 无差异 | — | 集成 | `cli_tool_framework/test/` |
|
||||
|
||||
> execTool 行为与设备形态无关;并发上限等可随产品配置调整,不影响行为语义。
|
||||
|
||||
## 全局特性影响
|
||||
|
||||
| 特性 | 适用? | 结论 | 关联场景 |
|
||||
|------|--------|------|----------|
|
||||
| 无障碍 | 否 | execTool 为无界面 System API | — |
|
||||
| 大字体 | N/A | — | — |
|
||||
| 深色模式 | N/A | — | — |
|
||||
| 多窗口/分屏 | 否 | 与窗口无关 | — |
|
||||
| 多用户 | 否 | 权限与沙箱按调用方 Token 校验,不依赖用户切换 | — |
|
||||
| 版本升级 | 否 | 无持久化数据需迁移 | — |
|
||||
| 生态兼容 | 否 | 仅系统应用可用 | — |
|
||||
|
||||
## Spec 自审清单
|
||||
|
||||
在提交审查前逐项自检:
|
||||
|
||||
- [x] 无"待定""TBD""TODO"等占位符("待基线"为上游 proposal 缺失的如实标注,非规格占位)
|
||||
- [x] 所有 AC 使用 WHEN/THEN 格式,可独立测试
|
||||
- [x] 范围边界明确(仅 execTool;execCmd 等不涉及)
|
||||
- [x] 无语义模糊表述
|
||||
- [x] AC 与规则表交叉一致(每个 AC 至少关联一条规则,每条规则至少关联一个 AC)
|
||||
- [x] 规则表每条通过 5 项质量检查(可复现/可观测/边界值/关联AC/无冲突)
|
||||
|
||||
## context-references
|
||||
|
||||
```yaml
|
||||
context-queries:
|
||||
- repo: "openharmony/ability_runtime"
|
||||
query: "cli_tool_framework execTool 的 SA 注册、IPC Stub/Proxy 序列化与沙箱生成实现"
|
||||
- repo: "openharmony/ability_runtime"
|
||||
query: "ExecToolParam/ExecOptions/CliSessionInfo 的 Parcelable 编解码分支"
|
||||
```
|
||||
|
||||
**关键文档:**
|
||||
- `cli_tool_framework/frameworks/js/napi/cli_tool_manager/src/js_cli_manager.cpp`(NAPI 入口 `execTool`/`OnExecTool`)
|
||||
- `cli_tool_framework/services/climgr/src/cli_tool_manager_service.cpp`(服务端 `ExecTool`、超时/让出处理)
|
||||
- `cli_tool_framework/services/climgr/src/tool_util.cpp`(参数与 inputSchema 校验)
|
||||
- `cli_tool_framework/interfaces/cli_tool/include/cli_error_code.h`(错误码定义)
|
||||
- `cli_tool_framework/interfaces/cli_tool/ICliToolManager.idl`(IPC 接口)
|
||||
Reference in New Issue
Block a user