【OpenHarmony】应用文件服务模块架构
应用文件服务模块摘要 应用文件服务模块是OpenHarmony系统中文件管理子系统的核心组件,提供文件分享、URI管理、权限控制等基础功能。该模块采用分层架构设计,包含文件分享、URI解析、沙箱管理等核心类,支持应用间文件共享、跨设备文件同步等场景。核心功能包括: 基于URI的统一文件标识和访问 跨设备文件分享能力 细粒度文件权限控制 数据备份恢复服务 应用沙箱安全管理
应用文件服务模块架构
1. 模块概述
应用文件服务是为应用提供文件分享和管理能力的服务,包含应用间文件分享、跨设备同应用文件分享以及跨设备跨应用文件分享的能力。 当前已具备基于分布式文件系统的跨设备同应用文件分享能力。
源码:https://gitee.com/openharmony/filemanagement_app_file_service
1.1 功能与目标
主要功能:
- 应用间文件分享:为应用提供文件分享和管理能力,支持应用间文件分享
- 跨设备文件分享:支持跨设备同应用文件分享以及跨设备跨应用文件分享
- 文件URI管理:提供统一的文件URI解析和管理功能
- 文件权限管理:实现基于URI的文件权限授权和持久化
- 备份恢复服务:为OpenHarmony设备提供完整的数据备份和恢复解决方案
- 沙箱管理:提供应用沙箱路径解析和安全管理
目标:
- 为OpenHarmony系统提供统一的文件分享和管理能力
- 支持多设备间的文件协作和数据同步
- 提供安全可靠的数据备份和恢复机制
- 实现细粒度的文件权限控制
使用场景:
- 应用间文件共享和传输
- 跨设备文件同步
- 数据备份和恢复
- 文件权限管理
- 应用数据迁移
1.2 系统位置
应用文件服务模块是OpenHarmony系统中文件管理子系统的重要组成部分,属于核心基础服务模块。
系统位置:
- 位于系统服务层,为上层应用提供文件分享和管理能力
- 作为文件管理子系统的核心模块,负责文件权限和分享管理
- 与存储服务、权限管理、设备管理等系统模块紧密协作
模块关系:
- 依赖存储服务模块进行文件系统操作
- 依赖权限管理模块进行权限验证
- 依赖设备管理模块进行跨设备通信
- 为上层应用框架提供文件服务接口
1.3 设计思路与模式
设计思路:
- 采用分层架构设计,将接口层、服务层、数据层分离
- 基于URI机制实现统一的文件标识和访问
- 支持多种文件分享场景的统一管理
- 实现异步事件驱动和回调机制
设计模式:
- 单例模式:Service等核心服务采用单例模式
- 代理模式:通过代理对象封装远程服务调用
- 观察者模式:文件状态变化通过回调机制通知
- 策略模式:不同文件类型采用不同的处理策略
- 工厂模式:会话管理和连接对象的创建
2. 模块结构
2.1 源文件与头文件
主要头文件:
file_share.h- 文件分享核心接口file_uri.h- 文件URI管理接口oh_file_share.h- NDK文件分享接口oh_file_uri.h- NDK文件URI接口backup_kit_inner.h- 备份恢复内部接口sandbox_helper.h- 沙箱管理辅助类service.h- 备份服务主服务类
主要源文件:
file_share.cpp- 文件分享实现file_uri.cpp- 文件URI实现oh_file_share.cpp- NDK文件分享实现oh_file_uri.cpp- NDK文件URI实现service.cpp- 备份服务实现sandbox_helper.cpp- 沙箱管理实现
2.2 类、结构体、函数与方法
核心类:
FileShare类
class FileShare {
public:
static int32_t CreateShareFile(const vector<string> &uriList,
uint32_t tokenId,
uint32_t flag,
vector<int32_t> &retList);
static int32_t DeleteShareFile(uint32_t tokenId, const vector<string> &uriList);
private:
static mutex mapMutex_;
};
FileUri类
class FileUri {
public:
std::string GetName();
std::string GetPath();
std::string GetRealPath();
std::string GetRealPathBySA(const std::string &targetBundleName = "");
std::string ToString();
std::string GetFullDirectoryUri();
bool IsRemoteUri();
bool CheckUriFormat(const std::string &uri);
explicit FileUri(const std::string &uriOrPath);
~FileUri() = default;
private:
Uri uri_;
};
SandboxHelper类
class SandboxHelper {
public:
static std::string Encode(const std::string &uri);
static std::string Decode(const std::string &uri);
static bool CheckValidPath(const std::string &filePath);
static int32_t GetMediaSharePath(const std::vector<std::string> &fileUris,
std::vector<std::string> &physicalPaths);
static int32_t GetPhysicalPath(const std::string &fileUri, const std::string &userId,
std::string &physicalPath);
static int32_t GetPhysicalDir(const std::string &fileUri, const std::string &userId,
std::string &physicalDir);
static int32_t GetBackupPhysicalPath(const std::string &fileUri, const std::string &userId,
std::string &physicalPath);
static bool IsValidPath(const std::string &path);
static void GetNetworkIdFromUri(const std::string &fileUri, std::string &networkId);
static std::string GetLowerDir(std::string &lowerPathHead, const std::string &userId,
const std::string &bundleName, const std::string &networkId);
private:
static std::mutex mapMutex_;
static bool GetSandboxPathMap();
static bool GetBackupSandboxPathMap();
static void* libMediaHandle_;
};
BSessionBackup类
class BSessionBackup {
public:
struct Callbacks {
std::function<void(const BFileInfo &, UniqueFd, ErrCode)> onFileReady;
std::function<void(ErrCode, const BundleName)> onBundleStarted;
std::function<void(ErrCode, const BundleName)> onBundleFinished;
std::function<void(ErrCode)> onAllBundlesFinished;
std::function<void(const std::string, const std::string)> onResultReport;
std::function<void()> onBackupServiceDied;
std::function<void(const std::string, const std::string)> onProcess;
std::function<void(const std::string)> onBackupSizeReport;
};
static std::unique_ptr<BSessionBackup> Init(Callbacks callbacks);
static std::unique_ptr<BSessionBackup> Init(Callbacks callbacks, std::string &errMsg, ErrCode &errCode);
UniqueFd GetLocalCapabilities();
ErrCode GetBackupDataSize(bool isPreciseScan, std::vector<BIncrementalData> bundleNameList);
ErrCode AppendBundles(std::vector<BundleName> bundlesToBackup);
ErrCode AppendBundles(std::vector<BundleName> bundlesToBackup, std::vector<std::string> detailInfos);
ErrCode Finish();
ErrCode Start();
ErrCode Release();
ErrCode Cancel(std::string bundleName);
void RegisterBackupServiceDied(std::function<void()> functor);
ErrCode CleanBundleTempDir(const std::string &bundleName);
ErrCode GetCompatibilityInfo(const std::string &bundleName, const std::string &extInfo,
std::string &compatInfo);
private:
sptr<SvcDeathRecipient> deathRecipient_;
};
Service类
class Service : public SystemAbility, public ServiceStub, protected NoCopyable {
public:
// IPC接口
ErrCode InitRestoreSession(const sptr<IServiceReverse>& remote) override;
ErrCode InitBackupSession(const sptr<IServiceReverse>& remote) override;
ErrCode Start() override;
ErrCode GetLocalCapabilities(int& fd) override;
ErrCode PublishFile(const BFileInfo &fileInfo) override;
ErrCode AppFileReady(const std::string &fileName, int fd, int32_t errCode) override;
ErrCode AppDone(ErrCode errCode) override;
ErrCode AppendBundlesBackupSession(const std::vector<BundleName> &bundleNames) override;
ErrCode Finish() override;
ErrCode Release() override;
ErrCode CancelForResult(const std::string& bundleName, int32_t &result) override;
// 非IPC接口
void OnStart() override;
void OnStop() override;
void StopAll(const wptr<IRemoteObject> &obj, bool force = false);
int Dump(int fd, const std::vector<std::u16string> &args) override;
virtual ErrCode LaunchBackupExtension(const BundleName &bundleName);
ErrCode LaunchBackupSAExtension(const BundleName &bundleName);
void OnBackupExtensionDied(const std::string &&bundleName, bool isCleanCalled = false);
void ExtConnectDone(std::string bundleName);
void ExtConnectFailed(const std::string &bundleName, ErrCode ret);
virtual void ExtStart(const std::string &bundleName);
private:
static sptr<Service> instance_;
static std::mutex instanceLock_;
sptr<SvcSessionManager> session_;
sptr<SchedScheduler> sched_;
std::shared_ptr<BJsonDisposalConfig> disposal_;
std::shared_ptr<BJsonClearDataConfig> clearRecorder_;
OHOS::ThreadPool threadPool_;
std::shared_ptr<RadarTotalStatistic> totalStatistic_;
};
核心结构体:
FileShareInfo结构体
struct FileShareInfo {
string providerBundleName_; // 提供者包名
string targetBundleName_; // 目标包名
string providerLowerPath_; // 提供者底层路径
string providerSandboxPath_; // 提供者沙箱路径
vector<string> sharePath_; // 分享路径列表
string currentUid_; // 当前用户ID
ShareFileType type_; // 文件类型
ino_t stIno_; // 文件节点号
};
FileShare_PolicyInfo结构体
typedef struct FileShare_PolicyInfo {
char *uri; // URI字符串
unsigned int length; // URI长度
unsigned int operationMode; // 操作模式(读/写)
} FileShare_PolicyInfo;
FileShare_PolicyErrorResult结构体
typedef struct FileShare_PolicyErrorResult {
char *uri; // 失败的URI
FileShare_PolicyErrorCode code; // 错误码
char *message; // 错误信息
} FileShare_PolicyErrorResult;
2.3 继承与多态
继承关系:
Service继承自SystemAbility和ServiceStubFileUri包含Uri对象进行URI解析- 各种回调类继承自相应的接口基类
多态设计:
- 通过接口抽象实现不同文件类型的统一管理
- 回调机制支持多种事件类型的统一处理
- 策略模式实现不同文件分享场景的动态切换
3. 模块间交互
3.1 交互描述
与系统模块的交互:
- 存储服务:通过StorageService进行文件系统操作
- 权限管理:通过AccessToken进行权限验证
- 设备管理:通过DeviceManager进行跨设备通信
- 包管理:通过BundleManager获取应用信息
- 沙箱管理:通过SandboxManager进行沙箱路径管理
外部库依赖:
- 系统服务:SAMGR、SAFWK等系统框架
- 第三方库:cJSON、OpenSSL、zlib等
- 系统库:libc、pthread等
异步处理机制:
- 使用线程池处理异步任务
- 通过回调机制处理文件操作结果
- 支持多线程并发处理多个文件分享请求
3.2 事件驱动机制
事件类型:
- 文件分享请求事件
- 文件权限变化事件
- 备份恢复进度事件
- 跨设备连接状态变化事件
- 应用生命周期事件
事件处理流程:
- 注册事件监听器
- 接收文件操作或系统事件
- 解析事件参数和上下文
- 执行相应的业务逻辑
- 通知相关回调
4. 状态机转换图
4.1 状态机模型
应用文件服务模块的状态机包含以下主要状态:
服务状态:
STATE_NOT_START- 服务未启动STATE_RUNNING- 服务运行中STATE_EXIT- 服务退出
文件分享状态:
SHARE_IDLE- 空闲状态SHARE_CREATING- 创建分享中SHARE_ACTIVE- 分享激活SHARE_DELETING- 删除分享中
备份恢复状态:
BACKUP_IDLE- 备份空闲BACKUP_PREPARING- 备份准备中BACKUP_RUNNING- 备份运行中BACKUP_FINISHED- 备份完成RESTORE_IDLE- 恢复空闲RESTORE_PREPARING- 恢复准备中RESTORE_RUNNING- 恢复运行中RESTORE_FINISHED- 恢复完成
4.2 状态切换规则
服务启动流程:
- 系统启动时,服务处于
STATE_NOT_START状态 - 收到启动事件后,进入
STATE_RUNNING状态 - 初始化各个子模块和连接管理器
- 注册到系统能力管理器
文件分享状态转换:
- 收到分享请求,从
SHARE_IDLE进入SHARE_CREATING状态 - 创建分享成功,进入
SHARE_ACTIVE状态 - 收到删除请求,进入
SHARE_DELETING状态 - 删除完成,回到
SHARE_IDLE状态
备份恢复状态转换:
- 收到备份请求,从
BACKUP_IDLE进入BACKUP_PREPARING状态 - 准备完成,进入
BACKUP_RUNNING状态 - 备份完成,进入
BACKUP_FINISHED状态 - 清理资源后,回到
BACKUP_IDLE状态
事件触发条件:
- 文件分享请求
- 权限变化事件
- 备份恢复任务
- 跨设备连接状态变化
- 应用生命周期变化
5. 接口设计
5.1 公共接口
文件分享接口:
创建分享文件
int32_t CreateShareFile(const vector<string> &uriList,
uint32_t tokenId,
uint32_t flag,
vector<int32_t> &retList);
- 功能:为指定的URI列表创建文件分享
- 参数:
uriList- 要分享的文件URI列表tokenId- 调用者令牌IDflag- 分享标志(读/写权限)retList- 返回结果列表
- 返回值:操作结果码
- 异常处理:URI无效时返回错误码
删除分享文件
int32_t DeleteShareFile(uint32_t tokenId, const vector<string> &uriList);
- 功能:删除指定的文件分享
- 参数:
tokenId- 调用者令牌IDuriList- 要删除分享的文件URI列表
- 返回值:操作结果码
文件URI接口:
获取文件路径
std::string GetRealPath();
- 功能:获取文件的真实路径
- 返回值:文件真实路径字符串
检查URI格式
bool CheckUriFormat(const std::string &uri);
- 功能:检查URI格式是否有效
- 参数:
uri- 要检查的URI字符串 - 返回值:true表示有效,false表示无效
NDK接口:
设置持久权限
FileManagement_ErrCode OH_FileShare_PersistPermission(const FileShare_PolicyInfo *policies,
unsigned int policyNum,
FileShare_PolicyErrorResult **result,
unsigned int *resultNum);
- 功能:为URI设置持久权限
- 参数:
policies- 权限策略信息数组policyNum- 策略数量result- 错误结果输出resultNum- 错误结果数量
- 返回值:操作结果码
- 权限要求:
ohos.permission.FILE_ACCESS_PERSIST
激活权限
FileManagement_ErrCode OH_FileShare_ActivatePermission(const FileShare_PolicyInfo *policies,
unsigned int policyNum,
FileShare_PolicyErrorResult **result,
unsigned int *resultNum);
- 功能:激活已授权的URI权限
- 参数:与设置持久权限相同
- 返回值:操作结果码
备份恢复接口:
初始化备份会话
std::unique_ptr<BSessionBackup> Init(Callbacks callbacks);
- 功能:初始化备份会话
- 参数:
callbacks- 回调函数集合 - 返回值:备份会话智能指针
开始备份
ErrCode Start();
- 功能:开始备份流程
- 返回值:操作结果码
获取本地能力
UniqueFd GetLocalCapabilities();
- 功能:获取本地备份能力信息
- 返回值:能力信息文件描述符
5.2 数据交换接口
文件分享数据结构:
enum ShareFileType {
DIR_TYPE = 0, // 目录类型
FILE_TYPE = 1 // 文件类型
};
enum FileShare_OperationMode {
READ_MODE = 1 << 0, // 读权限
WRITE_MODE = 1 << 1 // 写权限
};
enum FileShare_PolicyErrorCode {
PERSISTENCE_FORBIDDEN = 1, // 禁止持久化
INVALID_MODE = 2, // 无效模式
INVALID_PATH = 3, // 无效路径
PERMISSION_NOT_PERSISTED = 4 // 权限未持久化
};
备份恢复数据结构:
enum ErrCode {
ERR_OK = 0, // 成功
ERR_INVALID_PARAM = 401, // 参数错误
ERR_PERMISSION_DENIED = 201, // 权限不足
ERR_SERVICE_UNAVAILABLE = 3301000 // 服务不可用
};
enum BackupRestoreScenario {
BACKUP_SCENARIO = 0, // 备份场景
RESTORE_SCENARIO = 1 // 恢复场景
};
struct BFileInfo {
std::string fileName; // 文件名
std::string bundleName; // 包名
int64_t fileSize; // 文件大小
std::string filePath; // 文件路径
};
回调接口定义:
class IRemoteDevStaCallback : public IRemoteBroker {
public:
virtual void OnDeviceStatusChanged(const Data& data) = 0;
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.msdp.IRemoteDevStaCallback");
};
class IBackupCallback {
public:
virtual void OnBackupProgress(int32_t progress) = 0;
virtual void OnBackupComplete(ErrCode result) = 0;
virtual void OnBackupError(ErrCode error) = 0;
};
6. 系统架构图
6.1 整体系统架构
6.2 模块内部架构
6.3 类关系图
6.4 状态机转换图
6.5 接口调用时序图
7. 总结
应用文件服务模块是OpenHarmony系统中的核心文件管理服务,采用分层架构设计,支持多种文件分享场景和完整的数据备份恢复功能。模块通过统一的URI机制和权限管理,为上层应用提供安全可靠的文件服务能力。
主要特点:
- 统一文件管理:基于URI机制实现统一的文件标识和访问
- 跨设备协作:支持多设备间的文件分享和数据同步
- 安全权限控制:实现细粒度的文件权限管理和持久化
- 完整备份恢复:提供全面的数据备份和恢复解决方案
- 沙箱安全管理:通过沙箱机制确保应用数据安全
技术亮点:
- 采用单例模式管理核心服务
- 通过代理模式封装远程调用
- 使用观察者模式实现事件通知
- 基于策略模式支持多种场景
- 完善的错误处理和异常管理机制
应用场景:
- 应用间文件共享
- 跨设备文件同步
- 数据备份和恢复
- 文件权限管理
- 应用数据迁移
更多推荐
所有评论(0)