• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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);
326         session_->AppendBundles(supportBackupNames);
327         for (auto &bundleInfo : bundlesToBackup) {
328             session_->SetIncrementalData(bundleInfo);
329         }
330         SetCurrentBackupSessProperties(supportBackupNames, session_->GetSessionUserId(), backupInfos, true);
331         OnStartSched();
332         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
333         return BError(BError::Codes::OK);
334     } catch (const BError &e) {
335         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
336         HILOGE("Failed, errCode = %{public}d", e.GetCode());
337         return e.GetCode();
338     } catch (...) {
339         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
340         HILOGI("Unexpected exception");
341         return EPERM;
342     }
343 }
344 
AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> & bundlesToBackup,const std::vector<std::string> & infos)345 ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup,
346     const std::vector<std::string> &infos)
347 {
348     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
349     try {
350         if (session_ == nullptr || isCleanService_.load()) {
351             HILOGE("Init Incremental backup session error, session is empty");
352             return BError(BError::Codes::SA_INVAL_ARG);
353         }
354         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时
355         VerifyCaller(IServiceReverse::Scenario::BACKUP);
356         vector<string> bundleNames {};
357         for (auto &bundle : bundlesToBackup) {
358             bundleNames.emplace_back(bundle.bundleName);
359         }
360         std::vector<std::string> bundleNamesOnly;
361         std::map<std::string, bool> isClearDataFlags;
362         std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> bundleNameDetailMap =
363             BJsonUtil::BuildBundleInfos(bundleNames, infos, bundleNamesOnly,
364             session_->GetSessionUserId(), isClearDataFlags);
365         auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundlesToBackup,
366             session_->GetSessionUserId());
367         std::vector<std::string> supportBackupNames = GetSupportBackupBundleNames(backupInfos, true);
368         for (auto &bundleInfo : bundlesToBackup) {
369             session_->SetIncrementalData(bundleInfo);
370         }
371         session_->AppendBundles(supportBackupNames);
372         HandleCurGroupIncBackupInfos(backupInfos, bundleNameDetailMap, isClearDataFlags);
373         OnStartSched();
374         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
375         return BError(BError::Codes::OK);
376     } catch (const BError &e) {
377         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
378         HILOGE("Failed, errCode = %{public}d", e.GetCode());
379         return e.GetCode();
380     } catch (...) {
381         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
382         HILOGI("Unexpected exception");
383         return EPERM;
384     }
385 }
386 
HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> & backupInfos,std::map<std::string,std::vector<BJsonUtil::BundleDetailInfo>> & bundleNameDetailMap,std::map<std::string,bool> & isClearDataFlags)387 void Service::HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> &backupInfos,
388     std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> &bundleNameDetailMap,
389     std::map<std::string, bool> &isClearDataFlags)
390 {
391     for (auto &info : backupInfos) {
392         HILOGI("Current backupInfo bundleName:%{public}s, index:%{public}d, extName:%{public}s", info.name.c_str(),
393             info.appIndex, info.extensionName.c_str());
394         std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex);
395         SetCurrentSessProperties(info, isClearDataFlags, bundleNameIndexInfo);
396         session_->SetBundleDataSize(bundleNameIndexInfo, info.increSpaceOccupied);
397         BJsonUtil::BundleDetailInfo uniCastInfo;
398         if (BJsonUtil::FindBundleInfoByName(bundleNameDetailMap, bundleNameIndexInfo, UNICAST_TYPE, uniCastInfo)) {
399             HILOGI("current bundle:%{public}s, unicast info:%{public}s", bundleNameIndexInfo.c_str(),
400                 GetAnonyString(uniCastInfo.detail).c_str());
401             session_->SetBackupExtInfo(bundleNameIndexInfo, uniCastInfo.detail);
402         }
403         session_->SetBackupExtName(bundleNameIndexInfo, info.extensionName);
404         session_->SetIsReadyLaunch(bundleNameIndexInfo);
405     }
406 }
407 
PublishIncrementalFile(const BFileInfo & fileInfo)408 ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo)
409 {
410     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
411     try {
412         VerifyCaller(IServiceReverse::Scenario::RESTORE);
413         HILOGI("Start get ExtConnection, bundleName:%{public}s", fileInfo.owner.c_str());
414         if (!fileInfo.fileName.empty()) {
415             HILOGE("Forbit to use PublishIncrementalFile with fileName for App");
416             return EPERM;
417         }
418         if (session_ != nullptr) {
419             session_->SetPublishFlag(fileInfo.owner);
420         }
421         auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
422         if (backUpConnection == nullptr) {
423             HILOGE("PublishIncrementalFile error, backUpConnection is empty");
424             return BError(BError::Codes::SA_INVAL_ARG);
425         }
426         auto proxy = backUpConnection->GetBackupExtProxy();
427         if (!proxy) {
428             HILOGE("PublishIncrementalFile error, Extension backup Proxy is empty");
429             return BError(BError::Codes::SA_INVAL_ARG);
430         }
431         ErrCode res = proxy->PublishIncrementalFile(fileInfo.fileName);
432         if (res) {
433             HILOGE("Failed to publish file for backup extension");
434         }
435         return res;
436     } catch (const BError &e) {
437         return e.GetCode();
438     } catch (const exception &e) {
439         HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
440         return EPERM;
441     } catch (...) {
442         HILOGI("Unexpected exception");
443         return EPERM;
444     }
445 }
446 
PublishSAIncrementalFile(const BFileInfo & fileInfo,UniqueFd fd)447 ErrCode Service::PublishSAIncrementalFile(const BFileInfo &fileInfo, UniqueFd fd)
448 {
449     std::string bundleName = fileInfo.owner;
450     if (!SAUtils::IsSABundleName(bundleName)) {
451         HILOGE("Bundle name %{public}s is not sa", bundleName.c_str());
452         return BError(BError::Codes::SA_EXT_ERR_CALL);
453     }
454     HILOGI("Bundle name %{public}s is sa, publish sa incremental file", bundleName.c_str());
455     auto backupConnection = session_->GetSAExtConnection(bundleName);
456     std::shared_ptr<SABackupConnection> saConnection = backupConnection.lock();
457     if (saConnection == nullptr) {
458         HILOGE("lock sa connection ptr is nullptr");
459         return BError(BError::Codes::SA_INVAL_ARG);
460     }
461     return saConnection->CallRestoreSA(move(fd));
462 }
463 
AppIncrementalFileReady(const std::string & fileName,UniqueFd fd,UniqueFd manifestFd,int32_t errCode)464 ErrCode Service::AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd, int32_t errCode)
465 {
466     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
467     try {
468         string callerName = VerifyCallerAndGetCallerName();
469         if (session_->GetScenario() == IServiceReverse::Scenario::RESTORE) {
470             session_->GetServiceReverseProxy()->IncrementalRestoreOnFileReady(callerName, fileName, move(fd),
471                                                                               move(manifestFd), errCode);
472             FileReadyRadarReport(callerName, fileName, errCode, IServiceReverse::Scenario::RESTORE);
473             return BError(BError::Codes::OK);
474         }
475 
476         if (fileName == BConstants::EXT_BACKUP_MANAGE) {
477             fd = session_->OnBundleExtManageInfo(callerName, move(fd));
478         }
479         HILOGD("reverse: Will notify IncrementalBackupOnFileReady");
480         session_->GetServiceReverseProxy()->IncrementalBackupOnFileReady(callerName, fileName, move(fd),
481                                                                          move(manifestFd), errCode);
482         FileReadyRadarReport(callerName, fileName, errCode, IServiceReverse::Scenario::BACKUP);
483         if (session_->OnBundleFileReady(callerName, fileName)) {
484             auto backUpConnection = session_->GetExtConnection(callerName);
485             auto proxy = backUpConnection->GetBackupExtProxy();
486             if (!proxy) {
487                 throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
488             }
489             // 通知extension清空缓存
490             proxy->HandleClear();
491             // 清除Timer
492             session_->StopFwkTimer(callerName);
493             session_->StopExtTimer(callerName);
494             // 通知TOOL 备份完成
495             HILOGI("reverse: Will notify IncrementalBackupOnBundleFinished");
496             session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(BError(BError::Codes::OK),
497                                                                                   callerName);
498             BundleEndRadarReport(callerName, BError(BError::Codes::OK), IServiceReverse::Scenario::BACKUP);
499             // 断开extension
500             backUpConnection->DisconnectBackupExtAbility();
501             ClearSessionAndSchedInfo(callerName);
502         }
503         OnAllBundlesFinished(BError(BError::Codes::OK));
504         return BError(BError::Codes::OK);
505     } catch (const BError &e) {
506         return e.GetCode(); // 任意异常产生,终止监听该任务
507     } catch (const exception &e) {
508         HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
509         return EPERM;
510     } catch (...) {
511         HILOGI("Unexpected exception");
512         return EPERM;
513     }
514 }
515 
AppIncrementalDone(ErrCode errCode)516 ErrCode Service::AppIncrementalDone(ErrCode errCode)
517 {
518     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
519     try {
520         if (session_ == nullptr) {
521             HILOGE("AppIncrementalDone error, session is null");
522             return BError(BError::Codes::SA_INVAL_ARG);
523         }
524         string callerName = VerifyCallerAndGetCallerName();
525         HILOGI("Service AppIncrementalDone start, callerName is %{public}s, errCode is: %{public}d",
526             callerName.c_str(), errCode);
527         if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) {
528             std::shared_ptr<ExtensionMutexInfo> mutexPtr = GetExtensionMutex(callerName);
529             if (mutexPtr == nullptr) {
530                 HILOGE("extension mutex ptr is nullptr");
531                 return BError(BError::Codes::SA_INVAL_ARG, "Extension mutex ptr is null.");
532             }
533             std::lock_guard<std::mutex> lock(mutexPtr->callbackMutex);
534             auto tempBackUpConnection = session_->GetExtConnection(callerName);
535             auto backUpConnection = tempBackUpConnection.promote();
536             if (backUpConnection == nullptr) {
537                 return BError(BError::Codes::SA_INVAL_ARG, "Promote backUpConnection ptr is null.");
538             }
539             auto proxy = backUpConnection->GetBackupExtProxy();
540             if (!proxy) {
541                 return BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
542             }
543             proxy->HandleClear();
544             session_->StopFwkTimer(callerName);
545             session_->StopExtTimer(callerName);
546             backUpConnection->DisconnectBackupExtAbility();
547             ClearSessionAndSchedInfo(callerName);
548             NotifyCallerCurAppIncrementDone(errCode, callerName);
549         }
550         RemoveExtensionMutex(callerName);
551         OnAllBundlesFinished(BError(BError::Codes::OK));
552         return BError(BError::Codes::OK);
553     } catch (const BError &e) {
554         ReleaseOnException();
555         HILOGE("AppIncrementalDone error, err code is:%{public}d", e.GetCode());
556         return e.GetCode(); // 任意异常产生,终止监听该任务
557     } catch (...) {
558         ReleaseOnException();
559         HILOGI("Unexpected exception");
560         return EPERM;
561     }
562 }
563 
GetIncrementalFileHandle(const std::string & bundleName,const std::string & fileName)564 ErrCode Service::GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName)
565 {
566     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
567     try {
568         HILOGI("Begin get incrementalFileHandle");
569         VerifyCaller(IServiceReverse::Scenario::RESTORE);
570         auto action = session_->GetServiceSchedAction(bundleName);
571         if (action == BConstants::ServiceSchedAction::RUNNING) {
572             auto backUpConnection = session_->GetExtConnection(bundleName);
573             if (backUpConnection == nullptr) {
574                 HILOGE("GetIncrementalFileHandle error, backUpConnection is empty");
575                 return BError(BError::Codes::SA_INVAL_ARG);
576             }
577             auto proxy = backUpConnection->GetBackupExtProxy();
578             if (!proxy) {
579                 HILOGE("GetIncrementalFileHandle error, Extension backup Proxy is empty");
580                 return BError(BError::Codes::SA_INVAL_ARG);
581             }
582             ErrCode res = proxy->GetIncrementalFileHandle(fileName);
583             if (res != ERR_OK) {
584                 HILOGE("Failed to extension file handle");
585                 AppRadar::Info info (bundleName, "", "");
586                 AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::GetIncrementalFileHandle",
587                     GetUserIdDefault(), BizStageRestore::BIZ_STAGE_GET_FILE_HANDLE_FAIL, res);
588             }
589         } else {
590             SvcRestoreDepsManager::GetInstance().UpdateToRestoreBundleMap(bundleName, fileName);
591             session_->SetExtFileNameRequest(bundleName, fileName);
592         }
593         return BError(BError::Codes::OK);
594     } catch (const BError &e) {
595         return e.GetCode();
596     } catch (const exception &e) {
597         HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
598         return EPERM;
599     } catch (...) {
600         HILOGI("Unexpected exception");
601         return EPERM;
602     }
603 }
604 
IncrementalBackup(const string & bundleName)605 bool Service::IncrementalBackup(const string &bundleName)
606 {
607     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
608     IServiceReverse::Scenario scenario = session_->GetScenario();
609     auto backUpConnection = session_->GetExtConnection(bundleName);
610     if (backUpConnection == nullptr) {
611         throw BError(BError::Codes::SA_INVAL_ARG, "backUpConnection is empty");
612     }
613     auto proxy = backUpConnection->GetBackupExtProxy();
614     if (!proxy) {
615         throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
616     }
617     if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) {
618         auto ret = proxy->IncrementalOnBackup(session_->GetClearDataFlag(bundleName));
619         session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(ret, bundleName);
620         BundleBeginRadarReport(bundleName, ret, IServiceReverse::Scenario::BACKUP);
621         if (ret) {
622             ClearSessionAndSchedInfo(bundleName);
623             NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
624         }
625         return true;
626     } else if (scenario == IServiceReverse::Scenario::RESTORE && BackupPara().GetBackupOverrideIncrementalRestore() &&
627                session_->ValidRestoreDataType(RestoreTypeEnum::RESTORE_DATA_WAIT_SEND)) {
628         auto ret = proxy->HandleRestore(session_->GetClearDataFlag(bundleName));
629         session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleStarted(ret, bundleName);
630         BundleBeginRadarReport(bundleName, ret, IServiceReverse::Scenario::RESTORE);
631         auto fileNameVec = session_->GetExtFileNameRequest(bundleName);
632         for (auto &fileName : fileNameVec) {
633             ret = proxy->GetIncrementalFileHandle(fileName);
634             if (ret) {
635                 HILOGE("Failed to extension file handle %{public}s", fileName.c_str());
636             }
637         }
638         return true;
639     }
640     return false;
641 }
642 
NotifyCallerCurAppIncrementDone(ErrCode errCode,const std::string & callerName)643 void Service::NotifyCallerCurAppIncrementDone(ErrCode errCode, const std::string &callerName)
644 {
645     IServiceReverse::Scenario scenario = session_->GetScenario();
646     if (scenario == IServiceReverse::Scenario::BACKUP) {
647         HILOGI("will notify clone data, scenario is incremental backup");
648         session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(errCode, callerName);
649         BundleEndRadarReport(callerName, errCode, scenario);
650         auto now = std::chrono::system_clock::now();
651         auto time = std::chrono::system_clock::to_time_t(now);
652         auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
653         std::stringstream strTime;
654         strTime << (std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S:")) << (std::setfill('0'))
655             << (std::setw(INDEX)) << (ms.count() % MS_1000);
656         HiSysEventWrite(
657             OHOS::HiviewDFX::HiSysEvent::Domain::FILEMANAGEMENT,
658             FILE_BACKUP_EVENTS,
659             OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
660             "PROC_NAME", "ohos.appfileservice", "BUNDLENAME", callerName,
661             "PID", getpid(), "TIME", strTime.str()
662         );
663     } else if (scenario == IServiceReverse::Scenario::RESTORE) {
664         HILOGI("will notify clone data, scenario is Restore");
665         SendEndAppGalleryNotify(callerName);
666         session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleFinished(errCode, callerName);
667         BundleEndRadarReport(callerName, errCode, scenario);
668     }
669 }
670 
SendUserIdToApp(string & bundleName,int32_t userId)671 void Service::SendUserIdToApp(string &bundleName, int32_t userId)
672 {
673     if (session_ == nullptr) {
674         HILOGI("session_ is nullptr");
675         return;
676     }
677     HILOGI("Begin, bundleName: %{public}s", bundleName.c_str());
678     string detailInfo;
679     if (!BJsonUtil::BuildBundleInfoJson(userId, detailInfo)) {
680         HILOGE("BuildBundleInfoJson failed, bundleName : %{public}s", bundleName.c_str());
681         return;
682     }
683     session_->SetBackupExtInfo(bundleName, detailInfo);
684     HILOGI("End, bundleName:%{public}s, unicast info:%{public}s", bundleName.c_str(),
685         GetAnonyString(detailInfo).c_str());
686 }
687 
SetCurrentBackupSessProperties(const vector<string> & bundleNames,int32_t userId,vector<BJsonEntityCaps::BundleInfo> & backupBundleInfos,bool isIncBackup)688 void Service::SetCurrentBackupSessProperties(const vector<string> &bundleNames, int32_t userId,
689     vector<BJsonEntityCaps::BundleInfo> &backupBundleInfos, bool isIncBackup)
690 {
691     HILOGI("start SetCurrentBackupSessProperties");
692     std::map<std::string, BJsonEntityCaps::BundleInfo> bundleNameIndexBundleInfoMap;
693     for (auto &bundleInfo : backupBundleInfos) {
694         std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(bundleInfo.name, bundleInfo.appIndex);
695         bundleNameIndexBundleInfoMap[bundleNameIndexInfo] = bundleInfo;
696     }
697     for (auto item : bundleNames) {
698         std::string bundleName = item;
699         if (BundleMgrAdapter::IsUser0BundleName(bundleName, userId)) {
700             HILOGE("bundleName:%{public}s is zero user bundle", bundleName.c_str());
701             SendUserIdToApp(bundleName, userId);
702         }
703         auto it = bundleNameIndexBundleInfoMap.find(bundleName);
704         if (it == bundleNameIndexBundleInfoMap.end()) {
705             HILOGE("Current bundleName can not find bundleInfo, bundleName:%{public}s", bundleName.c_str());
706             session_->RemoveExtInfo(bundleName);
707             continue;
708         }
709         auto bundleInfo = it->second;
710         if (isIncBackup) {
711             session_->SetBundleDataSize(bundleName, bundleInfo.increSpaceOccupied);
712         } else {
713             session_->SetBundleDataSize(bundleName, bundleInfo.spaceOccupied);
714         }
715         session_->SetBackupExtName(bundleName, bundleInfo.extensionName);
716         session_->SetIsReadyLaunch(bundleName);
717     }
718     HILOGI("end SetCurrentBackupSessProperties");
719 }
720 } // namespace OHOS::FileManagement::Backup
721