1 /*
2 * Copyright (c) 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 <cstddef>
22 #include <cstdint>
23
24 #include <fcntl.h>
25 #include <iomanip>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <sys/vfs.h>
29
30 #include <directory_ex.h>
31 #include <unique_fd.h>
32
33 #include "accesstoken_kit.h"
34 #include "b_anony/b_anony.h"
35 #include "b_error/b_error.h"
36 #include "b_error/b_excep_utils.h"
37 #include "b_json/b_json_cached_entity.h"
38 #include "b_json/b_json_entity_caps.h"
39 #include "b_ohos/startup/backup_para.h"
40 #include "b_process/b_multiuser.h"
41 #include "b_radar/b_radar.h"
42 #include "b_resources/b_constants.h"
43 #include "b_sa/b_sa_utils.h"
44 #include "filemgmt_libhilog.h"
45 #include "hisysevent.h"
46 #include "ipc_skeleton.h"
47 #include "module_external/bms_adapter.h"
48 #include "module_ipc/svc_backup_connection.h"
49 #include "module_ipc/svc_restore_deps_manager.h"
50 #include "parameter.h"
51 #include "system_ability_definition.h"
52 #include "hitrace_meter.h"
53
54 namespace OHOS::FileManagement::Backup {
55 using namespace std;
56 const std::string FILE_BACKUP_EVENTS = "FILE_BACKUP_EVENTS";
57
58 namespace {
59 constexpr int32_t DEBUG_ID = 100;
60 constexpr int32_t INDEX = 3;
61 constexpr int32_t MS_1000 = 1000;
62 const static string UNICAST_TYPE = "unicast";
63 } // namespace
64
GetUserIdDefault()65 static inline int32_t GetUserIdDefault()
66 {
67 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
68 auto [isDebug, debugId] = BackupPara().GetBackupDebugOverrideAccount();
69 if (isDebug && debugId > DEBUG_ID) {
70 return debugId;
71 }
72 auto multiuser = BMultiuser::ParseUid(IPCSkeleton::GetCallingUid());
73 if ((multiuser.userId == BConstants::SYSTEM_UID) || (multiuser.userId == BConstants::XTS_UID)) {
74 return BConstants::DEFAULT_USER_ID;
75 }
76 return multiuser.userId;
77 }
78
Release()79 ErrCode Service::Release()
80 {
81 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
82 HILOGI("KILL");
83 IServiceReverse::Scenario scenario = session_->GetScenario();
84 VerifyCaller(scenario);
85 AppRadar::Info info("", "", "call release");
86 if (scenario == IServiceReverse::Scenario::RESTORE) {
87 AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::Release", session_->GetSessionUserId(),
88 BizStageRestore::BIZ_STAGE_RELEASE, ERR_OK);
89 } else if (scenario == IServiceReverse::Scenario::BACKUP) {
90 AppRadar::GetInstance().RecordBackupFuncRes(info, "Service::Release", session_->GetSessionUserId(),
91 BizStageBackup::BIZ_STAGE_RELEASE, ERR_OK);
92 }
93 SessionDeactive();
94 return BError(BError::Codes::OK);
95 }
96
GetExtensionMutex(const BundleName & bundleName)97 std::shared_ptr<ExtensionMutexInfo> Service::GetExtensionMutex(const BundleName &bundleName)
98 {
99 std::unique_lock<std::mutex> lock(extensionMutexLock_);
100 auto it = backupExtMutexMap_.find(bundleName);
101 if (it == backupExtMutexMap_.end()) {
102 HILOGI("BackupExtMutexMap not contain %{public}s", bundleName.c_str());
103 backupExtMutexMap_[bundleName] = std::make_shared<ExtensionMutexInfo>(bundleName);
104 return backupExtMutexMap_[bundleName];
105 }
106 HILOGI("BackupExtMutexMap contain %{public}s", bundleName.c_str());
107 return it->second;
108 }
109
RemoveExtensionMutex(const BundleName & bundleName)110 void Service::RemoveExtensionMutex(const BundleName &bundleName)
111 {
112 std::unique_lock<std::mutex> lock(extensionMutexLock_);
113 auto it = backupExtMutexMap_.find(bundleName);
114 if (it == backupExtMutexMap_.end()) {
115 HILOGI("BackupExtMutexMap not contain %{public}s", bundleName.c_str());
116 return;
117 }
118 backupExtMutexMap_.erase(it);
119 }
120
CreateDirIfNotExist(const std::string & path)121 void Service::CreateDirIfNotExist(const std::string &path)
122 {
123 if (access(path.c_str(), F_OK) != 0) {
124 bool created = ForceCreateDirectory(path.data());
125 if (created) {
126 HILOGI("Create directory successfully.");
127 } else {
128 HILOGE("Failed to create directory, path = %{private}s, err = %{public}d", path.c_str(), errno);
129 }
130 }
131 }
132
GetLocalCapabilitiesIncremental(const std::vector<BIncrementalData> & bundleNames)133 UniqueFd Service::GetLocalCapabilitiesIncremental(const std::vector<BIncrementalData> &bundleNames)
134 {
135 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
136 try {
137 /*
138 Only called by restore app before InitBackupSession,
139 so there must be set init userId.
140 */
141 HILOGI("Begin");
142 if (session_ == nullptr || isCleanService_.load()) {
143 HILOGE("Get LocalCapabilities Incremental Error, session is empty or cleaning up the service");
144 return UniqueFd(-ENOENT);
145 }
146 session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
147 session_->SetSessionUserId(GetUserIdDefault());
148 VerifyCaller();
149 string path = BConstants::GetSaBundleBackupRootDir(session_->GetSessionUserId());
150 BExcepUltils::VerifyPath(path, false);
151 CreateDirIfNotExist(path);
152 UniqueFd fd(open(path.data(), O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR));
153 if (fd < 0) {
154 HILOGE("GetLocalCapabilitiesIncremental: open file failed, err = %{public}d", errno);
155 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
156 return UniqueFd(-ENOENT);
157 }
158 BJsonCachedEntity<BJsonEntityCaps> cachedEntity(move(fd));
159 auto cache = cachedEntity.Structuralize();
160
161 cache.SetSystemFullName(GetOSFullName());
162 cache.SetDeviceType(GetDeviceType());
163 auto bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(session_->GetSessionUserId(), bundleNames);
164 cache.SetBundleInfos(bundleInfos, true);
165 cachedEntity.Persist();
166 HILOGI("Service GetLocalCapabilitiesIncremental persist");
167 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
168 HILOGI("End, bundleInfos size:%{public}zu", bundleInfos.size());
169 return move(cachedEntity.GetFd());
170 } catch (const BError &e) {
171 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
172 HILOGE("GetLocalCapabilitiesIncremental failed, errCode = %{public}d", e.GetCode());
173 return UniqueFd(-e.GetCode());
174 } catch (const exception &e) {
175 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
176 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
177 return UniqueFd(-EPERM);
178 } catch (...) {
179 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
180 HILOGI("Unexpected exception");
181 return UniqueFd(-EPERM);
182 }
183 }
184
StartGetFdTask(std::string bundleName,wptr<Service> ptr)185 void Service::StartGetFdTask(std::string bundleName, wptr<Service> ptr)
186 {
187 auto thisPtr = ptr.promote();
188 if (!thisPtr) {
189 HILOGE("this pointer is null");
190 return;
191 }
192 auto session = thisPtr->session_;
193 if (session == nullptr) {
194 throw BError(BError::Codes::SA_INVAL_ARG, "session is nullptr");
195 }
196 auto backUpConnection = session->GetExtConnection(bundleName);
197 if (backUpConnection == nullptr) {
198 throw BError(BError::Codes::SA_INVAL_ARG, "backUpConnection is empty");
199 }
200 auto proxy = backUpConnection->GetBackupExtProxy();
201 if (!proxy) {
202 throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
203 }
204 // distinguish whether it is 0 user
205 if (BundleMgrAdapter::IsUser0BundleName(bundleName, session_->GetSessionUserId())) {
206 auto ret = proxy->User0OnBackup();
207 if (ret) {
208 thisPtr->ClearSessionAndSchedInfo(bundleName);
209 thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
210 }
211 return;
212 }
213 int64_t lastTime = session->GetLastIncrementalTime(bundleName);
214 std::vector<BIncrementalData> bundleNames;
215 bundleNames.emplace_back(BIncrementalData {bundleName, lastTime});
216 BundleMgrAdapter::GetBundleInfosForIncremental(bundleNames, session->GetSessionUserId());
217 string path = BConstants::GetSaBundleBackupRootDir(session->GetSessionUserId()).
218 append(bundleName).
219 append("/").
220 append(BConstants::BACKUP_STAT_SYMBOL).
221 append(to_string(lastTime));
222 HILOGD("path = %{public}s,bundleName = %{public}s", path.c_str(), bundleName.c_str());
223 UniqueFd fdLocal(open(path.data(), O_RDWR, S_IRGRP | S_IWGRP));
224 if (fdLocal < 0) {
225 HILOGD("fdLocal open fail, error = %{public}d", errno);
226 throw BError(BError::Codes::SA_INVAL_ARG, "open local Manifest file failed");
227 }
228 UniqueFd lastManifestFd(session->GetIncrementalManifestFd(bundleName));
229 auto ret = proxy->HandleIncrementalBackup(move(fdLocal), move(lastManifestFd));
230 if (ret) {
231 thisPtr->ClearSessionAndSchedInfo(bundleName);
232 thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
233 }
234 }
235
GetAppLocalListAndDoIncrementalBackup()236 ErrCode Service::GetAppLocalListAndDoIncrementalBackup()
237 {
238 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
239 try {
240 if (session_ == nullptr || isCleanService_.load()) {
241 HILOGE("session is nullptr");
242 return BError(BError::Codes::SA_INVAL_ARG);
243 }
244 session_->IncreaseSessionCnt(__PRETTY_FUNCTION__);
245 session_->SetSessionUserId(GetUserIdDefault());
246 std::string bundleName = VerifyCallerAndGetCallerName();
247 auto task = [this, bundleName]() {
248 StartGetFdTask(bundleName, wptr(this));
249 };
250 threadPool_.AddTask([task]() {
251 try {
252 task();
253 } catch (const BError &e) {
254 HILOGE("GetAppLocalListAndDoIncrementalBackup failed, errCode = %{public}d", e.GetCode());
255 } catch (const exception &e) {
256 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
257 } catch (...) {
258 HILOGI("Unexpected exception");
259 }
260 });
261 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
262 return BError(BError::Codes::OK);
263 } catch (const BError &e) {
264 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
265 HILOGE("GetAppLocalListAndDoIncrementalBackup failed, errCode = %{public}d", e.GetCode());
266 return e.GetCode();
267 } catch (const exception &e) {
268 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
269 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
270 return EPERM;
271 } catch (...) {
272 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
273 HILOGI("Unexpected exception");
274 return EPERM;
275 }
276 }
277
InitIncrementalBackupSession(sptr<IServiceReverse> remote)278 ErrCode Service::InitIncrementalBackupSession(sptr<IServiceReverse> remote)
279 {
280 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
281 try {
282 VerifyCaller();
283 if (session_ == nullptr) {
284 HILOGE("Init Incremental backup session error, session is empty");
285 return BError(BError::Codes::SA_INVAL_ARG);
286 }
287 ErrCode errCode = session_->Active({.clientToken = IPCSkeleton::GetCallingTokenID(),
288 .scenario = IServiceReverse::Scenario::BACKUP,
289 .clientProxy = remote,
290 .userId = GetUserIdDefault(),
291 .isIncrementalBackup = true});
292 if (errCode == 0) {
293 ClearFailedBundles();
294 successBundlesNum_ = 0;
295 }
296 return errCode;
297 } catch (const BError &e) {
298 StopAll(nullptr, true);
299 return e.GetCode();
300 }
301 }
302
GetBundleNameByDetails(const std::vector<BIncrementalData> & bundlesToBackup)303 vector<string> Service::GetBundleNameByDetails(const std::vector<BIncrementalData> &bundlesToBackup)
304 {
305 vector<string> bundleNames {};
306 for (auto bundle : bundlesToBackup) {
307 bundleNames.emplace_back(bundle.bundleName);
308 }
309 return bundleNames;
310 }
311
AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> & bundlesToBackup)312 ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup)
313 {
314 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
315 try {
316 if (session_ == nullptr || isCleanService_.load()) {
317 HILOGE("Init Incremental backup session error, session is empty");
318 return BError(BError::Codes::SA_INVAL_ARG);
319 }
320 session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时
321 VerifyCaller(IServiceReverse::Scenario::BACKUP);
322 vector<string> bundleNames = GetBundleNameByDetails(bundlesToBackup);
323 auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundlesToBackup,
324 session_->GetSessionUserId());
325 std::vector<std::string> supportBackupNames = GetSupportBackupBundleNames(backupInfos, true, bundleNames);
326 session_->AppendBundles(supportBackupNames);
327 SetBundleIncDataInfo(bundlesToBackup, supportBackupNames);
328 SetCurrentBackupSessProperties(supportBackupNames, session_->GetSessionUserId(), backupInfos, true);
329 OnStartSched();
330 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
331 return BError(BError::Codes::OK);
332 } catch (const BError &e) {
333 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
334 HILOGE("Failed, errCode = %{public}d", e.GetCode());
335 return e.GetCode();
336 } catch (...) {
337 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
338 HILOGI("Unexpected exception");
339 return EPERM;
340 }
341 }
342
AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> & bundlesToBackup,const std::vector<std::string> & infos)343 ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup,
344 const std::vector<std::string> &infos)
345 {
346 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
347 try {
348 if (session_ == nullptr || isCleanService_.load()) {
349 HILOGE("Init Incremental backup session error, session is empty");
350 return BError(BError::Codes::SA_INVAL_ARG);
351 }
352 session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时
353 VerifyCaller(IServiceReverse::Scenario::BACKUP);
354 vector<string> bundleNames {};
355 for (auto &bundle : bundlesToBackup) {
356 bundleNames.emplace_back(bundle.bundleName);
357 }
358 std::vector<std::string> bundleNamesOnly;
359 std::map<std::string, bool> isClearDataFlags;
360 std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> bundleNameDetailMap =
361 BJsonUtil::BuildBundleInfos(bundleNames, infos, bundleNamesOnly,
362 session_->GetSessionUserId(), isClearDataFlags);
363 auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundlesToBackup,
364 session_->GetSessionUserId());
365 std::vector<std::string> supportBackupNames = GetSupportBackupBundleNames(backupInfos, true, bundleNames);
366 session_->AppendBundles(supportBackupNames);
367 SetBundleIncDataInfo(bundlesToBackup, supportBackupNames);
368 HandleCurGroupIncBackupInfos(backupInfos, bundleNameDetailMap, isClearDataFlags);
369 OnStartSched();
370 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
371 return BError(BError::Codes::OK);
372 } catch (const BError &e) {
373 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
374 HILOGE("Failed, errCode = %{public}d", e.GetCode());
375 return e.GetCode();
376 } catch (...) {
377 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
378 HILOGI("Unexpected exception");
379 return EPERM;
380 }
381 }
382
HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> & backupInfos,std::map<std::string,std::vector<BJsonUtil::BundleDetailInfo>> & bundleNameDetailMap,std::map<std::string,bool> & isClearDataFlags)383 void Service::HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> &backupInfos,
384 std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> &bundleNameDetailMap,
385 std::map<std::string, bool> &isClearDataFlags)
386 {
387 for (auto &info : backupInfos) {
388 HILOGI("Current backupInfo bundleName:%{public}s, index:%{public}d, extName:%{public}s", info.name.c_str(),
389 info.appIndex, info.extensionName.c_str());
390 std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex);
391 SetCurrentSessProperties(info, isClearDataFlags, bundleNameIndexInfo);
392 session_->SetBundleDataSize(bundleNameIndexInfo, info.increSpaceOccupied);
393 BJsonUtil::BundleDetailInfo uniCastInfo;
394 if (BJsonUtil::FindBundleInfoByName(bundleNameDetailMap, bundleNameIndexInfo, UNICAST_TYPE, uniCastInfo)) {
395 HILOGI("current bundle:%{public}s, unicast info:%{public}s", bundleNameIndexInfo.c_str(),
396 GetAnonyString(uniCastInfo.detail).c_str());
397 session_->SetBackupExtInfo(bundleNameIndexInfo, uniCastInfo.detail);
398 }
399 session_->SetBackupExtName(bundleNameIndexInfo, info.extensionName);
400 session_->SetIsReadyLaunch(bundleNameIndexInfo);
401 }
402 }
403
PublishIncrementalFile(const BFileInfo & fileInfo)404 ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo)
405 {
406 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
407 try {
408 VerifyCaller(IServiceReverse::Scenario::RESTORE);
409 HILOGI("Start get ExtConnection, bundleName:%{public}s", fileInfo.owner.c_str());
410 if (!fileInfo.fileName.empty()) {
411 HILOGE("Forbit to use PublishIncrementalFile with fileName for App");
412 return EPERM;
413 }
414 if (session_ != nullptr) {
415 session_->SetPublishFlag(fileInfo.owner);
416 }
417 auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
418 if (backUpConnection == nullptr) {
419 HILOGE("PublishIncrementalFile error, backUpConnection is empty");
420 return BError(BError::Codes::SA_INVAL_ARG);
421 }
422 auto proxy = backUpConnection->GetBackupExtProxy();
423 if (!proxy) {
424 HILOGE("PublishIncrementalFile error, Extension backup Proxy is empty");
425 return BError(BError::Codes::SA_INVAL_ARG);
426 }
427 ErrCode res = proxy->PublishIncrementalFile(fileInfo.fileName);
428 if (res) {
429 HILOGE("Failed to publish file for backup extension");
430 }
431 return res;
432 } catch (const BError &e) {
433 return e.GetCode();
434 } catch (const exception &e) {
435 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
436 return EPERM;
437 } catch (...) {
438 HILOGI("Unexpected exception");
439 return EPERM;
440 }
441 }
442
PublishSAIncrementalFile(const BFileInfo & fileInfo,UniqueFd fd)443 ErrCode Service::PublishSAIncrementalFile(const BFileInfo &fileInfo, UniqueFd fd)
444 {
445 std::string bundleName = fileInfo.owner;
446 if (!SAUtils::IsSABundleName(bundleName)) {
447 HILOGE("Bundle name %{public}s is not sa", bundleName.c_str());
448 return BError(BError::Codes::SA_EXT_ERR_CALL);
449 }
450 HILOGI("Bundle name %{public}s is sa, publish sa incremental file", bundleName.c_str());
451 auto backupConnection = session_->GetSAExtConnection(bundleName);
452 std::shared_ptr<SABackupConnection> saConnection = backupConnection.lock();
453 if (saConnection == nullptr) {
454 HILOGE("lock sa connection ptr is nullptr");
455 return BError(BError::Codes::SA_INVAL_ARG);
456 }
457 return saConnection->CallRestoreSA(move(fd));
458 }
459
AppIncrementalFileReady(const std::string & fileName,UniqueFd fd,UniqueFd manifestFd,int32_t errCode)460 ErrCode Service::AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd, int32_t errCode)
461 {
462 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
463 try {
464 string callerName = VerifyCallerAndGetCallerName();
465 if (session_->GetScenario() == IServiceReverse::Scenario::RESTORE) {
466 session_->GetServiceReverseProxy()->IncrementalRestoreOnFileReady(callerName, fileName, move(fd),
467 move(manifestFd), errCode);
468 FileReadyRadarReport(callerName, fileName, errCode, IServiceReverse::Scenario::RESTORE);
469 return BError(BError::Codes::OK);
470 }
471
472 if (fileName == BConstants::EXT_BACKUP_MANAGE) {
473 fd = session_->OnBundleExtManageInfo(callerName, move(fd));
474 }
475 HILOGD("reverse: Will notify IncrementalBackupOnFileReady");
476 session_->GetServiceReverseProxy()->IncrementalBackupOnFileReady(callerName, fileName, move(fd),
477 move(manifestFd), errCode);
478 FileReadyRadarReport(callerName, fileName, errCode, IServiceReverse::Scenario::BACKUP);
479 if (session_->OnBundleFileReady(callerName, fileName)) {
480 auto backUpConnection = session_->GetExtConnection(callerName);
481 auto proxy = backUpConnection->GetBackupExtProxy();
482 if (!proxy) {
483 throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
484 }
485 // 通知extension清空缓存
486 proxy->HandleClear();
487 // 清除Timer
488 session_->StopFwkTimer(callerName);
489 session_->StopExtTimer(callerName);
490 // 通知TOOL 备份完成
491 HILOGI("reverse: Will notify IncrementalBackupOnBundleFinished");
492 session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(BError(BError::Codes::OK),
493 callerName);
494 BundleEndRadarReport(callerName, BError(BError::Codes::OK), IServiceReverse::Scenario::BACKUP);
495 // 断开extension
496 backUpConnection->DisconnectBackupExtAbility();
497 ClearSessionAndSchedInfo(callerName);
498 }
499 OnAllBundlesFinished(BError(BError::Codes::OK));
500 return BError(BError::Codes::OK);
501 } catch (const BError &e) {
502 return e.GetCode(); // 任意异常产生,终止监听该任务
503 } catch (const exception &e) {
504 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
505 return EPERM;
506 } catch (...) {
507 HILOGI("Unexpected exception");
508 return EPERM;
509 }
510 }
511
AppIncrementalDone(ErrCode errCode)512 ErrCode Service::AppIncrementalDone(ErrCode errCode)
513 {
514 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
515 try {
516 if (session_ == nullptr) {
517 HILOGE("AppIncrementalDone error, session is null");
518 return BError(BError::Codes::SA_INVAL_ARG);
519 }
520 string callerName = VerifyCallerAndGetCallerName();
521 HILOGI("Service AppIncrementalDone start, callerName is %{public}s, errCode is: %{public}d",
522 callerName.c_str(), errCode);
523 if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) {
524 std::shared_ptr<ExtensionMutexInfo> mutexPtr = GetExtensionMutex(callerName);
525 if (mutexPtr == nullptr) {
526 HILOGE("extension mutex ptr is nullptr");
527 return BError(BError::Codes::SA_INVAL_ARG, "Extension mutex ptr is null.");
528 }
529 std::lock_guard<std::mutex> lock(mutexPtr->callbackMutex);
530 auto tempBackUpConnection = session_->GetExtConnection(callerName);
531 auto backUpConnection = tempBackUpConnection.promote();
532 if (backUpConnection == nullptr) {
533 return BError(BError::Codes::SA_INVAL_ARG, "Promote backUpConnection ptr is null.");
534 }
535 auto proxy = backUpConnection->GetBackupExtProxy();
536 if (!proxy) {
537 return BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
538 }
539 proxy->HandleClear();
540 session_->StopFwkTimer(callerName);
541 session_->StopExtTimer(callerName);
542 backUpConnection->DisconnectBackupExtAbility();
543 ClearSessionAndSchedInfo(callerName);
544 NotifyCallerCurAppIncrementDone(errCode, callerName);
545 }
546 RemoveExtensionMutex(callerName);
547 OnAllBundlesFinished(BError(BError::Codes::OK));
548 return BError(BError::Codes::OK);
549 } catch (const BError &e) {
550 ReleaseOnException();
551 HILOGE("AppIncrementalDone error, err code is:%{public}d", e.GetCode());
552 return e.GetCode(); // 任意异常产生,终止监听该任务
553 } catch (...) {
554 ReleaseOnException();
555 HILOGI("Unexpected exception");
556 return EPERM;
557 }
558 }
559
GetIncrementalFileHandle(const std::string & bundleName,const std::string & fileName)560 ErrCode Service::GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName)
561 {
562 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
563 try {
564 HILOGI("Begin get incrementalFileHandle");
565 VerifyCaller(IServiceReverse::Scenario::RESTORE);
566 auto action = session_->GetServiceSchedAction(bundleName);
567 if (action == BConstants::ServiceSchedAction::RUNNING) {
568 auto backUpConnection = session_->GetExtConnection(bundleName);
569 if (backUpConnection == nullptr) {
570 HILOGE("GetIncrementalFileHandle error, backUpConnection is empty");
571 return BError(BError::Codes::SA_INVAL_ARG);
572 }
573 auto proxy = backUpConnection->GetBackupExtProxy();
574 if (!proxy) {
575 HILOGE("GetIncrementalFileHandle error, Extension backup Proxy is empty");
576 return BError(BError::Codes::SA_INVAL_ARG);
577 }
578 ErrCode res = proxy->GetIncrementalFileHandle(fileName);
579 if (res != ERR_OK) {
580 HILOGE("Failed to extension file handle");
581 AppRadar::Info info (bundleName, "", "");
582 AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::GetIncrementalFileHandle",
583 GetUserIdDefault(), BizStageRestore::BIZ_STAGE_GET_FILE_HANDLE_FAIL, res);
584 }
585 } else {
586 SvcRestoreDepsManager::GetInstance().UpdateToRestoreBundleMap(bundleName, fileName);
587 session_->SetExtFileNameRequest(bundleName, fileName);
588 }
589 return BError(BError::Codes::OK);
590 } catch (const BError &e) {
591 return e.GetCode();
592 } catch (const exception &e) {
593 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
594 return EPERM;
595 } catch (...) {
596 HILOGI("Unexpected exception");
597 return EPERM;
598 }
599 }
600
IncrementalBackup(const string & bundleName)601 bool Service::IncrementalBackup(const string &bundleName)
602 {
603 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
604 IServiceReverse::Scenario scenario = session_->GetScenario();
605 auto backUpConnection = session_->GetExtConnection(bundleName);
606 if (backUpConnection == nullptr) {
607 throw BError(BError::Codes::SA_INVAL_ARG, "backUpConnection is empty");
608 }
609 auto proxy = backUpConnection->GetBackupExtProxy();
610 if (!proxy) {
611 throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
612 }
613 if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) {
614 auto ret = proxy->IncrementalOnBackup(session_->GetClearDataFlag(bundleName));
615 session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(ret, bundleName);
616 BundleBeginRadarReport(bundleName, ret, IServiceReverse::Scenario::BACKUP);
617 if (ret) {
618 ClearSessionAndSchedInfo(bundleName);
619 NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
620 }
621 return true;
622 } else if (scenario == IServiceReverse::Scenario::RESTORE && BackupPara().GetBackupOverrideIncrementalRestore() &&
623 session_->ValidRestoreDataType(RestoreTypeEnum::RESTORE_DATA_WAIT_SEND)) {
624 auto ret = proxy->HandleRestore(session_->GetClearDataFlag(bundleName));
625 session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleStarted(ret, bundleName);
626 BundleBeginRadarReport(bundleName, ret, IServiceReverse::Scenario::RESTORE);
627 auto fileNameVec = session_->GetExtFileNameRequest(bundleName);
628 for (auto &fileName : fileNameVec) {
629 ret = proxy->GetIncrementalFileHandle(fileName);
630 if (ret) {
631 HILOGE("Failed to extension file handle %{public}s", fileName.c_str());
632 }
633 }
634 return true;
635 }
636 return false;
637 }
638
NotifyCallerCurAppIncrementDone(ErrCode errCode,const std::string & callerName)639 void Service::NotifyCallerCurAppIncrementDone(ErrCode errCode, const std::string &callerName)
640 {
641 IServiceReverse::Scenario scenario = session_->GetScenario();
642 if (scenario == IServiceReverse::Scenario::BACKUP) {
643 HILOGI("will notify clone data, scenario is incremental backup");
644 session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(errCode, callerName);
645 BundleEndRadarReport(callerName, errCode, scenario);
646 auto now = std::chrono::system_clock::now();
647 auto time = std::chrono::system_clock::to_time_t(now);
648 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
649 std::stringstream strTime;
650 strTime << (std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S:")) << (std::setfill('0'))
651 << (std::setw(INDEX)) << (ms.count() % MS_1000);
652 HiSysEventWrite(
653 OHOS::HiviewDFX::HiSysEvent::Domain::FILEMANAGEMENT,
654 FILE_BACKUP_EVENTS,
655 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
656 "PROC_NAME", "ohos.appfileservice", "BUNDLENAME", callerName,
657 "PID", getpid(), "TIME", strTime.str()
658 );
659 } else if (scenario == IServiceReverse::Scenario::RESTORE) {
660 HILOGI("will notify clone data, scenario is Restore");
661 SendEndAppGalleryNotify(callerName);
662 session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleFinished(errCode, callerName);
663 BundleEndRadarReport(callerName, errCode, scenario);
664 }
665 }
666
SendUserIdToApp(string & bundleName,int32_t userId)667 void Service::SendUserIdToApp(string &bundleName, int32_t userId)
668 {
669 if (session_ == nullptr) {
670 HILOGI("session_ is nullptr");
671 return;
672 }
673 HILOGI("Begin, bundleName: %{public}s", bundleName.c_str());
674 string detailInfo;
675 if (!BJsonUtil::BuildBundleInfoJson(userId, detailInfo)) {
676 HILOGE("BuildBundleInfoJson failed, bundleName : %{public}s", bundleName.c_str());
677 return;
678 }
679 session_->SetBackupExtInfo(bundleName, detailInfo);
680 HILOGI("End, bundleName:%{public}s, unicast info:%{public}s", bundleName.c_str(),
681 GetAnonyString(detailInfo).c_str());
682 }
683
SetCurrentBackupSessProperties(const vector<string> & bundleNames,int32_t userId,vector<BJsonEntityCaps::BundleInfo> & backupBundleInfos,bool isIncBackup)684 void Service::SetCurrentBackupSessProperties(const vector<string> &bundleNames, int32_t userId,
685 vector<BJsonEntityCaps::BundleInfo> &backupBundleInfos, bool isIncBackup)
686 {
687 HILOGI("start SetCurrentBackupSessProperties");
688 std::map<std::string, BJsonEntityCaps::BundleInfo> bundleNameIndexBundleInfoMap;
689 for (auto &bundleInfo : backupBundleInfos) {
690 std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(bundleInfo.name, bundleInfo.appIndex);
691 bundleNameIndexBundleInfoMap[bundleNameIndexInfo] = bundleInfo;
692 }
693 for (auto item : bundleNames) {
694 std::string bundleName = item;
695 if (BundleMgrAdapter::IsUser0BundleName(bundleName, userId)) {
696 HILOGE("bundleName:%{public}s is zero user bundle", bundleName.c_str());
697 SendUserIdToApp(bundleName, userId);
698 }
699 auto it = bundleNameIndexBundleInfoMap.find(bundleName);
700 if (it == bundleNameIndexBundleInfoMap.end()) {
701 HILOGE("Current bundleName can not find bundleInfo, bundleName:%{public}s", bundleName.c_str());
702 session_->RemoveExtInfo(bundleName);
703 continue;
704 }
705 auto bundleInfo = it->second;
706 if (isIncBackup) {
707 session_->SetBundleDataSize(bundleName, bundleInfo.increSpaceOccupied);
708 } else {
709 session_->SetBundleDataSize(bundleName, bundleInfo.spaceOccupied);
710 }
711 session_->SetBackupExtName(bundleName, bundleInfo.extensionName);
712 session_->SetIsReadyLaunch(bundleName);
713 }
714 HILOGI("end SetCurrentBackupSessProperties");
715 }
716
SetBundleIncDataInfo(const std::vector<BIncrementalData> & bundlesToBackup,std::vector<std::string> & supportBundleNames)717 void Service::SetBundleIncDataInfo(const std::vector<BIncrementalData>& bundlesToBackup,
718 std::vector<std::string>& supportBundleNames)
719 {
720 for (auto &bundleInfo : bundlesToBackup) {
721 std::string bundleName = bundleInfo.bundleName;
722 auto it = std::find(supportBundleNames.begin(), supportBundleNames.end(), bundleName);
723 if (it == supportBundleNames.end()) {
724 HILOGE("Current bundle is not support to backup, bundleName:%{public}s", bundleName.c_str());
725 continue;
726 }
727 session_->SetIncrementalData(bundleInfo);
728 }
729 }
730 } // namespace OHOS::FileManagement::Backup
731