OpenHarmony Updater 升级包安装组件
文章目录
- [OpenHarmony Updater 升级包安装组件](#OpenHarmony Updater 升级包安装组件)
-
- [1. 模块概述](#1. 模块概述)
-
- [1.1 功能与目标](#1.1 功能与目标)
-
- [1.1.1 主要功能](#1.1.1 主要功能)
- [1.1.2 设计目标](#1.1.2 设计目标)
- [1.2 系统位置](#1.2 系统位置)
-
- [1.2.1 在整个系统中的位置](#1.2.1 在整个系统中的位置)
- [1.2.2 模块角色](#1.2.2 模块角色)
- [1.2.3 与其他模块的关系](#1.2.3 与其他模块的关系)
- [1.3 设计思路与模式](#1.3 设计思路与模式)
-
- [1.3.1 设计思路](#1.3.1 设计思路)
- [1.3.2 设计模式](#1.3.2 设计模式)
- [1.4 系统框图](#1.4 系统框图)
- [2. 模块结构](#2. 模块结构)
-
- [2.1 源文件与头文件](#2.1 源文件与头文件)
-
- [2.1.1 目录结构](#2.1.1 目录结构)
- [2.1.2 核心源文件说明](#2.1.2 核心源文件说明)
- [2.1.3 核心头文件说明](#2.1.3 核心头文件说明)
- [2.2 类、结构体、函数与方法](#2.2 类、结构体、函数与方法)
-
- [2.2.1 核心枚举类型](#2.2.1 核心枚举类型)
- [2.2.2 核心结构体](#2.2.2 核心结构体)
- [2.2.3 核心类](#2.2.3 核心类)
- [2.2.4 重要函数说明](#2.2.4 重要函数说明)
- [2.3 继承与多态](#2.3 继承与多态)
-
- [2.3.1 PkgFile继承体系](#2.3.1 PkgFile继承体系)
- [2.3.2 PkgStream继承体系](#2.3.2 PkgStream继承体系)
- [2.3.3 CommandFunction继承体系](#2.3.3 CommandFunction继承体系)
- [2.4 类图](#2.4 类图)
- [2.5 模块内部依赖框图](#2.5 模块内部依赖框图)
- [3. 模块间交互](#3. 模块间交互)
-
- [3.1 交互描述](#3.1 交互描述)
-
- [3.1.1 与外部模块的交互](#3.1.1 与外部模块的交互)
- [3.1.2 外部库依赖](#3.1.2 外部库依赖)
- [3.1.3 异步处理机制](#3.1.3 异步处理机制)
- [3.1.4 多线程处理](#3.1.4 多线程处理)
- [3.2 外部依赖框图](#3.2 外部依赖框图)
- [4. 状态机转换图](#4. 状态机转换图)
-
- [4.1 状态机模型](#4.1 状态机模型)
-
- [4.1.1 状态机树图](#4.1.1 状态机树图)
- [4.2 状态机切换规则](#4.2 状态机切换规则)
-
- [4.2.1 主状态切换](#4.2.1 主状态切换)
- [4.2.2 升级流程状态切换](#4.2.2 升级流程状态切换)
- [4.3 状态机转换图](#4.3 状态机转换图)
- [4.4 升级详细流程图](#4.4 升级详细流程图)
- [5. 接口设计](#5. 接口设计)
-
- [5.1 公共接口](#5.1 公共接口)
-
- [5.1.1 升级核心接口](#5.1.1 升级核心接口)
- [5.1.2 包管理接口](#5.1.2 包管理接口)
- [5.1.3 文件系统接口](#5.1.3 文件系统接口)
- [5.1.4 UI接口](#5.1.4 UI接口)
- [5.2 数据交换接口](#5.2 数据交换接口)
-
- [5.2.1 misc分区数据结构](#5.2.1 misc分区数据结构)
- [5.2.2 misc分区读写接口](#5.2.2 misc分区读写接口)
- [5.2.3 进程间通信协议](#5.2.3 进程间通信协议)
- [5.3 接口调用时序图](#5.3 接口调用时序图)
-
- [5.3.1 OTA升级时序图](#5.3.1 OTA升级时序图)
- [5.3.2 恢复出厂设置时序图](#5.3.2 恢复出厂设置时序图)
- 附录
-
- [A. 错误码定义](#A. 错误码定义)
- [B. 配置文件说明](#B. 配置文件说明)
1. 模块概述
源码:https://gitcode.com/openharmony/update_updater
1.1 功能与目标
1.1.1 主要功能
升级包安装组件(Updater)是OpenHarmony升级子系统的核心组件,运行在独立的updater分区中,主要实现以下功能:
| 功能模块 | 描述 |
|---|---|
| 升级包管理 | 读取misc分区信息获取升级包状态,对升级包进行校验,确保升级包合法有效 |
| 升级程序执行 | 从升级包中解析出升级的可执行程序,创建子进程并启动升级程序 |
| 差分还原 | 支持差分包的解析和还原,减少升级包大小 |
| 分区管理 | 管理文件系统和分区的挂载、格式化等操作 |
| 恢复出厂设置 | 支持用户级和工厂级的数据擦除和恢复 |
| SD卡升级 | 支持从SD卡读取升级包进行本地升级 |
| AB流式升级 | 支持AB分区独立升级,实现无缝更新 |
| Flashd刷机 | 提供格式化用户分区、擦除分区、刷写镜像等功能 |
| UI界面 | 提供升级过程中的用户界面显示和交互 |
1.1.2 设计目标
- 可靠性: 支持断点续传、异常回滚机制,确保升级失败时自动恢复
- 安全性: 多重安全校验,包括签名验证、哈希校验、完整性校验
- 灵活性: 支持多种升级模式(OTA、SD卡、Flashd、AB流式升级)
- 可扩展性: 采用模块化设计,便于功能扩展和定制
1.2 系统位置
1.2.1 在整个系统中的位置
Updater组件是OpenHarmony升级子系统的关键组成部分,位于系统底层服务层:
┌─────────────────────────────────────────────────────────────────┐
│ 应用层 (Application) │
├─────────────────────────────────────────────────────────────────┤
│ 框架层 (Framework) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ UpdateService│ │DownloadAgent│ │ UpdateManager│ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 服务层 (Services) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Updater 组件 (本模块) │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Package │ │ Script │ │ApplyPatch│ │ UI │ │ │
│ │ │ Manager │ │ Manager │ │ Manager │ │ Module │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ HAL层 (Hardware) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ FS Manager │ │ Partition │ │ Display │ │
│ │ │ │ Table │ │ Driver │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 内核层 (Kernel) │
└─────────────────────────────────────────────────────────────────┘
1.2.2 模块角色
- 核心模块: Updater是升级子系统的核心执行模块
- 独立分区: 运行在独立的updater分区,与主系统隔离
- 底层服务: 直接操作分区、文件系统,属于系统底层服务
1.2.3 与其他模块的关系
| 关联模块 | 关系类型 | 描述 |
|---|---|---|
| UpdateService | 被调用 | 接收来自框架层的升级指令 |
| misc分区 | 数据交换 | 读写升级命令和状态信息 |
| 内核 | 依赖 | 依赖内核的文件系统、分区驱动 |
| HDC | 通信 | Flashd模式下通过HDC与PC端通信 |
| Display驱动 | 依赖 | UI显示依赖显示驱动 |
1.3 设计思路与模式
1.3.1 设计思路
1. 分层架构设计
采用分层架构,将功能划分为多个层次:
- 入口层: main.cpp,负责模式选择和初始化
- 业务逻辑层: updater_main.cpp,处理升级流程
- 功能模块层: package、script、applypatch等独立功能模块
- 基础服务层: fs_manager、log、utils等基础服务
2. 模块化设计
各功能模块相对独立,通过定义良好的接口进行交互:
- Package模块:负责升级包的解析和验证
- Script模块:负责升级脚本的解析和执行
- ApplyPatch模块:负责差分包的应用
- UI模块:负责界面显示和用户交互
3. 事件驱动设计
采用事件驱动机制,通过UpdaterInit类管理各阶段事件:
cpp
UpdaterInit::GetInstance().InvokeEvent(UPDATER_PRE_INIT_EVENT);
UpdaterInit::GetInstance().InvokeEvent(UPDATER_INIT_EVENT);
UpdaterInit::GetInstance().InvokeEvent(UPDATER_POST_INIT_EVENT);
1.3.2 设计模式
| 设计模式 | 应用场景 | 实现类/函数 |
|---|---|---|
| 单例模式 | 全局唯一实例管理 | PkgManager::GetPackageInstance(), UpdaterUiFacade::GetInstance(), TransferManager |
| 工厂模式 | 对象创建 | PkgManager::CreatePackageInstance(), CommandFunctionFactory |
| 策略模式 | UI显示策略 | UiStrategy, ProgressStrategy, LogoStrategy |
| 外观模式 | 统一接口封装 | UpdaterUiFacade |
| 命令模式 | 升级命令执行 | Command, CommandFunction |
| 观察者模式 | 进度回调 | callbackProgress |
| 模板方法模式 | 升级流程模板 | StartUpdaterEntry(), DoUpdaterEntry() |
1.4 系统框图
┌─────────────────────────────────────────────────────────────────────────┐
│ Updater 系统架构 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 入口模块 (main.cpp) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Updater │ │ Flashd │ │ 其他模式 │ │ │
│ │ │ Mode │ │ Mode │ │ Mode │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ └────────┼───────────────┼───────────────┼────────────────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 核心业务层 (updater_main) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ OTA升级 │ │ SD卡升级 │ │ 恢复出厂 │ │ │
│ │ │ InstallPkg() │ │UpdaterFromSD │ │FactoryReset │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 功能模块层 │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Package │ │ Script │ │ ApplyPatch │ │ │
│ │ │ Manager │ │ Manager │ │ Manager │ │ │
│ │ │ ─────────── │ │ ─────────── │ │ ─────────── │ │ │
│ │ │ • 包解析 │ │ • 脚本解析 │ │ • 差分还原 │ │ │
│ │ │ • 签名验证 │ │ • 指令执行 │ │ • 块写入 │ │ │
│ │ │ • 文件提取 │ │ • 线程池 │ │ • 进度管理 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ UI │ │ DiffPatch │ │ Flashd │ │ │
│ │ │ Module │ │ Module │ │ Module │ │ │
│ │ │ ─────────── │ │ ─────────── │ │ ─────────── │ │ │
│ │ │ • 页面管理 │ │ • bsdiff │ │ • 镜像写入 │ │ │
│ │ │ • 进度显示 │ │ • 压缩/解压 │ │ • 分区操作 │ │ │
│ │ │ • 事件处理 │ │ • imgdiff │ │ • HDC通信 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 基础服务层 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Log │ │ Utils │ │FS Manager│ │ Ptable │ │ │
│ │ │ Module │ │ Module │ │ Module │ │ Parse │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
2. 模块结构
2.1 源文件与头文件
2.1.1 目录结构
base/update/updater/
├── resources/ # UI图片资源目录
├── services/ # 组件服务层代码目录
│ ├── applypatch/ # 升级包数据更新代码
│ ├── diffpatch/ # 差分还原代码
│ ├── etc/ # 启动配置文件
│ ├── flashd/ # flashd模式镜像写入和升级
│ ├── fs_manager/ # 文件系统和分区管理
│ ├── hdi/ # 硬件相关接口定义
│ ├── include/ # 头文件目录
│ ├── log/ # 日志模块
│ ├── package/ # 升级包管理模块
│ ├── ptable_parse/ # 分区表解析
│ ├── script/ # 升级脚本管理
│ ├── ui/ # UI界面代码
│ └── updater_binary/ # 升级可执行程序
├── interfaces/
│ └── kits/ # 对外模块接口定义
└── utils/ # 通用工具代码
2.1.2 核心源文件说明
| 文件路径 | 功能描述 |
|---|---|
services/main.cpp |
程序入口,负责模式选择和初始化 |
services/updater_main.cpp |
升级主流程控制,包含OTA升级、SD卡升级、恢复出厂设置等 |
services/updater.cpp |
升级核心逻辑,包含包安装、进程管理、状态处理 |
services/updater_ui.cpp |
UI界面初始化和控制 |
2.1.3 核心头文件说明
| 头文件路径 | 功能描述 |
|---|---|
services/include/updater/updater.h |
升级核心接口定义 |
services/include/package/pkg_manager.h |
包管理器接口定义 |
services/include/script/script_manager.h |
脚本管理器接口定义 |
services/include/fs_manager/mount.h |
文件系统挂载接口 |
services/include/applypatch/transfer_manager.h |
传输管理器接口 |
2.2 类、结构体、函数与方法
2.2.1 核心枚举类型
UpdaterStatus - 升级状态枚举
cpp
enum UpdaterStatus {
UPDATE_ERROR = -1, // 升级错误
UPDATE_SUCCESS, // 升级成功
UPDATE_CORRUPT, // 包损坏或验证失败
UPDATE_SKIP, // 跳过升级(条件不满足,如电量低)
UPDATE_RETRY, // 需要重试
UPDATE_RETRY_FAIL, // 重试失败
UPDATE_SPACE_NOTENOUGH, // 空间不足
UPDATE_UNKNOWN // 未知状态
};
PackageUpdateMode - 升级模式枚举
cpp
enum PackageUpdateMode {
HOTA_UPDATE = 0, // OTA升级
SDCARD_UPDATE, // SD卡升级
SUBPKG_UPDATE, // 子包升级
UNKNOWN_UPDATE, // 未知模式
};
FactoryResetMode - 恢复出厂模式枚举
cpp
enum FactoryResetMode {
USER_WIPE_DATA = 0, // 用户级数据擦除
FACTORY_WIPE_DATA, // 工厂级数据擦除
MENU_WIPE_DATA, // 菜单触发的数据擦除
CLEAR_SPACE, // 清理空间
INVALID_MODE, // 无效模式
};
2.2.2 核心结构体
UpdaterParams - 升级参数结构体
cpp
struct UpdaterParams {
bool forceUpdate = false; // 强制升级标志
bool forceReboot = false; // 强制重启标志
bool isLoadReduction = false; // 负载降低标志
std::string sdExtMode {}; // SD卡扩展模式
std::string factoryResetMode {}; // 恢复出厂模式
PackageUpdateMode updateMode; // 升级模式
int retryCount = 0; // 重试次数
int panicCount = 0; // panic计数
pid_t binaryPid = -1; // 二进制进程ID
float initialProgress = 0; // 初始进度
float currentPercentage = 0; // 当前进度百分比
unsigned int pkgLocation = 0; // 包位置索引
int64_t allMaxStashSize = -1; // 最大stash大小
std::string shrinkInfo = ""; // 收缩信息
std::string miscCmd {"boot_updater"}; // misc命令
std::vector<std::string> updateBin {}; // 升级bin文件列表
std::vector<std::string> updatePackage {}; // 升级包列表
std::vector<std::chrono::duration<double>> installTime {}; // 安装时间
std::function<void(float)> callbackProgress {}; // 进度回调
std::vector<std::string> binaryTids {}; // 二进制线程ID列表
};
BootMode - 启动模式结构体
cpp
struct BootMode {
CondFunc cond {nullptr}; // 进入模式的条件函数
std::string modeName {}; // 模式名称
std::string modePara {}; // 模式参数配置
EntryFunc entryFunc {nullptr}; // 模式入口函数
void InitMode(void) const; // 模式初始化函数
};
TransferParams - 传输参数结构体
cpp
struct TransferParams {
size_t version; // 版本号
size_t blockCount; // 块数量
size_t maxEntries; // 最大条目数
size_t maxBlocks; // 最大块数
size_t written; // 已写入数量
pthread_t thread; // 线程句柄
Uscript::UScriptEnv *env; // 脚本环境
std::unique_ptr<WriterThreadInfo> writerThreadInfo; // 写线程信息
int storeCreated; // store创建标志
std::string storeBase; // store基础路径
std::string freeStash; // 空闲stash
std::string retryFile; // 重试文件
std::string devPath; // 设备路径
std::string patchDatFile; // patch数据文件
uint8_t *dataBuffer; // 数据缓冲区
size_t dataBufferSize; // 缓冲区大小
bool canWrite; // 可写标志
bool isUpdaterMode; // updater模式标志
};
2.2.3 核心类
PkgManager - 包管理器类
| 成员/方法 | 类型 | 描述 |
|---|---|---|
CreatePackageInstance() |
静态方法 | 创建包管理器实例 |
GetPackageInstance() |
静态方法 | 获取包管理器实例 |
ReleasePackageInstance() |
静态方法 | 释放包管理器实例 |
LoadPackage() |
虚方法 | 加载并解析升级包 |
VerifyPackage() |
虚方法 | 验证升级包签名 |
VerifyOtaPackage() |
虚方法 | 验证OTA升级包 |
ExtractFile() |
虚方法 | 提取文件 |
GetFileInfo() |
虚方法 | 获取文件信息 |
CreatePkgStream() |
虚方法 | 创建包流 |
ClosePkgStream() |
虚方法 | 关闭包流 |
ScriptManager - 脚本管理器类
| 成员/方法 | 类型 | 描述 |
|---|---|---|
MAX_PRIORITY |
常量 | 最大优先级值(4) |
GetScriptManager() |
静态方法 | 获取脚本管理器实例 |
ReleaseScriptManager() |
静态方法 | 释放脚本管理器 |
ExecuteScript() |
虚方法 | 执行指定优先级的脚本 |
TransferManager - 传输管理器类
| 成员/方法 | 类型 | 描述 |
|---|---|---|
transferParams_ |
私有成员 | 传输参数 |
CommandsParser() |
公有方法 | 解析并执行命令 |
GetTransferParams() |
公有方法 | 获取传输参数 |
ReloadForRetry() |
公有方法 | 重试时重新加载 |
CheckResult() |
公有方法 | 检查执行结果 |
CommandsExecute() |
私有方法 | 执行命令 |
RegisterForRetry() |
私有方法 | 注册重试 |
UpdateProgress() |
私有方法 | 更新进度 |
UpdaterUiFacade - UI外观类
| 成员/方法 | 类型 | 描述 |
|---|---|---|
GetInstance() |
静态方法 | 获取单例实例 |
InitEnv() |
公有方法 | 初始化环境 |
SetMode() |
公有方法 | 设置UI模式 |
GetMode() |
公有方法 | 获取当前模式 |
ShowLog() |
公有方法 | 显示日志 |
ShowProgress() |
公有方法 | 显示进度 |
ShowProgressPage() |
公有方法 | 显示进度页面 |
ShowSuccessPage() |
公有方法 | 显示成功页面 |
ShowFailedPage() |
公有方法 | 显示失败页面 |
ShowMainpage() |
公有方法 | 显示主页面 |
Sleep() |
公有方法 | 休眠 |
GetCurrentPercent() |
公有方法 | 获取当前进度百分比 |
2.2.4 重要函数说明
入口函数
cpp
// 程序主入口
int main(int argc, char **argv);
// Updater模式主函数
int UpdaterMain(int argc, char **argv);
// Flashd模式主函数
int FlashdMain(int argc, char **argv);
升级流程函数
cpp
// 启动升级入口
UpdaterStatus StartUpdaterEntry(UpdaterParams &upParams);
// 执行升级入口
UpdaterStatus DoUpdaterEntry(UpdaterParams &upParams);
// 安装升级包
UpdaterStatus InstallUpdaterPackages(UpdaterParams &upParams);
// 执行升级包安装
UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager,
UpdaterParams &upParams, PackageUpdateMode updateMode);
// 启动升级子进程
UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager,
UpdaterParams &upParams);
// SD卡升级
UpdaterStatus UpdaterFromSdcard(UpdaterParams &upParams);
// 恢复出厂设置
int FactoryReset(FactoryResetMode mode, const std::string &path);
验证函数
cpp
// OTA包预检查
int OtaUpdatePreCheck(PkgManager::PkgManagerPtr pkgManager,
const std::string &packagePath);
// 获取升级包信息
int GetUpdatePackageInfo(PkgManager::PkgManagerPtr pkgManager,
const std::string& path);
// 提取升级二进制
int32_t ExtractUpdaterBinary(PkgManager::PkgManagerPtr manager,
std::string &packagePath, const std::string &updaterBinary);
工具函数
cpp
// 检查电池电量是否充足
bool IsBatteryCapacitySufficient();
// 检查空间是否充足
UpdaterStatus IsSpaceCapacitySufficient(UpdaterParams &upParams);
// 设置分区
int SetupPartitions(bool isMountData = true, bool isMountMetadata = false);
// 获取工作路径
std::string GetWorkPath();
// 清除misc分区
bool ClearMisc();
2.3 继承与多态
2.3.1 PkgFile继承体系
继承
继承
继承
继承
<<abstract>>
PkgFile
+LoadPackage()
+ExtractFile()
+GetPkgInfo()
+GetPkgType()
PkgZipFile
+LoadPackage()
+ExtractFile()
PkgUpgradeFile
+LoadPackage()
+ExtractFile()
PkgLz4File
+LoadPackage()
+ExtractFile()
PkgGzipFile
+LoadPackage()
+ExtractFile()
设计目的:
- 统一不同格式升级包的处理接口
- 支持多种压缩格式的透明处理
- 便于扩展新的包格式
2.3.2 PkgStream继承体系
继承
继承
继承
继承
<<abstract>>
PkgStream
+Read()
+Write()
+Flush()
+GetBuffer()
FileStream
+Read()
+Write()
MemoryStream
+Read()
+Write()
ProcessStream
+Read()
+Write()
BufferStream
+Read()
+Write()
设计目的:
- 统一不同数据源的读写接口
- 支持文件、内存、流式数据等多种数据源
- 支持边解析边处理的流式操作
2.3.3 CommandFunction继承体系
继承
继承
继承
继承
继承
继承
<<abstract>>
CommandFunction
+Execute()
NewCmd
+Execute()
MoveCmd
+Execute()
BsdiffCmd
+Execute()
EraseCmd
+Execute()
ZeroCmd
+Execute()
FreeCmd
+Execute()
设计目的:
- 实现命令模式,将命令封装为对象
- 统一命令执行接口
- 便于扩展新的命令类型
2.4 类图
uses
implements
creates
creates
uses
uses
creates
UpdaterParams
-forceUpdate: bool
-updateMode: enum
-retryCount: int
-updatePackage: vector
-callbackProgress: function
BootMode
-cond: CondFunc
-modeName: string
-modePara: string
-entryFunc: EntryFunc
+InitMode()
<<interface>>
PkgManager
+CreatePackageInstance()
+LoadPackage()
+VerifyPackage()
+ExtractFile()
+CreatePkgStream()
PkgManagerImpl
-pkgFiles_: map
-streams_: map
+LoadPackage()
+VerifyPackage()
+ExtractFile()
<<abstract>>
PkgFile
+LoadPackage()
+ExtractFile()
+GetPkgInfo()
+GetPkgType()
<<abstract>>
PkgStream
+Read()
+Write()
+Flush()
+GetBuffer()
<<abstract>>
ScriptManager
+ExecuteScript()
+GetScriptManager()
+ReleaseScriptManager()
TransferManager
-transferParams_: unique_ptr
+CommandsParser()
+GetTransferParams()
+CheckResult()
<<abstract>>
CommandFunction
+Execute()
CommandFunctionFactory
-functions_: map
+GetCommandFunc()
+GetInstance()
UpdaterUiFacade
-strategies_: map
-pgMgr_: PageManager
-mode_: string
+GetInstance()
+InitEnv()
+SetMode()
+ShowProgress()
+ShowSuccessPage()
+ShowFailedPage()
2.5 模块内部依赖框图
┌─────────────────────────────────────────────────────────────────────────┐
│ 模块内部依赖关系 │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────┐
│ main.cpp │
│ (程序入口) │
└────────┬────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────┐ ┌─────────────────┐
│ updater_main.cpp│ │flashd/ │ │ (其他模式入口) │
│ (升级主流程) │ │daemon/ │ │ │
└────────┬────────┘ └────┬────┘ └─────────────────┘
│ │
▼ │
┌─────────────────┐ │
│ updater.cpp │◄─────┘
│ (核心逻辑) │
└────────┬────────┘
│
┌────────┴────────────────────────────────────┐
│ │
▼ ▼ ▼
┌───────────┐ ┌───────────────┐ ┌───────────────────┐
│ package/ │ │ script/ │ │ applypatch/ │
│ (包管理) │ │ (脚本管理) │ │ (差分应用) │
├───────────┤ ├───────────────┤ ├───────────────────┤
│pkg_manager│ │script_manager │ │transfer_manager │
│pkg_verify │ │script_interp │ │command_function │
│pkg_stream │ │script_instruc │ │block_writer │
└─────┬─────┘ └───────┬───────┘ └─────────┬─────────┘
│ │ │
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ diffpatch/ (差分还原) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ bsdiff │ │ imgdiff │ │ bzip2 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 基础服务层 │
│ ┌───────────┐ ┌───────────┐ ┌───────────────────┐ │
│ │fs_manager/│ │ log/ │ │ utils/ │ │
│ │(文件系统) │ │ (日志) │ │ (工具函数) │ │
│ └───────────┘ └───────────┘ └───────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ UI模块 │
│ ┌───────────┐ ┌───────────┐ ┌───────────────────┐ │
│ │ view/ │ │ control/ │ │ driver/ │ │
│ │ (视图) │ │ (控制) │ │ (驱动) │ │
│ ├───────────┤ ├───────────┤ ├───────────────────┤ │
│ │page_mgr │ │event_mgr │ │graphic_engine │ │
│ │component │ │callback │ │input_event │ │
│ │layout │ │listener │ │drm_driver │ │
│ └───────────┘ └───────────┘ └───────────────────┘ │
└─────────────────────────────────────────────────────────┘
3. 模块间交互
3.1 交互描述
3.1.1 与外部模块的交互
| 交互对象 | 交互方式 | 描述 |
|---|---|---|
| misc分区 | 直接读写 | 读取升级命令,写入升级状态 |
| data分区 | 文件系统操作 | 存储升级包,读写升级日志 |
| 各镜像分区 | 块设备操作 | 写入升级后的镜像数据 |
| HDC | 网络/USB通信 | Flashd模式下与PC端通信 |
| 显示驱动 | DRM/FB接口 | UI界面显示 |
| 输入驱动 | Input子系统 | 用户输入处理 |
3.1.2 外部库依赖
| 外部库 | 用途 |
|---|---|
| OpenSSL | 签名验证、哈希计算 |
| zlib | ZIP格式解压缩 |
| bzip2 | bsdiff差分还原 |
| lz4 | LZ4格式解压缩 |
| libuv | HDC异步IO |
3.1.3 异步处理机制
1. 升级子进程机制
cpp
// 创建管道用于父子进程通信
int pfd[2];
pipe(pfd);
pid_t pid = fork();
if (pid == 0) {
// 子进程:执行升级二进制
execl(fullPath.c_str(), ...);
} else {
// 父进程:监听子进程输出,更新进度
HandlePipeMsg(upParams, pipeRead, retryUpdate);
}
2. 进度回调机制
cpp
// 设置进度回调
upParams.callbackProgress = [](float value) {
UPDATER_UI_INSTANCE.ShowProgress(value);
};
// 子进程通过管道发送进度
// 格式: "set_progress:0.5"
HandleChildOutput(buffer, bufferLen, retryUpdate, upParams);
3. 线程池机制
cpp
// Script模块使用线程池并行执行任务
class ThreadPool {
std::vector<std::thread> workers_;
std::queue<std::function<void()>> tasks_;
// ...
};
3.1.4 多线程处理
| 线程 | 职责 |
|---|---|
| 主线程 | 升级流程控制、UI更新 |
| 升级子进程 | 执行实际的镜像写入操作 |
| 写线程 | ApplyPatch模块中的异步写入 |
| UI事件线程 | 处理用户输入事件 |
3.2 外部依赖框图
┌─────────────────────────────────────────────────────────────────────────┐
│ 外部依赖关系图 │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────┐
│ Updater │
│ 组件 │
└────────┬────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ 系统分区 │ │ 外部库 │ │ 硬件驱动 │
├───────────────┤ ├───────────────┤ ├───────────────┤
│ │ │ │ │ │
│ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ misc │ │ │ │ OpenSSL │ │ │ │ Display │ │
│ │ 分区 │ │ │ │ (签名验证)│ │ │ │ Driver │ │
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
│ │ │ │ │ │
│ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ data │ │ │ │ zlib │ │ │ │ Input │ │
│ │ 分区 │ │ │ │ (ZIP解压) │ │ │ │ Driver │ │
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
│ │ │ │ │ │
│ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ system │ │ │ │ bzip2 │ │ │ │ Block │ │
│ │ 分区 │ │ │ │(差分还原) │ │ │ │ Device │ │
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
│ │ │ │ │ │
│ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ vendor │ │ │ │ lz4 │ │ │ │ USB │ │
│ │ 分区 │ │ │ │(LZ4解压) │ │ │ │ Driver │ │
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
│ │ │ │ │ │
└───────────────┘ │ ┌───────────┐ │ └───────────────┘
│ │ libuv │ │
│ │(异步IO) │ │
│ └───────────┘ │
│ │
└───────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ 通信协议 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ USB/TCP ┌─────────────┐ │
│ │ Updater │◄──────────────►│ HDC Host │ │
│ │ (Flashd) │ │ (PC端) │ │
│ └─────────────┘ └─────────────┘ │
│ │
│ 协议: HDC (Huawei Device Connector) │
│ 功能: 镜像刷写、分区擦除、文件传输 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
4. 状态机转换图
4.1 状态机模型
Updater组件采用层次化状态机设计,主要包含以下状态层次:
4.1.1 状态机树图
FACTORY RESET
USER WIPE
FACTORY WIPE
FLASHD MODE
FLASH IMAGE
ERASE PART
FORMAT PART
UPDATER MODE
OTA UPDATE
SDCARD UPDATE
SUBPKG UPDATE
IDLE
空闲态
4.2 状态机切换规则
4.2.1 主状态切换
| 当前状态 | 触发事件 | 目标状态 | 转移条件 |
|---|---|---|---|
| IDLE | 读取misc命令 | UPDATER_MODE | command == "boot_updater" |
| IDLE | 读取misc命令 | FLASHD_MODE | command == "boot_flash" |
| IDLE | 读取misc命令 | FACTORY_RESET | command包含"wipe_data" |
| UPDATER_MODE | 解析参数 | OTA_UPDATE | updatePackage非空 |
| UPDATER_MODE | 解析参数 | SDCARD_UPDATE | sdcard_update标志 |
| UPDATER_MODE | 解析参数 | SUBPKG_UPDATE | subpkg_update标志 |
4.2.2 升级流程状态切换
| 当前状态 | 触发事件 | 目标状态 | 转移条件 |
|---|---|---|---|
| INIT | 初始化完成 | VERIFY | - |
| VERIFY | 验证成功 | INSTALL | verifyret == SUCCESS |
| VERIFY | 验证失败 | FAILED | verifyret != SUCCESS |
| INSTALL | 安装成功 | SUCCESS | status == UPDATE_SUCCESS |
| INSTALL | 安装失败 | RETRY | status == UPDATE_RETRY |
| INSTALL | 安装失败 | FAILED | status == UPDATE_ERROR |
| RETRY | 重试次数<3 | INSTALL | retryCount < 3 |
| RETRY | 重试次数>=3 | FAILED | retryCount >= 3 |
| SUCCESS | - | REBOOT | - |
| FAILED | - | WAIT_INPUT | - |
4.3 状态机转换图
┌─────────────────────────────────────────────────────────────────────────┐
│ 升级流程状态机转换图 │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────┐
│ START │
└──────┬──────┘
│ ReadMiscMsg()
▼
┌─────────────┐
│ SELECT_ │
│ MODE │
└──────┬──────┘
│ SelectMode()
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ UPDATER │ │ FLASHD │ │ FACTORY │
│ INIT │ │ INIT │ │ RESET │
└──────┬──────┘ └─────────────┘ └──────┬──────┘
│ │
│ InitEnv() │ DoFactoryReset()
▼ ▼
┌─────────────┐ ┌─────────────┐
│ PARSE_ │ │ WIPING │
│ PARAMS │ │ DATA │
└──────┬──────┘ └──────┬──────┘
│ │
│ ParseParams() │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ VERIFY │ │ RESET │
│ PACKAGE │ │ COMPLETE │──────┐
└──────┬──────┘ └─────────────┘ │
│ │
┌─────────┴─────────┐ │
│VerifyPackages() │ │
▼ ▼ │
┌─────────────┐ ┌─────────────┐ │
│ VERIFY │ │ VERIFY │ │
│ SUCCESS │ │ FAILED │ │
└──────┬──────┘ └──────┬──────┘ │
│ │ │
│ │ ShowFailedPage() │
▼ ▼ │
┌─────────────┐ ┌─────────────┐ │
│ CHECK_ │ │ WAIT_ │ │
│ BATTERY │ │ INPUT │ │
└──────┬──────┘ └─────────────┘ │
│ │
│ IsBatteryCapacitySufficient() │
▼ │
┌─────────────┐ │
│ INSTALL_ │ │
│ PACKAGE │ │
└──────┬──────┘ │
│ │
│ DoInstallUpdaterPackage() │
│ │
┌──────┴───────────────────────────────┐ │
│ │ │
▼ ▼ │
┌─────────────┐ ┌─────────────┐ │
│ INSTALL │ │ INSTALL │ │
│ SUCCESS │ │ FAILED │ │
└──────┬──────┘ └──────┬──────┘ │
│ │ │
│ ┌───────┴───────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ RETRY │ │ ERROR │ │
│ │ UPDATE │ │ STATE │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ │ retryCount<3 │ │
│ ▼ │ │
│ ┌─────────────┐ │ │
│ │ RETRY_ │ │ │
│ │ INSTALL │────────┤ │
│ └─────────────┘ │ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ SHOW_ │ │
│ │ FAILED │ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ WAIT_ │ │
│ │ INPUT │ │
│ └─────────────┘ │
│ │
│ PostUpdater() │
▼ │
┌─────────────┐ │
│ SHOW_ │ │
│ SUCCESS │ │
└──────┬──────┘ │
│ │
│ RebootAfterUpdateSuccess() │
▼ │
┌─────────────┐ │
│ REBOOT │◄──────────────────────────────────────────────────┘
└─────────────┘
图例:
─────────────────────────────────────────────────────────────────────────
│ 状态框 │ 表示一个状态节点
─────────────────────────────────────────────────────────────────────────
│ 状态转移线
▼ 转移方向
─────────────────────────────────────────────────────────────────────────
函数名() 触发转移的事件/函数
─────────────────────────────────────────────────────────────────────────
4.4 升级详细流程图
boot_updater
boot_flash
wipe_data
成功
失败
电量充足
电量不足
成功
需重试
失败
是
否
开始
ReadMiscMsg
SelectMode
Updater Init
Flashd Init
Factory Reset
ParseParams
VerifyPackages
CheckBattery
ShowFailedPage
DoInstallUpdaterPackage
ShowLowPower
PostUpdater
retryCount < 3?
ShowError
WaitInput
ShowSuccess
RebootAfterUpdateSuccess
DoFactoryReset
WipeData
ShowResetComplete
结束
5. 接口设计
5.1 公共接口
5.1.1 升级核心接口
StartUpdaterEntry - 启动升级入口
cpp
/**
* @brief 启动升级入口函数
* @param upParams 升级参数结构体引用
* @return UpdaterStatus 升级状态
* - UPDATE_SUCCESS: 升级成功
* - UPDATE_ERROR: 升级错误
* - UPDATE_CORRUPT: 包损坏
* - UPDATE_SKIP: 跳过升级
* @exception 无
* @note 此函数是升级流程的总入口,会依次调用Pre、Do、Post三个阶段
*/
UpdaterStatus StartUpdaterEntry(UpdaterParams &upParams);
DoInstallUpdaterPackage - 执行升级包安装
cpp
/**
* @brief 执行升级包安装
* @param pkgManager 包管理器指针
* @param upParams 升级参数
* @param updateMode 升级模式(HOTA_UPDATE/SDCARD_UPDATE)
* @return UpdaterStatus 安装状态
* @exception 无
* @note 会启动子进程执行实际的升级操作
*/
UpdaterStatus DoInstallUpdaterPackage(
Hpackage::PkgManager::PkgManagerPtr pkgManager,
UpdaterParams &upParams,
PackageUpdateMode updateMode);
StartUpdaterProc - 启动升级子进程
cpp
/**
* @brief 启动升级子进程
* @param pkgManager 包管理器指针
* @param upParams 升级参数
* @return UpdaterStatus 进程执行状态
* @exception 无
* @note 使用fork()创建子进程,通过管道进行进程间通信
*/
UpdaterStatus StartUpdaterProc(
Hpackage::PkgManager::PkgManagerPtr pkgManager,
UpdaterParams &upParams);
5.1.2 包管理接口
PkgManager::CreatePackageInstance - 创建包管理器实例
cpp
/**
* @brief 创建包管理器实例
* @return PkgManagerPtr 包管理器指针,失败返回nullptr
* @exception 无
* @note 采用工厂模式创建实例
*/
static PkgManagerPtr CreatePackageInstance();
PkgManager::LoadPackage - 加载升级包
cpp
/**
* @brief 加载并解析升级包
* @param packagePath 升级包路径
* @param keyPath 密钥路径
* @param fileIds [out] 返回的文件ID列表
* @return int32_t 0成功,其他失败
* @exception 无
*/
virtual int32_t LoadPackage(
const std::string &packagePath,
const std::string &keyPath,
std::vector<std::string> &fileIds) = 0;
PkgManager::VerifyOtaPackage - 验证OTA包
cpp
/**
* @brief 验证OTA升级包签名
* @param packagePath 升级包路径
* @return int32_t 0成功,其他失败
* @exception 无
*/
virtual int32_t VerifyOtaPackage(const std::string &packagePath) = 0;
PkgManager::ExtractFile - 提取文件
cpp
/**
* @brief 从升级包中提取文件
* @param fileId 文件ID
* @param output 输出流
* @return int32_t 0成功,其他失败
* @exception 无
*/
virtual int32_t ExtractFile(const std::string &fileId, StreamPtr output) = 0;
5.1.3 文件系统接口
SetupPartitions - 设置分区
cpp
/**
* @brief 设置并挂载分区
* @param isMountData 是否挂载data分区
* @param isMountMetadata 是否挂载metadata分区
* @return int 0成功,其他失败
* @exception 无
*/
int SetupPartitions(bool isMountData = true, bool isMountMetadata = false);
FormatPartition - 格式化分区
cpp
/**
* @brief 格式化指定分区
* @param path 分区挂载点路径
* @param isZeroErase 是否零填充擦除
* @return int 0成功,其他失败
* @exception 无
*/
int FormatPartition(const std::string &path, bool isZeroErase = false);
5.1.4 UI接口
UpdaterUiFacade - UI外观类接口
cpp
class UpdaterUiFacade {
public:
/**
* @brief 获取单例实例
*/
static UpdaterUiFacade &GetInstance();
/**
* @brief 初始化UI环境
*/
void InitEnv() const;
/**
* @brief 设置UI模式
* @param mode 模式名称
* @return bool 设置是否成功
*/
[[nodiscard]] bool SetMode(std::string mode);
/**
* @brief 显示进度
* @param value 进度值(0-100)
*/
void ShowProgress(float value) const;
/**
* @brief 显示进度页面
*/
void ShowProgressPage() const;
/**
* @brief 显示成功页面
*/
void ShowSuccessPage() const;
/**
* @brief 显示失败页面
*/
void ShowFailedPage() const;
/**
* @brief 显示日志信息
* @param tag 日志标签
* @param isClear 是否清除之前的日志
*/
void ShowLog(const std::string &tag, bool isClear = false) const;
};
5.2 数据交换接口
5.2.1 misc分区数据结构
cpp
/**
* @brief misc分区升级消息结构
*/
struct UpdateMessage {
char command[32]; // 升级命令 (boot_updater/boot_flash等)
char status[32]; // 升级状态
char update[768]; // 升级包路径
char stage[32]; // 升级阶段
char keyinfo[32]; // 密钥信息
char reserved[224]; // 保留字段
};
5.2.2 misc分区读写接口
cpp
/**
* @brief 读取misc分区升级消息
* @param boot [out] 升级消息结构体
* @return bool 读取是否成功
*/
bool ReadUpdaterMiscMsg(UpdateMessage &boot);
/**
* @brief 写入misc分区升级消息
* @param boot 升级消息结构体
* @return bool 写入是否成功
*/
bool WriteUpdaterMiscMsg(const UpdateMessage &boot);
/**
* @brief 清除misc分区
* @return bool 清除是否成功
*/
bool ClearMisc();
5.2.3 进程间通信协议
父子进程管道通信格式:
| 消息类型 | 格式 | 描述 |
|---|---|---|
| 进度更新 | set_progress:0.xx |
设置当前进度(0-1) |
| 日志输出 | write_log:message |
输出日志信息 |
| UI日志 | ui_log:message |
UI显示日志 |
| 显示进度 | show_progress:ratio,duration |
显示进度信息 |
| 重试标志 | retry_update:reason |
需要重试升级 |
| 完成标志 | subProcessResult:status |
子进程执行结果 |
5.3 接口调用时序图
5.3.1 OTA升级时序图
UI Facade ScriptManager PkgManager UpdaterMain main UI Facade ScriptManager PkgManager UpdaterMain main fork() + execl() 子进程执行升级 main() ReadUpdaterMiscMsg() SelectMode() UpdaterMain() InitEnv() CreatePackageInstance() VerifyOtaPackage() ShowProgressPage() LoadPackage() ExtractFile("updater_binary") GetScriptManager() ExecuteScript(priority) pipe: "set_progress:0.5" ShowProgress() pipe: "subProcessResult" waitpid() ShowSuccessPage() PostUpdater() RebootAfterUpdateSuccess()
5.3.2 恢复出厂设置时序图
UI Facade FS Manager UpdaterMain main UI Facade FS Manager UpdaterMain main main() ParseParams("factory_wipe_data") ShowProgressPage() DoFactoryRstEntry() FactoryReset(mode, "/data") UmountForPath("/data") FormatPartition("/data") MountForPath("/data") ShowSuccessPage() ClearUpdaterParaMisc() NotifyReboot()
附录
A. 错误码定义
| 错误码 | 名称 | 描述 |
|---|---|---|
| 0 | PKG_SUCCESS | 操作成功 |
| -1 | UPDATE_ERROR | 升级错误 |
| 1 | UPDATE_SUCCESS | 升级成功 |
| 2 | UPDATE_CORRUPT | 包损坏或验证失败 |
| 3 | UPDATE_SKIP | 跳过升级 |
| 4 | UPDATE_RETRY | 需要重试 |
| 500 | USCRIPT_INVALID_PARAM | 脚本参数无效 |
| 501 | USCRIPT_INVALID_SCRIPT | 脚本无效 |
B. 配置文件说明
| 配置文件 | 路径 | 描述 |
|---|---|---|
| fstab.updater | /etc/ | 分区配置表 |
| updater_common.cfg | services/etc/ | 通用启动配置 |
| product_cfg.json | /etc/ | 产品配置(电量阈值等) |