@shijing/taoyao

发布人:仓颉技术交流平台官方
分类:编程框架与基础设施 / 其他框架

TaoYao是为 OpenHarmony 系统开发的权限请求框架,采用链式调用方式封装了运行时权限、通知权限的申请逻辑,并支持联系人、相机、媒体、文档、音频等系统选择器的便捷调用。它简化了鸿蒙应用中繁琐的权限处理流程,兼容 API 12 及以上版本,适用于 UIAbility、UI 和 UIExtensionAbility 等多种场景

等待接取
37

悬赏内容

招募内容

项目背景与战略目标

在 OpenHarmony 应用开发中,权限申请(Runtime Permissions)与系统选择器(System Pickers,如联系人、相机、文件)的调用逻辑繁琐且易错。现有的 @shijing/taoyao 基于 ArkTS/JS 实现,虽然提供了链式调用,但在后端服务化或高可靠性场景下存在显著缺陷:

  1. 运行时错误风险:动态类型系统无法在编译期拦截非法的权限字符串、错误的选择器参数配置,导致应用在真机上崩溃或行为未定义。

  2. 状态管理脆弱:权限申请的异步回调嵌套深,容易出现状态竞争(Race Condition),特别是在快速连续请求或页面切换时。

  3. 性能开销:JS 桥接层在处理大量并发选择器调用或复杂权限校验逻辑时,存在序列化和上下文切换开销。

  4. 缺乏细粒度控制:难以实现基于编译期策略的权限最小化原则,代码中常混入未使用的权限检查逻辑。

本项目旨在利用 仓颉编程语言(Cangjie Language)1.0.0+ 重构 TaoYao,打造一款编译期类型安全、零运行时开销、状态机驱动的系统交互框架。它将包含:

  • 泛型权限约束:将权限常量定义为枚举或泛型标记,确保只有合法的权限组合才能通过编译,彻底消除“拼写错误”导致的运行时失败。

  • 代数数据类型状态机:利用 enum 和模式匹配精确描述权限状态(Granted, Denied, ForeverDenied, NotDetermined),强制开发者处理所有分支。

  • 零拷贝选择器桥接:直接映射原生 System Picker 接口,利用仓颉的结构体(Struct)高效传递配置,减少序列化开销。

  • 无锁并发流:基于仓颉通道(Channel)和协程重构异步回调,将“回调地狱”转化为线性的异步代码流,提升可维护性。

这将为企业提供一个工业级、高可靠的系统能力交互底座,不仅适用于 UI 应用,也可用于纯后端服务(如 Headless Ability)中的自动化权限管理与资源调度。

核心功能需求与技术规格

2.1 功能模块分解

模块类别

核心职责

关键技术要求 (仓颉特性)

验收依据

类型安全权限定义

定义所有系统权限常量与组合规则

使用 枚举 (Enum) 替代字符串;利用 泛型约束 限制权限组合作用域

编译期拦截 100% 非法权限字符串,无运行时校验开销

权限状态机引擎

管理权限申请生命周期与状态流转

利用 代数数据类型 定义状态;模式匹配强制处理所有状态分支

状态流转无死锁,异常路径(如用户取消)处理完备

链式请求构建器

封装 requestPermissions, checkPermissions 流程

使用 Builder 模式内联函数;支持异步挂起函数 (async/await)

代码可读性提升 50%,链式调用无额外对象分配

系统选择器适配

封装联系人、相机、媒体、文档等 Picker

定义强类型 PickerConfig 结构体;直接映射 Native 接口

选择器启动延迟 < 10ms,配置错误编译期报错

结果流式处理

统一处理权限结果与选择器返回数据

基于 Channel/Stream 的响应式编程模型;背压控制

支持高并发选择器调用,内存占用稳定

上下文感知适配

适配 UIAbility, ExtensionAbility 等不同上下文

利用 特质 (Trait) 抽象上下文能力;编译期注入依赖

同一套代码无缝运行于不同 Ability 场景

2.2 非功能性需求规范

  • 性能指标:权限检查耗时 < 50μs;选择器启动延迟与原生一致;内存占用比 TS 版降低 60%(无 JS 引擎开销)。

  • 安全要求:强制编译期权限最小化检查;敏感数据(如联系人列表)在内存中自动脱敏或加密存储;防止权限提升攻击。

  • 可靠性:100% 覆盖所有权限状态分支;在应用被杀后台恢复后能正确重建状态;无内存泄漏。

  • 可维护性:API 设计符合仓颉惯用风格,提供详尽的编译期错误提示。

2.3 核心接口设计示例 (伪代码)

// 1. 强类型权限定义 (替代字符串)
enum SystemPermission {
    case Camera
    case Microphone
    case Location
    case ContactRead
    case FileWrite
    // ... 所有系统权限
}

// 权限状态 (代数数据类型)
enum PermissionState {
    case Granted
    case Denied(CanRequestAgain: Bool) // 是否可再次请求
    case ForeverDenied // 需引导去设置页
    case NotDetermined
}

// 2. 强类型选择器配置
struct ContactPickerConfig {
    let maxSelectCount: Int32 = 1
    let allowedFields: List<ContactField> // 编译期指定所需字段,减少数据拷贝
}

struct MediaPickerConfig {
    let mediaType: MediaType // Enum: Image, Video, Audio
    let maxSelectCount: Int32
    let sourceType: SourceType // Enum: Gallery, Camera
}

// 3. 核心框架类
class TaoYao {
    private var context: AbilityContext // 通过 Trait 抽象
    
    init(context: AbilityContext) {
        self.context = context
    }
    
    // 权限检查 (编译期类型安全)
    async func checkPermission(perm: SystemPermission): Result<PermissionState, String> {
        // 调用原生 API,返回强类型状态
        // ...
    }
    
    // 链式权限请求
    async func requestPermissions(perms: List<SystemPermission>): Result<List<PermissionState>, String> {
        // 内部状态机管理
        // ...
    }
    
    // 强类型联系人选择器
    async func pickContacts(config: ContactPickerConfig): Result<List<ContactInfo>, String> {
        // 直接传递 struct 给 Native,零拷贝
        // ...
    }
    
    // 强类型媒体选择器
    async func pickMedia(config: MediaPickerConfig): Result<List<MediaAsset>, String> {
        // ...
    }
}

// 4. 业务场景示例:发布带图动态
class PostService {
    private var taoyao: TaoYao
    
    init(taoyao: TaoYao) { self.taoyao = taoyao }
    
    async func createPostWithImage(): Unit {
        // 1. 编译期确保权限类型正确
        let perms = [SystemPermission.Camera, SystemPermission.Microphone]
        
        // 2. 异步请求权限,线性流程
        let states = try await this.taoyao.requestPermissions(perms)
        
        // 3. 模式匹配处理所有状态分支 (编译器强制检查)
        for i in 0..<states.size() {
            match (states[i]) {
                case .Granted => { /* 继续 */ }
                case .Denied(canRequest: true) => { 
                    print("Permission denied, retrying...") 
                    // 重试逻辑
                }
                case .ForeverDenied => { 
                    print("Please enable in settings") 
                    this.openSettings()
                    return 
                }
                case .NotDetermined => { /* 不应出现 */ }
            }
        }
        
        // 4. 调用选择器,配置编译期校验
        let config = MediaPickerConfig(mediaType: .Image, maxSelectCount: 9, sourceType: .Gallery)
        let images = try await this.taoyao.pickMedia(config)
        
        // 5. 业务处理
        this.uploadImages(images)
    }
}

项目交付物与实施路线图

3.1 阶段性交付物清单

  • 第一阶段:核心权限枚举定义、状态机引擎、基础权限申请/检查接口、单元测试。

  • 第二阶段:系统选择器(联系人、媒体、文件、相机)强类型封装、链式调用构建器、集成测试。

  • 第三阶段:上下文适配层(UIAbility/Extension)、性能调优报告、cjpm 发布包及完整文档。

3.2 项目实施路线图

阶段

核心任务

交付成果

周期预估

里程碑

基础构建

权限类型系统与状态机

可编译库、基础权限功能、单测集

4-6 周

编译期拦截非法权限,状态流转正确

核心攻坚

选择器封装与链式调用

全量选择器支持、流畅的异步体验、压测报告

6-8 周

选择器启动无延迟,内存零泄漏

生态集成

多场景适配与发布

支持 ExtensionAbility、用户手册、cjpm 包

3-4 周

上架仓颉社区,提供最佳实践 Demo

技术实现规范与质量认证体系

4.1 仓颉语言专项质量规范

  • 编译期即正确:利用泛型和枚举,确保所有非法调用在 cjpm build 阶段报错,运行时无类型检查。

  • 零开销抽象:链式调用构建器必须使用 inline 和值类型优化,避免产生临时对象。

  • exhaustive 匹配:所有 match 表达式必须覆盖所有枚举情况,利用编译器特性防止逻辑遗漏。

  • 资源自动管理:选择器打开的底层资源必须通过 deferusing 自动释放。

4.2 测试与验证标准

  • 类型测试:编写负向测试用例,验证非法权限字符串、错误配置能否被编译器拒绝。

  • 状态覆盖测试:模拟所有权限状态(授予、拒绝、永久拒绝),验证业务逻辑分支的正确性。

  • 真机兼容性:在 API 12+ 的真机或模拟器上,测试所有选择器的实际表现。

  • 压力测试:高频次连续调用权限和选择器,验证框架的稳定性与内存表现。

4.3 文档与可维护性

  • API 文档:每个枚举、结构体和公开方法均需包含详细 Doc Comments。

  • 迁移指南:提供从 ArkTS 版迁移到仓颉版的代码对照,重点展示类型安全带来的改进。

  • 示例工程:提供包含相机拍照、文件选择、联系人导入等完整场景的 Demo。

4.4 持续集成质量门禁

# PR 自动化流水线
cjpm fmt --check
cjpm build --release
cjpm lint --deny-warnings
cjpm test --coverage --min-coverage 90
# 类型严格性检查 (确保没有 Any 滥用)
cjpm analyze --strict-types

技术栈与开发环境

  • 核心语言:仓颉编程语言(Cangjie Language)1.0.0+。

  • 构建工具:CJPM (Cangjie Package Manager)。

  • 依赖组件:OpenHarmony SDK (API 12+), Access Token Kit, Photo View Kit, Contact Kit。

  • 测试环境:DevEco Studio 模拟器,真机调试环境。

  • 环境要求:仓颉 1.0.0+ SDK,CI 使用官方认证 Docker 镜像(含模拟器支持)。

相关附件

暂无附件

质量认证要求

交付件

NO

交付件描述

备注

1

三方库源代码

源代码

2

三方库测试方案和用例

测试用例和文档

3

用户手册,API文档,设计文档,license文档

 资料和文档

验收标准

1.功能

  1. 三方库必须有明确的功能;

  2. 如果参考对标库移值开发,功能与参考三方库保持一致。

2.资料

  1. Readme:包含简介,软件架构,目录结构,下载安装(编译构建),接口说明,使用示例,约束限制,开源协议,参与贡献等内容;

  2. Changelog,三方库版本需包含基本的修改说明。

3.标准遵从性(可选),三方库实现需满足对应协议或行业标准,举例

  1. appquth:支持对OAuth 的PKCE扩展;

  2. icu4j:支持unicode标准库,通用字符集ISO/IEC 10646。

4.性能目标

  1. 性能敏感三方库接口运行性能持平对标三方库

5.开源协议遵从,必须包含License文件

  1. 放置合适的开源License协议,建议Apache License Version 2.0;

  2. 引用或参考开源三方库,需遵从开源协议。

6.网络安全要求

  1. 满足基础的网络安全红线及隐私要求,符合安全编码规范。

过程质量要求

指标分类

指标名称

指标要求

度量工具

牵引 OR Must

代码度量

平均文件代码行

≤300 LOC

CMetricsPlus,CJMetric

Must

总文件重复率

C/C++≤4%;相比开源不劣化

CMetricsPlus,CJMetric

Must

源文件重复率

C/C++≤4%;相比开源不劣化

CMetricsPlus,CJMetric

Must

平均函数或方法代码行*

≤30  LOC

CMetricsPlus,CJMetric

Must

总代码重复率

C/C++≤10%;相比开源不劣化

CMetricsPlus,CJMetric

Must

源文件代码重复率

C/C++≤10%;相比开源不劣化

CMetricsPlus,CJMetric

Must

平均圈复杂度

≤5;相比开源不劣化

CMetricsPlus,CJMetric

Must

冗余代码

“0” 【2】;

CMetricsPlus,CJMetric

Must

不安全函数

NA

CMetricsPlus,CJMetric

Must

静态检查

编译告警

“0” 【2】

Compile工具

牵引

通用静态告警

“0” 【2】

Pclint plus,CJLINT

Must

开发者测试

DT用例密度(个/KLOC)

> 40

手工

牵引 

DT代码语句覆盖率

>=85%

Gcov,cjcov

牵引

DT代码分支覆盖率

>=50%

Gcov,cjcov

牵引

未做DT文件数

0

手工

牵引

问题解决率

遗留问题DI

整体<10

Issue

牵引 

遗留致命缺陷数(0)

0

Issue

Must

累计缺陷解决率

85%

Issue

牵引 

软件开发

每日构建成功率

100%

CI

牵引

测试评估

测试缺陷密度(/KLOC)

5-9

人工

牵引

测试用例密度(个/KLOC)

20-40

人工

牵引

初验用例自动化率

100%

CIDA

牵引 

HLT自动化用例比率

【85%,95%】

CIDA

牵引 

开源第三方(含构建工具)

开源片段引用

0(除例外备案类)

FOSSBOT+人工

Must

可信构建

二进制一致性

0(含可澄清)

人工

Mus