1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_FILEMGMT_BACKUP_SERVICE_H
17 #define OHOS_FILEMGMT_BACKUP_SERVICE_H
18 
19 #include <cstdint>
20 #include <mutex>
21 
22 #include "b_jsonutil/b_jsonutil.h"
23 #include "b_json/b_json_clear_data_config.h"
24 #include "b_json/b_json_entity_caps.h"
25 #include "b_json/b_json_service_disposal_config.h"
26 #include "i_service_reverse.h"
27 #include "iremote_stub.h"
28 #include "module_sched/sched_scheduler.h"
29 #include "service_stub.h"
30 #include "svc_session_manager.h"
31 #include "system_ability.h"
32 #include "thread_pool.h"
33 
34 namespace OHOS::FileManagement::Backup {
35 struct ExtensionMutexInfo {
36     std::string bundleName;
37     std::mutex callbackMutex;
ExtensionMutexInfoExtensionMutexInfo38     ExtensionMutexInfo(std::string bundleName_) : bundleName(bundleName_) {};
39 };
40 
41 struct BundleTaskInfo {
42     std::string reportTime;
43     ErrCode errCode;
44 };
45 
46 class Service : public SystemAbility, public ServiceStub, protected NoCopyable {
47     DECLARE_SYSTEM_ABILITY(Service);
48 
49     // 以下都是IPC接口
50 public:
51     ErrCode InitRestoreSession(sptr<IServiceReverse> remote) override;
52     ErrCode InitBackupSession(sptr<IServiceReverse> remote) override;
53     ErrCode Start() override;
54     UniqueFd GetLocalCapabilities() override;
55     ErrCode PublishFile(const BFileInfo &fileInfo) override;
56     ErrCode AppFileReady(const std::string &fileName, UniqueFd fd, int32_t errCode) override;
57     ErrCode AppDone(ErrCode errCode) override;
58     ErrCode ServiceResultReport(const std::string restoreRetInfo,
59         BackupRestoreScenario sennario, ErrCode errCode) override;
60     ErrCode GetFileHandle(const std::string &bundleName, const std::string &fileName) override;
61     ErrCode AppendBundlesRestoreSession(UniqueFd fd,
62                                         const std::vector<BundleName> &bundleNames,
63                                         const std::vector<std::string> &bundleInfos,
64                                         RestoreTypeEnum restoreType = RestoreTypeEnum::RESTORE_DATA_WAIT_SEND,
65                                         int32_t userId = DEFAULT_INVAL_VALUE) override;
66     ErrCode AppendBundlesRestoreSession(UniqueFd fd,
67                                         const std::vector<BundleName> &bundleNames,
68                                         RestoreTypeEnum restoreType = RestoreTypeEnum::RESTORE_DATA_WAIT_SEND,
69                                         int32_t userId = DEFAULT_INVAL_VALUE) override;
70     ErrCode AppendBundlesBackupSession(const std::vector<BundleName> &bundleNames) override;
71     ErrCode AppendBundlesDetailsBackupSession(const std::vector<BundleName> &bundleNames,
72                                               const std::vector<std::string> &bundleInfos) override;
73     ErrCode Finish() override;
74     ErrCode Release() override;
75 
76     UniqueFd GetLocalCapabilitiesIncremental(const std::vector<BIncrementalData> &bundleNames) override;
77     ErrCode GetAppLocalListAndDoIncrementalBackup() override;
78     ErrCode InitIncrementalBackupSession(sptr<IServiceReverse> remote) override;
79     ErrCode AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup) override;
80     ErrCode AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup,
81         const std::vector<std::string> &infos) override;
82 
83     ErrCode PublishIncrementalFile(const BFileInfo &fileInfo) override;
84     ErrCode PublishSAIncrementalFile(const BFileInfo &fileInfo, UniqueFd fd) override;
85     ErrCode AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd,
86         int32_t errCode) override;
87     ErrCode AppIncrementalDone(ErrCode errCode) override;
88     ErrCode GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName) override;
89     ErrCode GetBackupInfo(BundleName &bundleName, std::string &result) override;
90     ErrCode UpdateTimer(BundleName &bundleName, uint32_t timeout, bool &result) override;
91     ErrCode UpdateSendRate(std::string &bundleName, int32_t sendRate, bool &result) override;
92     ErrCode ReportAppProcessInfo(const std::string processInfo, const BackupRestoreScenario sennario) override;
93     ErrCode StartExtTimer(bool &isExtStart) override;
94     ErrCode StartFwkTimer(bool &isFwkStart) override;
95 
96     ErrCode SAResultReport(const std::string bundleName, const std::string resultInfo,
97                            const ErrCode errCode, const BackupRestoreScenario sennario);
98     void StartGetFdTask(std::string bundleName, wptr<Service> ptr);
99 
100     // 以下都是非IPC接口
101 public:
102     void OnStart() override;
103     void OnStop() override;
104     void StopAll(const wptr<IRemoteObject> &obj, bool force = false);
105     int Dump(int fd, const std::vector<std::u16string> &args) override;
106 
107     /**
108      * @brief 执行启动 backup extension
109      *
110      * @param bundleName
111      * @return ErrCode
112      */
113     virtual ErrCode LaunchBackupExtension(const BundleName &bundleName);
114 
115     /**
116      * @brief 执行启动 backup sa extension
117      *
118      * @param bundleName
119      * @return ErrCode
120      */
121     ErrCode LaunchBackupSAExtension(const BundleName &bundleName);
122 
123     /**
124      * @brief backup extension died
125      *
126      * @param bundleName 应用名称
127      */
128     void OnBackupExtensionDied(const std::string &&bundleName, bool isSecondCalled = false);
129 
130     /**
131      * @brief extension启动连接成功
132      *
133      * @param bundleName 应用名称
134      */
135     void ExtConnectDone(std::string bundleName);
136 
137     /**
138      * @brief extension启动连接失败
139      *
140      * @param bundleName 应用名称
141      */
142     void ExtConnectFailed(const std::string &bundleName, ErrCode ret);
143 
144     /**
145      * @brief 执行backup extension 备份恢复流程
146      *
147      * @param bundleName 应用名称
148      */
149     virtual void ExtStart(const std::string &bundleName);
150 
151     /**
152      * @brief 备份恢复开始,设置处置位
153      *
154      * @param bundleName 应用名称
155      *
156      */
157     void SendStartAppGalleryNotify(const std::string &bundleName);
158 
159     /**
160      * @brief 备份恢复结束,清理处置位
161      *
162      * @param bundleName 应用名称
163      *
164      */
165     void SendEndAppGalleryNotify(const std::string &bundleName);
166 
167     /**
168      * @brief 备份恢复异常结束,清理处置位
169      *
170      */
171     void SendErrAppGalleryNotify();
172 
173     /**
174      * @brief SA开始时,清理配置文件中的处置位
175      *
176      */
177     void ClearDisposalOnSaStart();
178 
179     /**
180      * @brief 备份恢复全部结束,删除配置文件
181      *
182      *
183      */
184     void DeleteDisConfigFile();
185 
186     /**
187      * @brief 尝试清理处置
188      *
189      * @param bundleName 应用名称
190      *
191      */
192     void TryToClearDispose(const BundleName &bundleName);
193 
194     /**
195      * @brief 结束会话删除session,卸载服务
196      *
197      */
198     void SessionDeactive();
199 
200     /**
201      * @brief 构造拉起应用所需的want
202      *
203      * @param bundleName 应用名称
204      *
205      */
206     AAFwk::Want CreateConnectWant (BundleName &bundleName);
207 
208     /**
209      * @brief SA backup回调
210      *
211      * @param bundleName 应用名称
212      * @param fd 备份数据
213      * @param result SA备份的结果(异常)
214      * @param errCode backup的错误
215      *
216      */
217     void OnSABackup(const std::string &bundleName, const int &fd, const std::string &result, const ErrCode &errCode);
218 
219     /**
220      * @brief SA restore回调
221      *
222      * @param bundleName 应用名称
223      * @param result SA恢复的结果(异常)
224      * @param errCode restore的错误
225      *
226      */
227     void OnSARestore(const std::string &bundleName, const std::string &result, const ErrCode &errCode);
228 
229     /**
230      * @brief GetBackupInfo extension成功回调
231      *
232      * @param obj 当前对象
233      * @param bundleName 应用名称
234      *
235      */
236     std::function<void(const std::string &&)> GetBackupInfoConnectDone(wptr<Service> obj, std::string &bundleName);
237 
238     /**
239      * @brief GetBackupInfo extension死亡回调
240      *
241      * @param obj 当前对象
242      * @param bundleName 应用名称
243      *
244      */
245     std::function<void(const std::string &&, bool)> GetBackupInfoConnectDied(
246         wptr<Service> obj, std::string &bundleName);
247 
248     /**
249      * @brief timeout callback
250      *
251      * @param ptr 当前对象
252      * @param bundleName 应用名称
253      */
254     std::function<void()> TimeOutCallback(wptr<Service> ptr, std::string bundleName);
255 
256     /**
257      * @brief do timeout
258      *
259      * @param ptr 当前对象
260      * @param bundleName 应用名称
261      */
262     void DoTimeout(wptr<Service> ptr, std::string bundleName);
263 
264     /**
265      * @brief 清理残留数据
266      *
267      * @param bundleName 应用名称
268      *
269      */
270     ErrCode ClearResidualBundleData(const std::string &bundleName);
271 
272     /**
273      * @brief 添加清理记录
274      *
275      * @param bundleName 应用名称
276      *
277      */
278     void AddClearBundleRecord(const std::string &bundleName);
279 
280     /**
281      * @brief 删除清理记录
282      *
283      * @param bundleName 应用名称
284      *
285      */
286     void DelClearBundleRecord(const std::vector<std::string> &bundleNames);
287 
288     /**
289      * @brief 获取extension锁
290      *
291      * @param bundleName 应用名称
292      *
293      */
294     std::shared_ptr<ExtensionMutexInfo> GetExtensionMutex(const BundleName &bundleName);
295 
296     /**
297      * @brief 清理extension锁
298      *
299      * @param bundleName 应用名称
300      *
301      */
302     void RemoveExtensionMutex(const BundleName &bundleName);
303     void StartRunningTimer(const std::string &bundleName);
304 public:
305     explicit Service(int32_t saID, bool runOnCreate = false) : SystemAbility(saID, runOnCreate)
306     {
307         threadPool_.Start(BConstants::EXTENSION_THREAD_POOL_COUNT);
308         session_ = sptr<SvcSessionManager>(new SvcSessionManager(wptr(this)));
309         disposal_ = make_shared<BJsonDisposalConfig>();
310         clearRecorder_ = make_shared<BJsonClearDataConfig>();
311         sched_ = sptr(new SchedScheduler(wptr(this), wptr(session_)));
312     };
~Service()313     ~Service() override
314     {
315         threadPool_.Stop();
316     };
317 
318 private:
319     /**
320      * @brief 验证调用者
321      *
322      */
323     void VerifyCaller();
324 
325     /**
326      * @brief 验证调用者
327      *
328      * @param scenario Scenario状态
329      */
330     void VerifyCaller(IServiceReverse::Scenario scenario);
331 
332     /**
333      * @brief 验证调用者并返回名称
334      *
335      * @return std::string
336      */
337     std::string VerifyCallerAndGetCallerName();
338 
339     /**
340      * @brief 清除Session Sched相关资源
341      *
342      * @param bundleName 应用名称
343      */
344     void ClearSessionAndSchedInfo(const std::string &bundleName);
345 
346     /**
347      * @brief 整个备份恢复流程结束
348      *
349      * @param errCode 错误码
350      */
351     void OnAllBundlesFinished(ErrCode errCode);
352 
353     /**
354      * @brief 执行调度器
355      *
356      */
357     void OnStartSched();
358 
359     /**
360      * @brief 通知客户端程序扩展能力处理结果
361      *
362      * @param bundleName 应用名称
363      *
364      */
365     void NoticeClientFinish(const std::string &bundleName, ErrCode errCode);
366 
367     /**
368      * @brief 处理有依赖的应用恢复
369      *
370      * @param bundleName 应用名称
371      *
372      */
373     void HandleRestoreDepsBundle(const std::string &bundleName);
374 
375     /**
376      * @brief 增量备份恢复逻辑处理
377      *
378      * @param bundleName
379      * @return true
380      * @return false
381      */
382     bool IncrementalBackup(const std::string &bundleName);
383 
384     /**
385      * @brief extension连接断开
386      *
387      * @param bundleName
388      */
389     void ExtConnectDied(const std::string &bundleName);
390 
391     /**
392      * @brief 设置当前session的关键信息
393      *
394      * @param restoreBundleInfos 待恢复的应用
395      * @param restoreBundleNames 待恢复的应用包信息
396      * @param bundleNameDetailMap bundle和detail的对应关系
397      * @param isClearDataFlags 清理数据标志集合
398      * @param restoreType 任务类型
399      */
400     void SetCurrentSessProperties(std::vector<BJsonEntityCaps::BundleInfo> &restoreBundleInfos,
401         std::vector<std::string> &restoreBundleNames,
402         std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> &bundleNameDetailMap,
403         std::map<std::string, bool> &isClearDataFlags, RestoreTypeEnum restoreType);
404 
405     /**
406      * @brief set session info
407      *
408      * @param restoreBundleInfos: bundles to be restored
409      * @param restoreBundleNames: bundles info to be restored
410      * @param restoreType: retore type
411      */
412     void SetCurrentSessProperties(std::vector<BJsonEntityCaps::BundleInfo> &restoreBundleInfos,
413         std::vector<std::string> &restoreBundleNames, RestoreTypeEnum restoreType);
414 
415     void SetCurrentSessProperties(BJsonEntityCaps::BundleInfo &info, std::map<std::string, bool> &isClearDataFlags,
416         const std::string &bundleNameIndexInfo);
417 
418     /**
419      * @brief add useridinfo to  current backup session
420      *
421      * @param bundleNames: bundleNames list
422      * @param userId: userId
423      * @param backupBundleInfos: backupBundleInfos
424      * @param isIncBackup: isIncBackup
425      *
426      */
427     void SetCurrentBackupSessProperties(const std::vector<std::string> &bundleNames, int32_t userId,
428         std::vector<BJsonEntityCaps::BundleInfo> &backupBundleInfos, bool isIncBackup);
429 
430     /**
431      * @brief send userid to app
432      *
433      * @param bundleName: bundleName
434      * @param userId: userId
435      *
436      */
437     void SendUserIdToApp(std::string &bundleName, int32_t userId);
438 
439     /**
440      * @brief 通知权限模块
441      *
442      * @param bundleName 包名称
443      *
444     */
445     void NotifyCloneBundleFinish(std::string bundleName, const BackupRestoreScenario sennario);
446 
447     /**
448      * @brief SA 备份恢复结束
449      *
450      * @param bundleName SAID
451      *
452      * @return ErrCode OK if saDone, otherwise saDone failed.
453     */
454     ErrCode SADone(const ErrCode errCode, std::string bundleName);
455 
456     /**
457      * @brief SA备份恢复入口
458      *
459      * @param bundleName SAID
460      *
461      * @return ErrCode OK if backup sa, otherwise backup sa failed.
462     */
463     ErrCode BackupSA(std::string bundleName);
464 
465     /**
466      * @brief 执行通知调用方
467      *
468      * @param errCode 错误码
469      * @param callerName 业务调用方
470      *
471      */
472     void NotifyCallerCurAppDone(ErrCode errCode, const std::string &callerName);
473 
474     /**
475      * @brief 执行通知调用方
476      *
477      * @param errCode 错误码
478      * @param callerName 业务调用方
479      *
480      */
481     void NotifyCallerCurAppIncrementDone(ErrCode errCode, const std::string &callerName);
482 
483     void SetWant(AAFwk::Want &want, const BundleName &bundleName, const BConstants::ExtensionAction &action);
484 
485     /**
486      * @brief GetBackupInfo 任务执行
487      *
488      * @param bundleName 应用名称
489      * @param result 业务结果出参
490      *
491      */
492     ErrCode GetBackupInfoCmdHandle(BundleName &bundleName, std::string &result);
493 
494     /**
495      * @brief 添加需要清理的Session
496      *
497      * @param bundleNames 需要清理的应用包信息
498      *
499      */
500     ErrCode AppendBundlesClearSession(const std::vector<BundleName> &bundleNames);
501 
502     void ReportOnExtConnectFailed(const IServiceReverse::Scenario scenario,
503         const std::string &bundleName, const ErrCode ret);
504 
505     void ReleaseOnException();
506 
507     vector<BIncrementalData> MakeDetailList(const vector<BundleName> &bundleNames);
508 
509     vector<string> GetBundleNameByDetails(const std::vector<BIncrementalData> &bundlesToBackup);
510 
511     void HandleCurGroupBackupInfos(vector<BJsonEntityCaps::BundleInfo> &bundleInfos,
512         std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> &bundleNameDetailMap,
513         std::map<std::string, bool> &isClearDataFlags);
514 
515     void HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> &bundleInfos,
516         std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> &bundleNameDetailMap,
517         std::map<std::string, bool> &isClearDataFlags);
518 
519     void TimeoutRadarReport(IServiceReverse::Scenario scenario, std::string &bundleName);
520 
521     void CreateDirIfNotExist(const std::string &path);
522 
523     void OnBundleStarted(BError error, sptr<SvcSessionManager> session, const BundleName &bundleName);
524 
525     void HandleExceptionOnAppendBundles(sptr<SvcSessionManager> session, const vector<BundleName> &appendBundleNames,
526         const vector<BundleName> &restoreBundleNames);
527 
528     void BundleBeginRadarReport(const std::string &bundleName, const ErrCode errCode,
529         const IServiceReverse::Scenario scenario);
530 
531     void BundleEndRadarReport(const std::string &bundleName, const ErrCode errCode,
532         const IServiceReverse::Scenario scenario);
533 
534     void FileReadyRadarReport(const std::string &bundleName, const std::string &fileName, const ErrCode errCode,
535         const IServiceReverse::Scenario scenario);
536 
537     void ExtensionConnectFailRadarReport(const std::string &bundleName, const ErrCode errCode,
538         const IServiceReverse::Scenario scenario);
539 
540     void UpdateFailedBundles(const std::string &bundleName, BundleTaskInfo taskInfo);
541 
542     void ClearFailedBundles();
543     std::vector<std::string> GetSupportBackupBundleNames(vector<BJsonEntityCaps::BundleInfo> &bundleInfos,
544         bool isIncBackup, const vector<std::string> &srcBundleNames);
545     void HandleNotSupportBundleNames(const std::vector<std::string> &srcBundleNames,
546         std::vector<std::string> &supportBundleNames, bool isIncBackup);
547     void SetBundleIncDataInfo(const std::vector<BIncrementalData> &bundlesToBackup,
548         std::vector<std::string> &supportBundleNames);
549 private:
550     static sptr<Service> instance_;
551     static std::mutex instanceLock_;
552     std::mutex getBackupInfoProcLock_;
553     std::mutex getBackupInfoSyncLock_;
554     std::condition_variable getBackupInfoCondition_;
555     static inline std::atomic<uint32_t> seed {1};
556     std::atomic<bool> isConnectDied_ {false};
557     std::atomic<bool> isCleanService_ {false};
558 
559     sptr<SvcSessionManager> session_;
560     sptr<SchedScheduler> sched_;
561     std::shared_ptr<BJsonDisposalConfig> disposal_;
562     std::shared_ptr<BJsonClearDataConfig> clearRecorder_;
563     std::atomic<bool> isInRelease_ {false};
564     std::atomic<bool> isRmConfigFile_ {true};
565     friend class ServiceTest;
566 
567     OHOS::ThreadPool threadPool_;
568     std::mutex extensionMutexLock_;
569     std::mutex failedBundlesLock_;
570 public:
571     std::map<BundleName, std::shared_ptr<ExtensionMutexInfo>> backupExtMutexMap_;
572     std::map<BundleName, BundleTaskInfo> failedBundles_;
573     std::atomic<uint32_t> successBundlesNum_ {0};
574 };
575 } // namespace OHOS::FileManagement::Backup
576 
577 #endif // OHOS_FILEMGMT_BACKUP_SERVICE_H