• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #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 #include <cstring>
25 #include <regex>
26 
27 #include <fcntl.h>
28 #include <iomanip>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <sys/vfs.h>
32 
33 #include <directory_ex.h>
34 
35 #include "ability_manager_client.h"
36 #include "accesstoken_kit.h"
37 #include "b_anony/b_anony.h"
38 #include "b_error/b_error.h"
39 #include "b_error/b_excep_utils.h"
40 #include "b_file_info.h"
41 #include "b_hiaudit/hi_audit.h"
42 #include "b_json/b_json_cached_entity.h"
43 #include "b_jsonutil/b_jsonutil.h"
44 #include "b_ohos/startup/backup_para.h"
45 #include "b_process/b_multiuser.h"
46 #include "b_radar/b_radar.h"
47 #include "b_resources/b_constants.h"
48 #include "b_sa/b_sa_utils.h"
49 #include "b_utils/b_time.h"
50 #include "bundle_mgr_client.h"
51 #include "filemgmt_libhilog.h"
52 #include "hisysevent.h"
53 #include "hitrace_meter.h"
54 #include "ipc_skeleton.h"
55 #include "access_token.h"
56 #include "tokenid_kit.h"
57 #include "module_app_gallery/app_gallery_dispose_proxy.h"
58 #include "module_external/bms_adapter.h"
59 #include "module_external/sms_adapter.h"
60 #include "module_ipc/svc_backup_connection.h"
61 #include "module_ipc/svc_restore_deps_manager.h"
62 #include "module_notify/notify_work_service.h"
63 #include "parameter.h"
64 #include "parameters.h"
65 #include "system_ability_definition.h"
66 
67 namespace OHOS::FileManagement::Backup {
68 using namespace std;
69 
70 namespace {
71 const int32_t MAX_FILE_READY_REPORT_TIME = 2;
72 const int32_t WAIT_SCANNING_INFO_SEND_TIME = 5;
73 const int ERR_SIZE = -1;
74 } // namespace
75 
AppendBundles(const std::vector<std::string> & bundleNames)76 void Service::AppendBundles(const std::vector<std::string> &bundleNames)
77 {
78     std::vector<std::string> failedBundles;
79     session_->AppendBundles(bundleNames, failedBundles);
80     if (!failedBundles.empty()) {
81         HILOGE("Handle exception on failed bundles, size = %{public}zu", failedBundles.size());
82         HandleExceptionOnAppendBundles(session_, failedBundles, {});
83     }
84 }
85 
ReportOnBundleStarted(IServiceReverse::Scenario scenario,const std::string & bundleName)86 void Service::ReportOnBundleStarted(IServiceReverse::Scenario scenario, const std::string &bundleName)
87 {
88     if (scenario == IServiceReverse::Scenario::BACKUP) {
89         session_->GetServiceReverseProxy()->BackupOnBundleStarted(BError(BError::Codes::SA_INVAL_ARG), bundleName);
90     } else if (scenario == IServiceReverse::Scenario::RESTORE) {
91         session_->GetServiceReverseProxy()->RestoreOnBundleStarted(BError(BError::Codes::SA_INVAL_ARG), bundleName);
92     }
93 }
94 
BundleNameWithUserId(const string & bundleName,const int32_t userId)95 string Service::BundleNameWithUserId(const string& bundleName, const int32_t userId)
96 {
97     return to_string(userId) + "-" + bundleName;
98 }
99 
SplitBundleName(const string & bundleNameWithId)100 std::tuple<std::string, int32_t> Service::SplitBundleName(const string& bundleNameWithId)
101 {
102     size_t found = bundleNameWithId.find('-');
103     if (found == std::string::npos) {
104         HILOGE("Can not split bundleName = %{public}s", bundleNameWithId.c_str());
105         return { "", -1 };
106     }
107     std::string bundleName = bundleNameWithId.substr(found + 1, bundleNameWithId.length());
108     int32_t userId = std::atoi(bundleNameWithId.substr(0, found).c_str());
109     return { bundleName, userId };
110 }
111 
MakeDetailList(const vector<BundleName> & bundleNames)112 vector<BIncrementalData> Service::MakeDetailList(const vector<BundleName> &bundleNames)
113 {
114     vector<BIncrementalData> bundleDetails {};
115     for (const auto &bundleName : bundleNames) {
116         bundleDetails.emplace_back(BIncrementalData {bundleName, 0});
117     }
118     return bundleDetails;
119 }
120 
UpdateBundleRadarReport(const std::string & bundleName)121 void Service::UpdateBundleRadarReport(const std::string &bundleName)
122 {
123     std::unique_lock<std::mutex> lock(bundleExecRadarLock_);
124     bundleExecRadarSet_.insert(bundleName);
125 }
126 
ClearBundleRadarReport()127 void Service::ClearBundleRadarReport()
128 {
129     std::unique_lock<std::mutex> lock(bundleExecRadarLock_);
130     bundleExecRadarSet_.clear();
131 }
132 
IsReportBundleExecFail(const std::string & bundleName)133 bool Service::IsReportBundleExecFail(const std::string &bundleName)
134 {
135     std::unique_lock<std::mutex> lock(bundleExecRadarLock_);
136     auto it = bundleExecRadarSet_.find(bundleName);
137     if (it != bundleExecRadarSet_.end()) {
138         HILOGI("BundleName %{public}s has already been reported", bundleName.c_str());
139         return false;
140     }
141     return true;
142 }
143 
ClearFileReadyRadarReport()144 void Service::ClearFileReadyRadarReport()
145 {
146     std::unique_lock<std::mutex> lock(fileReadyRadarLock_);
147     fileReadyRadarMap_.clear();
148 }
149 
IsReportFileReadyFail(const std::string & bundleName)150 bool Service::IsReportFileReadyFail(const std::string &bundleName)
151 {
152     std::unique_lock<std::mutex> lock(fileReadyRadarLock_);
153     auto it = fileReadyRadarMap_.find(bundleName);
154     if (it != fileReadyRadarMap_.end()) {
155         it->second++;
156     } else {
157         fileReadyRadarMap_[bundleName] = 1;
158     }
159     if (it->second > MAX_FILE_READY_REPORT_TIME) {
160         HILOGI("FileReady radar report more than %{public}d times, bundleName = %{public}s",
161             MAX_FILE_READY_REPORT_TIME, bundleName.c_str());
162         return false;
163     }
164     return true;
165 }
166 
TimeoutRadarReport(IServiceReverse::Scenario scenario,std::string & bundleName)167 void Service::TimeoutRadarReport(IServiceReverse::Scenario scenario, std::string &bundleName)
168 {
169     if (!IsReportBundleExecFail(bundleName)) {
170         return;
171     }
172     UpdateBundleRadarReport(bundleName);
173     int32_t errCode = BError::BackupErrorCode::E_ETO;
174     if (session_->GetTimeoutValue(bundleName) == 0) {
175         errCode = BError::BackupErrorCode::E_FORCE_TIMEOUT;
176     }
177     if (scenario == IServiceReverse::Scenario::BACKUP) {
178         AppRadar::Info info(bundleName, "", "on backup timeout");
179         AppRadar::GetInstance().RecordBackupFuncRes(info, "Service::TimeOutCallback", GetUserIdDefault(),
180             BizStageBackup::BIZ_STAGE_ON_BACKUP, errCode);
181     } else if (scenario == IServiceReverse::Scenario::RESTORE) {
182         AppRadar::Info info(bundleName, "", "on restore timeout");
183         AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::TimeOutCallback", GetUserIdDefault(),
184             BizStageRestore::BIZ_STAGE_ON_RESTORE, errCode);
185     }
186 }
187 
Finish()188 ErrCode Service::Finish()
189 {
190     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
191     try {
192         ErrCode ret = VerifyCaller(session_->GetScenario());
193         if (ret != ERR_OK) {
194             HILOGE("Failde to Finish, verify caller failed, ret:%{public}d", ret);
195             ReleaseOnException();
196             return ret;
197         }
198         ret = session_->Finish();
199         if (ret != ERR_OK) {
200             HILOGE("Failde to Finish, session finish failed, ret:%{public}d", ret);
201             ReleaseOnException();
202             return ret;
203         }
204         OnAllBundlesFinished(BError(BError::Codes::OK));
205         return BError(BError::Codes::OK);
206     } catch (const BError &e) {
207         ReleaseOnException();
208         HILOGE("Failde to Finish");
209         return e.GetCode();
210     }
211 }
212 
PublishFile(const BFileInfo & fileInfo)213 ErrCode Service::PublishFile(const BFileInfo &fileInfo)
214 {
215     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
216     if (session_ == nullptr) {
217         HILOGE("PublishFile error, session is empty");
218         return BError(BError::Codes::SA_INVAL_ARG);
219     }
220     ErrCode ret = VerifyCaller(IServiceReverse::Scenario::RESTORE);
221     if (ret != ERR_OK) {
222         HILOGE("PublishFile error, verify caller by scenario failed, ret:%{public}d", ret);
223         return ret;
224     }
225     if (!fileInfo.fileName.empty()) {
226         HILOGE("Forbit to use publishFile with fileName for App");
227         return EPERM;
228     }
229     auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
230     if (backUpConnection == nullptr) {
231         HILOGE("backUpConnection is empty, bundle:%{public}s", fileInfo.owner.c_str());
232         return BError(BError::Codes::SA_INVAL_ARG);
233     }
234     auto proxy = backUpConnection->GetBackupExtProxy();
235     if (!proxy) {
236         HILOGE("PublishFile error, Extension backup Proxy is empty");
237         return BError(BError::Codes::SA_INVAL_ARG);
238     }
239     ret = proxy->PublishFile(fileInfo.fileName);
240     if (ret != ERR_OK) {
241         HILOGE("Failed to publish file for backup extension, ret:%{public}d", ret);
242         return ret;
243     }
244     return BError(BError::Codes::OK);
245 }
246 
AppFileReady(const string & fileName,UniqueFd fd,int32_t errCode)247 ErrCode Service::AppFileReady(const string &fileName, UniqueFd fd, int32_t errCode)
248 {
249     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
250     try {
251         if (session_ == nullptr) {
252             HILOGE("AppFileReady error, session is empty");
253             return BError(BError::Codes::SA_INVAL_ARG);
254         }
255         string callerName;
256         ErrCode ret = VerifyCallerAndGetCallerName(callerName);
257         if (ret != ERR_OK) {
258             HILOGE("AppFileReady error, Get bundle name failed, ret:%{public}d", ret);
259             return ret;
260         }
261         if (fileName.find('/') != string::npos) {
262             HILOGE("AppFileReady error, filename is not valid, fileName:%{public}s", GetAnonyPath(fileName).c_str());
263             return BError(BError::Codes::SA_INVAL_ARG);
264         }
265         if (fileName == BConstants::EXT_BACKUP_MANAGE) {
266             fd = session_->OnBundleExtManageInfo(callerName, move(fd));
267         }
268         session_->GetServiceReverseProxy()->BackupOnFileReady(callerName, fileName, move(fd), errCode);
269         FileReadyRadarReport(callerName, fileName, errCode, session_->GetScenario());
270         if (session_->OnBundleFileReady(callerName, fileName)) {
271             ret = HandleCurBundleFileReady(callerName, fileName, false);
272             if (ret != ERR_OK) {
273                 HILOGE("Handle current bundle file failed, bundleName:%{public}s, fileName:%{public}s",
274                     callerName.c_str(),  GetAnonyPath(fileName).c_str());
275                 return ret;
276             }
277         }
278         OnAllBundlesFinished(BError(BError::Codes::OK));
279         return BError(BError::Codes::OK);
280     } catch (const BError &e) {
281         return e.GetCode(); // 任意异常产生,终止监听该任务
282     } catch (...) {
283         HILOGE("Unexpected exception");
284         return EPERM;
285     }
286 }
287 
AppDone(ErrCode errCode)288 ErrCode Service::AppDone(ErrCode errCode)
289 {
290     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
291     try {
292         if (session_ == nullptr) {
293             HILOGE("App finish error, session info is empty");
294             return BError(BError::Codes::SA_INVAL_ARG);
295         }
296         string callerName;
297         ErrCode ret = VerifyCallerAndGetCallerName(callerName);
298         if (ret != ERR_OK) {
299             HILOGE("App done failed, Get bundle name failed, ret:%{public}d", ret);
300             return ret;
301         }
302         HILOGI("Begin, callerName is: %{public}s, errCode: %{public}d", callerName.c_str(), errCode);
303         if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) {
304             std::shared_ptr<ExtensionMutexInfo> mutexPtr = GetExtensionMutex(callerName);
305             if (mutexPtr == nullptr) {
306                 HILOGE("extension mutex ptr is nullptr, bundleName:%{public}s", callerName.c_str());
307                 return BError(BError::Codes::SA_INVAL_ARG);
308             }
309             std::lock_guard<std::mutex> lock(mutexPtr->callbackMutex);
310             ret = HandleCurAppDone(errCode, callerName, false);
311             if (ret != ERR_OK) {
312                 HILOGE("Handle current app done error, bundleName:%{public}s", callerName.c_str());
313                 return ret;
314             }
315         }
316         RemoveExtensionMutex(callerName);
317         OnAllBundlesFinished(BError(BError::Codes::OK));
318         return BError(BError::Codes::OK);
319     } catch (const BError &e) {
320         ReleaseOnException();
321         HILOGE("AppDone error, err code is: %{public}d", e.GetCode());
322         return e.GetCode(); // 任意异常产生,终止监听该任务
323     } catch (...) {
324         HILOGE("Unexpected exception");
325         ReleaseOnException();
326         return EPERM;
327     }
328 }
329 
LaunchBackupExtension(const BundleName & bundleName)330 ErrCode Service::LaunchBackupExtension(const BundleName &bundleName)
331 {
332     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
333     HILOGI("begin %{public}s", bundleName.data());
334     IServiceReverse::Scenario scenario = session_->GetScenario();
335     BConstants::ExtensionAction action;
336     if (scenario == IServiceReverse::Scenario::BACKUP || scenario == IServiceReverse::Scenario::CLEAN) {
337         action = BConstants::ExtensionAction::BACKUP;
338     } else if (scenario == IServiceReverse::Scenario::RESTORE) {
339         action = BConstants::ExtensionAction::RESTORE;
340     } else {
341         action = BConstants::ExtensionAction::INVALID;
342         HILOGE("Launch current bundle backupExtension failed, action is unknown, bundleName:%{public}s",
343             bundleName.c_str());
344         return BError(BError::Codes::SA_INVAL_ARG);
345     }
346     if (SAUtils::IsSABundleName(bundleName)) {
347         return LaunchBackupSAExtension(bundleName);
348     }
349     AAFwk::Want want;
350     SetWant(want, bundleName, action);
351     auto backUpConnection = session_->GetExtConnection(bundleName);
352     if (backUpConnection == nullptr) {
353         HILOGE("LaunchBackupExtension error, backUpConnection is empty");
354         return BError(BError::Codes::SA_INVAL_ARG);
355     }
356     if (backUpConnection->IsExtAbilityConnected() && !backUpConnection->WaitDisconnectDone()) {
357         HILOGE("LaunchBackupExtension error, WaitDisconnectDone failed");
358         return BError(BError::Codes::SA_INVAL_ARG);
359     }
360     BConstants::ServiceSchedAction bundleAction = session_->GetServiceSchedAction(bundleName);
361     if (bundleAction == BConstants::ServiceSchedAction::UNKNOWN) {
362         HILOGE("action is unknown, bundleName:%{public}s", bundleName.c_str());
363         return BError(BError::Codes::SA_INVAL_ARG);
364     }
365     ErrCode ret = backUpConnection->ConnectBackupExtAbility(want, session_->GetSessionUserId(),
366         bundleAction == BConstants::ServiceSchedAction::CLEAN);
367     if (ret != ERR_OK) {
368         HILOGE("ConnectBackupExtAbility failed, bundleName:%{public}s, ret:%{public}d", bundleName.c_str(), ret);
369         ExtensionConnectFailRadarReport(bundleName, ret, scenario);
370         return BError(BError::Codes::SA_BOOT_EXT_FAIL);
371     }
372     return BError(BError::Codes::OK);
373 }
374 
SetWant(AAFwk::Want & want,const BundleName & bundleName,const BConstants::ExtensionAction & action)375 void Service::SetWant(AAFwk::Want &want, const BundleName &bundleName, const BConstants::ExtensionAction &action)
376 {
377     BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(bundleName);
378     string backupExtName = session_->GetBackupExtName(bundleName); /* new device app ext name */
379     HILOGI("BackupExtName: %{public}s, bundleName: %{public}s", backupExtName.data(), bundleName.data());
380     string versionName = session_->GetBundleVersionName(bundleName); /* old device app version name */
381     int64_t versionCode = session_->GetBundleVersionCode(bundleName); /* old device app version code */
382     RestoreTypeEnum restoreType = session_->GetBundleRestoreType(bundleName); /* app restore type */
383     string bundleExtInfo = session_->GetBackupExtInfo(bundleName);
384     HILOGI("BundleExtInfo is:%{public}s", GetAnonyString(bundleExtInfo).c_str());
385     string oldBackupVersion = session_->GetOldBackupVersion(); /* old device backup version */
386     if (oldBackupVersion.empty()) {
387         HILOGE("Failed to get backupVersion of old device");
388     }
389     want.SetElementName(bundleDetail.bundleName, backupExtName);
390     want.SetParam(BConstants::EXTENSION_ACTION_PARA, static_cast<int>(action));
391     want.SetParam(BConstants::EXTENSION_VERSION_CODE_PARA, static_cast<long>(versionCode));
392     want.SetParam(BConstants::EXTENSION_RESTORE_TYPE_PARA, static_cast<int>(restoreType));
393     want.SetParam(BConstants::EXTENSION_VERSION_NAME_PARA, versionName);
394     want.SetParam(BConstants::EXTENSION_RESTORE_EXT_INFO_PARA, bundleExtInfo);
395     want.SetParam(BConstants::EXTENSION_BACKUP_EXT_INFO_PARA, bundleExtInfo);
396     want.SetParam(BConstants::EXTENSION_APP_CLONE_INDEX_PARA, bundleDetail.bundleIndex);
397     want.SetParam(BConstants::EXTENSION_OLD_BACKUP_VERSION_PARA, oldBackupVersion);
398 }
399 
GetSupportBackupBundleNames(vector<BJsonEntityCaps::BundleInfo> & backupInfos,bool isIncBackup,const std::vector<std::string> & srcBundleNames)400 std::vector<std::string> Service::GetSupportBackupBundleNames(vector<BJsonEntityCaps::BundleInfo> &backupInfos,
401     bool isIncBackup, const std::vector<std::string> &srcBundleNames)
402 {
403     HILOGI("Begin");
404     std::vector<std::string> supportBackupNames;
405     for (const auto &info : backupInfos) {
406         HILOGI("Current backupInfo bundleName:%{public}s, index:%{public}d, extName:%{public}s", info.name.c_str(),
407             info.appIndex, info.extensionName.c_str());
408         std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex);
409         if (!info.allToBackup) {
410             if (isIncBackup) {
411                 session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(
412                     BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), bundleNameIndexInfo);
413             } else {
414                 session_->GetServiceReverseProxy()->BackupOnBundleStarted(
415                     BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), bundleNameIndexInfo);
416             }
417             BundleBeginRadarReport(bundleNameIndexInfo, BError(BError::Codes::SA_FORBID_BACKUP_RESTORE).GetCode(),
418                 IServiceReverse::Scenario::BACKUP);
419             continue;
420         }
421         supportBackupNames.emplace_back(bundleNameIndexInfo);
422     }
423     HandleNotSupportBundleNames(srcBundleNames, supportBackupNames, isIncBackup);
424     HILOGI("End");
425     return supportBackupNames;
426 }
427 
SetCurrentSessProperties(BJsonEntityCaps::BundleInfo & info,std::map<std::string,bool> & isClearDataFlags,const std::string & bundleNameIndexInfo)428 void Service::SetCurrentSessProperties(BJsonEntityCaps::BundleInfo &info,
429     std::map<std::string, bool> &isClearDataFlags, const std::string &bundleNameIndexInfo)
430 {
431     HILOGI("Begin");
432     if (session_ == nullptr) {
433         HILOGE("Set currrent session properties error, session is empty");
434         return;
435     }
436     session_->SetBundleDataSize(bundleNameIndexInfo, info.spaceOccupied);
437     auto iter = isClearDataFlags.find(bundleNameIndexInfo);
438     if (iter != isClearDataFlags.end()) {
439         session_->SetClearDataFlag(bundleNameIndexInfo, iter->second);
440     }
441     HILOGI("End");
442 }
443 
RefreshDataSize(int64_t totalDataSize)444 ErrCode Service::RefreshDataSize(int64_t totalDataSize)
445 {
446     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
447     try {
448         if (session_ == nullptr) {
449             HILOGE("session is nullptr");
450             return BError(BError::Codes::SA_INVAL_ARG);
451         }
452         std::string bundleName;
453         ErrCode ret = VerifyCallerAndGetCallerName(bundleName);
454         if (ret != ERR_OK) {
455             HILOGE("Refresh data size failed, bundleName:%{public}s, ret:%{public}d", bundleName.c_str(), ret);
456             return ret;
457         }
458         session_->SetBundleDataSize(bundleName, totalDataSize);
459         HILOGI("RefreshDataSize, bundleName:%{public}s ,datasize = %{public}" PRId64 "",
460             bundleName.c_str(), totalDataSize);
461         return BError(BError::Codes::OK);
462     } catch (const BError &e) {
463         return e.GetCode();
464     }
465 }
466 
467 
HandleNotSupportBundleNames(const std::vector<std::string> & srcBundleNames,std::vector<std::string> & supportBundleNames,bool isIncBackup)468 void Service::HandleNotSupportBundleNames(const std::vector<std::string> &srcBundleNames,
469     std::vector<std::string> &supportBundleNames, bool isIncBackup)
470 {
471     for (const auto &bundleName : srcBundleNames) {
472         auto it = std::find(supportBundleNames.begin(), supportBundleNames.end(), bundleName);
473         if (it != supportBundleNames.end()) {
474             continue;
475         }
476         HILOGE("bundleName:%{public}s, can not find from supportBundleNames", bundleName.c_str());
477         if (isIncBackup) {
478             session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(
479                 BError(BError::Codes::SA_BUNDLE_INFO_EMPTY), bundleName);
480         } else {
481             session_->GetServiceReverseProxy()->BackupOnBundleStarted(
482                 BError(BError::Codes::SA_BUNDLE_INFO_EMPTY), bundleName);
483         }
484     }
485 }
486 
StopExtTimer(bool & isExtStop)487 ErrCode Service::StopExtTimer(bool &isExtStop)
488 {
489     try {
490         HILOGI("Service::StopExtTimer begin.");
491         if (session_ == nullptr) {
492             HILOGE("StopExtTimer error, session_ is nullptr.");
493             isExtStop = false;
494             return BError(BError::Codes::SA_INVAL_ARG);
495         }
496         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
497         string bundleName;
498         ErrCode ret = VerifyCallerAndGetCallerName(bundleName);
499         if (ret != ERR_OK) {
500             HILOGE("Stop extension error, ret:%{public}d", ret);
501             isExtStop = false;
502             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
503             return ret;
504         }
505         isExtStop = session_->StopExtTimer(bundleName);
506         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
507         return BError(BError::Codes::OK);
508     } catch (...) {
509         HILOGE("Unexpected exception");
510         isExtStop = false;
511         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
512         return EPERM;
513     }
514 }
515 
ClearFailedBundles()516 void Service::ClearFailedBundles()
517 {
518     std::lock_guard<std::mutex> lock(failedBundlesLock_);
519     failedBundles_.clear();
520 }
521 
UpdateFailedBundles(const std::string & bundleName,BundleTaskInfo taskInfo)522 void Service::UpdateFailedBundles(const std::string &bundleName, BundleTaskInfo taskInfo)
523 {
524     std::lock_guard<std::mutex> lock(failedBundlesLock_);
525     failedBundles_[bundleName] = taskInfo;
526 }
527 
GetOldDeviceBackupVersion()528 void Service::GetOldDeviceBackupVersion()
529 {
530     std::string oldBackupVersion = session_->GetOldBackupVersion();
531     if (oldBackupVersion.empty()) {
532         HILOGE("Failed to get backupVersion of old device");
533     }
534     HILOGI("backupVersion of old device = %{public}s", oldBackupVersion.c_str());
535 }
536 
ExtConnectDied(const string & callName)537 void Service::ExtConnectDied(const string &callName)
538 {
539     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
540     try {
541         HILOGI("Begin, bundleName: %{public}s", callName.c_str());
542         std::shared_ptr<ExtensionMutexInfo> mutexPtr = GetExtensionMutex(callName);
543         if (mutexPtr == nullptr) {
544             HILOGE("extension mutex ptr is nullptr");
545             return;
546         }
547         std::lock_guard<std::mutex> lock(mutexPtr->callbackMutex);
548         /* Clear Timer */
549         session_->StopFwkTimer(callName);
550         session_->StopExtTimer(callName);
551         auto backUpConnection = session_->GetExtConnection(callName);
552         if (backUpConnection != nullptr && backUpConnection->IsExtAbilityConnected()) {
553             backUpConnection->DisconnectBackupExtAbility();
554         }
555         bool needCleanData = session_->GetClearDataFlag(callName);
556         if (!needCleanData) {
557             HILOGE("Current extension is died, but not need clean data, bundleName:%{public}s", callName.c_str());
558             SendEndAppGalleryNotify(callName);
559             ClearSessionAndSchedInfo(callName);
560             NoticeClientFinish(callName, BError(BError::Codes::EXT_ABILITY_DIED));
561             return;
562         }
563         session_->SetServiceSchedAction(callName, BConstants::ServiceSchedAction::CLEAN);
564         auto ret = LaunchBackupExtension(callName);
565         if (ret) {
566             /* Clear Session before notice client finish event */
567             HILOGE("Current bundle launch extension failed, bundleName:%{public}s", callName.c_str());
568             SendEndAppGalleryNotify(callName);
569             ClearSessionAndSchedInfo(callName);
570         }
571         /* Notice Client Ext Ability Process Died */
572         NoticeClientFinish(callName, BError(BError::Codes::EXT_ABILITY_DIED));
573     } catch (...) {
574         HILOGE("Unexpected exception, bundleName: %{public}s", callName.c_str());
575         SendEndAppGalleryNotify(callName);
576         ClearSessionAndSchedInfo(callName);
577         NoticeClientFinish(callName, BError(BError::Codes::EXT_ABILITY_DIED));
578     }
579     RemoveExtensionMutex(callName);
580 }
581 
OnBackupExtensionDied(const string && bundleName,bool isCleanCalled)582 void Service::OnBackupExtensionDied(const string &&bundleName, bool isCleanCalled)
583 {
584     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
585     if (isCleanCalled) {
586         HILOGE("Backup <%{public}s> Extension Process second Died", bundleName.c_str());
587         ClearSessionAndSchedInfo(bundleName);
588         OnAllBundlesFinished(BError(BError::Codes::OK));
589         return;
590     }
591     try {
592         string callName = move(bundleName);
593         HILOGE("Backup <%{public}s> Extension Process Died", callName.c_str());
594         ErrCode ret = session_->VerifyBundleName(callName);
595         if (ret != ERR_OK) {
596             HILOGE("Backup Extension died error, verify bundleName failed, bundleName:%{public}s, ret:%{public}d",
597                 bundleName.c_str(), ret);
598             ExtConnectDied(bundleName);
599             return;
600         }
601         // 重新连接清理缓存
602         HILOGI("Clear backup extension data, bundleName: %{public}s", callName.c_str());
603         ExtConnectDied(callName);
604     } catch (...) {
605         HILOGE("Unexpected exception, bundleName: %{public}s", bundleName.c_str());
606         ExtConnectDied(bundleName);
607         return;
608     }
609 }
610 
NoticeClientFinish(const string & bundleName,ErrCode errCode)611 void Service::NoticeClientFinish(const string &bundleName, ErrCode errCode)
612 {
613     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
614     HILOGI("begin %{public}s", bundleName.c_str());
615     try {
616         auto scenario = session_->GetScenario();
617         if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) {
618             session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(errCode, bundleName);
619         } else if (scenario == IServiceReverse::Scenario::RESTORE &&
620                 BackupPara().GetBackupOverrideIncrementalRestore() &&
621                 session_->ValidRestoreDataType(RestoreTypeEnum::RESTORE_DATA_WAIT_SEND)) {
622             session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleFinished(errCode, bundleName);
623         } else if (scenario == IServiceReverse::Scenario::BACKUP) {
624             session_->GetServiceReverseProxy()->BackupOnBundleFinished(errCode, bundleName);
625         } else if (scenario == IServiceReverse::Scenario::RESTORE) {
626             session_->GetServiceReverseProxy()->RestoreOnBundleFinished(errCode, bundleName);
627         };
628         BundleEndRadarReport(bundleName, errCode, scenario);
629         /* If all bundle ext process finish, notice client. */
630         OnAllBundlesFinished(BError(BError::Codes::OK));
631     } catch(const BError &e) {
632         HILOGE("NoticeClientFinish exception, bundleName:%{public}s", bundleName.c_str());
633         ReleaseOnException();
634         return;
635     } catch (...) {
636         HILOGE("Unexpected exception");
637         ReleaseOnException();
638         return;
639     }
640 }
641 
OnAllBundlesFinished(ErrCode errCode)642 void Service::OnAllBundlesFinished(ErrCode errCode)
643 {
644     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
645     HILOGI("called begin.");
646     if (session_->IsOnAllBundlesFinished()) {
647         IServiceReverse::Scenario scenario = session_->GetScenario();
648         if (isInRelease_.load() && (scenario == IServiceReverse::Scenario::RESTORE)) {
649             HILOGI("Will destory session info");
650             SessionDeactive();
651         }
652         if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) {
653             session_->GetServiceReverseProxy()->IncrementalBackupOnAllBundlesFinished(errCode);
654         } else if (scenario == IServiceReverse::Scenario::RESTORE &&
655                    BackupPara().GetBackupOverrideIncrementalRestore() &&
656                    session_->ValidRestoreDataType(RestoreTypeEnum::RESTORE_DATA_WAIT_SEND)) {
657             session_->GetServiceReverseProxy()->IncrementalRestoreOnAllBundlesFinished(errCode);
658         } else if (scenario == IServiceReverse::Scenario::BACKUP) {
659             session_->GetServiceReverseProxy()->BackupOnAllBundlesFinished(errCode);
660         } else if (scenario == IServiceReverse::Scenario::RESTORE) {
661             session_->GetServiceReverseProxy()->RestoreOnAllBundlesFinished(errCode);
662         }
663         if (!BackupPara().GetBackupOverrideBackupSARelease()) {
664             HILOGI("Will unload backup sa");
665             sched_->TryUnloadServiceTimer(true);
666         }
667     }
668     HILOGI("called end.");
669 }
670 
VerifySendRateParam()671 ErrCode Service::VerifySendRateParam()
672 {
673     ErrCode ret = VerifyCaller();
674     if (ret != ERR_OK) {
675         HILOGE("Update send rate fail, verify caller failed, ret:%{public}d", ret);
676         return ret;
677     }
678     IServiceReverse::Scenario scenario = session_ -> GetScenario();
679     if (scenario != IServiceReverse::Scenario::BACKUP) {
680         HILOGE("This method is applicable to the backup scenario");
681         return BError(BError::Codes::SA_INVAL_ARG);
682     }
683     return BError(BError::Codes::OK);
684 }
685 
HandleCurBundleFileReady(const std::string & bundleName,const std::string & fileName,bool isIncBackup)686 ErrCode Service::HandleCurBundleFileReady(const std::string &bundleName, const std::string &fileName, bool isIncBackup)
687 {
688     auto backUpConnection = session_->GetExtConnection(bundleName);
689     if (backUpConnection == nullptr) {
690         HILOGE("AppFileReady error, backUpConnection is empty, bundleName:%{public}s", bundleName.c_str());
691         return BError(BError::Codes::SA_INVAL_ARG);
692     }
693     auto proxy = backUpConnection->GetBackupExtProxy();
694     if (!proxy) {
695         HILOGE("AppFileReady error, Extension backup Proxy is empty, bundleName:%{public}s", bundleName.c_str());
696         return BError(BError::Codes::SA_INVAL_ARG);
697     }
698     // 通知extension清空缓存
699     proxy->HandleClear();
700     // 清除Timer
701     session_->StopFwkTimer(bundleName);
702     session_->StopExtTimer(bundleName);
703     // 通知TOOL 备份完成
704     if (isIncBackup) {
705         session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(BError(BError::Codes::OK),
706             bundleName);
707         BundleEndRadarReport(bundleName, BError(BError::Codes::OK), IServiceReverse::Scenario::BACKUP);
708     } else {
709         session_->GetServiceReverseProxy()->BackupOnBundleFinished(BError(BError::Codes::OK), bundleName);
710         BundleEndRadarReport(bundleName, BError(BError::Codes::OK), session_->GetScenario());
711     }
712     // 断开extension
713     backUpConnection->DisconnectBackupExtAbility();
714     ClearSessionAndSchedInfo(bundleName);
715     return BError(BError::Codes::OK);
716 }
717 
HandleCurAppDone(ErrCode errCode,const std::string & bundleName,bool isIncBackup)718 ErrCode Service::HandleCurAppDone(ErrCode errCode, const std::string &bundleName, bool isIncBackup)
719 {
720     auto backUpConnection = session_->GetExtConnection(bundleName);
721     if (backUpConnection == nullptr) {
722         HILOGE("App finish error, backUpConnection is empty, bundleName:%{public}s", bundleName.c_str());
723         return BError(BError::Codes::SA_INVAL_ARG);
724     }
725     auto proxy = backUpConnection->GetBackupExtProxy();
726     if (!proxy) {
727         HILOGE("App finish error, extension backup Proxy is empty, bundleName:%{public}s", bundleName.c_str());
728         return BError(BError::Codes::SA_INVAL_ARG);
729     }
730     proxy->HandleClear();
731     session_->StopFwkTimer(bundleName);
732     session_->StopExtTimer(bundleName);
733     SendEndAppGalleryNotify(bundleName);
734     backUpConnection->DisconnectBackupExtAbility();
735     ClearSessionAndSchedInfo(bundleName);
736     if (isIncBackup) {
737         HILOGI("Incremental backup or restore app done, bundleName:%{public}s, errCode:%{public}d",
738             bundleName.c_str(), errCode);
739         NotifyCallerCurAppIncrementDone(errCode, bundleName);
740     } else {
741         HILOGI("Full backup or restore app done, bundleName:%{public}s, errCode:%{public}d",
742             bundleName.c_str(), errCode);
743         NotifyCallerCurAppDone(errCode, bundleName);
744     }
745     return BError(BError::Codes::OK);
746 }
747 
GetCallerName()748 std::string Service::GetCallerName()
749 {
750     std::string callerName;
751     uint32_t tokenCaller = IPCSkeleton::GetCallingTokenID();
752     int tokenType = Security::AccessToken::AccessTokenKit::GetTokenType(tokenCaller);
753     switch (tokenType) {
754         case Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE: { /* Update Service */
755             Security::AccessToken::NativeTokenInfo nativeTokenInfo;
756             if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenCaller, nativeTokenInfo) != 0) {
757                 HILOGE("Failed to get native token info");
758                 break;
759             }
760             callerName = nativeTokenInfo.processName;
761             break;
762         }
763         case Security::AccessToken::ATokenTypeEnum::TOKEN_HAP: {
764             Security::AccessToken::HapTokenInfo hapTokenInfo;
765             if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenCaller, hapTokenInfo) != 0) {
766                 HILOGE("Failed to get hap token info");
767                 break;
768             }
769             callerName = hapTokenInfo.bundleName;
770             break;
771         }
772         default:
773             HILOGE("Invalid token type, %{public}s", to_string(tokenType).c_str());
774             break;
775     }
776     return callerName;
777 }
778 
InitRestoreSession(sptr<IServiceReverse> remote,std::string & errMsg)779 ErrCode Service::InitRestoreSession(sptr<IServiceReverse> remote, std::string &errMsg)
780 {
781     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
782     ErrCode ret = VerifyCaller();
783     if (ret != ERR_OK) {
784         HILOGE("Init restore session failed, verify caller failed");
785         return ret;
786     }
787     ret = session_->Active({
788         .clientToken = IPCSkeleton::GetCallingTokenID(),
789         .scenario = IServiceReverse::Scenario::RESTORE,
790         .clientProxy = remote,
791         .userId = GetUserIdDefault(),
792         .callerName = GetCallerName(),
793         .activeTime = TimeUtils::GetCurrentTime(),
794     });
795     if (ret == ERR_OK) {
796         ClearFailedBundles();
797         successBundlesNum_ = 0;
798         ClearBundleRadarReport();
799         ClearFileReadyRadarReport();
800         return ret;
801     }
802     if (ret == BError(BError::Codes::SA_SESSION_CONFLICT)) {
803         errMsg = BJsonUtil::BuildInitSessionErrInfo(session_->GetSessionUserId(),
804                                                     session_->GetSessionCallerName(),
805                                                     session_->GetSessionActiveTime());
806         HILOGE("Active restore session error, Already have a session");
807         return ret;
808     }
809     HILOGE("Active restore session error");
810     StopAll(nullptr, true);
811     return ret;
812 }
813 
InitBackupSession(sptr<IServiceReverse> remote,std::string & errMsg)814 ErrCode Service::InitBackupSession(sptr<IServiceReverse> remote, std::string &errMsg)
815 {
816     HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
817     ErrCode ret = VerifyCaller();
818     if (ret != ERR_OK) {
819         HILOGE("Init full backup session fail, verify caller failed");
820         return ret;
821     }
822     int32_t oldSize = StorageMgrAdapter::UpdateMemPara(BConstants::BACKUP_VFS_CACHE_PRESSURE);
823     HILOGI("InitBackupSession oldSize %{public}d", oldSize);
824     session_->SetMemParaCurSize(oldSize);
825     ret = session_->Active({
826         .clientToken = IPCSkeleton::GetCallingTokenID(),
827         .scenario = IServiceReverse::Scenario::BACKUP,
828         .clientProxy = remote,
829         .userId = GetUserIdDefault(),
830         .callerName = GetCallerName(),
831         .activeTime = TimeUtils::GetCurrentTime(),
832     });
833     if (ret == ERR_OK) {
834         ClearFailedBundles();
835         successBundlesNum_ = 0;
836         ClearBundleRadarReport();
837         ClearFileReadyRadarReport();
838         return ret;
839     }
840     if (ret == BError(BError::Codes::SA_SESSION_CONFLICT)) {
841         errMsg = BJsonUtil::BuildInitSessionErrInfo(session_->GetSessionUserId(),
842                                                     session_->GetSessionCallerName(),
843                                                     session_->GetSessionActiveTime());
844         HILOGE("Active backup session error, Already have a session");
845         return ret;
846     }
847     HILOGE("Active backup session error");
848     StopAll(nullptr, true);
849     return ret;
850 }
851 
GetLocalCapabilitiesForBundleInfos()852 UniqueFd Service::GetLocalCapabilitiesForBundleInfos()
853 {
854     try {
855         HILOGI("start GetLocalCapabilitiesForBundleInfos");
856         if (session_ == nullptr) {
857             HILOGE("GetLocalCapabilitiesForBundleInfos failed, session is nullptr");
858             return UniqueFd(-EPERM);
859         }
860         ErrCode ret = VerifyCaller();
861         if (ret != ERR_OK) {
862             HILOGE("GetLocalCapabilitiesForBundleInfos failed, verify caller failed");
863             return UniqueFd(-EPERM);
864         }
865         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
866         string path = BConstants::GetSaBundleBackupRootDir(GetUserIdDefault());
867         BExcepUltils::VerifyPath(path, false);
868         CreateDirIfNotExist(path);
869         UniqueFd fd(open(path.data(), O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR));
870         if (fd < 0) {
871             HILOGE("Failed to open config file = %{private}s, err = %{public}d", path.c_str(), errno);
872             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
873             return UniqueFd(-EPERM);
874         }
875         BJsonCachedEntity<BJsonEntityCaps> cachedEntity(std::move(fd));
876         auto cache = cachedEntity.Structuralize();
877         cache.SetSystemFullName(GetOSFullName());
878         cache.SetDeviceType(GetDeviceType());
879         auto bundleInfos = BundleMgrAdapter::GetBundleInfosForLocalCapabilities(GetUserIdDefault());
880         if (bundleInfos.size() == 0) {
881             HILOGE("getBundleInfos failed, size = 0");
882             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
883             return UniqueFd(-EPERM);
884         }
885         cache.SetBundleInfos(bundleInfos);
886         cachedEntity.Persist();
887         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
888         HILOGI("End");
889         return move(cachedEntity.GetFd());
890     } catch (const BError &e) {
891         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
892         HILOGE("GetLocalCapabilitiesForBundleInfos failed, errCode = %{public}d", e.GetCode());
893         return UniqueFd(-e.GetCode());
894     } catch (...) {
895         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
896         HILOGI("Unexpected exception");
897         return UniqueFd(-EPERM);
898     }
899 }
900 
CallOnBundleEndByScenario(const std::string & bundleName,BackupRestoreScenario scenario,ErrCode errCode)901 void Service::CallOnBundleEndByScenario(const std::string &bundleName, BackupRestoreScenario scenario, ErrCode errCode)
902 {
903     if (session_ == nullptr) {
904         HILOGE("Session is empty, bundleName:%{public}s", bundleName.c_str());
905         return;
906     }
907     HILOGI("Begin");
908     try {
909         if (scenario == BackupRestoreScenario::FULL_RESTORE) {
910             session_->GetServiceReverseProxy()->RestoreOnBundleFinished(errCode, bundleName);
911         } else if (scenario == BackupRestoreScenario::INCREMENTAL_RESTORE) {
912             session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleFinished(errCode, bundleName);
913         } else if (scenario == BackupRestoreScenario::FULL_BACKUP) {
914             session_->GetServiceReverseProxy()->BackupOnBundleFinished(errCode, bundleName);
915         } else if (scenario == BackupRestoreScenario::INCREMENTAL_BACKUP) {
916             session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(errCode, bundleName);
917         }
918     } catch (const BError &e) {
919         HILOGE("Call onBundleFinished error, client is died");
920         return;
921     }
922 }
923 
GetBackupDataSize(bool isPreciseScan,vector<BIncrementalData> bundleNameList)924 ErrCode Service::GetBackupDataSize(bool isPreciseScan, vector<BIncrementalData> bundleNameList)
925 {
926     try {
927         HILOGI("start GetBackupDataSize");
928         if (session_ == nullptr || onScanning_.load()) {
929             HILOGE("GetBackupDataSize error 1.session is nullptr 2.onScanning_ = %{public}d", onScanning_.load());
930             return BError(BError::Codes::SA_INVAL_ARG);
931         }
932         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
933         onScanning_.store(true);
934         ErrCode ret = VerifyCaller();
935         if (ret != ERR_OK) {
936             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
937             return BError(BError::Codes::SA_INVAL_ARG, "verify caller failed");
938         }
939         BundleMgrAdapter::CreatBackupEnv(bundleNameList, GetUserIdDefault());
940         CyclicSendScannedInfo(isPreciseScan, bundleNameList);
941         return BError(BError::Codes::OK);
942     } catch (...) {
943         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
944         return BError(BError::Codes::SA_INVAL_ARG);
945     }
946 }
947 
CyclicSendScannedInfo(bool isPreciseScan,vector<BIncrementalData> bundleNameList)948 void Service::CyclicSendScannedInfo(bool isPreciseScan, vector<BIncrementalData> bundleNameList)
949 {
950     auto task = [isPreciseScan {isPreciseScan}, bundleNameList {move(bundleNameList)},
951         obj {wptr<Service>(this)}, session {session_}]() {
952         auto ptr = obj.promote();
953         if (ptr == nullptr) {
954             HILOGE("ptr is nullptr");
955             session->DecreaseSessionCnt(__PRETTY_FUNCTION__);
956             return;
957         }
958         size_t listSize = bundleNameList.size();
959         HILOGI("need scanf num = %{public}zu", listSize);
960         string scanning;
961         size_t allScannedSize = 0;
962         ptr->GetDataSizeStepByStep(isPreciseScan, bundleNameList, scanning);
963         while (!ptr->isScannedEnd_.load()) {
964             std::unique_lock<mutex> lock(ptr->getDataSizeLock_);
965             ptr->getDataSizeCon_.wait_for(lock, std::chrono::seconds(WAIT_SCANNING_INFO_SEND_TIME),
966                 [ptr] { return ptr->isScannedEnd_.load(); });
967             auto scannedSize = ptr->bundleDataSizeList_.size();
968             allScannedSize += scannedSize;
969             HILOGI("ScannedSize = %{public}zu, allScannedSize = %{public}zu", scannedSize, allScannedSize);
970             if (!ptr->GetScanningInfo(obj, scannedSize, scanning)) {
971                 ptr->SendScannedInfo("", session);
972                 continue;
973             }
974             ptr->DeleteFromList(scannedSize);
975             ptr->SendScannedInfo(ptr->scannedInfo_, session);
976         }
977         ptr->isScannedEnd_.store(false);
978         session->DecreaseSessionCnt(__PRETTY_FUNCTION__);
979     };
980 
981     callbackScannedInfoThreadPool_.AddTask([task, session {session_}]() {
982         try {
983             task();
984         } catch (...) {
985             session->DecreaseSessionCnt(__PRETTY_FUNCTION__);
986             HILOGE("Failed to add task to thread pool");
987         }
988     });
989 }
990 
GetDataSizeStepByStep(bool isPreciseScan,vector<BIncrementalData> bundleNameList,string & scanning)991 void Service::GetDataSizeStepByStep(bool isPreciseScan, vector<BIncrementalData> bundleNameList, string &scanning)
992 {
993     auto task = [isPreciseScan {isPreciseScan}, bundleNameList {move(bundleNameList)},
994         &scanning, obj {wptr<Service>(this)}]() {
995         auto ptr = obj.promote();
996         if (ptr == nullptr) {
997             HILOGE("ptr is nullptr");
998             return;
999         }
1000         if (!isPreciseScan) {
1001             HILOGI("start GetPresumablySize");
1002             ptr->GetPresumablySize(bundleNameList, scanning);
1003         } else {
1004             HILOGI("start GetPrecisesSize");
1005             ptr->GetPrecisesSize(bundleNameList, scanning);
1006         }
1007         std::lock_guard lock(ptr->getDataSizeLock_);
1008         ptr->isScannedEnd_.store(true);
1009         ptr->getDataSizeCon_.notify_all();
1010         ptr->onScanning_.store(false);
1011     };
1012 
1013     getDataSizeThreadPool_.AddTask([task]() {
1014         try {
1015             task();
1016         } catch (...) {
1017             HILOGE("Failed to add task to thread pool");
1018         }
1019     });
1020 }
1021 
GetPresumablySize(vector<BIncrementalData> bundleNameList,string & scanning)1022 void Service::GetPresumablySize(vector<BIncrementalData> bundleNameList, string &scanning)
1023 {
1024     int32_t userId = GetUserIdDefault();
1025     for (const auto &bundleData : bundleNameList) {
1026         string name = bundleData.bundleName;
1027         SetScanningInfo(scanning, name);
1028         if (SAUtils::IsSABundleName(name)) {
1029             WriteScannedInfoToList(name, 0, ERR_SIZE);
1030             continue;
1031         }
1032         int64_t dataSize = BundleMgrAdapter::GetBundleDataSize(name, userId);
1033         if (dataSize == 0) {
1034             WriteScannedInfoToList(name, ERR_SIZE, ERR_SIZE);
1035             continue;
1036         }
1037         WriteScannedInfoToList(name, dataSize, ERR_SIZE);
1038     }
1039     SetScanningInfo(scanning, "");
1040     HILOGI("GetPresumablySize end");
1041 }
1042 
GetPrecisesSize(vector<BIncrementalData> bundleNameList,string & scanning)1043 void Service::GetPrecisesSize(vector<BIncrementalData> bundleNameList, string &scanning)
1044 {
1045     for (const auto &bundleData : bundleNameList) {
1046         vector<string> bundleNames;
1047         vector<int64_t> lastBackTimes;
1048         string name = bundleData.bundleName;
1049         SetScanningInfo(scanning, name);
1050         BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(name);
1051         if (bundleDetail.bundleIndex > 0) {
1052             std::string bundleNameIndex  = "+clone-" + std::to_string(bundleDetail.bundleIndex) + "+" +
1053             bundleDetail.bundleName;
1054             bundleNames.push_back(bundleNameIndex);
1055         } else {
1056             bundleNames.push_back(name);
1057         }
1058         int64_t lastTime = bundleData.lastIncrementalTime;
1059         lastBackTimes.push_back(lastTime);
1060         vector<int64_t> pkgFileSizes {};
1061         vector<int64_t> incPkgFileSizes {};
1062         int32_t err = StorageMgrAdapter::GetBundleStatsForIncrease(GetUserIdDefault(), bundleNames, lastBackTimes,
1063             pkgFileSizes, incPkgFileSizes);
1064         if (err != 0) {
1065             HILOGE("filed to get datasize from storage, err =%{public}d, bundlename = %{public}s, index = %{public}d",
1066                 err, name.c_str(), bundleDetail.bundleIndex);
1067             WriteScannedInfoToList(name, ERR_SIZE, ERR_SIZE);
1068             continue;
1069         }
1070         if (lastTime == 0 && pkgFileSizes.size() > 0) {
1071             WriteScannedInfoToList(name, pkgFileSizes[0], ERR_SIZE);
1072         } else if (pkgFileSizes.size() > 0 && incPkgFileSizes.size() > 0) {
1073             WriteScannedInfoToList(name, pkgFileSizes[0], incPkgFileSizes[0]);
1074         } else {
1075             HILOGE ("pkgFileSizes or incPkgFileSizes error, %{public}zu, %{public}zu",
1076                 pkgFileSizes.size(), incPkgFileSizes.size());
1077         }
1078     }
1079     SetScanningInfo(scanning, "");
1080     HILOGI("GetPrecisesSize end");
1081 }
1082 
WriteToList(BJsonUtil::BundleDataSize bundleDataSize)1083 void Service::WriteToList(BJsonUtil::BundleDataSize bundleDataSize)
1084 {
1085     std::lock_guard<std::mutex> lock(scannedListLock_);
1086     bundleDataSizeList_.push_back(bundleDataSize);
1087 }
1088 
DeleteFromList(size_t scannedSize)1089 void Service::DeleteFromList(size_t scannedSize)
1090 {
1091     std::lock_guard<std::mutex> lock(scannedListLock_);
1092     bundleDataSizeList_.erase(bundleDataSizeList_.begin(), bundleDataSizeList_.begin() + scannedSize);
1093 }
1094 
GetScanningInfo(wptr<Service> obj,size_t scannedSize,string & scanning)1095 bool Service::GetScanningInfo(wptr<Service> obj, size_t scannedSize, string &scanning)
1096 {
1097     auto ptr = obj.promote();
1098     if (ptr == nullptr) {
1099         HILOGE("ptr is nullptr");
1100         return false;
1101     }
1102     std::lock_guard<std::mutex> lock(scannedListLock_);
1103     if (!BJsonUtil::WriteToStr(ptr->bundleDataSizeList_, scannedSize, scanning, ptr->scannedInfo_)) {
1104         return false;
1105     }
1106     return true;
1107 }
1108 
SetScanningInfo(string & scanning,string name)1109 void Service::SetScanningInfo(string &scanning, string name)
1110 {
1111     std::lock_guard<std::mutex> lock(scannedListLock_);
1112     scanning = name;
1113 }
1114 
WriteScannedInfoToList(const string & bundleName,int64_t dataSize,int64_t incDataSize)1115 void Service::WriteScannedInfoToList(const string &bundleName, int64_t dataSize, int64_t incDataSize)
1116 {
1117     BJsonUtil::BundleDataSize bundleDataSize;
1118     bundleDataSize.bundleName = bundleName;
1119     bundleDataSize.dataSize = dataSize;
1120     bundleDataSize.incDataSize = incDataSize;
1121     HILOGI("name = %{public}s, size = %{public}" PRId64 ", incSize = %{public}" PRId64 "",
1122         bundleName.c_str(), dataSize, incDataSize);
1123     WriteToList(bundleDataSize);
1124 }
1125 
SendScannedInfo(const string & scannendInfos,sptr<SvcSessionManager> session)1126 void Service::SendScannedInfo(const string&scannendInfos, sptr<SvcSessionManager> session)
1127 {
1128     if (scannendInfos.empty()) {
1129         HILOGE("write json failed , info is null");
1130     }
1131     if (session == nullptr) {
1132         HILOGE("session is nullptr");
1133         return;
1134     }
1135     HILOGI("start send scanned info");
1136     auto task = [session {session}, scannendInfos {scannendInfos}]() {
1137         if (session->GetScenario() == IServiceReverse::Scenario::BACKUP && session->GetIsIncrementalBackup()) {
1138             HILOGI("this is incremental backup sending info");
1139             session->GetServiceReverseProxy()->IncrementalBackupOnScanningInfo(scannendInfos);
1140             return;
1141         }
1142         HILOGI("this is full backup sending info");
1143         session->GetServiceReverseProxy()->BackupOnScanningInfo(scannendInfos);
1144     };
1145 
1146     sendScannendResultThreadPool_.AddTask([task]() {
1147         try {
1148             task();
1149         } catch (...) {
1150             HILOGE("Failed to add task to thread pool");
1151         }
1152     });
1153 }
1154 
StartExtTimer(bool & isExtStart)1155 ErrCode Service::StartExtTimer(bool &isExtStart)
1156 {
1157     try {
1158         HILOGI("Service::StartExtTimer begin.");
1159         if (session_ == nullptr) {
1160             HILOGE("StartExtTimer error, session_ is nullptr.");
1161             isExtStart = false;
1162             return BError(BError::Codes::SA_INVAL_ARG);
1163         }
1164         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
1165         string bundleName;
1166         ErrCode ret = VerifyCallerAndGetCallerName(bundleName);
1167         if (ret != ERR_OK) {
1168             HILOGE("Start extension timer fail, get bundleName failed, ret:%{public}d", ret);
1169             isExtStart = false;
1170             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
1171             return ret;
1172         }
1173         auto timeoutCallback = TimeOutCallback(wptr<Service>(this), bundleName);
1174         session_->StopFwkTimer(bundleName);
1175         isExtStart = session_->StartExtTimer(bundleName, timeoutCallback);
1176         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
1177         return BError(BError::Codes::OK);
1178     } catch (...) {
1179         HILOGE("Unexpected exception");
1180         isExtStart = false;
1181         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
1182         return EPERM;
1183     }
1184 }
1185 
StartFwkTimer(bool & isFwkStart)1186 ErrCode Service::StartFwkTimer(bool &isFwkStart)
1187 {
1188     try {
1189         HILOGI("Service::StartFwkTimer begin.");
1190         if (session_ == nullptr) {
1191             HILOGE("StartFwkTimer error, session_ is nullptr.");
1192             isFwkStart = false;
1193             return BError(BError::Codes::SA_INVAL_ARG);
1194         }
1195         session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
1196         std::string bundleName;
1197         ErrCode ret = VerifyCallerAndGetCallerName(bundleName);
1198         if (ret != ERR_OK) {
1199             HILOGE("Start fwk timer fail, get bundleName failed, ret:%{public}d", ret);
1200             isFwkStart = false;
1201             session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
1202             return ret;
1203         }
1204         auto timeoutCallback = TimeOutCallback(wptr<Service>(this), bundleName);
1205         session_->StopExtTimer(bundleName);
1206         isFwkStart = session_->StartFwkTimer(bundleName, timeoutCallback);
1207         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
1208         return BError(BError::Codes::OK);
1209     } catch (...) {
1210         HILOGE("Unexpected exception");
1211         isFwkStart = false;
1212         session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
1213         return EPERM;
1214     }
1215 }
1216 }