• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 <cinttypes>
22 #include <cstddef>
23 #include <cstdint>
24 
25 #include <fcntl.h>
26 #include <iomanip>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <sys/vfs.h>
30 
31 #include <directory_ex.h>
32 #include <unique_fd.h>
33 
34 #include "accesstoken_kit.h"
35 #include "b_anony/b_anony.h"
36 #include "b_error/b_error.h"
37 #include "b_error/b_excep_utils.h"
38 #include "b_filesystem/b_dir.h"
39 #include "b_hiaudit/hi_audit.h"
40 #include "b_json/b_json_cached_entity.h"
41 #include "b_json/b_json_entity_caps.h"
42 #include "b_ohos/startup/backup_para.h"
43 #include "b_process/b_multiuser.h"
44 #include "b_radar/b_radar.h"
45 #include "b_resources/b_constants.h"
46 #include "b_sa/b_sa_utils.h"
47 #include "b_utils/b_time.h"
48 #include "filemgmt_libhilog.h"
49 #include "hisysevent.h"
50 #include "ipc_skeleton.h"
51 #include "module_external/bms_adapter.h"
52 #include "module_ipc/svc_backup_connection.h"
53 #include "module_ipc/svc_restore_deps_manager.h"
54 #include "parameter.h"
55 #include "system_ability_definition.h"
56 #include "hitrace_meter.h"
57 
58 namespace OHOS::FileManagement::Backup {
59 using namespace std;
60 const std::string FILE_BACKUP_EVENTS = "FILE_BACKUP_EVENTS";
61 
62 namespace {
63 constexpr int32_t INDEX = 3;
64 constexpr int32_t MS_1000 = 1000;
65 constexpr int32_t INCREMENTAL_COUNT = 1;
66 const static string UNICAST_TYPE = "unicast";
67 } // namespace
68 
Release()69 ErrCode Service::Release()
70 {
71     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
72     HILOGI("KILL");
73     if (session_ == nullptr) {
74         HILOGE("Release error, session is empty");
75         return BError(BError::Codes::SA_INVAL_ARG);
76     }
77     IServiceReverseType::Scenario scenario = session_->GetScenario();
78     VerifyCaller(scenario);
79     AppRadar::Info info("", "", "call release");
80     if (scenario == IServiceReverseType::Scenario::RESTORE) {
81         AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::Release", session_->GetSessionUserId(),
82             BizStageRestore::BIZ_STAGE_RELEASE, ERR_OK);
83     } else if (scenario == IServiceReverseType::Scenario::BACKUP) {
84         AppRadar::GetInstance().RecordBackupFuncRes(info, "Service::Release", session_->GetSessionUserId(),
85             BizStageBackup::BIZ_STAGE_RELEASE, ERR_OK);
86     }
87     SessionDeactive();
88     return BError(BError::Codes::OK);
89 }
90 
GetExtensionMutex(const BundleName & bundleName)91 std::shared_ptr<ExtensionMutexInfo> Service::GetExtensionMutex(const BundleName &bundleName)
92 {
93     std::unique_lock<std::mutex> lock(extensionMutexLock_);
94     auto it = backupExtMutexMap_.find(bundleName);
95     if (it == backupExtMutexMap_.end()) {
96         HILOGI("BackupExtMutexMap not contain %{public}s", bundleName.c_str());
97         backupExtMutexMap_[bundleName] = std::make_shared<ExtensionMutexInfo>(bundleName);
98         return backupExtMutexMap_[bundleName];
99     }
100     HILOGI("BackupExtMutexMap contain %{public}s", bundleName.c_str());
101     return it->second;
102 }
103 
RemoveExtensionMutex(const BundleName & bundleName)104 void Service::RemoveExtensionMutex(const BundleName &bundleName)
105 {
106     std::unique_lock<std::mutex> lock(extensionMutexLock_);
107     auto it = backupExtMutexMap_.find(bundleName);
108     if (it == backupExtMutexMap_.end()) {
109         HILOGI("BackupExtMutexMap not contain %{public}s", bundleName.c_str());
110         return;
111     }
112     backupExtMutexMap_.erase(it);
113 }
114 
CreateDirIfNotExist(const std::string & path)115 void Service::CreateDirIfNotExist(const std::string &path)
116 {
117     if (access(path.c_str(), F_OK) != 0) {
118         bool created = ForceCreateDirectory(path.data());
119         if (created) {
120             HILOGI("Create directory successfully.");
121         } else {
122             HILOGE("Failed to create directory, path = %{private}s, err = %{public}d", path.c_str(), errno);
123         }
124     }
125 }
GetLocalCapabilitiesIncremental(const std::vector<BIncrementalData> & bundleNames,int & fd)126 ErrCode Service::GetLocalCapabilitiesIncremental(const std::vector<BIncrementalData> &bundleNames, int &fd)
127 {
128     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
129     UniqueFd fdResult(GetLocalCapabilitiesIncremental(bundleNames));
130     fd = dup(fdResult.Get());
131     return BError(BError::Codes::OK); // anytime return OK
132 }
133 
CreateJsonEntity(UniqueFd & fd,vector<BJsonEntityCaps::BundleInfo> & bundleInfos,const std::vector<BIncrementalData> & bundleNames)134 BJsonCachedEntity<BJsonEntityCaps> Service::CreateJsonEntity(UniqueFd &fd,
135     vector<BJsonEntityCaps::BundleInfo>& bundleInfos, const std::vector<BIncrementalData> &bundleNames)
136 {
137     BJsonCachedEntity<BJsonEntityCaps> cachedEntity(move(fd));
138     auto cache = cachedEntity.Structuralize();
139     std::string backupVersion = BJsonUtil::ParseBackupVersion();
140     cache.SetBackupVersion(backupVersion);
141     cache.SetSystemFullName(GetOSFullName());
142     cache.SetDeviceType(GetDeviceType());
143     bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(GetUserIdDefault(), bundleNames);
144     cache.SetBundleInfos(bundleInfos, true);
145     cachedEntity.Persist();
146     HILOGI("Service GetLocalCapabilitiesIncremental persist, bundleInfos size:%{public}zu", bundleInfos.size());
147     isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT);
148     if (isCreatingIncreaseFile_.load() <= 0) {
149         isCreatingIncreaseFile_.store(0);
150         const int userId = GetUserIdDefault();
151         for (const auto &bundleInfo : bundleInfos) {
152             ClearIncrementalStatFile(userId, bundleInfo.name);
153         }
154         HILOGI("do ClearIncrementalStatFile finished");
155     }
156     return cachedEntity;
157 }
158 
GetLocalCapabilitiesIncremental(const std::vector<BIncrementalData> & bundleNames)159 UniqueFd Service::GetLocalCapabilitiesIncremental(const std::vector<BIncrementalData> &bundleNames)
160 {
161     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
162     try {
163         HILOGI("Begin");
164         if (session_ == nullptr || isOccupyingSession_.load()) {
165             HILOGE("Get LocalCapabilities Incremental Error, session is empty or cleaning up the service");
166             return UniqueFd(-ENOENT);
167         }
168         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
169         isCreatingIncreaseFile_.fetch_add(INCREMENTAL_COUNT);
170         ErrCode errCode = VerifyCaller();
171         if (errCode != ERR_OK) {
172             HILOGE("Get local abilities info failed, Verify caller failed, errCode:%{public}d", errCode);
173             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
174             isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT);
175             return UniqueFd(-ENOENT);
176         }
177         string path = BConstants::GetSaBundleBackupRootDir(GetUserIdDefault());
178         BExcepUltils::VerifyPath(path, false);
179         CreateDirIfNotExist(path);
180         UniqueFd fd(open(path.data(), O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR));
181         if (fd < 0) {
182             HILOGE("GetLocalCapabilitiesIncremental: open file failed, err = %{public}d", errno);
183             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
184             isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT);
185             return UniqueFd(-ENOENT);
186         }
187         vector<BJsonEntityCaps::BundleInfo> bundleInfos;
188         BJsonCachedEntity<BJsonEntityCaps> cachedEntity = CreateJsonEntity(fd, bundleInfos, bundleNames);
189         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
190         return move(cachedEntity.GetFd());
191     } catch (const BError &e) {
192         isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT);
193         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
194         HILOGE("GetLocalCapabilitiesIncremental failed, errCode = %{public}d", e.GetCode());
195         return UniqueFd(-e.GetCode());
196     } catch (...) {
197         isCreatingIncreaseFile_.fetch_sub(INCREMENTAL_COUNT);
198         HILOGE("Unexpected exception");
199         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
200         return UniqueFd(-EPERM);
201     }
202 }
203 
StartGetFdTask(std::string bundleName,wptr<Service> ptr)204 void Service::StartGetFdTask(std::string bundleName, wptr<Service> ptr)
205 {
206     auto thisPtr = ptr.promote();
207     if (!thisPtr) {
208         HILOGE("this pointer is null");
209         return;
210     }
211     auto session = thisPtr->session_;
212     if (session == nullptr) {
213         throw BError(BError::Codes::SA_INVAL_ARG, "session is nullptr");
214     }
215     auto backUpConnection = session->GetExtConnection(bundleName);
216     if (backUpConnection == nullptr) {
217         throw BError(BError::Codes::SA_INVAL_ARG, "backUpConnection is empty");
218     }
219     auto proxy = backUpConnection->GetBackupExtProxy();
220     if (!proxy) {
221         throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
222     }
223     // distinguish whether it is 0 user
224     if (BundleMgrAdapter::IsUser0BundleName(bundleName, session_->GetSessionUserId())) {
225         if (proxy->User0OnBackup()) {
226             SendEndAppGalleryNotify(bundleName);
227             thisPtr->ClearSessionAndSchedInfo(bundleName);
228             thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
229         }
230         return;
231     }
232     if (!session->StopExtTimer(bundleName)) {
233         throw BError(BError::Codes::SA_INVAL_ARG, "StopExtTimer error");
234     }
235     int64_t lastTime = session->GetLastIncrementalTime(bundleName);
236     std::vector<BIncrementalData> bundleNames;
237     bundleNames.emplace_back(BIncrementalData {bundleName, lastTime});
238     auto newBundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(bundleNames, session->GetSessionUserId());
239     RefreshBundleDataSize(newBundleInfos, bundleName, ptr);
240     string path = BConstants::GetSaBundleBackupRootDir(session->GetSessionUserId()).
241         append(bundleName).append("/").append(BConstants::BACKUP_STAT_SYMBOL).append(to_string(lastTime));
242     UniqueFd fdLocal(open(path.data(), O_RDWR, S_IRGRP | S_IWGRP));
243     if (fdLocal < 0) {
244         HILOGD("fdLocal open fail, error = %{public}d", errno);
245         throw BError(BError::Codes::SA_INVAL_ARG, "open local Manifest file failed");
246     }
247     UniqueFd lastManifestFd(session->GetIncrementalManifestFd(bundleName));
248     auto ret = proxy->HandleIncrementalBackup(move(fdLocal), move(lastManifestFd));
249     if (ret) {
250         SendEndAppGalleryNotify(bundleName);
251         thisPtr->ClearSessionAndSchedInfo(bundleName);
252         thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
253     }
254 }
255 
RefreshBundleDataSize(const vector<BJsonEntityCaps::BundleInfo> & newBundleInfos,std::string bundleName,wptr<Service> ptr)256 void Service::RefreshBundleDataSize(const vector<BJsonEntityCaps::BundleInfo> &newBundleInfos,
257     std::string bundleName, wptr<Service> ptr)
258 {
259     auto thisPtr = ptr.promote();
260     if (!thisPtr) {
261         HILOGE("this pointer is null");
262         return;
263     }
264     auto session = thisPtr->session_;
265     if (session == nullptr) {
266         HILOGE("session is nullptr");
267         return;
268     }
269     BJsonUtil::BundleDetailInfo bundleInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName);
270     for (const auto &info : newBundleInfos) {
271         if (info.name == bundleInfo.bundleName && info.appIndex == bundleInfo.bundleIndex) {
272             session->SetBundleDataSize(bundleName, info.increSpaceOccupied);
273             HILOGI("RefreshBundleDataSize, bundlename = %{public}s , datasize = %{public}" PRId64 "",
274                 bundleName.c_str(), info.increSpaceOccupied);
275         }
276     }
277 }
278 
GetAppLocalListAndDoIncrementalBackup()279 ErrCode Service::GetAppLocalListAndDoIncrementalBackup()
280 {
281     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
282     try {
283         if (session_ == nullptr || isOccupyingSession_.load()) {
284             HILOGE("session is nullptr");
285             return BError(BError::Codes::SA_INVAL_ARG);
286         }
287         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
288         session_->SetSessionUserId(GetUserIdDefault());
289         std::string bundleName;
290         ErrCode ret = VerifyCallerAndGetCallerName(bundleName);
291         if (ret != ERR_OK) {
292             HILOGE("Get AppLocalList failed, Get bundle failed, ret:%{public}d", ret);
293             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
294             return ret;
295         }
296         auto task = [this, bundleName]() {
297             StartGetFdTask(bundleName, wptr(this));
298         };
299         threadPool_.AddTask([task]() {
300             try {
301                 task();
302             } catch (const BError &e) {
303                 HILOGE("GetAppLocalListAndDoIncrementalBackup failed, errCode = %{public}d", e.GetCode());
304             } catch (...) {
305                 HILOGE("Unexpected exception");
306             }
307         });
308         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
309         return BError(BError::Codes::OK);
310     } catch (const BError &e) {
311         HILOGE("GetAppLocalListAndDoIncrementalBackup failed, errCode = %{public}d", e.GetCode());
312         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
313         return e.GetCode();
314     } catch (...) {
315         HILOGE("Unexpected exception");
316         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
317         return EPERM;
318     }
319 }
320 
InitIncrementalBackupSession(const sptr<IServiceReverse> & remote)321 ErrCode Service::InitIncrementalBackupSession(const sptr<IServiceReverse>& remote)
322 {
323     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
324     totalStatistic_ = std::make_shared<RadarTotalStatistic>(BizScene::BACKUP, GetCallerName(), Mode::INCREMENTAL);
325     ErrCode errCode = VerifyCaller();
326     if (errCode != ERR_OK) {
327         HILOGE("Init incremental backup session fail, Verify caller failed, errCode:%{public}d", errCode);
328         totalStatistic_->Report("InitIncrementalBackupSession", MODULE_INIT, errCode);
329         return errCode;
330     }
331     if (session_ == nullptr) {
332         HILOGE("Init Incremental backup session  error, session is empty");
333         return BError(BError::Codes::SA_INVAL_ARG);
334     }
335     errCode = session_->Active({.clientToken = IPCSkeleton::GetCallingTokenID(),
336                                 .scenario = IServiceReverseType::Scenario::BACKUP,
337                                 .clientProxy = remote,
338                                 .userId = GetUserIdDefault(),
339                                 .isIncrementalBackup = true,
340                                 .callerName = GetCallerName(),
341                                 .activeTime = TimeUtils::GetCurrentTime()});
342     if (errCode == ERR_OK) {
343         HILOGE("Success to init a new incremental backup session");
344         ClearFailedBundles();
345         successBundlesNum_ = 0;
346         ClearBundleRadarReport();
347         ClearFileReadyRadarReport();
348         return errCode;
349     }
350     totalStatistic_->Report("InitIncrementalBackupSession", MODULE_INIT, errCode);
351     if (errCode == BError(BError::Codes::SA_SESSION_CONFLICT)) {
352         HILOGE("Active incremental backup error, Already have a session");
353         return errCode;
354     }
355     HILOGE("Active backup session error");
356     StopAll(nullptr, true);
357     return errCode;
358 }
359 
InitIncrementalBackupSessionWithErrMsg(const sptr<IServiceReverse> & remote,int32_t & errCodeForMsg,std::string & errMsg)360 ErrCode Service::InitIncrementalBackupSessionWithErrMsg(const sptr<IServiceReverse>& remote, int32_t &errCodeForMsg,
361                                                         std::string &errMsg)
362 {
363     errCodeForMsg = InitIncrementalBackupSession(remote, errMsg);
364     HILOGI("Start InitIncrementalBackupSessionWithErrMsg, errCode:%{public}d, Msg :%{public}s",
365            errCodeForMsg,
366            errMsg.c_str());
367     return ERR_OK;
368 }
369 
InitIncrementalBackupSession(const sptr<IServiceReverse> & remote,std::string & errMsg)370 ErrCode Service::InitIncrementalBackupSession(const sptr<IServiceReverse>& remote, std::string &errMsg)
371 {
372     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
373     totalStatistic_ = std::make_shared<RadarTotalStatistic>(BizScene::BACKUP, GetCallerName(), Mode::INCREMENTAL);
374     ErrCode errCode = VerifyCaller();
375     if (errCode != ERR_OK) {
376         HILOGE("Init incremental backup session fail, Verify caller failed, errCode:%{public}d", errCode);
377         totalStatistic_->Report("InitIncrementalBackupSessionWithErrMsg", MODULE_INIT, errCode);
378         return errCode;
379     }
380     if (session_ == nullptr) {
381         HILOGE("Init Incremental backup session  error, session is empty");
382         return BError(BError::Codes::SA_INVAL_ARG);
383     }
384     errCode = session_->Active({.clientToken = IPCSkeleton::GetCallingTokenID(),
385                                 .scenario = IServiceReverseType::Scenario::BACKUP,
386                                 .clientProxy = remote,
387                                 .userId = GetUserIdDefault(),
388                                 .isIncrementalBackup = true,
389                                 .callerName = GetCallerName(),
390                                 .activeTime = TimeUtils::GetCurrentTime()});
391     if (errCode == ERR_OK) {
392         ClearFailedBundles();
393         successBundlesNum_ = 0;
394         ClearBundleRadarReport();
395         ClearFileReadyRadarReport();
396         return errCode;
397     }
398     totalStatistic_->Report("InitIncrementalBackupSessionWithErrMsg", MODULE_INIT, errCode);
399     if (errCode == BError(BError::Codes::SA_SESSION_CONFLICT)) {
400         errMsg = BJsonUtil::BuildInitSessionErrInfo(session_->GetSessionUserId(),
401                                                     session_->GetSessionCallerName(),
402                                                     session_->GetSessionActiveTime());
403         HILOGE("Active incremental backup session error, Already have a session");
404         return errCode;
405     }
406     HILOGE("Active incremental backup session error");
407     StopAll(nullptr, true);
408     return errCode;
409 }
410 
GetBundleNameByDetails(const std::vector<BIncrementalData> & bundlesToBackup)411 vector<string> Service::GetBundleNameByDetails(const std::vector<BIncrementalData> &bundlesToBackup)
412 {
413     vector<string> bundleNames {};
414     for (const auto &bundle : bundlesToBackup) {
415         bundleNames.emplace_back(bundle.bundleName);
416     }
417     return bundleNames;
418 }
419 
AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> & bundlesToBackup)420 ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup)
421 {
422     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
423     TotalStart();
424     vector<string> bundleNames;
425     try {
426         if (session_ == nullptr || isOccupyingSession_.load()) {
427             HILOGE("Init Incremental backup session  error, session is empty");
428             return BError(BError::Codes::SA_INVAL_ARG);
429         }
430         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时
431         bundleNames = GetBundleNameByDetails(bundlesToBackup);
432         ErrCode ret = VerifyCaller(IServiceReverseType::Scenario::BACKUP);
433         if (ret != ERR_OK) {
434             HILOGE("Append bundles incremental session failed, verify caller failed, ret:%{public}d", ret);
435             HandleExceptionOnAppendBundles(session_, bundleNames, {});
436             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
437             return ret;
438         }
439         GetBundleInfoStart();
440         auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppendBundles(bundlesToBackup,
441             session_->GetSessionUserId());
442         GetBundleInfoEnd();
443         std::vector<std::string> supportBackupNames = GetSupportBackupBundleNames(backupInfos, true, bundleNames);
444         AppendBundles(supportBackupNames);
445         SetBundleIncDataInfo(bundlesToBackup, supportBackupNames);
446         SetCurrentBackupSessProperties(supportBackupNames, session_->GetSessionUserId(), backupInfos, true);
447         OnStartSched();
448         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
449         return BError(BError::Codes::OK);
450     } catch (const BError &e) {
451         HILOGE("Failed, errCode = %{public}d", e.GetCode());
452         HandleExceptionOnAppendBundles(session_, bundleNames, {});
453         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
454         return e.GetCode();
455     } catch (...) {
456         HILOGE("Unexpected exception");
457         HandleExceptionOnAppendBundles(session_, bundleNames, {});
458         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
459         return EPERM;
460     }
461 }
AppendBundlesIncrementalBackupSessionWithBundleInfos(const std::vector<BIncrementalData> & bundlesToBackup,const std::vector<std::string> & bundleInfos)462 ErrCode Service::AppendBundlesIncrementalBackupSessionWithBundleInfos(
463     const std::vector<BIncrementalData> &bundlesToBackup, const std::vector<std::string> &bundleInfos)
464 {
465     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
466     return AppendBundlesIncrementalBackupSession(bundlesToBackup, bundleInfos);
467 }
468 
AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> & bundlesToBackup,const std::vector<std::string> & infos)469 ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup,
470     const std::vector<std::string> &infos)
471 {
472     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
473     TotalStart();
474     vector<string> bundleNames;
475     try {
476         if (session_ == nullptr || isOccupyingSession_.load()) {
477             HILOGE("Init Incremental backup session error, session is empty");
478             return BError(BError::Codes::SA_INVAL_ARG);
479         }
480         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时
481         bundleNames = GetBundleNameByDetails(bundlesToBackup);
482         ErrCode ret = VerifyCaller(IServiceReverseType::Scenario::BACKUP);
483         if (ret != ERR_OK) {
484             HILOGE("Append bundles incremental session with infos failed, verify caller failed, ret:%{public}d", ret);
485             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
486             HandleExceptionOnAppendBundles(session_, bundleNames, {});
487             return ret;
488         }
489         std::vector<std::string> bundleNamesOnly;
490         std::map<std::string, bool> isClearDataFlags;
491         std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> bundleNameDetailMap =
492             BJsonUtil::BuildBundleInfos(bundleNames, infos, bundleNamesOnly,
493             session_->GetSessionUserId(), isClearDataFlags);
494         GetBundleInfoStart();
495         auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppendBundles(bundlesToBackup,
496             session_->GetSessionUserId());
497         GetBundleInfoEnd();
498         std::vector<std::string> supportBackupNames = GetSupportBackupBundleNames(backupInfos, true, bundleNames);
499         AppendBundles(supportBackupNames);
500         SetBundleIncDataInfo(bundlesToBackup, supportBackupNames);
501         HandleCurGroupIncBackupInfos(backupInfos, bundleNameDetailMap, isClearDataFlags);
502         OnStartSched();
503         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
504         return BError(BError::Codes::OK);
505     } catch (const BError &e) {
506         HILOGE("Failed, errCode = %{public}d", e.GetCode());
507         HandleExceptionOnAppendBundles(session_, bundleNames, {});
508         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
509         return e.GetCode();
510     } catch (...) {
511         HILOGE("Unexpected exception");
512         HandleExceptionOnAppendBundles(session_, bundleNames, {});
513         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
514         return EPERM;
515     }
516 }
517 
HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> & backupInfos,std::map<std::string,std::vector<BJsonUtil::BundleDetailInfo>> & bundleNameDetailMap,std::map<std::string,bool> & isClearDataFlags)518 void Service::HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> &backupInfos,
519     std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> &bundleNameDetailMap,
520     std::map<std::string, bool> &isClearDataFlags)
521 {
522     for (auto &info : backupInfos) {
523         HILOGI("Current backupInfo bundleName:%{public}s, index:%{public}d, extName:%{public}s", info.name.c_str(),
524             info.appIndex, info.extensionName.c_str());
525         std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex);
526         SetCurrentSessProperties(info, isClearDataFlags, bundleNameIndexInfo);
527         session_->SetBundleDataSize(bundleNameIndexInfo, info.increSpaceOccupied);
528         BJsonUtil::BundleDetailInfo uniCastInfo;
529         if (BJsonUtil::FindBundleInfoByName(bundleNameDetailMap, bundleNameIndexInfo, UNICAST_TYPE, uniCastInfo)) {
530             HILOGI("current bundle:%{public}s, unicast info:%{public}s", bundleNameIndexInfo.c_str(),
531                 GetAnonyString(uniCastInfo.detail).c_str());
532             session_->SetBackupExtInfo(bundleNameIndexInfo, uniCastInfo.detail);
533         }
534         session_->SetBackupExtName(bundleNameIndexInfo, info.extensionName);
535         session_->SetIsReadyLaunch(bundleNameIndexInfo);
536     }
537 }
538 
PublishIncrementalFile(const BFileInfo & fileInfo)539 ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo)
540 {
541     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
542     ErrCode ret = VerifyCaller(IServiceReverseType::Scenario::RESTORE);
543     if (ret != ERR_OK) {
544         HILOGE("Publish incremental file failed, bundleName:%{public}s", fileInfo.owner.c_str());
545         return ret;
546     }
547     HILOGI("Start get ExtConnection, bundleName:%{public}s", fileInfo.owner.c_str());
548     if (!fileInfo.fileName.empty()) {
549         HILOGE("Forbit to use PublishIncrementalFile with fileName for App");
550         return EPERM;
551     }
552     if (session_ == nullptr) {
553         HILOGE("session is empty, bundleName:%{public}s", fileInfo.owner.c_str());
554         return BError(BError::Codes::SA_INVAL_ARG);
555     }
556     session_->SetPublishFlag(fileInfo.owner);
557     auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
558     if (backUpConnection == nullptr) {
559         HILOGE("backUpConnection is empty, bundle:%{public}s", fileInfo.owner.c_str());
560         return BError(BError::Codes::SA_INVAL_ARG);
561     }
562     auto proxy = backUpConnection->GetBackupExtProxy();
563     if (!proxy) {
564         HILOGE("Publish Incremental file failed, bundleName:%{public}s", fileInfo.owner.c_str());
565         return BError(BError::Codes::SA_INVAL_ARG);
566     }
567     ret = proxy->PublishIncrementalFile(fileInfo.fileName);
568     if (ret != ERR_OK) {
569         HILOGE("Failed to publish file for backup extension, bundleName:%{public}s", fileInfo.owner.c_str());
570         return ret;
571     }
572     return BError(BError::Codes::OK);
573 }
574 
PublishSAIncrementalFile(const BFileInfo & fileInfo,int fd)575 ErrCode Service::PublishSAIncrementalFile(const BFileInfo& fileInfo, int fd)
576 {
577     UniqueFd uniquedParameter(fd);
578     return PublishSAIncrementalFile(fileInfo, std::move(uniquedParameter));
579 }
580 
PublishSAIncrementalFile(const BFileInfo & fileInfo,UniqueFd fd)581 ErrCode Service::PublishSAIncrementalFile(const BFileInfo &fileInfo, UniqueFd fd)
582 {
583     std::string bundleName = fileInfo.owner;
584     if (totalStatistic_ != nullptr) {
585         std::unique_lock<std::shared_mutex> mapLock(statMapMutex_);
586         std::shared_ptr<RadarAppStatistic> saStatistic = std::make_shared<RadarAppStatistic>(bundleName,
587             totalStatistic_->GetUniqId(), totalStatistic_->GetBizScene());
588         saStatistic->doRestoreStart_ = static_cast<uint64_t>(TimeUtils::GetTimeMS());
589         saStatisticMap_[bundleName] = saStatistic;
590     }
591     ErrCode errCode = VerifyCaller();
592     if (errCode != ERR_OK) {
593         HILOGE("PublishSAIncrementalFile failed, verify caller failed, bundleName:%{public}s, errCode:%{public}d",
594             bundleName.c_str(), errCode);
595         return errCode;
596     }
597     if (!SAUtils::IsSABundleName(bundleName)) {
598         HILOGE("Bundle name %{public}s is not sa", bundleName.c_str());
599         return BError(BError::Codes::SA_EXT_ERR_CALL);
600     }
601     HILOGI("Bundle name %{public}s is sa, publish sa incremental file", bundleName.c_str());
602     auto backupConnection = session_->GetSAExtConnection(bundleName);
603     std::shared_ptr<SABackupConnection> saConnection = backupConnection.lock();
604     if (saConnection == nullptr) {
605         HILOGE("lock sa connection ptr is nullptr");
606         return BError(BError::Codes::SA_INVAL_ARG);
607     }
608     return saConnection->CallRestoreSA(move(fd));
609 }
610 
AppIncrementalFileReady(const std::string & bundleName,const std::string & fileName,UniqueFd fd,UniqueFd manifestFd,int32_t errCode)611 ErrCode Service::AppIncrementalFileReady(const std::string &bundleName, const std::string &fileName, UniqueFd fd,
612                                          UniqueFd manifestFd, int32_t errCode)
613 {
614     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
615     try {
616         bool fdFlag = (fd < 0 || manifestFd < 0) ? true : false;
617         if (session_->GetScenario() == IServiceReverseType::Scenario::RESTORE) {
618             fdFlag ? session_->GetServiceReverseProxy()->IncrementalRestoreOnFileReadyWithoutFd(bundleName, fileName,
619                                                                                                 errCode) :
620                      session_->GetServiceReverseProxy()->IncrementalRestoreOnFileReady(bundleName, fileName, move(fd),
621                                                                                        move(manifestFd), errCode);
622             FileReadyRadarReport(bundleName, fileName, errCode, IServiceReverseType::Scenario::RESTORE);
623             return BError(BError::Codes::OK);
624         }
625         if (fileName == BConstants::EXT_BACKUP_MANAGE) {
626             fd = session_->OnBundleExtManageInfo(bundleName, move(fd));
627         }
628         fdFlag = (fd < 0 || manifestFd < 0) ? true : false;
629         fdFlag ? session_->GetServiceReverseProxy()->IncrementalBackupOnFileReadyWithoutFd(bundleName, fileName,
630                                                                                            errCode) :
631                  session_->GetServiceReverseProxy()->IncrementalBackupOnFileReady(bundleName, fileName, move(fd),
632                                                                                   move(manifestFd), errCode);
633         FileReadyRadarReport(bundleName, fileName, errCode, IServiceReverseType::Scenario::BACKUP);
634         if (session_->OnBundleFileReady(bundleName, fileName)) {
635             ErrCode ret = HandleCurBundleFileReady(bundleName, fileName, true);
636             if (ret != ERR_OK) {
637                 HILOGE("Handle current file failed, bundleName:%{public}s, fileName:%{public}s",
638                     bundleName.c_str(), GetAnonyPath(fileName).c_str());
639                 return ret;
640             }
641         }
642         OnAllBundlesFinished(BError(BError::Codes::OK));
643         return BError(BError::Codes::OK);
644     } catch (const BError &e) {
645         HILOGE("AppIncrementalFileReady exception");
646         return e.GetCode(); // 任意异常产生,终止监听该任务
647     } catch (...) {
648         HILOGE("Unexpected exception");
649         return EPERM;
650     }
651 }
652 
AppIncrementalFileReady(const std::string & fileName,int fd,int manifestFd,int32_t appIncrementalFileReadyErrCode)653 ErrCode Service::AppIncrementalFileReady(const std::string &fileName, int fd, int manifestFd,
654                                          int32_t appIncrementalFileReadyErrCode)
655 {
656     HILOGI("Begin AppIncrementalFileReady:%{public}s, fd:%{public}d, manifestFd:%{public}d, errcode:%{public}d",
657            fileName.c_str(), fd, manifestFd, appIncrementalFileReadyErrCode);
658     UniqueFd fdUnique(fd);
659     UniqueFd manifestFdUnique(manifestFd);
660     return AppIncrementalFileReady(fileName, std::move(fdUnique), std::move(manifestFdUnique),
661                                    appIncrementalFileReadyErrCode);
662 }
663 
AppIncrementalFileReadyWithoutFd(const std::string & fileName,int32_t appIncrementalFileReadyErrCode)664 ErrCode Service::AppIncrementalFileReadyWithoutFd(const std::string &fileName, int32_t appIncrementalFileReadyErrCode)
665 {
666     return AppIncrementalFileReady(fileName, UniqueFd(BConstants::INVALID_FD_NUM),
667                                    UniqueFd(BConstants::INVALID_FD_NUM),
668                                    appIncrementalFileReadyErrCode);
669 }
670 
AppIncrementalFileReady(const std::string & fileName,UniqueFd fd,UniqueFd manifestFd,int32_t errCode)671 ErrCode Service::AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd, int32_t errCode)
672 {
673     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
674     try {
675         string callerName;
676         ErrCode ret = VerifyCallerAndGetCallerName(callerName);
677         if (ret != ERR_OK) {
678             HILOGE("Verify caller failed, ret:%{public}d", ret);
679             return ret;
680         }
681         bool fdFlag = (fd < 0 || manifestFd < 0) ? true : false;
682         if (session_->GetScenario() == IServiceReverseType::Scenario::RESTORE) {
683             fdFlag ? session_->GetServiceReverseProxy()->IncrementalRestoreOnFileReadyWithoutFd(callerName, fileName,
684                                                                                                 errCode) :
685                      session_->GetServiceReverseProxy()->IncrementalRestoreOnFileReady(callerName, fileName, move(fd),
686                                                                                        move(manifestFd), errCode);
687             FileReadyRadarReport(callerName, fileName, errCode, IServiceReverseType::Scenario::RESTORE);
688             return BError(BError::Codes::OK);
689         }
690         if (fileName == BConstants::EXT_BACKUP_MANAGE) {
691             fd = session_->OnBundleExtManageInfo(callerName, move(fd));
692         }
693         fdFlag = (fd < 0 || manifestFd < 0) ? true : false;
694         fdFlag ? session_->GetServiceReverseProxy()->IncrementalBackupOnFileReadyWithoutFd(callerName, fileName,
695                                                                                            errCode) :
696                  session_->GetServiceReverseProxy()->IncrementalBackupOnFileReady(callerName, fileName, move(fd),
697                                                                                   move(manifestFd), errCode);
698         FileReadyRadarReport(callerName, fileName, errCode, IServiceReverseType::Scenario::BACKUP);
699         if (session_->OnBundleFileReady(callerName, fileName)) {
700             ErrCode ret = HandleCurBundleFileReady(callerName, fileName, true);
701             if (ret != ERR_OK) {
702                 HILOGE("Handle current file failed, bundleName:%{public}s, fileName:%{public}s",
703                     callerName.c_str(), GetAnonyPath(fileName).c_str());
704                 return ret;
705             }
706         }
707         OnAllBundlesFinished(BError(BError::Codes::OK));
708         return BError(BError::Codes::OK);
709     } catch (const BError &e) {
710         HILOGE("AppIncrementalFileReady exception");
711         return e.GetCode(); // 任意异常产生,终止监听该任务
712     } catch (...) {
713         HILOGE("Unexpected exception");
714         return EPERM;
715     }
716 }
717 
AppIncrementalDone(ErrCode errCode)718 ErrCode Service::AppIncrementalDone(ErrCode errCode)
719 {
720     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
721     try {
722         if (session_ == nullptr) {
723             HILOGE("AppIncrementalDone error, session is null");
724             return BError(BError::Codes::SA_INVAL_ARG);
725         }
726         string callerName;
727         ErrCode ret = VerifyCallerAndGetCallerName(callerName);
728         if (ret != ERR_OK) {
729             HILOGE("App incremental done fail, ret:%{public}d", ret);
730             return ret;
731         }
732         HILOGI("Service AppIncrementalDone start, callerName is %{public}s, errCode is: %{public}d",
733             callerName.c_str(), errCode);
734         ClearIncrementalStatFile(GetUserIdDefault(), callerName);
735         if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) {
736             std::shared_ptr<ExtensionMutexInfo> mutexPtr = GetExtensionMutex(callerName);
737             if (mutexPtr == nullptr) {
738                 HILOGE("extension mutex ptr is nullptr, bundleName:%{public}s", callerName.c_str());
739                 return BError(BError::Codes::SA_INVAL_ARG);
740             }
741             std::lock_guard<std::mutex> lock(mutexPtr->callbackMutex);
742             SetExtOnRelease(callerName, true);
743             return BError(BError::Codes::OK);
744         }
745         RemoveExtensionMutex(callerName);
746         OnAllBundlesFinished(BError(BError::Codes::OK));
747         return BError(BError::Codes::OK);
748     } catch (const BError &e) {
749         ReleaseOnException();
750         HILOGE("AppIncrementalDone error, err code is:%{public}d", e.GetCode());
751         return e.GetCode(); // 任意异常产生,终止监听该任务
752     } catch (...) {
753         ReleaseOnException();
754         HILOGI("Unexpected exception");
755         return EPERM;
756     }
757 }
758 
GetIncrementalFileHandle(const std::string & bundleName,const std::string & fileName)759 ErrCode Service::GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName)
760 {
761     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
762     try {
763         HILOGI("Begin get incrementalFileHandle");
764         if (session_ == nullptr) {
765             HILOGE("GetIncrementalFileHandle error, session is empty");
766             return BError(BError::Codes::SA_INVAL_ARG);
767         }
768         ErrCode ret = VerifyCaller(IServiceReverseType::Scenario::RESTORE);
769         if (ret != ERR_OK) {
770             HILOGE("Error, bundleName:%{public}s, fileName:%{public}s", bundleName.c_str(),
771                    GetAnonyPath(fileName).c_str());
772             return ret;
773         }
774         if (!BDir::IsFilePathValid(fileName)) {
775             HILOGE("path is forbidden, path : %{public}s", GetAnonyPath(fileName).c_str());
776             return BError(BError::Codes::SA_INVAL_ARG);
777         }
778         auto action = session_->GetServiceSchedAction(bundleName);
779         if (action == BConstants::ServiceSchedAction::UNKNOWN) {
780             HILOGE("action is unknown, bundleName:%{public}s", bundleName.c_str());
781             return BError(BError::Codes::SA_INVAL_ARG);
782         }
783         if (action == BConstants::ServiceSchedAction::RUNNING) {
784             HILOGI("Restore getIncrementalFileHandle begin, bundleName:%{public}s, fileName:%{public}s",
785                 bundleName.c_str(), GetAnonyPath(fileName).c_str());
786             auto err = SendIncrementalFileHandle(bundleName, fileName);
787             if (err != ERR_OK) {
788                 HILOGE("SendIncrementalFileHandle failed, bundle:%{public}s", bundleName.c_str());
789                 return err;
790             }
791         } else {
792             SvcRestoreDepsManager::GetInstance().UpdateToRestoreBundleMap(bundleName, fileName);
793             session_->SetExtFileNameRequest(bundleName, fileName);
794         }
795         return BError(BError::Codes::OK);
796     } catch (const BError &e) {
797         HILOGE("GetIncrementalFileHandle exception, bundleName:%{public}s", bundleName.c_str());
798         return e.GetCode();
799     }
800 }
801 
SendIncrementalFileHandle(const std::string & bundleName,const std::string & fileName)802 ErrCode Service::SendIncrementalFileHandle(const std::string &bundleName, const std::string &fileName)
803 {
804     auto backUpConnection = session_->GetExtConnection(bundleName);
805     if (backUpConnection == nullptr) {
806         HILOGE("backUpConnection is empty, bundle:%{public}s", bundleName.c_str());
807         return BError(BError::Codes::SA_INVAL_ARG);
808     }
809     auto proxy = backUpConnection->GetBackupExtProxy();
810     if (!proxy) {
811         HILOGE("GetIncrementalFileHandle failed, bundleName:%{public}s", bundleName.c_str());
812         return BError(BError::Codes::SA_INVAL_ARG);
813     }
814     int fdVal = BConstants::INVALID_FD_NUM;
815     int reportFdVal = BConstants::INVALID_FD_NUM;
816     int errCode = BConstants::INVALID_FD_NUM;
817     proxy->GetIncrementalFileHandle(fileName, fdVal, reportFdVal, errCode);
818     UniqueFd fd(fdVal);
819     UniqueFd reportFd(reportFdVal);
820     auto err = AppIncrementalFileReady(bundleName, fileName, move(fd), move(reportFd), errCode);
821     if (err != ERR_OK) {
822         HILOGE("Failed to send file handle, bundleName:%{public}s, fileName:%{public}s",
823             bundleName.c_str(), GetAnonyPath(fileName).c_str());
824         AppRadar::Info info (bundleName, "", "");
825         AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::GetIncrementalFileHandle",
826             GetUserIdDefault(), BizStageRestore::BIZ_STAGE_GET_FILE_HANDLE_FAIL, err);
827     }
828     return BError(BError::Codes::OK);
829 }
830 
IncrementalBackup(const string & bundleName)831 bool Service::IncrementalBackup(const string &bundleName)
832 {
833     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
834     IServiceReverseType::Scenario scenario = session_->GetScenario();
835     auto backUpConnection = session_->GetExtConnection(bundleName);
836     if (backUpConnection == nullptr) {
837         HILOGE("backUpConnection is empty, bundle:%{public}s", bundleName.c_str());
838         SendEndAppGalleryNotify(bundleName);
839         NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
840         return true;
841     }
842     auto proxy = backUpConnection->GetBackupExtProxy();
843     if (!proxy) {
844         HILOGE("Increment backup error, extension proxy is empty, bundleName:%{public}s", bundleName.c_str());
845         SendEndAppGalleryNotify(bundleName);
846         NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
847         return true;
848     }
849     if (scenario == IServiceReverseType::Scenario::BACKUP && session_->GetIsIncrementalBackup()) {
850         auto ret = proxy->IncrementalOnBackup(session_->GetClearDataFlag(bundleName));
851         session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(ret, bundleName);
852         BundleBeginRadarReport(bundleName, ret, IServiceReverseType::Scenario::BACKUP);
853         if (ret) {
854             SendEndAppGalleryNotify(bundleName);
855             ClearSessionAndSchedInfo(bundleName);
856             NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
857         }
858         return true;
859     } else if (scenario == IServiceReverseType::Scenario::RESTORE &&
860                BackupPara().GetBackupOverrideIncrementalRestore() &&
861                session_->ValidRestoreDataType(RestoreTypeEnum::RESTORE_DATA_WAIT_SEND)) {
862         auto ret = proxy->HandleRestore(session_->GetClearDataFlag(bundleName));
863         session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleStarted(ret, bundleName);
864         std::string oldBackupVersion = session_->GetOldBackupVersion();
865         if (oldBackupVersion.empty()) {
866             HILOGE("Failed to get backupVersion of old device");
867         }
868         HILOGD("backupVersion of old device = %{public}s", oldBackupVersion.c_str());
869         BundleBeginRadarReport(bundleName, ret, IServiceReverseType::Scenario::RESTORE);
870         auto fileNameVec = session_->GetExtFileNameRequest(bundleName);
871         for (const auto &fileName : fileNameVec) {
872             ret = HelpToAppIncrementalFileReady(bundleName, fileName, proxy);
873             if (ret) {
874                 HILOGE("Failed to send file handle %{public}s", GetAnonyString(fileName).c_str());
875             }
876         }
877         return true;
878     }
879     return false;
880 }
HelpToAppIncrementalFileReady(const string & bundleName,const string & fileName,sptr<IExtension> proxy)881 ErrCode Service::HelpToAppIncrementalFileReady(const string &bundleName, const string &fileName, sptr<IExtension> proxy)
882 {
883     int fdVal = BConstants::INVALID_FD_NUM;
884     int reportFdVal = BConstants::INVALID_FD_NUM;
885     int errCode = BConstants::INVALID_FD_NUM;
886     proxy->GetIncrementalFileHandle(fileName, fdVal, reportFdVal, errCode);
887     UniqueFd fd(fdVal);
888     UniqueFd reportFd(reportFdVal);
889     auto ret = AppIncrementalFileReady(bundleName, fileName, move(fd), move(reportFd), errCode);
890     return ret;
891 }
892 
IncrementalBackupSA(std::string bundleName)893 ErrCode Service::IncrementalBackupSA(std::string bundleName)
894 {
895     HILOGI("IncrementalBackupSA begin %{public}s", bundleName.c_str());
896     if (totalStatistic_ != nullptr) {
897         std::unique_lock<std::shared_mutex> mapLock(statMapMutex_);
898         std::shared_ptr<RadarAppStatistic> saStatistic = std::make_shared<RadarAppStatistic>(bundleName,
899             totalStatistic_->GetUniqId(), totalStatistic_->GetBizScene());
900         saStatistic->doBackupSpend_.Start();
901         saStatisticMap_[bundleName] = saStatistic;
902     }
903     IServiceReverseType::Scenario scenario = session_->GetScenario();
904     auto backUpConnection = session_->GetSAExtConnection(bundleName);
905     std::shared_ptr<SABackupConnection> saConnection = backUpConnection.lock();
906     if (saConnection == nullptr) {
907         HILOGE("lock sa connection ptr is nullptr");
908         return BError(BError::Codes::SA_INVAL_ARG);
909     }
910     if (scenario == IServiceReverseType::Scenario::BACKUP) {
911         auto ret = saConnection->CallBackupSA();
912         session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(ret, bundleName);
913         BundleBeginRadarReport(bundleName, ret, scenario);
914         if (ret) {
915             HILOGE("IncrementalBackupSA ret is %{public}d", ret);
916             ClearSessionAndSchedInfo(bundleName);
917             NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
918             return BError(ret);
919         }
920     } else if (scenario == IServiceReverseType::Scenario::RESTORE) {
921         session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleStarted(BError(BError::Codes::OK), bundleName);
922     }
923     return BError(BError::Codes::OK);
924 }
925 
NotifyCallerCurAppIncrementDone(ErrCode errCode,const std::string & callerName)926 void Service::NotifyCallerCurAppIncrementDone(ErrCode errCode, const std::string &callerName)
927 {
928     UpdateHandleCnt(errCode);
929     IServiceReverseType::Scenario scenario = session_->GetScenario();
930     if (scenario == IServiceReverseType::Scenario::BACKUP) {
931         HILOGI("will notify clone data, scenario is incremental backup");
932         session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(errCode, callerName);
933         BundleEndRadarReport(callerName, errCode, scenario);
934         auto now = std::chrono::system_clock::now();
935         auto time = std::chrono::system_clock::to_time_t(now);
936         auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
937         std::stringstream strTime;
938         strTime << (std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S:")) << (std::setfill('0'))
939             << (std::setw(INDEX)) << (ms.count() % MS_1000);
940         HiSysEventWrite(
941             OHOS::HiviewDFX::HiSysEvent::Domain::FILEMANAGEMENT,
942             FILE_BACKUP_EVENTS,
943             OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
944             "PROC_NAME", "ohos.appfileservice", "BUNDLENAME", callerName,
945             "PID", getpid(), "TIME", strTime.str()
946         );
947     } else if (scenario == IServiceReverseType::Scenario::RESTORE) {
948         HILOGI("will notify clone data, scenario is Restore");
949         session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleFinished(errCode, callerName);
950         BundleEndRadarReport(callerName, errCode, scenario);
951     }
952 }
953 
SendUserIdToApp(string & bundleName,int32_t userId)954 void Service::SendUserIdToApp(string &bundleName, int32_t userId)
955 {
956     if (session_ == nullptr) {
957         HILOGI("session_ is nullptr");
958         return;
959     }
960     HILOGI("Begin, bundleName: %{public}s", bundleName.c_str());
961     string detailInfo;
962     if (!BJsonUtil::BuildBundleInfoJson(userId, detailInfo)) {
963         HILOGE("BuildBundleInfoJson failed, bundleName : %{public}s", bundleName.c_str());
964         return;
965     }
966     session_->SetBackupExtInfo(bundleName, detailInfo);
967     HILOGI("End, bundleName:%{public}s, unicast info:%{public}s", bundleName.c_str(),
968         GetAnonyString(detailInfo).c_str());
969 }
970 
SetCurrentBackupSessProperties(const vector<string> & bundleNames,int32_t userId,vector<BJsonEntityCaps::BundleInfo> & backupBundleInfos,bool isIncBackup)971 void Service::SetCurrentBackupSessProperties(const vector<string> &bundleNames, int32_t userId,
972     vector<BJsonEntityCaps::BundleInfo> &backupBundleInfos, bool isIncBackup)
973 {
974     HILOGI("start SetCurrentBackupSessProperties");
975     std::map<std::string, BJsonEntityCaps::BundleInfo> bundleNameIndexBundleInfoMap;
976     for (const auto &bundleInfo : backupBundleInfos) {
977         std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(bundleInfo.name, bundleInfo.appIndex);
978         bundleNameIndexBundleInfoMap[bundleNameIndexInfo] = bundleInfo;
979     }
980     for (const auto &item : bundleNames) {
981         std::string bundleName = item;
982         if (BundleMgrAdapter::IsUser0BundleName(bundleName, userId)) {
983             HILOGE("bundleName:%{public}s is zero user bundle", bundleName.c_str());
984             SendUserIdToApp(bundleName, userId);
985         }
986         auto it = bundleNameIndexBundleInfoMap.find(bundleName);
987         if (it == bundleNameIndexBundleInfoMap.end()) {
988             HILOGE("Current bundleName can not find bundleInfo, bundleName:%{public}s", bundleName.c_str());
989             session_->RemoveExtInfo(bundleName);
990             continue;
991         }
992         auto bundleInfo = it->second;
993         if (isIncBackup) {
994             session_->SetBundleDataSize(bundleName, bundleInfo.increSpaceOccupied);
995         } else {
996             session_->SetBundleDataSize(bundleName, bundleInfo.spaceOccupied);
997         }
998         session_->SetBundleUserId(bundleName, userId);
999         session_->SetBackupExtName(bundleName, bundleInfo.extensionName);
1000         session_->SetIsReadyLaunch(bundleName);
1001     }
1002     HILOGI("end SetCurrentBackupSessProperties");
1003 }
1004 
1005 
SetBundleIncDataInfo(const std::vector<BIncrementalData> & bundlesToBackup,std::vector<std::string> & supportBundleNames)1006 void Service::SetBundleIncDataInfo(const std::vector<BIncrementalData>& bundlesToBackup,
1007     std::vector<std::string> &supportBundleNames)
1008 {
1009     for (const auto &bundleInfo : bundlesToBackup) {
1010         std::string bundleName = bundleInfo.bundleName;
1011         auto it = std::find(supportBundleNames.begin(), supportBundleNames.end(), bundleName);
1012         if (it == supportBundleNames.end()) {
1013             HILOGE("Current bundle is not support to backup, bundleName:%{public}s", bundleName.c_str());
1014             continue;
1015         }
1016         session_->SetIncrementalData(bundleInfo);
1017     }
1018 }
1019 
CancelSessionClean(sptr<SvcSessionManager> session,std::string bundleName)1020 bool Service::CancelSessionClean(sptr<SvcSessionManager> session, std::string bundleName)
1021 {
1022     if (session == nullptr) {
1023         HILOGE("Session is nullptr");
1024         return false;
1025     }
1026     auto connectionWptr = session->GetExtConnection(bundleName);
1027     if (connectionWptr == nullptr) {
1028         HILOGE("connectionWptr is null.");
1029         return false;
1030     }
1031     auto backUpConnection = connectionWptr.promote();
1032     if (backUpConnection == nullptr) {
1033         HILOGE("Promote backUpConnection ptr is null.");
1034         return false;
1035     }
1036     auto proxy = backUpConnection->GetBackupExtProxy();
1037     if (!proxy) {
1038         HILOGE("Extension backup Proxy is empty.");
1039         return false;
1040     }
1041     proxy->HandleClear();
1042     session->StopFwkTimer(bundleName);
1043     session->StopExtTimer(bundleName);
1044     session->HandleOnRelease(proxy);
1045     backUpConnection->DisconnectBackupExtAbility();
1046     return true;
1047 }
1048 
CancelTask(std::string bundleName,wptr<Service> ptr)1049 void Service::CancelTask(std::string bundleName, wptr<Service> ptr)
1050 {
1051     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
1052     auto thisPtr = ptr.promote();
1053     if (!thisPtr) {
1054         HILOGE("this pointer is null");
1055         return;
1056     }
1057     auto session = thisPtr->session_;
1058     if (session == nullptr) {
1059         HILOGE("Session is nullptr");
1060         return;
1061     }
1062     HILOGI("Service CancelTask start, bundleName is %{public}s", bundleName.c_str());
1063     std::shared_ptr<ExtensionMutexInfo> mutexPtr = thisPtr->GetExtensionMutex(bundleName);
1064     if (mutexPtr == nullptr) {
1065         HILOGE("Extension mutex ptr is nullptr");
1066         return;
1067     }
1068     do {
1069         std::lock_guard<std::mutex> lock(mutexPtr->callbackMutex);
1070         if (!CancelSessionClean(session, bundleName)) {
1071             break;
1072         }
1073         thisPtr->ClearSessionAndSchedInfo(bundleName);
1074         IServiceReverseType::Scenario scenario = session->GetScenario();
1075         if ((scenario == IServiceReverseType::Scenario::BACKUP && session->GetIsIncrementalBackup()) ||
1076             (scenario == IServiceReverseType::Scenario::RESTORE &&
1077             session->ValidRestoreDataType(RestoreTypeEnum::RESTORE_DATA_WAIT_SEND))) {
1078             thisPtr->NotifyCallerCurAppIncrementDone(BError(BError::Codes::OK), bundleName);
1079         } else {
1080             thisPtr->NotifyCallerCurAppDone(BError(BError::Codes::OK), bundleName);
1081         }
1082     } while (0);
1083     thisPtr->RemoveExtensionMutex(bundleName);
1084     thisPtr->OnAllBundlesFinished(BError(BError::Codes::OK));
1085 }
1086 
CancelForResult(const std::string & bundleName,int32_t & result)1087 ErrCode Service::CancelForResult(const std::string& bundleName, int32_t &result)
1088 {
1089     ErrCode errCode = Cancel(bundleName, result);
1090     if (errCode != 0) {
1091         HILOGE("Cancel failed, errCode:%{public}d.", errCode);
1092     }
1093     return BError(BError::Codes::OK);
1094 }
1095 
Cancel(const std::string & bundleName,int32_t & result)1096 ErrCode Service::Cancel(const std::string& bundleName, int32_t &result)
1097 {
1098     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
1099     HILOGI("Begin, bundle name:%{public}s", bundleName.c_str());
1100     if (session_ == nullptr) {
1101         HILOGE("Cancel error, session is null");
1102         return BError(BError::BackupErrorCode::E_CANCEL_UNSTARTED_TASK);
1103     }
1104     IServiceReverseType::Scenario scenario = session_->GetScenario();
1105     ErrCode ret = VerifyCaller(scenario);
1106     if (ret != ERR_OK) {
1107         HILOGE("Verify caller failed, bundleName:%{public}s, scenario:%{public}d", bundleName.c_str(), scenario);
1108         return BError(BError::BackupErrorCode::E_CANCEL_UNSTARTED_TASK);
1109     }
1110     auto impl = session_->GetImpl();
1111     auto it = impl.backupExtNameMap.find(bundleName);
1112     if (it == impl.backupExtNameMap.end()) {
1113         result = BError::BackupErrorCode::E_CANCEL_NO_TASK;
1114         return BError(BError::Codes::OK);
1115     }
1116     auto action = session_->GetServiceSchedAction(bundleName);
1117     if (action == BConstants::ServiceSchedAction::UNKNOWN) {
1118         HILOGE("action is unknown, bundleName:%{public}s", bundleName.c_str());
1119         result = BError::BackupErrorCode::E_CANCEL_NO_TASK;
1120         return BError(BError::BackupErrorCode::E_CANCEL_UNSTARTED_TASK);
1121     }
1122     auto task = [this, bundleName]() {
1123         try {
1124             CancelTask(bundleName, wptr(this));
1125         } catch (const BError &e) {
1126             HILOGE("CancelTask failed, errCode = %{public}d", e.GetCode());
1127         } catch (...) {
1128             HILOGE("Unexpected exception");
1129         }
1130     };
1131     if (action == BConstants::ServiceSchedAction::RUNNING) {
1132         threadPool_.AddTask(task);
1133         result = BError(BError::Codes::OK);
1134         return BError(BError::Codes::OK);
1135     }
1136     if (action == BConstants::ServiceSchedAction::CLEAN) {
1137         result = BError::BackupErrorCode::E_CANCEL_NO_TASK;
1138     } else {
1139         result = BError::BackupErrorCode::E_CANCEL_UNSTARTED_TASK;
1140     }
1141     return BError(BError::Codes::OK);
1142 }
1143 
ClearIncrementalStatFile(int32_t userId,const string & bundleName)1144 void Service::ClearIncrementalStatFile(int32_t userId, const string &bundleName)
1145 {
1146     BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(bundleName);
1147     string backupSaBundleDir;
1148     if (bundleDetail.bundleIndex > 0) {
1149         const std::string bundleNameIndex  = "+clone-" + std::to_string(bundleDetail.bundleIndex) + "+" +
1150             bundleDetail.bundleName;
1151         backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX +
1152             bundleNameIndex + BConstants::FILE_SEPARATOR_CHAR;
1153     } else {
1154         backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX +
1155             bundleDetail.bundleName + BConstants::FILE_SEPARATOR_CHAR;
1156     }
1157     if (access(backupSaBundleDir.c_str(), F_OK) != ERR_OK) {
1158         HILOGD("ClearIncrementalStatFile, access dir failed errno = %{public}d", errno);
1159         return;
1160     }
1161     if (!ForceRemoveDirectoryBMS(backupSaBundleDir.c_str())) {
1162         HILOGE("Failed to delete SaBundleBackupDir cache: %{public}s",
1163             backupSaBundleDir.c_str());
1164         return;
1165     }
1166 }
1167 
1168 } // namespace OHOS::FileManagement::Backup
1169