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_BACKUP_EXT_EXTENSION_H
17 #define OHOS_FILEMGMT_BACKUP_BACKUP_EXT_EXTENSION_H
18 
19 #include <chrono>
20 #include <shared_mutex>
21 #include <string>
22 #include <vector>
23 #include <tuple>
24 
25 #include <sys/stat.h>
26 
27 #include "b_json/b_json_entity_extension_config.h"
28 #include "b_json/b_json_entity_ext_manage.h"
29 #include "b_json/b_report_entity.h"
30 #include "b_radar/b_radar.h"
31 #include "ext_backup_js.h"
32 #include "ext_extension_stub.h"
33 #include "i_service.h"
34 #include "tar_file.h"
35 #include "thread_pool.h"
36 #include "timer.h"
37 #include "unique_fd.h"
38 #include "untar_file.h"
39 
40 namespace OHOS::FileManagement::Backup {
41 using CompareFilesResult = tuple<map<string, struct ReportFileInfo>,
42                                  map<string, struct ReportFileInfo>,
43                                  map<string, struct ReportFileInfo>>;
44 class BackupExtExtension : public ExtExtensionStub {
45 public:
46     UniqueFd GetFileHandle(const std::string &fileName, int32_t &errCode) override;
47     ErrCode HandleClear() override;
48     ErrCode PublishFile(const std::string &fileName) override;
49     ErrCode HandleBackup(bool isClearData) override;
50     ErrCode HandleRestore(bool isClearData) override;
51     ErrCode GetIncrementalFileHandle(const std::string &fileName) override;
52     ErrCode PublishIncrementalFile(const std::string &fileName) override;
53     ErrCode HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) override;
54     ErrCode IncrementalOnBackup(bool isClearData) override;
55     std::tuple<UniqueFd, UniqueFd> GetIncrementalBackupFileHandle() override;
56     ErrCode GetBackupInfo(std::string &result) override;
57     ErrCode UpdateFdSendRate(std::string &bundleName, int32_t sendRate) override;
58     void AsyncTaskRestoreForUpgrade(void);
59     void ExtClear(void);
60     void AsyncTaskIncrementalRestoreForUpgrade(void);
61     ErrCode User0OnBackup() override;
62 
63 public:
64     explicit BackupExtExtension(const std::shared_ptr<Backup::ExtBackup> &extension,
65         const std::string &bundleName) : extension_(extension)
66     {
67         if (extension_ != nullptr) {
68             extension_->SetBackupExtExtension(this);
69         }
70         bundleName_ = bundleName;
71         threadPool_.Start(BConstants::EXTENSION_THREAD_POOL_COUNT);
72         onProcessTaskPool_.Start(BConstants::EXTENSION_THREAD_POOL_COUNT);
73         reportOnProcessRetPool_.Start(BConstants::EXTENSION_THREAD_POOL_COUNT);
74         SetStagingPathProperties();
75     }
76     ~BackupExtExtension()
77     {
78         onProcessTimeoutTimer_.Shutdown();
79         threadPool_.Stop();
80         onProcessTaskPool_.Stop();
81         reportOnProcessRetPool_.Stop();
82         if (callJsOnProcessThread_.joinable()) {
83             callJsOnProcessThread_.join();
84         }
85     }
86 
87 private:
88     /**
89      * @brief verify caller uid
90      *
91      */
92     void VerifyCaller();
93 
94     /**
95      * @brief backup
96      *
97      * @param usrConfig user configure
98      */
99     int DoBackup(const BJsonEntityExtensionConfig &usrConfig);
100 
101     /**
102      * @brief restore
103      *
104      * @param fileName name of the file that to be untar
105      */
106     int DoRestore(const string &fileName, const off_t fileSize);
107 
108     /**
109      * @brief incremental restore
110      *
111      */
112     int DoIncrementalRestore();
113 
114     /** @brief clear backup restore data */
115     void DoClear();
116 
117     /**
118      * @brief extension backup restore is done
119      *
120      * @param errCode
121      */
122     void AppDone(ErrCode errCode);
123 
124     /**
125      * @brief extension backup restore is done
126      *
127      * @param restoreRetInfo app restore reportInfo
128      */
129     void AppResultReport(const std::string restoreRetInfo, BackupRestoreScenario scenario,
130         ErrCode errCode = 0);
131 
132     /**
133      * @brief extension process Info
134      *
135      * @param restoreRetInfo app processInfo
136      * @param scenario backup or restore
137      */
138     void ReportAppProcessInfo(const std::string processInfo, BackupRestoreScenario scenario);
139 
140     /**
141      * @brief Executing Backup Tasks Asynchronously
142      *
143      * @param extAction action
144      *
145      * @param config user configure
146      */
147     void AsyncTaskBackup(const std::string config);
148 
149     /**
150      * @brief Executing Restoration Tasks Asynchronously
151      *
152      */
153     void AsyncTaskRestore(std::set<std::string> fileSet, const std::vector<ExtManageInfo> extManageInfo);
154 
155     /**
156      * @brief Executing Incremental Restoration Tasks Asynchronously
157      *
158      */
159     void AsyncTaskIncrementalRestore();
160 
161     /**
162      * @brief Executing Incremental Restoration Tasks Asynchronously for special clone & cloud
163      *
164      */
165     void AsyncTaskIncreRestoreSpecialVersion();
166 
167     void AsyncTaskOnBackup();
168 
169     bool IfAllowToBackupRestore();
170 
171     void AsyncTaskUser0Backup();
172 
173     void DoUser0Backup(const BJsonEntityExtensionConfig &usrConfig);
174 
175     int User0DoBackup(const BJsonEntityExtensionConfig &usrConfig);
176 
177     int DoIncrementalBackup(const std::vector<struct ReportFileInfo> &allFiles,
178                             const std::vector<struct ReportFileInfo> &smallFiles,
179                             const std::vector<struct ReportFileInfo> &bigFiles);
180 
181     void CompareFiles(UniqueFd incrementalFd,
182                       UniqueFd manifestFd,
183                       vector<struct ReportFileInfo> &allFiles,
184                       vector<struct ReportFileInfo> &smallFiles,
185                       vector<struct ReportFileInfo> &bigFiles);
186 
187     void AsyncTaskDoIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd);
188     void AsyncTaskOnIncrementalBackup();
189     int DoIncrementalBackupTask(UniqueFd incrementalFd, UniqueFd manifestFd);
190     ErrCode IncrementalBigFileReady(TarMap &pkgInfo, const vector<struct ReportFileInfo> &bigInfos,
191         sptr<IService> proxy);
192     ErrCode BigFileReady(TarMap &bigFileInfo, sptr<IService> proxy);
193     void WaitToSendFd(std::chrono::system_clock::time_point &startTime, int &fdSendNum);
194     void RefreshTimeInfo(std::chrono::system_clock::time_point &startTime, int &fdSendNum);
195     void IncrementalPacket(const vector<struct ReportFileInfo> &infos, TarMap &tar, sptr<IService> proxy);
196     void DoPacket(const map<string, size_t> &srcFiles, TarMap &tar, sptr<IService> proxy);
197     void CheckTmpDirFileInfos(bool isSpecialVersion = false);
198     std::map<std::string, off_t> GetIdxFileInfos(bool isSpecialVersion = false);
199     tuple<bool, vector<string>> CheckRestoreFileInfos();
200     /**
201      * @brief extension incremental backup restore is done
202      *
203      * @param errCode
204      */
205     void AppIncrementalDone(ErrCode errCode);
206 
207     /**
208      * @brief start extension timer by ipc
209      *
210      * @param result
211      */
212     void StartExtTimer(bool &isExtStart);
213 
214     /**
215      * @brief start fwk timer by ipc
216      *
217      * @param errCode
218      */
219     void StartFwkTimer(bool &isFwkStart);
220 
221     /**
222      * @brief get callbackEx for execute onRestore
223      *
224      * @param obj
225      */
226     std::function<void(ErrCode, const std::string)> IncreOnRestoreExCallback(wptr<BackupExtExtension> obj);
227 
228     /**
229      * @brief get increCallback for execute onRestore with string param
230      *
231      * @param obj
232      */
233     std::function<void(ErrCode, const std::string)> IncreOnRestoreCallback(wptr<BackupExtExtension> obj);
234 
235     /**
236      * @brief get callback for execute onRestore with string param
237      *
238      * @param obj
239      */
240     std::function<void(ErrCode, std::string)> OnRestoreCallback(wptr<BackupExtExtension> obj);
241 
242     /**
243      * @brief get increCallbackEx for execute onRestore with string param
244      *
245      * @param obj
246      */
247     std::function<void(ErrCode, std::string)> OnRestoreExCallback(wptr<BackupExtExtension> obj);
248 
249     /**
250      * @brief get callbackEx for execute appDone
251      */
252     std::function<void(ErrCode, std::string)> AppDoneCallbackEx(wptr<BackupExtExtension> obj);
253 
254     std::function<void(ErrCode, const std::string)> IncOnBackupExCallback(wptr<BackupExtExtension> obj);
255     std::function<void(ErrCode, const std::string)> IncOnBackupCallback(wptr<BackupExtExtension> obj);
256 
257     std::function<void(ErrCode, const std::string)> OnBackupExCallback(wptr<BackupExtExtension> obj);
258     std::function<void(ErrCode, const std::string)> OnBackupCallback(wptr<BackupExtExtension> obj);
259 
260     void HandleSpecialVersionRestore();
261     void DeleteBackupIncrementalIdxFile();
262     void DeleteBackupIdxFile();
263     void DeleteBackupIncrementalTars(const string &tarName);
264     void SetClearDataFlag(bool isClearData);
265     std::string GetBundlePath();
266     std::vector<ExtManageInfo> GetExtManageInfo();
267     ErrCode RestoreFilesForSpecialCloneCloud();
268     void RestoreBigFilesForSpecialCloneCloud(const ExtManageInfo &item);
269     ErrCode RestoreTarForSpecialCloneCloud(const ExtManageInfo &item);
270     void RestoreBigFiles(bool appendTargetPath);
271     void FillEndFileInfos(const std::string &path, const unordered_map<string, struct ReportFileInfo> &result);
272     void RestoreBigFileAfter(const string &filePath, const struct stat &sta);
273     void DealIncreUnPacketResult(const off_t tarFileSize, const std::string &tarFileName,
274         const std::tuple<int, EndFileInfo, ErrFileInfo> &result);
275 
276     ErrCode StartOnProcessTaskThread(wptr<BackupExtExtension> obj, BackupRestoreScenario scenario);
277     void FinishOnProcessTask();
278     void ExecCallOnProcessTask(wptr<BackupExtExtension> obj, BackupRestoreScenario scenario);
279     void AsyncCallJsOnProcessTask(wptr<BackupExtExtension> obj, BackupRestoreScenario scenario);
280     void SyncCallJsOnProcessTask(wptr<BackupExtExtension> obj, BackupRestoreScenario scenario);
281     void StartOnProcessTimeOutTimer(wptr<BackupExtExtension> obj, BackupRestoreScenario scenario);
282     void CloseOnProcessTimeOutTimer();
283     void UpdateOnStartTime();
284     int32_t GetOnStartTimeCost();
285     bool SetStagingPathProperties();
286 
287     std::function<void(std::string, int)> ReportErrFileByProc(wptr<BackupExtExtension> obj,
288         BackupRestoreScenario scenario);
289     ErrCode GetIncreFileHandleForNormalVersion(const std::string &fileName);
290     void RestoreOneBigFile(const std::string &path, const ExtManageInfo &item, const bool appendTargetPath);
291     int DealIncreRestoreBigAndTarFile();
292     void ClearNoPermissionFiles(TarMap &pkgInfo, vector<std::string> &noPermissionFiles);
293     std::function<void(ErrCode, std::string)> ReportOnProcessResultCallback(wptr<BackupExtExtension> obj,
294         BackupRestoreScenario scenario);
295 
296 private:
297     std::shared_mutex lock_;
298     std::shared_ptr<ExtBackup> extension_;
299     std::string backupInfo_;
300     OHOS::ThreadPool threadPool_;
301     std::mutex updateSendRateLock_;
302     std::condition_variable startSendFdRateCon_;
303     std::condition_variable waitSendFdCon_;
304     std::mutex startSendMutex_;
305     std::mutex waitTimeLock_;
306     std::string bundleName_;
307     int32_t sendRate_ = BConstants::DEFAULT_FD_SEND_RATE;
308     bool isClearData_ {true};
309     bool isDebug_ {true};
310     std::map<std::string, off_t> endFileInfos_;
311     std::map<std::string, std::vector<ErrCode>> errFileInfos_;
312     bool isRpValid_ {false};
313 
314     std::thread callJsOnProcessThread_;
315     Utils::Timer onProcessTimeoutTimer_ {"onProcessTimeoutTimer_"};
316     uint32_t onProcessTimeoutTimerId_ { 0 };
317     std::atomic<int> onProcessTimeoutCnt_ { 0 };
318     std::atomic<bool> stopCallJsOnProcess_ {false};
319     std::condition_variable execOnProcessCon_;
320     std::mutex onProcessLock_;
321     std::atomic<bool> onProcessTimeout_ {false};
322     std::chrono::time_point<std::chrono::system_clock> g_onStart;
323     std::mutex onStartTimeLock_;
324     AppRadar::DoRestoreInfo radarRestoreInfo_ { 0 };
325     OHOS::ThreadPool onProcessTaskPool_;
326     std::atomic<bool> isFirstCallOnProcess_ {false};
327     std::atomic<bool> isExecAppDone_ {false};
328     OHOS::ThreadPool reportOnProcessRetPool_;
329 
330     BackupRestoreScenario curScenario_ { BackupRestoreScenario::FULL_BACKUP };
331 };
332 } // namespace OHOS::FileManagement::Backup
333 
334 #endif // OHOS_FILEMGMT_BACKUP_BACKUP_EXT_EXTENSION_H