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