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