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 }