应用文件服务模块架构
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类
cpp
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类
cpp
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类
cpp
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类
cpp
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类
cpp
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结构体
cpp
struct FileShareInfo {
string providerBundleName_; // 提供者包名
string targetBundleName_; // 目标包名
string providerLowerPath_; // 提供者底层路径
string providerSandboxPath_; // 提供者沙箱路径
vector<string> sharePath_; // 分享路径列表
string currentUid_; // 当前用户ID
ShareFileType type_; // 文件类型
ino_t stIno_; // 文件节点号
};
FileShare_PolicyInfo结构体
cpp
typedef struct FileShare_PolicyInfo {
char *uri; // URI字符串
unsigned int length; // URI长度
unsigned int operationMode; // 操作模式(读/写)
} FileShare_PolicyInfo;
FileShare_PolicyErrorResult结构体
cpp
typedef struct FileShare_PolicyErrorResult {
char *uri; // 失败的URI
FileShare_PolicyErrorCode code; // 错误码
char *message; // 错误信息
} FileShare_PolicyErrorResult;
2.3 继承与多态
继承关系:
Service
继承自SystemAbility
和ServiceStub
FileUri
包含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 公共接口
文件分享接口:
创建分享文件
cpp
int32_t CreateShareFile(const vector<string> &uriList,
uint32_t tokenId,
uint32_t flag,
vector<int32_t> &retList);
- 功能:为指定的URI列表创建文件分享
- 参数 :
uriList
- 要分享的文件URI列表tokenId
- 调用者令牌IDflag
- 分享标志(读/写权限)retList
- 返回结果列表
- 返回值:操作结果码
- 异常处理:URI无效时返回错误码
删除分享文件
cpp
int32_t DeleteShareFile(uint32_t tokenId, const vector<string> &uriList);
- 功能:删除指定的文件分享
- 参数 :
tokenId
- 调用者令牌IDuriList
- 要删除分享的文件URI列表
- 返回值:操作结果码
文件URI接口:
获取文件路径
cpp
std::string GetRealPath();
- 功能:获取文件的真实路径
- 返回值:文件真实路径字符串
检查URI格式
cpp
bool CheckUriFormat(const std::string &uri);
- 功能:检查URI格式是否有效
- 参数 :
uri
- 要检查的URI字符串 - 返回值:true表示有效,false表示无效
NDK接口:
设置持久权限
cpp
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
激活权限
cpp
FileManagement_ErrCode OH_FileShare_ActivatePermission(const FileShare_PolicyInfo *policies,
unsigned int policyNum,
FileShare_PolicyErrorResult **result,
unsigned int *resultNum);
- 功能:激活已授权的URI权限
- 参数:与设置持久权限相同
- 返回值:操作结果码
备份恢复接口:
初始化备份会话
cpp
std::unique_ptr<BSessionBackup> Init(Callbacks callbacks);
- 功能:初始化备份会话
- 参数 :
callbacks
- 回调函数集合 - 返回值:备份会话智能指针
开始备份
cpp
ErrCode Start();
- 功能:开始备份流程
- 返回值:操作结果码
获取本地能力
cpp
UniqueFd GetLocalCapabilities();
- 功能:获取本地备份能力信息
- 返回值:能力信息文件描述符
5.2 数据交换接口
文件分享数据结构:
cpp
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 // 权限未持久化
};
备份恢复数据结构:
cpp
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; // 文件路径
};
回调接口定义:
cpp
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 整体系统架构
硬件层 系统层 服务层 框架层 应用层 本地存储 网络存储 外部存储 存储服务 权限管理 设备管理 包管理 沙箱管理 FileShare
文件分享服务 FileUri
文件URI服务 BackupService
备份恢复服务 SandboxHelper
沙箱管理 JS API NDK API Inner API NAPI 文件管理应用 备份恢复应用 跨设备协作应用
6.2 模块内部架构
系统层 数据层 服务层 接口层 存储服务 权限管理 设备管理 FileShareInfo
分享信息 FileShare_PolicyInfo
权限策略 BSessionBackup
备份会话 沙箱路径映射 FileShare
文件分享服务 FileUri
文件URI服务 Service
备份服务 SandboxHelper
沙箱管理 file_share.h
文件分享接口 file_uri.h
文件URI接口 oh_file_share.h
NDK接口 backup_kit_inner.h
备份接口
6.3 类关系图
FileShare -mapMutex_ mutex +CreateShareFile() : int32_t +DeleteShareFile() : int32_t FileUri -uri_ Uri +GetName() : string +GetPath() : string +GetRealPath() : string +CheckUriFormat() : bool SandboxHelper -mapMutex_ mutex +Encode() : string +Decode() : string +GetPhysicalPath() : int32_t +CheckValidPath() : bool BSessionBackup -deathRecipient_ SvcDeathRecipient +Init() +Start() : ErrCode +AppendBundles() : ErrCode +GetLocalCapabilities() : UniqueFd Service -session_ SvcSessionManager -sched_ SchedScheduler +OnStart() : void +OnStop() : void +InitBackupSession() : ErrCode +PublishFile() : ErrCode +LaunchBackupExtension() : ErrCode FileShareInfo +providerBundleName_ string +targetBundleName_ string +sharePath_ vector<string> +type_ ShareFileType FileShare_PolicyInfo +uri char +length unsigned int +operationMode unsigned int
6.4 状态机转换图
系统启动 OnStart() OnStop() 重启服务 文件分享空闲 备份空闲 恢复空闲 创建分享请求 分享创建成功 删除分享请求 删除完成 备份准备 备份运行 备份完成 清理完成 恢复准备 恢复运行 恢复完成 清理完成 NotStarted Running Exit ShareIdle BackupIdle RestoreIdle ShareCreating ShareActive ShareDeleting BackupPreparing BackupRunning BackupFinished RestorePreparing RestoreRunning RestoreFinished 服务运行状态,可以处理
文件分享、备份恢复等操作 文件分享激活状态,
支持跨设备访问
6.5 接口调用时序图
应用程序 FileShare BackupService SandboxHelper 存储服务 回调函数 CreateShareFile() GetPhysicalPath() 获取物理路径 返回路径 返回路径 创建分享路径 创建成功 返回结果 InitBackupSession() 初始化会话 返回会话 Start() OnBundleStarted() 备份开始回调 OnFileReady() 文件准备回调 OnBundleFinished() 备份完成回调 应用程序 FileShare BackupService SandboxHelper 存储服务 回调函数
7. 总结
应用文件服务模块是OpenHarmony系统中的核心文件管理服务,采用分层架构设计,支持多种文件分享场景和完整的数据备份恢复功能。模块通过统一的URI机制和权限管理,为上层应用提供安全可靠的文件服务能力。
主要特点:
- 统一文件管理:基于URI机制实现统一的文件标识和访问
- 跨设备协作:支持多设备间的文件分享和数据同步
- 安全权限控制:实现细粒度的文件权限管理和持久化
- 完整备份恢复:提供全面的数据备份和恢复解决方案
- 沙箱安全管理:通过沙箱机制确保应用数据安全
技术亮点:
- 采用单例模式管理核心服务
- 通过代理模式封装远程调用
- 使用观察者模式实现事件通知
- 基于策略模式支持多种场景
- 完善的错误处理和异常管理机制
应用场景:
- 应用间文件共享
- 跨设备文件同步
- 数据备份和恢复
- 文件权限管理
- 应用数据迁移