1 /*
2  * Copyright (c) 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 #include "module_ipc/service.h"
17 
18 #include <algorithm>
19 #include <cerrno>
20 #include <chrono>
21 #include <cstddef>
22 #include <cstdint>
23 
24 #include <fcntl.h>
25 #include <iomanip>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <sys/vfs.h>
29 
30 #include <directory_ex.h>
31 #include <unique_fd.h>
32 
33 #include "accesstoken_kit.h"
34 #include "b_anony/b_anony.h"
35 #include "b_error/b_error.h"
36 #include "b_error/b_excep_utils.h"
37 #include "b_json/b_json_cached_entity.h"
38 #include "b_json/b_json_entity_caps.h"
39 #include "b_ohos/startup/backup_para.h"
40 #include "b_process/b_multiuser.h"
41 #include "b_radar/b_radar.h"
42 #include "b_resources/b_constants.h"
43 #include "b_sa/b_sa_utils.h"
44 #include "filemgmt_libhilog.h"
45 #include "hisysevent.h"
46 #include "ipc_skeleton.h"
47 #include "module_external/bms_adapter.h"
48 #include "module_ipc/svc_backup_connection.h"
49 #include "module_ipc/svc_restore_deps_manager.h"
50 #include "parameter.h"
51 #include "system_ability_definition.h"
52 #include "hitrace_meter.h"
53 
54 namespace OHOS::FileManagement::Backup {
55 using namespace std;
56 const std::string FILE_BACKUP_EVENTS = "FILE_BACKUP_EVENTS";
57 
58 namespace {
59 constexpr int32_t DEBUG_ID = 100;
60 constexpr int32_t INDEX = 3;
61 constexpr int32_t MS_1000 = 1000;
62 const static string UNICAST_TYPE = "unicast";
63 } // namespace
64 
GetUserIdDefault()65 static inline int32_t GetUserIdDefault()
66 {
67     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
68     auto [isDebug, debugId] = BackupPara().GetBackupDebugOverrideAccount();
69     if (isDebug && debugId > DEBUG_ID) {
70         return debugId;
71     }
72     auto multiuser = BMultiuser::ParseUid(IPCSkeleton::GetCallingUid());
73     if ((multiuser.userId == BConstants::SYSTEM_UID) || (multiuser.userId == BConstants::XTS_UID)) {
74         return BConstants::DEFAULT_USER_ID;
75     }
76     return multiuser.userId;
77 }
78 
Release()79 ErrCode Service::Release()
80 {
81     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
82     HILOGI("KILL");
83     IServiceReverse::Scenario scenario = session_->GetScenario();
84     VerifyCaller(scenario);
85     AppRadar::Info info("", "", "call release");
86     if (scenario == IServiceReverse::Scenario::RESTORE) {
87         AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::Release", session_->GetSessionUserId(),
88             BizStageRestore::BIZ_STAGE_RELEASE, ERR_OK);
89     } else if (scenario == IServiceReverse::Scenario::BACKUP) {
90         AppRadar::GetInstance().RecordBackupFuncRes(info, "Service::Release", session_->GetSessionUserId(),
91             BizStageBackup::BIZ_STAGE_RELEASE, ERR_OK);
92     }
93     SessionDeactive();
94     return BError(BError::Codes::OK);
95 }
96 
GetExtensionMutex(const BundleName & bundleName)97 std::shared_ptr<ExtensionMutexInfo> Service::GetExtensionMutex(const BundleName &bundleName)
98 {
99     std::unique_lock<std::mutex> lock(extensionMutexLock_);
100     auto it = backupExtMutexMap_.find(bundleName);
101     if (it == backupExtMutexMap_.end()) {
102         HILOGI("BackupExtMutexMap not contain %{public}s", bundleName.c_str());
103         backupExtMutexMap_[bundleName] = std::make_shared<ExtensionMutexInfo>(bundleName);
104         return backupExtMutexMap_[bundleName];
105     }
106     HILOGI("BackupExtMutexMap contain %{public}s", bundleName.c_str());
107     return it->second;
108 }
109 
RemoveExtensionMutex(const BundleName & bundleName)110 void Service::RemoveExtensionMutex(const BundleName &bundleName)
111 {
112     std::unique_lock<std::mutex> lock(extensionMutexLock_);
113     auto it = backupExtMutexMap_.find(bundleName);
114     if (it == backupExtMutexMap_.end()) {
115         HILOGI("BackupExtMutexMap not contain %{public}s", bundleName.c_str());
116         return;
117     }
118     backupExtMutexMap_.erase(it);
119 }
120 
CreateDirIfNotExist(const std::string & path)121 void Service::CreateDirIfNotExist(const std::string &path)
122 {
123     if (access(path.c_str(), F_OK) != 0) {
124         bool created = ForceCreateDirectory(path.data());
125         if (created) {
126             HILOGI("Create directory successfully.");
127         } else {
128             HILOGE("Failed to create directory, path = %{private}s, err = %{public}d", path.c_str(), errno);
129         }
130     }
131 }
132 
GetLocalCapabilitiesIncremental(const std::vector<BIncrementalData> & bundleNames)133 UniqueFd Service::GetLocalCapabilitiesIncremental(const std::vector<BIncrementalData> &bundleNames)
134 {
135     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
136     try {
137         /*
138          Only called by restore app before InitBackupSession,
139            so there must be set init userId.
140         */
141         HILOGI("Begin");
142         if (session_ == nullptr || isCleanService_.load()) {
143             HILOGE("Get LocalCapabilities Incremental Error, session is empty or cleaning up the service");
144             return UniqueFd(-ENOENT);
145         }
146         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
147         session_->SetSessionUserId(GetUserIdDefault());
148         VerifyCaller();
149         string path = BConstants::GetSaBundleBackupRootDir(session_->GetSessionUserId());
150         BExcepUltils::VerifyPath(path, false);
151         CreateDirIfNotExist(path);
152         UniqueFd fd(open(path.data(), O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR));
153         if (fd < 0) {
154             HILOGE("GetLocalCapabilitiesIncremental: open file failed, err = %{public}d", errno);
155             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
156             return UniqueFd(-ENOENT);
157         }
158         BJsonCachedEntity<BJsonEntityCaps> cachedEntity(move(fd));
159         auto cache = cachedEntity.Structuralize();
160 
161         cache.SetSystemFullName(GetOSFullName());
162         cache.SetDeviceType(GetDeviceType());
163         auto bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(session_->GetSessionUserId(), bundleNames);
164         cache.SetBundleInfos(bundleInfos, true);
165         cachedEntity.Persist();
166         HILOGI("Service GetLocalCapabilitiesIncremental persist");
167         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
168         HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size());
169         return move(cachedEntity.GetFd());
170     } catch (const BError &e) {
171         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
172         HILOGE("GetLocalCapabilitiesIncremental failed, errCode = %{public}d", e.GetCode());
173         return UniqueFd(-e.GetCode());
174     } catch (const exception &e) {
175         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
176         HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
177         return UniqueFd(-EPERM);
178     } catch (...) {
179         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
180         HILOGI("Unexpected exception");
181         return UniqueFd(-EPERM);
182     }
183 }
184 
StartGetFdTask(std::string bundleName,wptr<Service> ptr)185 void Service::StartGetFdTask(std::string bundleName, wptr<Service> ptr)
186 {
187     auto thisPtr = ptr.promote();
188     if (!thisPtr) {
189         HILOGE("this pointer is null");
190         return;
191     }
192     auto session = thisPtr->session_;
193     if (session == nullptr) {
194         throw BError(BError::Codes::SA_INVAL_ARG, "session is nullptr");
195     }
196     auto backUpConnection = session->GetExtConnection(bundleName);
197     if (backUpConnection == nullptr) {
198         throw BError(BError::Codes::SA_INVAL_ARG, "backUpConnection is empty");
199     }
200     auto proxy = backUpConnection->GetBackupExtProxy();
201     if (!proxy) {
202         throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
203     }
204     // distinguish whether it is 0 user
205     if (BundleMgrAdapter::IsUser0BundleName(bundleName, session_->GetSessionUserId())) {
206         auto ret = proxy->User0OnBackup();
207         if (ret) {
208             thisPtr->ClearSessionAndSchedInfo(bundleName);
209             thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
210         }
211         return;
212     }
213     int64_t lastTime = session->GetLastIncrementalTime(bundleName);
214     std::vector<BIncrementalData> bundleNames;
215     bundleNames.emplace_back(BIncrementalData {bundleName, lastTime});
216     BundleMgrAdapter::GetBundleInfosForIncremental(bundleNames, session->GetSessionUserId());
217     string path = BConstants::GetSaBundleBackupRootDir(session->GetSessionUserId()).
218                     append(bundleName).
219                     append("/").
220                     append(BConstants::BACKUP_STAT_SYMBOL).
221                     append(to_string(lastTime));
222     HILOGD("path = %{public}s,bundleName = %{public}s", path.c_str(), bundleName.c_str());
223     UniqueFd fdLocal(open(path.data(), O_RDWR, S_IRGRP | S_IWGRP));
224     if (fdLocal < 0) {
225         HILOGD("fdLocal open fail, error = %{public}d", errno);
226         throw BError(BError::Codes::SA_INVAL_ARG, "open local Manifest file failed");
227     }
228     UniqueFd lastManifestFd(session->GetIncrementalManifestFd(bundleName));
229     auto ret = proxy->HandleIncrementalBackup(move(fdLocal), move(lastManifestFd));
230     if (ret) {
231         thisPtr->ClearSessionAndSchedInfo(bundleName);
232         thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
233     }
234 }
235 
GetAppLocalListAndDoIncrementalBackup()236 ErrCode Service::GetAppLocalListAndDoIncrementalBackup()
237 {
238     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
239     try {
240         if (session_ == nullptr || isCleanService_.load()) {
241             HILOGE("session is nullptr");
242             return BError(BError::Codes::SA_INVAL_ARG);
243         }
244         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
245         session_->SetSessionUserId(GetUserIdDefault());
246         std::string bundleName = VerifyCallerAndGetCallerName();
247         auto task = [this, bundleName]() {
248             StartGetFdTask(bundleName, wptr(this));
249         };
250         threadPool_.AddTask([task]() {
251             try {
252                 task();
253             } catch (const BError &e) {
254                 HILOGE("GetAppLocalListAndDoIncrementalBackup failed, errCode = %{public}d", e.GetCode());
255             } catch (const exception &e) {
256                 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
257             } catch (...) {
258                 HILOGI("Unexpected exception");
259             }
260         });
261         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
262         return BError(BError::Codes::OK);
263     } catch (const BError &e) {
264         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
265         HILOGE("GetAppLocalListAndDoIncrementalBackup failed, errCode = %{public}d", e.GetCode());
266         return e.GetCode();
267     } catch (const exception &e) {
268         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
269         HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
270         return EPERM;
271     } catch (...) {
272         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
273         HILOGI("Unexpected exception");
274         return EPERM;
275     }
276 }
277 
InitIncrementalBackupSession(sptr<IServiceReverse> remote)278 ErrCode Service::InitIncrementalBackupSession(sptr<IServiceReverse> remote)
279 {
280     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
281     try {
282         VerifyCaller();
283         if (session_ == nullptr) {
284             HILOGE("Init Incremental backup session  error, session is empty");
285             return BError(BError::Codes::SA_INVAL_ARG);
286         }
287         ErrCode errCode = session_->Active({.clientToken = IPCSkeleton::GetCallingTokenID(),
288                                             .scenario = IServiceReverse::Scenario::BACKUP,
289                                             .clientProxy = remote,
290                                             .userId = GetUserIdDefault(),
291                                             .isIncrementalBackup = true});
292         if (errCode == 0) {
293             ClearFailedBundles();
294             successBundlesNum_ = 0;
295         }
296         return errCode;
297     } catch (const BError &e) {
298         StopAll(nullptr, true);
299         return e.GetCode();
300     }
301 }
302 
GetBundleNameByDetails(const std::vector<BIncrementalData> & bundlesToBackup)303 vector<string> Service::GetBundleNameByDetails(const std::vector<BIncrementalData> &bundlesToBackup)
304 {
305     vector<string> bundleNames {};
306     for (auto bundle : bundlesToBackup) {
307         bundleNames.emplace_back(bundle.bundleName);
308     }
309     return bundleNames;
310 }
311 
AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> & bundlesToBackup)312 ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup)
313 {
314     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
315     try {
316         if (session_ == nullptr || isCleanService_.load()) {
317             HILOGE("Init Incremental backup session  error, session is empty");
318             return BError(BError::Codes::SA_INVAL_ARG);
319         }
320         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时
321         VerifyCaller(IServiceReverse::Scenario::BACKUP);
322         vector<string> bundleNames = GetBundleNameByDetails(bundlesToBackup);
323         auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundlesToBackup,
324             session_->GetSessionUserId());
325         std::vector<std::string> supportBackupNames = GetSupportBackupBundleNames(backupInfos, true, bundleNames);
326         session_->AppendBundles(supportBackupNames);
327         SetBundleIncDataInfo(bundlesToBackup, supportBackupNames);
328         SetCurrentBackupSessProperties(supportBackupNames, session_->GetSessionUserId(), backupInfos, true);
329         OnStartSched();
330         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
331         return BError(BError::Codes::OK);
332     } catch (const BError &e) {
333         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
334         HILOGE("Failed, errCode = %{public}d", e.GetCode());
335         return e.GetCode();
336     } catch (...) {
337         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
338         HILOGI("Unexpected exception");
339         return EPERM;
340     }
341 }
342 
AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> & bundlesToBackup,const std::vector<std::string> & infos)343 ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup,
344     const std::vector<std::string> &infos)
345 {
346     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
347     try {
348         if (session_ == nullptr || isCleanService_.load()) {
349             HILOGE("Init Incremental backup session error, session is empty");
350             return BError(BError::Codes::SA_INVAL_ARG);
351         }
352         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时
353         VerifyCaller(IServiceReverse::Scenario::BACKUP);
354         vector<string> bundleNames {};
355         for (auto &bundle : bundlesToBackup) {
356             bundleNames.emplace_back(bundle.bundleName);
357         }
358         std::vector<std::string> bundleNamesOnly;
359         std::map<std::string, bool> isClearDataFlags;
360         std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> bundleNameDetailMap =
361             BJsonUtil::BuildBundleInfos(bundleNames, infos, bundleNamesOnly,
362             session_->GetSessionUserId(), isClearDataFlags);
363         auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundlesToBackup,
364             session_->GetSessionUserId());
365         std::vector<std::string> supportBackupNames = GetSupportBackupBundleNames(backupInfos, true, bundleNames);
366         session_->AppendBundles(supportBackupNames);
367         SetBundleIncDataInfo(bundlesToBackup, supportBackupNames);
368         HandleCurGroupIncBackupInfos(backupInfos, bundleNameDetailMap, isClearDataFlags);
369         OnStartSched();
370         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
371         return BError(BError::Codes::OK);
372     } catch (const BError &e) {
373         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
374         HILOGE("Failed, errCode = %{public}d", e.GetCode());
375         return e.GetCode();
376     } catch (...) {
377         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
378         HILOGI("Unexpected exception");
379         return EPERM;
380     }
381 }
382 
HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> & backupInfos,std::map<std::string,std::vector<BJsonUtil::BundleDetailInfo>> & bundleNameDetailMap,std::map<std::string,bool> & isClearDataFlags)383 void Service::HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> &backupInfos,
384     std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> &bundleNameDetailMap,
385     std::map<std::string, bool> &isClearDataFlags)
386 {
387     for (auto &info : backupInfos) {
388         HILOGI("Current backupInfo bundleName:%{public}s, index:%{public}d, extName:%{public}s", info.name.c_str(),
389             info.appIndex, info.extensionName.c_str());
390         std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex);
391         SetCurrentSessProperties(info, isClearDataFlags, bundleNameIndexInfo);
392         session_->SetBundleDataSize(bundleNameIndexInfo, info.increSpaceOccupied);
393         BJsonUtil::BundleDetailInfo uniCastInfo;
394         if (BJsonUtil::FindBundleInfoByName(bundleNameDetailMap, bundleNameIndexInfo, UNICAST_TYPE, uniCastInfo)) {
395             HILOGI("current bundle:%{public}s, unicast info:%{public}s", bundleNameIndexInfo.c_str(),
396                 GetAnonyString(uniCastInfo.detail).c_str());
397             session_->SetBackupExtInfo(bundleNameIndexInfo, uniCastInfo.detail);
398         }
399         session_->SetBackupExtName(bundleNameIndexInfo, info.extensionName);
400         session_->SetIsReadyLaunch(bundleNameIndexInfo);
401     }
402 }
403 
PublishIncrementalFile(const BFileInfo & fileInfo)404 ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo)
405 {
406     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
407     try {
408         VerifyCaller(IServiceReverse::Scenario::RESTORE);
409         HILOGI("Start get ExtConnection, bundleName:%{public}s", fileInfo.owner.c_str());
410         if (!fileInfo.fileName.empty()) {
411             HILOGE("Forbit to use PublishIncrementalFile with fileName for App");
412             return EPERM;
413         }
414         if (session_ != nullptr) {
415             session_->SetPublishFlag(fileInfo.owner);
416         }
417         auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
418         if (backUpConnection == nullptr) {
419             HILOGE("PublishIncrementalFile error, backUpConnection is empty");
420             return BError(BError::Codes::SA_INVAL_ARG);
421         }
422         auto proxy = backUpConnection->GetBackupExtProxy();
423         if (!proxy) {
424             HILOGE("PublishIncrementalFile error, Extension backup Proxy is empty");
425             return BError(BError::Codes::SA_INVAL_ARG);
426         }
427         ErrCode res = proxy->PublishIncrementalFile(fileInfo.fileName);
428         if (res) {
429             HILOGE("Failed to publish file for backup extension");
430         }
431         return res;
432     } catch (const BError &e) {
433         return e.GetCode();
434     } catch (const exception &e) {
435         HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
436         return EPERM;
437     } catch (...) {
438         HILOGI("Unexpected exception");
439         return EPERM;
440     }
441 }
442 
PublishSAIncrementalFile(const BFileInfo & fileInfo,UniqueFd fd)443 ErrCode Service::PublishSAIncrementalFile(const BFileInfo &fileInfo, UniqueFd fd)
444 {
445     std::string bundleName = fileInfo.owner;
446     if (!SAUtils::IsSABundleName(bundleName)) {
447         HILOGE("Bundle name %{public}s is not sa", bundleName.c_str());
448         return BError(BError::Codes::SA_EXT_ERR_CALL);
449     }
450     HILOGI("Bundle name %{public}s is sa, publish sa incremental file", bundleName.c_str());
451     auto backupConnection = session_->GetSAExtConnection(bundleName);
452     std::shared_ptr<SABackupConnection> saConnection = backupConnection.lock();
453     if (saConnection == nullptr) {
454         HILOGE("lock sa connection ptr is nullptr");
455         return BError(BError::Codes::SA_INVAL_ARG);
456     }
457     return saConnection->CallRestoreSA(move(fd));
458 }
459 
AppIncrementalFileReady(const std::string & fileName,UniqueFd fd,UniqueFd manifestFd,int32_t errCode)460 ErrCode Service::AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd, int32_t errCode)
461 {
462     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
463     try {
464         string callerName = VerifyCallerAndGetCallerName();
465         if (session_->GetScenario() == IServiceReverse::Scenario::RESTORE) {
466             session_->GetServiceReverseProxy()->IncrementalRestoreOnFileReady(callerName, fileName, move(fd),
467                                                                               move(manifestFd), errCode);
468             FileReadyRadarReport(callerName, fileName, errCode, IServiceReverse::Scenario::RESTORE);
469             return BError(BError::Codes::OK);
470         }
471 
472         if (fileName == BConstants::EXT_BACKUP_MANAGE) {
473             fd = session_->OnBundleExtManageInfo(callerName, move(fd));
474         }
475         HILOGD("reverse: Will notify IncrementalBackupOnFileReady");
476         session_->GetServiceReverseProxy()->IncrementalBackupOnFileReady(callerName, fileName, move(fd),
477                                                                          move(manifestFd), errCode);
478         FileReadyRadarReport(callerName, fileName, errCode, IServiceReverse::Scenario::BACKUP);
479         if (session_->OnBundleFileReady(callerName, fileName)) {
480             auto backUpConnection = session_->GetExtConnection(callerName);
481             auto proxy = backUpConnection->GetBackupExtProxy();
482             if (!proxy) {
483                 throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
484             }
485             // 通知extension清空缓存
486             proxy->HandleClear();
487             // 清除Timer
488             session_->StopFwkTimer(callerName);
489             session_->StopExtTimer(callerName);
490             // 通知TOOL 备份完成
491             HILOGI("reverse: Will notify IncrementalBackupOnBundleFinished");
492             session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(BError(BError::Codes::OK),
493                                                                                   callerName);
494             BundleEndRadarReport(callerName, BError(BError::Codes::OK), IServiceReverse::Scenario::BACKUP);
495             // 断开extension
496             backUpConnection->DisconnectBackupExtAbility();
497             ClearSessionAndSchedInfo(callerName);
498         }
499         OnAllBundlesFinished(BError(BError::Codes::OK));
500         return BError(BError::Codes::OK);
501     } catch (const BError &e) {
502         return e.GetCode(); // 任意异常产生,终止监听该任务
503     } catch (const exception &e) {
504         HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
505         return EPERM;
506     } catch (...) {
507         HILOGI("Unexpected exception");
508         return EPERM;
509     }
510 }
511 
AppIncrementalDone(ErrCode errCode)512 ErrCode Service::AppIncrementalDone(ErrCode errCode)
513 {
514     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
515     try {
516         if (session_ == nullptr) {
517             HILOGE("AppIncrementalDone error, session is null");
518             return BError(BError::Codes::SA_INVAL_ARG);
519         }
520         string callerName = VerifyCallerAndGetCallerName();
521         HILOGI("Service AppIncrementalDone start, callerName is %{public}s, errCode is: %{public}d",
522             callerName.c_str(), errCode);
523         if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) {
524             std::shared_ptr<ExtensionMutexInfo> mutexPtr = GetExtensionMutex(callerName);
525             if (mutexPtr == nullptr) {
526                 HILOGE("extension mutex ptr is nullptr");
527                 return BError(BError::Codes::SA_INVAL_ARG, "Extension mutex ptr is null.");
528             }
529             std::lock_guard<std::mutex> lock(mutexPtr->callbackMutex);
530             auto tempBackUpConnection = session_->GetExtConnection(callerName);
531             auto backUpConnection = tempBackUpConnection.promote();
532             if (backUpConnection == nullptr) {
533                 return BError(BError::Codes::SA_INVAL_ARG, "Promote backUpConnection ptr is null.");
534             }
535             auto proxy = backUpConnection->GetBackupExtProxy();
536             if (!proxy) {
537                 return BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
538             }
539             proxy->HandleClear();
540             session_->StopFwkTimer(callerName);
541             session_->StopExtTimer(callerName);
542             backUpConnection->DisconnectBackupExtAbility();
543             ClearSessionAndSchedInfo(callerName);
544             NotifyCallerCurAppIncrementDone(errCode, callerName);
545         }
546         RemoveExtensionMutex(callerName);
547         OnAllBundlesFinished(BError(BError::Codes::OK));
548         return BError(BError::Codes::OK);
549     } catch (const BError &e) {
550         ReleaseOnException();
551         HILOGE("AppIncrementalDone error, err code is:%{public}d", e.GetCode());
552         return e.GetCode(); // 任意异常产生,终止监听该任务
553     } catch (...) {
554         ReleaseOnException();
555         HILOGI("Unexpected exception");
556         return EPERM;
557     }
558 }
559 
GetIncrementalFileHandle(const std::string & bundleName,const std::string & fileName)560 ErrCode Service::GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName)
561 {
562     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
563     try {
564         HILOGI("Begin get incrementalFileHandle");
565         VerifyCaller(IServiceReverse::Scenario::RESTORE);
566         auto action = session_->GetServiceSchedAction(bundleName);
567         if (action == BConstants::ServiceSchedAction::RUNNING) {
568             auto backUpConnection = session_->GetExtConnection(bundleName);
569             if (backUpConnection == nullptr) {
570                 HILOGE("GetIncrementalFileHandle error, backUpConnection is empty");
571                 return BError(BError::Codes::SA_INVAL_ARG);
572             }
573             auto proxy = backUpConnection->GetBackupExtProxy();
574             if (!proxy) {
575                 HILOGE("GetIncrementalFileHandle error, Extension backup Proxy is empty");
576                 return BError(BError::Codes::SA_INVAL_ARG);
577             }
578             ErrCode res = proxy->GetIncrementalFileHandle(fileName);
579             if (res != ERR_OK) {
580                 HILOGE("Failed to extension file handle");
581                 AppRadar::Info info (bundleName, "", "");
582                 AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::GetIncrementalFileHandle",
583                     GetUserIdDefault(), BizStageRestore::BIZ_STAGE_GET_FILE_HANDLE_FAIL, res);
584             }
585         } else {
586             SvcRestoreDepsManager::GetInstance().UpdateToRestoreBundleMap(bundleName, fileName);
587             session_->SetExtFileNameRequest(bundleName, fileName);
588         }
589         return BError(BError::Codes::OK);
590     } catch (const BError &e) {
591         return e.GetCode();
592     } catch (const exception &e) {
593         HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
594         return EPERM;
595     } catch (...) {
596         HILOGI("Unexpected exception");
597         return EPERM;
598     }
599 }
600 
IncrementalBackup(const string & bundleName)601 bool Service::IncrementalBackup(const string &bundleName)
602 {
603     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
604     IServiceReverse::Scenario scenario = session_->GetScenario();
605     auto backUpConnection = session_->GetExtConnection(bundleName);
606     if (backUpConnection == nullptr) {
607         throw BError(BError::Codes::SA_INVAL_ARG, "backUpConnection is empty");
608     }
609     auto proxy = backUpConnection->GetBackupExtProxy();
610     if (!proxy) {
611         throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
612     }
613     if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) {
614         auto ret = proxy->IncrementalOnBackup(session_->GetClearDataFlag(bundleName));
615         session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(ret, bundleName);
616         BundleBeginRadarReport(bundleName, ret, IServiceReverse::Scenario::BACKUP);
617         if (ret) {
618             ClearSessionAndSchedInfo(bundleName);
619             NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
620         }
621         return true;
622     } else if (scenario == IServiceReverse::Scenario::RESTORE && BackupPara().GetBackupOverrideIncrementalRestore() &&
623                session_->ValidRestoreDataType(RestoreTypeEnum::RESTORE_DATA_WAIT_SEND)) {
624         auto ret = proxy->HandleRestore(session_->GetClearDataFlag(bundleName));
625         session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleStarted(ret, bundleName);
626         BundleBeginRadarReport(bundleName, ret, IServiceReverse::Scenario::RESTORE);
627         auto fileNameVec = session_->GetExtFileNameRequest(bundleName);
628         for (auto &fileName : fileNameVec) {
629             ret = proxy->GetIncrementalFileHandle(fileName);
630             if (ret) {
631                 HILOGE("Failed to extension file handle %{public}s", fileName.c_str());
632             }
633         }
634         return true;
635     }
636     return false;
637 }
638 
NotifyCallerCurAppIncrementDone(ErrCode errCode,const std::string & callerName)639 void Service::NotifyCallerCurAppIncrementDone(ErrCode errCode, const std::string &callerName)
640 {
641     IServiceReverse::Scenario scenario = session_->GetScenario();
642     if (scenario == IServiceReverse::Scenario::BACKUP) {
643         HILOGI("will notify clone data, scenario is incremental backup");
644         session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(errCode, callerName);
645         BundleEndRadarReport(callerName, errCode, scenario);
646         auto now = std::chrono::system_clock::now();
647         auto time = std::chrono::system_clock::to_time_t(now);
648         auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
649         std::stringstream strTime;
650         strTime << (std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S:")) << (std::setfill('0'))
651             << (std::setw(INDEX)) << (ms.count() % MS_1000);
652         HiSysEventWrite(
653             OHOS::HiviewDFX::HiSysEvent::Domain::FILEMANAGEMENT,
654             FILE_BACKUP_EVENTS,
655             OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
656             "PROC_NAME", "ohos.appfileservice", "BUNDLENAME", callerName,
657             "PID", getpid(), "TIME", strTime.str()
658         );
659     } else if (scenario == IServiceReverse::Scenario::RESTORE) {
660         HILOGI("will notify clone data, scenario is Restore");
661         SendEndAppGalleryNotify(callerName);
662         session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleFinished(errCode, callerName);
663         BundleEndRadarReport(callerName, errCode, scenario);
664     }
665 }
666 
SendUserIdToApp(string & bundleName,int32_t userId)667 void Service::SendUserIdToApp(string &bundleName, int32_t userId)
668 {
669     if (session_ == nullptr) {
670         HILOGI("session_ is nullptr");
671         return;
672     }
673     HILOGI("Begin, bundleName: %{public}s", bundleName.c_str());
674     string detailInfo;
675     if (!BJsonUtil::BuildBundleInfoJson(userId, detailInfo)) {
676         HILOGE("BuildBundleInfoJson failed, bundleName : %{public}s", bundleName.c_str());
677         return;
678     }
679     session_->SetBackupExtInfo(bundleName, detailInfo);
680     HILOGI("End, bundleName:%{public}s, unicast info:%{public}s", bundleName.c_str(),
681         GetAnonyString(detailInfo).c_str());
682 }
683 
SetCurrentBackupSessProperties(const vector<string> & bundleNames,int32_t userId,vector<BJsonEntityCaps::BundleInfo> & backupBundleInfos,bool isIncBackup)684 void Service::SetCurrentBackupSessProperties(const vector<string> &bundleNames, int32_t userId,
685     vector<BJsonEntityCaps::BundleInfo> &backupBundleInfos, bool isIncBackup)
686 {
687     HILOGI("start SetCurrentBackupSessProperties");
688     std::map<std::string, BJsonEntityCaps::BundleInfo> bundleNameIndexBundleInfoMap;
689     for (auto &bundleInfo : backupBundleInfos) {
690         std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(bundleInfo.name, bundleInfo.appIndex);
691         bundleNameIndexBundleInfoMap[bundleNameIndexInfo] = bundleInfo;
692     }
693     for (auto item : bundleNames) {
694         std::string bundleName = item;
695         if (BundleMgrAdapter::IsUser0BundleName(bundleName, userId)) {
696             HILOGE("bundleName:%{public}s is zero user bundle", bundleName.c_str());
697             SendUserIdToApp(bundleName, userId);
698         }
699         auto it = bundleNameIndexBundleInfoMap.find(bundleName);
700         if (it == bundleNameIndexBundleInfoMap.end()) {
701             HILOGE("Current bundleName can not find bundleInfo, bundleName:%{public}s", bundleName.c_str());
702             session_->RemoveExtInfo(bundleName);
703             continue;
704         }
705         auto bundleInfo = it->second;
706         if (isIncBackup) {
707             session_->SetBundleDataSize(bundleName, bundleInfo.increSpaceOccupied);
708         } else {
709             session_->SetBundleDataSize(bundleName, bundleInfo.spaceOccupied);
710         }
711         session_->SetBackupExtName(bundleName, bundleInfo.extensionName);
712         session_->SetIsReadyLaunch(bundleName);
713     }
714     HILOGI("end SetCurrentBackupSessProperties");
715 }
716 
SetBundleIncDataInfo(const std::vector<BIncrementalData> & bundlesToBackup,std::vector<std::string> & supportBundleNames)717 void Service::SetBundleIncDataInfo(const std::vector<BIncrementalData>& bundlesToBackup,
718     std::vector<std::string>& supportBundleNames)
719 {
720     for (auto &bundleInfo : bundlesToBackup) {
721         std::string bundleName = bundleInfo.bundleName;
722         auto it = std::find(supportBundleNames.begin(), supportBundleNames.end(), bundleName);
723         if (it == supportBundleNames.end()) {
724             HILOGE("Current bundle is not support to backup, bundleName:%{public}s", bundleName.c_str());
725             continue;
726         }
727         session_->SetIncrementalData(bundleInfo);
728     }
729 }
730 } // namespace OHOS::FileManagement::Backup
731