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);
326 session_->AppendBundles(supportBackupNames);
327 for (auto &bundleInfo : bundlesToBackup) {
328 session_->SetIncrementalData(bundleInfo);
329 }
330 SetCurrentBackupSessProperties(supportBackupNames, session_->GetSessionUserId(), backupInfos, true);
331 OnStartSched();
332 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
333 return BError(BError::Codes::OK);
334 } catch (const BError &e) {
335 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
336 HILOGE("Failed, errCode = %{public}d", e.GetCode());
337 return e.GetCode();
338 } catch (...) {
339 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
340 HILOGI("Unexpected exception");
341 return EPERM;
342 }
343 }
344
AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> & bundlesToBackup,const std::vector<std::string> & infos)345 ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector<BIncrementalData> &bundlesToBackup,
346 const std::vector<std::string> &infos)
347 {
348 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
349 try {
350 if (session_ == nullptr || isCleanService_.load()) {
351 HILOGE("Init Incremental backup session error, session is empty");
352 return BError(BError::Codes::SA_INVAL_ARG);
353 }
354 session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时
355 VerifyCaller(IServiceReverse::Scenario::BACKUP);
356 vector<string> bundleNames {};
357 for (auto &bundle : bundlesToBackup) {
358 bundleNames.emplace_back(bundle.bundleName);
359 }
360 std::vector<std::string> bundleNamesOnly;
361 std::map<std::string, bool> isClearDataFlags;
362 std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> bundleNameDetailMap =
363 BJsonUtil::BuildBundleInfos(bundleNames, infos, bundleNamesOnly,
364 session_->GetSessionUserId(), isClearDataFlags);
365 auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundlesToBackup,
366 session_->GetSessionUserId());
367 std::vector<std::string> supportBackupNames = GetSupportBackupBundleNames(backupInfos, true);
368 for (auto &bundleInfo : bundlesToBackup) {
369 session_->SetIncrementalData(bundleInfo);
370 }
371 session_->AppendBundles(supportBackupNames);
372 HandleCurGroupIncBackupInfos(backupInfos, bundleNameDetailMap, isClearDataFlags);
373 OnStartSched();
374 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
375 return BError(BError::Codes::OK);
376 } catch (const BError &e) {
377 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
378 HILOGE("Failed, errCode = %{public}d", e.GetCode());
379 return e.GetCode();
380 } catch (...) {
381 session_->DecreaseSessionCnt(__PRETTY_FUNCTION__);
382 HILOGI("Unexpected exception");
383 return EPERM;
384 }
385 }
386
HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> & backupInfos,std::map<std::string,std::vector<BJsonUtil::BundleDetailInfo>> & bundleNameDetailMap,std::map<std::string,bool> & isClearDataFlags)387 void Service::HandleCurGroupIncBackupInfos(vector<BJsonEntityCaps::BundleInfo> &backupInfos,
388 std::map<std::string, std::vector<BJsonUtil::BundleDetailInfo>> &bundleNameDetailMap,
389 std::map<std::string, bool> &isClearDataFlags)
390 {
391 for (auto &info : backupInfos) {
392 HILOGI("Current backupInfo bundleName:%{public}s, index:%{public}d, extName:%{public}s", info.name.c_str(),
393 info.appIndex, info.extensionName.c_str());
394 std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex);
395 SetCurrentSessProperties(info, isClearDataFlags, bundleNameIndexInfo);
396 session_->SetBundleDataSize(bundleNameIndexInfo, info.increSpaceOccupied);
397 BJsonUtil::BundleDetailInfo uniCastInfo;
398 if (BJsonUtil::FindBundleInfoByName(bundleNameDetailMap, bundleNameIndexInfo, UNICAST_TYPE, uniCastInfo)) {
399 HILOGI("current bundle:%{public}s, unicast info:%{public}s", bundleNameIndexInfo.c_str(),
400 GetAnonyString(uniCastInfo.detail).c_str());
401 session_->SetBackupExtInfo(bundleNameIndexInfo, uniCastInfo.detail);
402 }
403 session_->SetBackupExtName(bundleNameIndexInfo, info.extensionName);
404 session_->SetIsReadyLaunch(bundleNameIndexInfo);
405 }
406 }
407
PublishIncrementalFile(const BFileInfo & fileInfo)408 ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo)
409 {
410 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
411 try {
412 VerifyCaller(IServiceReverse::Scenario::RESTORE);
413 HILOGI("Start get ExtConnection, bundleName:%{public}s", fileInfo.owner.c_str());
414 if (!fileInfo.fileName.empty()) {
415 HILOGE("Forbit to use PublishIncrementalFile with fileName for App");
416 return EPERM;
417 }
418 if (session_ != nullptr) {
419 session_->SetPublishFlag(fileInfo.owner);
420 }
421 auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
422 if (backUpConnection == nullptr) {
423 HILOGE("PublishIncrementalFile error, backUpConnection is empty");
424 return BError(BError::Codes::SA_INVAL_ARG);
425 }
426 auto proxy = backUpConnection->GetBackupExtProxy();
427 if (!proxy) {
428 HILOGE("PublishIncrementalFile error, Extension backup Proxy is empty");
429 return BError(BError::Codes::SA_INVAL_ARG);
430 }
431 ErrCode res = proxy->PublishIncrementalFile(fileInfo.fileName);
432 if (res) {
433 HILOGE("Failed to publish file for backup extension");
434 }
435 return res;
436 } catch (const BError &e) {
437 return e.GetCode();
438 } catch (const exception &e) {
439 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
440 return EPERM;
441 } catch (...) {
442 HILOGI("Unexpected exception");
443 return EPERM;
444 }
445 }
446
PublishSAIncrementalFile(const BFileInfo & fileInfo,UniqueFd fd)447 ErrCode Service::PublishSAIncrementalFile(const BFileInfo &fileInfo, UniqueFd fd)
448 {
449 std::string bundleName = fileInfo.owner;
450 if (!SAUtils::IsSABundleName(bundleName)) {
451 HILOGE("Bundle name %{public}s is not sa", bundleName.c_str());
452 return BError(BError::Codes::SA_EXT_ERR_CALL);
453 }
454 HILOGI("Bundle name %{public}s is sa, publish sa incremental file", bundleName.c_str());
455 auto backupConnection = session_->GetSAExtConnection(bundleName);
456 std::shared_ptr<SABackupConnection> saConnection = backupConnection.lock();
457 if (saConnection == nullptr) {
458 HILOGE("lock sa connection ptr is nullptr");
459 return BError(BError::Codes::SA_INVAL_ARG);
460 }
461 return saConnection->CallRestoreSA(move(fd));
462 }
463
AppIncrementalFileReady(const std::string & fileName,UniqueFd fd,UniqueFd manifestFd,int32_t errCode)464 ErrCode Service::AppIncrementalFileReady(const std::string &fileName, UniqueFd fd, UniqueFd manifestFd, int32_t errCode)
465 {
466 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
467 try {
468 string callerName = VerifyCallerAndGetCallerName();
469 if (session_->GetScenario() == IServiceReverse::Scenario::RESTORE) {
470 session_->GetServiceReverseProxy()->IncrementalRestoreOnFileReady(callerName, fileName, move(fd),
471 move(manifestFd), errCode);
472 FileReadyRadarReport(callerName, fileName, errCode, IServiceReverse::Scenario::RESTORE);
473 return BError(BError::Codes::OK);
474 }
475
476 if (fileName == BConstants::EXT_BACKUP_MANAGE) {
477 fd = session_->OnBundleExtManageInfo(callerName, move(fd));
478 }
479 HILOGD("reverse: Will notify IncrementalBackupOnFileReady");
480 session_->GetServiceReverseProxy()->IncrementalBackupOnFileReady(callerName, fileName, move(fd),
481 move(manifestFd), errCode);
482 FileReadyRadarReport(callerName, fileName, errCode, IServiceReverse::Scenario::BACKUP);
483 if (session_->OnBundleFileReady(callerName, fileName)) {
484 auto backUpConnection = session_->GetExtConnection(callerName);
485 auto proxy = backUpConnection->GetBackupExtProxy();
486 if (!proxy) {
487 throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
488 }
489 // 通知extension清空缓存
490 proxy->HandleClear();
491 // 清除Timer
492 session_->StopFwkTimer(callerName);
493 session_->StopExtTimer(callerName);
494 // 通知TOOL 备份完成
495 HILOGI("reverse: Will notify IncrementalBackupOnBundleFinished");
496 session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(BError(BError::Codes::OK),
497 callerName);
498 BundleEndRadarReport(callerName, BError(BError::Codes::OK), IServiceReverse::Scenario::BACKUP);
499 // 断开extension
500 backUpConnection->DisconnectBackupExtAbility();
501 ClearSessionAndSchedInfo(callerName);
502 }
503 OnAllBundlesFinished(BError(BError::Codes::OK));
504 return BError(BError::Codes::OK);
505 } catch (const BError &e) {
506 return e.GetCode(); // 任意异常产生,终止监听该任务
507 } catch (const exception &e) {
508 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
509 return EPERM;
510 } catch (...) {
511 HILOGI("Unexpected exception");
512 return EPERM;
513 }
514 }
515
AppIncrementalDone(ErrCode errCode)516 ErrCode Service::AppIncrementalDone(ErrCode errCode)
517 {
518 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
519 try {
520 if (session_ == nullptr) {
521 HILOGE("AppIncrementalDone error, session is null");
522 return BError(BError::Codes::SA_INVAL_ARG);
523 }
524 string callerName = VerifyCallerAndGetCallerName();
525 HILOGI("Service AppIncrementalDone start, callerName is %{public}s, errCode is: %{public}d",
526 callerName.c_str(), errCode);
527 if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) {
528 std::shared_ptr<ExtensionMutexInfo> mutexPtr = GetExtensionMutex(callerName);
529 if (mutexPtr == nullptr) {
530 HILOGE("extension mutex ptr is nullptr");
531 return BError(BError::Codes::SA_INVAL_ARG, "Extension mutex ptr is null.");
532 }
533 std::lock_guard<std::mutex> lock(mutexPtr->callbackMutex);
534 auto tempBackUpConnection = session_->GetExtConnection(callerName);
535 auto backUpConnection = tempBackUpConnection.promote();
536 if (backUpConnection == nullptr) {
537 return BError(BError::Codes::SA_INVAL_ARG, "Promote backUpConnection ptr is null.");
538 }
539 auto proxy = backUpConnection->GetBackupExtProxy();
540 if (!proxy) {
541 return BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
542 }
543 proxy->HandleClear();
544 session_->StopFwkTimer(callerName);
545 session_->StopExtTimer(callerName);
546 backUpConnection->DisconnectBackupExtAbility();
547 ClearSessionAndSchedInfo(callerName);
548 NotifyCallerCurAppIncrementDone(errCode, callerName);
549 }
550 RemoveExtensionMutex(callerName);
551 OnAllBundlesFinished(BError(BError::Codes::OK));
552 return BError(BError::Codes::OK);
553 } catch (const BError &e) {
554 ReleaseOnException();
555 HILOGE("AppIncrementalDone error, err code is:%{public}d", e.GetCode());
556 return e.GetCode(); // 任意异常产生,终止监听该任务
557 } catch (...) {
558 ReleaseOnException();
559 HILOGI("Unexpected exception");
560 return EPERM;
561 }
562 }
563
GetIncrementalFileHandle(const std::string & bundleName,const std::string & fileName)564 ErrCode Service::GetIncrementalFileHandle(const std::string &bundleName, const std::string &fileName)
565 {
566 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
567 try {
568 HILOGI("Begin get incrementalFileHandle");
569 VerifyCaller(IServiceReverse::Scenario::RESTORE);
570 auto action = session_->GetServiceSchedAction(bundleName);
571 if (action == BConstants::ServiceSchedAction::RUNNING) {
572 auto backUpConnection = session_->GetExtConnection(bundleName);
573 if (backUpConnection == nullptr) {
574 HILOGE("GetIncrementalFileHandle error, backUpConnection is empty");
575 return BError(BError::Codes::SA_INVAL_ARG);
576 }
577 auto proxy = backUpConnection->GetBackupExtProxy();
578 if (!proxy) {
579 HILOGE("GetIncrementalFileHandle error, Extension backup Proxy is empty");
580 return BError(BError::Codes::SA_INVAL_ARG);
581 }
582 ErrCode res = proxy->GetIncrementalFileHandle(fileName);
583 if (res != ERR_OK) {
584 HILOGE("Failed to extension file handle");
585 AppRadar::Info info (bundleName, "", "");
586 AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::GetIncrementalFileHandle",
587 GetUserIdDefault(), BizStageRestore::BIZ_STAGE_GET_FILE_HANDLE_FAIL, res);
588 }
589 } else {
590 SvcRestoreDepsManager::GetInstance().UpdateToRestoreBundleMap(bundleName, fileName);
591 session_->SetExtFileNameRequest(bundleName, fileName);
592 }
593 return BError(BError::Codes::OK);
594 } catch (const BError &e) {
595 return e.GetCode();
596 } catch (const exception &e) {
597 HILOGI("Catched an unexpected low-level exception %{public}s", e.what());
598 return EPERM;
599 } catch (...) {
600 HILOGI("Unexpected exception");
601 return EPERM;
602 }
603 }
604
IncrementalBackup(const string & bundleName)605 bool Service::IncrementalBackup(const string &bundleName)
606 {
607 HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
608 IServiceReverse::Scenario scenario = session_->GetScenario();
609 auto backUpConnection = session_->GetExtConnection(bundleName);
610 if (backUpConnection == nullptr) {
611 throw BError(BError::Codes::SA_INVAL_ARG, "backUpConnection is empty");
612 }
613 auto proxy = backUpConnection->GetBackupExtProxy();
614 if (!proxy) {
615 throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty");
616 }
617 if (scenario == IServiceReverse::Scenario::BACKUP && session_->GetIsIncrementalBackup()) {
618 auto ret = proxy->IncrementalOnBackup(session_->GetClearDataFlag(bundleName));
619 session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted(ret, bundleName);
620 BundleBeginRadarReport(bundleName, ret, IServiceReverse::Scenario::BACKUP);
621 if (ret) {
622 ClearSessionAndSchedInfo(bundleName);
623 NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED));
624 }
625 return true;
626 } else if (scenario == IServiceReverse::Scenario::RESTORE && BackupPara().GetBackupOverrideIncrementalRestore() &&
627 session_->ValidRestoreDataType(RestoreTypeEnum::RESTORE_DATA_WAIT_SEND)) {
628 auto ret = proxy->HandleRestore(session_->GetClearDataFlag(bundleName));
629 session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleStarted(ret, bundleName);
630 BundleBeginRadarReport(bundleName, ret, IServiceReverse::Scenario::RESTORE);
631 auto fileNameVec = session_->GetExtFileNameRequest(bundleName);
632 for (auto &fileName : fileNameVec) {
633 ret = proxy->GetIncrementalFileHandle(fileName);
634 if (ret) {
635 HILOGE("Failed to extension file handle %{public}s", fileName.c_str());
636 }
637 }
638 return true;
639 }
640 return false;
641 }
642
NotifyCallerCurAppIncrementDone(ErrCode errCode,const std::string & callerName)643 void Service::NotifyCallerCurAppIncrementDone(ErrCode errCode, const std::string &callerName)
644 {
645 IServiceReverse::Scenario scenario = session_->GetScenario();
646 if (scenario == IServiceReverse::Scenario::BACKUP) {
647 HILOGI("will notify clone data, scenario is incremental backup");
648 session_->GetServiceReverseProxy()->IncrementalBackupOnBundleFinished(errCode, callerName);
649 BundleEndRadarReport(callerName, errCode, scenario);
650 auto now = std::chrono::system_clock::now();
651 auto time = std::chrono::system_clock::to_time_t(now);
652 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
653 std::stringstream strTime;
654 strTime << (std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S:")) << (std::setfill('0'))
655 << (std::setw(INDEX)) << (ms.count() % MS_1000);
656 HiSysEventWrite(
657 OHOS::HiviewDFX::HiSysEvent::Domain::FILEMANAGEMENT,
658 FILE_BACKUP_EVENTS,
659 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
660 "PROC_NAME", "ohos.appfileservice", "BUNDLENAME", callerName,
661 "PID", getpid(), "TIME", strTime.str()
662 );
663 } else if (scenario == IServiceReverse::Scenario::RESTORE) {
664 HILOGI("will notify clone data, scenario is Restore");
665 SendEndAppGalleryNotify(callerName);
666 session_->GetServiceReverseProxy()->IncrementalRestoreOnBundleFinished(errCode, callerName);
667 BundleEndRadarReport(callerName, errCode, scenario);
668 }
669 }
670
SendUserIdToApp(string & bundleName,int32_t userId)671 void Service::SendUserIdToApp(string &bundleName, int32_t userId)
672 {
673 if (session_ == nullptr) {
674 HILOGI("session_ is nullptr");
675 return;
676 }
677 HILOGI("Begin, bundleName: %{public}s", bundleName.c_str());
678 string detailInfo;
679 if (!BJsonUtil::BuildBundleInfoJson(userId, detailInfo)) {
680 HILOGE("BuildBundleInfoJson failed, bundleName : %{public}s", bundleName.c_str());
681 return;
682 }
683 session_->SetBackupExtInfo(bundleName, detailInfo);
684 HILOGI("End, bundleName:%{public}s, unicast info:%{public}s", bundleName.c_str(),
685 GetAnonyString(detailInfo).c_str());
686 }
687
SetCurrentBackupSessProperties(const vector<string> & bundleNames,int32_t userId,vector<BJsonEntityCaps::BundleInfo> & backupBundleInfos,bool isIncBackup)688 void Service::SetCurrentBackupSessProperties(const vector<string> &bundleNames, int32_t userId,
689 vector<BJsonEntityCaps::BundleInfo> &backupBundleInfos, bool isIncBackup)
690 {
691 HILOGI("start SetCurrentBackupSessProperties");
692 std::map<std::string, BJsonEntityCaps::BundleInfo> bundleNameIndexBundleInfoMap;
693 for (auto &bundleInfo : backupBundleInfos) {
694 std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(bundleInfo.name, bundleInfo.appIndex);
695 bundleNameIndexBundleInfoMap[bundleNameIndexInfo] = bundleInfo;
696 }
697 for (auto item : bundleNames) {
698 std::string bundleName = item;
699 if (BundleMgrAdapter::IsUser0BundleName(bundleName, userId)) {
700 HILOGE("bundleName:%{public}s is zero user bundle", bundleName.c_str());
701 SendUserIdToApp(bundleName, userId);
702 }
703 auto it = bundleNameIndexBundleInfoMap.find(bundleName);
704 if (it == bundleNameIndexBundleInfoMap.end()) {
705 HILOGE("Current bundleName can not find bundleInfo, bundleName:%{public}s", bundleName.c_str());
706 session_->RemoveExtInfo(bundleName);
707 continue;
708 }
709 auto bundleInfo = it->second;
710 if (isIncBackup) {
711 session_->SetBundleDataSize(bundleName, bundleInfo.increSpaceOccupied);
712 } else {
713 session_->SetBundleDataSize(bundleName, bundleInfo.spaceOccupied);
714 }
715 session_->SetBackupExtName(bundleName, bundleInfo.extensionName);
716 session_->SetIsReadyLaunch(bundleName);
717 }
718 HILOGI("end SetCurrentBackupSessProperties");
719 }
720 } // namespace OHOS::FileManagement::Backup
721