From 3d856dea01e757c30f500d5625a5a92b1822375b Mon Sep 17 00:00:00 2001 From: "yaoruozi1@huawei.com" Date: Thu, 17 Oct 2024 15:43:40 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8D=E5=BA=94=E7=94=A8=E5=88=86?= =?UTF-8?q?=E8=BA=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yaoruozi1@huawei.com --- .../native/backup_ext/include/ext_extension.h | 8 +- .../backup_ext/src/sub_ext_extension.cpp | 34 +- services/backup_sa/BUILD.gn | 1 + .../include/module_external/bms_adapter.h | 3 + .../backup_sa/include/module_ipc/service.h | 18 +- .../src/module_external/bms_adapter.cpp | 63 +++- services/backup_sa/src/module_ipc/service.cpp | 338 ++++-------------- .../src/module_ipc/service_incremental.cpp | 76 ++-- .../backup_sa/src/module_ipc/sub_service.cpp | 280 +++++++++++++++ .../src/module_ipc/svc_backup_connection.cpp | 14 +- tests/unittests/backup_sa/module_ipc/BUILD.gn | 3 + utils/include/b_resources/b_constants.h | 1 + 12 files changed, 509 insertions(+), 330 deletions(-) create mode 100644 services/backup_sa/src/module_ipc/sub_service.cpp diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index 20a5c5652..ef6a42a42 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -265,7 +265,7 @@ private: void DealIncreUnPacketResult(const off_t tarFileSize, const std::string &tarFileName, const std::tuple &result); - void StartOnProcessTaskThread(wptr obj, BackupRestoreScenario scenario); + ErrCode StartOnProcessTaskThread(wptr obj, BackupRestoreScenario scenario); void FinishOnProcessTask(); void ExecCallOnProcessTask(wptr obj, BackupRestoreScenario scenario); void AsyncCallJsOnProcessTask(wptr obj, BackupRestoreScenario scenario); @@ -297,7 +297,7 @@ private: std::thread callJsOnProcessThread_; Utils::Timer onProcessTimeoutTimer_ {"onProcessTimeoutTimer_"}; uint32_t onProcessTimeoutTimerId_ { 0 }; - std::atomic onProcessTimeoutCnt_; + std::atomic onProcessTimeoutCnt_ { 0 }; std::atomic stopCallJsOnProcess_ {false}; std::condition_variable execOnProcessCon_; std::mutex onProcessLock_; @@ -306,6 +306,10 @@ private: std::mutex onStartTimeLock_; AppRadar::DoRestoreInfo radarRestoreInfo_ { 0 }; OHOS::ThreadPool onProcessTaskPool_; + std::atomic isFirstCallOnProcess_ { false }; + std::atomic isExecAppDone_ { false }; + + BackupRestoreScenario curScenario_ { BackupRestoreScenario::FULL_BACKUP }; }; } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_ext/src/sub_ext_extension.cpp b/frameworks/native/backup_ext/src/sub_ext_extension.cpp index 4101f56ec..933a174ec 100644 --- a/frameworks/native/backup_ext/src/sub_ext_extension.cpp +++ b/frameworks/native/backup_ext/src/sub_ext_extension.cpp @@ -591,6 +591,7 @@ void BackupExtExtension::ReportAppProcessInfo(const std::string processInfo, Bac HILOGE("Report app process error, proxy is empty"); return; } + HILOGI("Will notify backup sa process result"); auto ret = proxy->ReportAppProcessInfo(processInfo, scenario); if (ret != ERR_OK) { HILOGE("Report app process error, ipc failed, ret:%{public}d", ret); @@ -598,12 +599,17 @@ void BackupExtExtension::ReportAppProcessInfo(const std::string processInfo, Bac } } -void BackupExtExtension::StartOnProcessTaskThread(wptr obj, BackupRestoreScenario scenario) +ErrCode BackupExtExtension::StartOnProcessTaskThread(wptr obj, BackupRestoreScenario scenario) { HILOGI("Begin Create onProcess Task Thread"); onProcessTimeoutTimer_.Setup(); + isFirstCallOnProcess_.store(true); StartOnProcessTimeOutTimer(obj, scenario); SyncCallJsOnProcessTask(obj, scenario); + if (isExecAppDone_.load()) { + HILOGE("Call onProcess timeout, Current extension finished"); + return BError(BError::Codes::EXT_ABILITY_TIMEOUT); + } callJsOnProcessThread_ = std::thread([obj, scenario]() { auto extPtr = obj.promote(); if (extPtr == nullptr) { @@ -613,11 +619,13 @@ void BackupExtExtension::StartOnProcessTaskThread(wptr obj, extPtr->ExecCallOnProcessTask(obj, scenario); }); HILOGI("End Create onProcess Task End"); + return BError(BError::Codes::OK); } void BackupExtExtension::ExecCallOnProcessTask(wptr obj, BackupRestoreScenario scenario) { HILOGI("Begin"); + isFirstCallOnProcess_.store(false); while (!stopCallJsOnProcess_.load()) { std::unique_lock lock(onProcessLock_); execOnProcessCon_.wait_for(lock, std::chrono::seconds(BConstants::CALL_APP_ON_PROCESS_TIME_INTERVAL), @@ -627,8 +635,8 @@ void BackupExtExtension::ExecCallOnProcessTask(wptr obj, Bac return; } HILOGI("Continue call js method onProcess"); - AsyncCallJsOnProcessTask(obj, scenario); StartOnProcessTimeOutTimer(obj, scenario); + AsyncCallJsOnProcessTask(obj, scenario); } HILOGI("End"); } @@ -665,7 +673,13 @@ void BackupExtExtension::SyncCallJsOnProcessTask(wptr obj, B HILOGE("Async call js onPreocess callback failed, exPtr is empty"); return; } + if (extPtr->onProcessTimeout_.load()) { + HILOGE("The result of invoking onProcess is timeout."); + extPtr->onProcessTimeout_.store(false); + return; + } extPtr->CloseOnProcessTimeOutTimer(); + extPtr->isFirstCallOnProcess_.store(false); extPtr->onProcessTimeout_.store(false); if (extPtr->onProcessTimeoutCnt_.load() > 0) { extPtr->onProcessTimeoutCnt_ = 0; @@ -674,6 +688,7 @@ void BackupExtExtension::SyncCallJsOnProcessTask(wptr obj, B if (processInfo.size() == 0) { HILOGE("Current extension has no js method named onProcess."); std::unique_lock lock(extPtr->onProcessLock_); + extPtr->isFirstCallOnProcess_.store(false); extPtr->stopCallJsOnProcess_.store(true); extPtr->execOnProcessCon_.notify_one(); lock.unlock(); @@ -681,7 +696,6 @@ void BackupExtExtension::SyncCallJsOnProcessTask(wptr obj, B } std::string processInfoJsonStr; BJsonUtil::BuildOnProcessRetInfo(processInfoJsonStr, processInfo); - HILOGI("Will notify backup sa process result"); extPtr->ReportAppProcessInfo(processInfoJsonStr, scenario); }; auto extenionPtr = obj.promote(); @@ -702,6 +716,8 @@ void BackupExtExtension::FinishOnProcessTask() HILOGI("Begin"); std::unique_lock lock(onProcessLock_); stopCallJsOnProcess_.store(true); + isFirstCallOnProcess_.store(false); + isExecAppDone_.store(false); onProcessTimeoutCnt_ = 0; execOnProcessCon_.notify_one(); lock.unlock(); @@ -724,10 +740,14 @@ void BackupExtExtension::StartOnProcessTimeOutTimer(wptr obj HILOGE("Start Create timeout callback failed, extPtr is empty"); return; } - if (extPtr->onProcessTimeoutCnt_.load() >= BConstants::APP_ON_PROCESS_TIMEOUT_MAX_COUNT) { - HILOGE("Current extension onProcess timeout more than three times"); + if (extPtr->onProcessTimeoutCnt_.load() >= BConstants::APP_ON_PROCESS_TIMEOUT_MAX_COUNT || + extPtr->isFirstCallOnProcess_.load()) { + HILOGE("The extension invokes the onProcess for more than three times or the first invoking of the" + "onProcess times out, timeoutCnt:%{public}d", extPtr->onProcessTimeoutCnt_.load()); std::unique_lock lock(extPtr->onProcessLock_); extPtr->stopCallJsOnProcess_.store(true); + extPtr->isFirstCallOnProcess_.store(false); + extPtr->isExecAppDone_.store(false); extPtr->onProcessTimeoutCnt_ = 0; extPtr->execOnProcessCon_.notify_one(); lock.unlock(); @@ -743,7 +763,9 @@ void BackupExtExtension::StartOnProcessTimeOutTimer(wptr obj extPtr->onProcessTimeout_.store(true); HILOGE("Extension onProcess timeout, Increase cnt:%{public}d", extPtr->onProcessTimeoutCnt_.load()); }; - uint32_t timerId = onProcessTimeoutTimer_.Register(timeoutCallback, BConstants::APP_ON_PROCESS_MAX_TIMEOUT, true); + int timeout = isFirstCallOnProcess_.load() ? BConstants::FIRST_CALL_APP_ON_PROCESS_MAX_TIMEOUT : + BConstants::APP_ON_PROCESS_MAX_TIMEOUT; + uint32_t timerId = onProcessTimeoutTimer_.Register(timeoutCallback, timeout, true); onProcessTimeoutTimerId_ = timerId; HILOGI("End"); } diff --git a/services/backup_sa/BUILD.gn b/services/backup_sa/BUILD.gn index 027216afe..21b78cac5 100644 --- a/services/backup_sa/BUILD.gn +++ b/services/backup_sa/BUILD.gn @@ -36,6 +36,7 @@ ohos_shared_library("backup_sa") { "src/module_ipc/service_incremental_reverse_proxy.cpp", "src/module_ipc/service_reverse_proxy.cpp", "src/module_ipc/service_stub.cpp", + "src/module_ipc/sub_service.cpp", "src/module_ipc/svc_backup_connection.cpp", "src/module_ipc/svc_extension_incremental_proxy.cpp", "src/module_ipc/svc_extension_proxy.cpp", diff --git a/services/backup_sa/include/module_external/bms_adapter.h b/services/backup_sa/include/module_external/bms_adapter.h index 4e94ebfea..5f2dc4497 100644 --- a/services/backup_sa/include/module_external/bms_adapter.h +++ b/services/backup_sa/include/module_external/bms_adapter.h @@ -67,6 +67,9 @@ public: static void GetBundleInfoForSA(std::string bundleName, std::vector &bundleInfos); static bool IsUser0BundleName(std::string bundleName, int32_t userId); + + static std::vector GetBundleInfosForAppend( + const std::vector &incrementalDataList, int32_t userId); private: static bool GetCurBundleExtenionInfo(AppExecFwk::BundleInfo &installedBundle, const std::string &bundleName, std::vector &extensionInfos, sptr bms, diff --git a/services/backup_sa/include/module_ipc/service.h b/services/backup_sa/include/module_ipc/service.h index 040974d2b..1329df10d 100644 --- a/services/backup_sa/include/module_ipc/service.h +++ b/services/backup_sa/include/module_ipc/service.h @@ -272,6 +272,7 @@ public: session_ = sptr(new SvcSessionManager(wptr(this))); disposal_ = make_shared(); clearRecorder_ = make_shared(); + sched_ = sptr(new SchedScheduler(wptr(this), wptr(session_))); }; ~Service() override { @@ -375,8 +376,9 @@ private: void SetCurrentSessProperties(std::vector &restoreBundleInfos, std::vector &restoreBundleNames, RestoreTypeEnum restoreType); - void SetCurrentSessProperties(BJsonEntityCaps::BundleInfo &info, std::map &isClearDataFlags); - + void SetCurrentSessProperties(BJsonEntityCaps::BundleInfo &info, std::map &isClearDataFlags, + const std::string &bundleNameIndexInfo); + /** * @brief add useridinfo to current backup session * @@ -461,6 +463,18 @@ private: const std::string &bundleName, const ErrCode ret); void ReleaseOnException(); + + vector MakeDetailList(const vector &bundleNames); + + vector GetBundleNameByDetails(const std::vector &bundlesToBackup); + + void HandleCurGroupBackupInfos(vector &bundleInfos, + std::map> &bundleNameDetailMap, + std::map &isClearDataFlags); + + void HandleCurGroupIncBackupInfos(vector &bundleInfos, + std::map> &bundleNameDetailMap, + std::map &isClearDataFlags); private: static sptr instance_; static std::mutex instanceLock_; diff --git a/services/backup_sa/src/module_external/bms_adapter.cpp b/services/backup_sa/src/module_external/bms_adapter.cpp index 59b73f550..e1f415e89 100644 --- a/services/backup_sa/src/module_external/bms_adapter.cpp +++ b/services/backup_sa/src/module_external/bms_adapter.cpp @@ -133,7 +133,7 @@ vector BundleMgrAdapter::GetBundleInfos(const vecto GetAllowAndExtName(extensionInfos); int64_t dataSize = 0; if (allToBackup) { - dataSize = GetBundleStats(installedBundle.name, userId); + dataSize = GetBundleStats(bundleName, userId); } bundleInfos.emplace_back(BJsonEntityCaps::BundleInfo {installedBundle.name, installedBundle.appIndex, installedBundle.versionCode, @@ -191,8 +191,18 @@ static bool CreateIPCInteractionFiles(int32_t userId, const string &bundleName, const vector &includes, const vector &excludes) { // backup_sa bundle path - string backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX + - bundleName + BConstants::FILE_SEPARATOR_CHAR; + BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(bundleName); + string backupSaBundleDir; + if (bundleDetail.bundleIndex > 0) { + std::string bundleNameIndex = "+clone-" + std::to_string(bundleDetail.bundleIndex) + "+" + + bundleDetail.bundleName; + backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX + + bundleNameIndex + BConstants::FILE_SEPARATOR_CHAR; + } else { + backupSaBundleDir = BConstants::BACKUP_PATH_PREFIX + to_string(userId) + BConstants::BACKUP_PATH_SURFFIX + + bundleDetail.bundleName + BConstants::FILE_SEPARATOR_CHAR; + } + HILOGI("bundleInteraction dir is:%{public}s", backupSaBundleDir.c_str()); if (access(backupSaBundleDir.data(), F_OK) != 0) { int32_t err = mkdir(backupSaBundleDir.data(), S_IRWXU | S_IRWXG); if (err != 0 && errno != EEXIST) { @@ -279,7 +289,6 @@ vector BundleMgrAdapter::GetBundleInfosForIncrement auto bms = GetBundleManager(); for (auto const &bundleNameTime : incrementalDataList) { auto bundleName = bundleNameTime.bundleName; - HILOGD("Begin get bundleName:%{private}s", bundleName.c_str()); AppExecFwk::BundleInfo installedBundle; std::vector extensionInfos; bool getBundleSuccess = GetCurBundleExtenionInfo(installedBundle, bundleName, extensionInfos, bms, userId); @@ -289,7 +298,7 @@ vector BundleMgrAdapter::GetBundleInfosForIncrement } struct BJsonEntityCaps::BundleBackupConfigPara backupPara; if (!GetBackupExtConfig(extensionInfos, backupPara)) { - HILOGE("No backup extension ability found"); + HILOGE("No backup extension ability found, bundleName:%{public}s", bundleName.c_str()); continue; } if (!CreateIPCInteractionFiles(userId, bundleName, bundleNameTime.lastIncrementalTime, backupPara.includes, @@ -303,7 +312,13 @@ vector BundleMgrAdapter::GetBundleInfosForIncrement backupPara.extensionName, backupPara.restoreDeps, backupPara.supportScene, backupPara.extraInfo}); - bundleNames.emplace_back(bundleName); + if (installedBundle.appIndex > 0) { + std::string bundleNameIndex = "+clone-" + std::to_string(installedBundle.appIndex) + "+" + + installedBundle.name; + bundleNames.emplace_back(bundleNameIndex); + } else { + bundleNames.emplace_back(bundleName); + } incrementalBackTimes.emplace_back(bundleNameTime.lastIncrementalTime); } vector newBundleInfos {}; @@ -327,7 +342,7 @@ vector BundleMgrAdapter::GetBundleInfosForIncrement vector bundleNames; vector bundleInfos; - HILOGI("Begin get bundle infos"); + HILOGI("End get installedBundles count is:%{public}zu", installedBundles.size()); for (auto const &installedBundle : installedBundles) { if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH || installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) { @@ -370,13 +385,20 @@ vector BundleMgrAdapter::GetFullBundleInfos(int32_t } vector bundleNames; vector bundleInfos; + HILOGI("End get installedBundles count is:%{public}zu", installedBundles.size()); for (auto const &installedBundle : installedBundles) { - HILOGI("Begin get bundle infos, bundleName = %{public}s", installedBundle.name.data()); if (installedBundle.applicationInfo.codePath == HMOS_HAP_CODE_PATH || installedBundle.applicationInfo.codePath == LINUX_HAP_CODE_PATH) { HILOGI("Unsupported applications, name : %{public}s", installedBundle.name.data()); continue; } + if (installedBundle.appIndex > 0) { + HILOGI("Current bundle %{public}s is a twin application", installedBundle.name.c_str()); + std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(installedBundle.name, + installedBundle.appIndex); + bundleNames.emplace_back(bundleNameIndexInfo); + continue; + } auto [allToBackup, fullBackupOnly, extName, restoreDeps, supportScene, extraInfo] = GetAllowAndExtName(installedBundle.extensionInfos); if (!allToBackup) { @@ -490,8 +512,6 @@ bool BundleMgrAdapter::GetCurBundleExtenionInfo(AppExecFwk::BundleInfo &installe HILOGE("Unsupported applications, name : %{public}s", installedBundle.name.data()); return false; } - HILOGI("bundleName:%{public}s, hapMoudleInfos size:%{public}zu", bundleName.c_str(), - installedBundle.hapModuleInfos.size()); std::vector hapModuleInfos = installedBundle.hapModuleInfos; for (auto &hapModuleInfo : hapModuleInfos) { extensionInfos.insert(extensionInfos.end(), hapModuleInfo.extensionInfos.begin(), @@ -505,8 +525,15 @@ bool BundleMgrAdapter::IsUser0BundleName(std::string bundleName, int32_t userId) { auto bms = GetBundleManager(); AppExecFwk::BundleInfo installedBundle; - if (!bms->GetBundleInfo(bundleName, AppExecFwk::GET_BUNDLE_WITH_EXTENSION_INFO, installedBundle, userId)) { - HILOGI("GetBundleInfo failed, bundleName:%{public}s", bundleName.c_str()); + BJsonUtil::BundleDetailInfo bundleDetailInfo = BJsonUtil::ParseBundleNameIndexStr(bundleName); + int32_t flags = static_cast(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) | + static_cast(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY) | + static_cast(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_METADATA) | + static_cast(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION); + ErrCode ret = bms->GetCloneBundleInfo(bundleDetailInfo.bundleName, flags, bundleDetailInfo.bundleIndex, + installedBundle, userId); + if (ret != ERR_OK) { + HILOGE("bundleName:%{public}s, ret:%{public}d, GetBundle Failed from BMS", bundleName.c_str(), ret); return false; } if (installedBundle.applicationInfo.singleton == true) { @@ -516,4 +543,16 @@ bool BundleMgrAdapter::IsUser0BundleName(std::string bundleName, int32_t userId) HILOGI("bundleName:%{public}s is not zero user bundle", bundleName.c_str()); return false; } + +vector BundleMgrAdapter::GetBundleInfosForAppend(const std::vector &list, + int32_t userId) +{ + auto bundleInfos = BundleMgrAdapter::GetBundleInfosForIncremental(list, userId); + for (auto const &info : list) { + if (SAUtils::IsSABundleName(info.bundleName)) { + GetBundleInfoForSA(info.bundleName, bundleInfos); + } + } + return bundleInfos; +} } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_ipc/service.cpp b/services/backup_sa/src/module_ipc/service.cpp index 3fb3b2045..beffa1821 100644 --- a/services/backup_sa/src/module_ipc/service.cpp +++ b/services/backup_sa/src/module_ipc/service.cpp @@ -410,8 +410,9 @@ static vector GetRestoreBundleNames(UniqueFd fd, restoreBundleInfos.emplace_back(info); continue; } - auto it = find_if(bundleInfos.begin(), bundleInfos.end(), - [&restoreInfo](const auto &obj) { return obj.name == restoreInfo.name; }); + auto it = find_if(bundleInfos.begin(), bundleInfos.end(), [&restoreInfo](const auto &obj) { + return obj.name == restoreInfo.name && obj.appIndex == restoreInfo.appIndex; + }); if (it == bundleInfos.end()) { HILOGE("Bundle not need restore, bundleName is %{public}s.", restoreInfo.name.c_str()); continue; @@ -503,26 +504,29 @@ void Service::SetCurrentSessProperties(std::vector { HILOGI("Start"); for (auto restoreInfo : restoreBundleInfos) { - auto it = find_if(restoreBundleNames.begin(), restoreBundleNames.end(), - [&restoreInfo](const auto &bundleName) { return bundleName == restoreInfo.name; }); + auto it = find_if(restoreBundleNames.begin(), restoreBundleNames.end(), [&restoreInfo](const auto &bundleName) { + std::string bundleNameIndex = BJsonUtil::BuildBundleNameIndexInfo(restoreInfo.name, restoreInfo.appIndex); + return bundleName == bundleNameIndex; + }); if (it == restoreBundleNames.end()) { throw BError(BError::Codes::SA_BUNDLE_INFO_EMPTY, "Can't find bundle name"); } HILOGI("bundleName: %{public}s, extensionName: %{public}s", restoreInfo.name.c_str(), restoreInfo.extensionName.c_str()); + std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(restoreInfo.name, restoreInfo.appIndex); if ((restoreInfo.allToBackup == false && !SpecialVersion(restoreInfo.versionName)) || (restoreInfo.extensionName.empty() && !SAUtils::IsSABundleName(restoreInfo.name))) { - OnBundleStarted(BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), session_, restoreInfo.name); - session_->RemoveExtInfo(restoreInfo.name); + OnBundleStarted(BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), session_, bundleNameIndexInfo); + session_->RemoveExtInfo(bundleNameIndexInfo); continue; } - session_->SetBundleRestoreType(restoreInfo.name, restoreType); - session_->SetBundleVersionCode(restoreInfo.name, restoreInfo.versionCode); - session_->SetBundleVersionName(restoreInfo.name, restoreInfo.versionName); - session_->SetBundleDataSize(restoreInfo.name, restoreInfo.spaceOccupied); - session_->SetBackupExtName(restoreInfo.name, restoreInfo.extensionName); - if (BundleMgrAdapter::IsUser0BundleName(restoreInfo.name, session_->GetSessionUserId())) { - SendUserIdToApp(restoreInfo.name, session_->GetSessionUserId()); + session_->SetBundleRestoreType(bundleNameIndexInfo, restoreType); + session_->SetBundleVersionCode(bundleNameIndexInfo, restoreInfo.versionCode); + session_->SetBundleVersionName(bundleNameIndexInfo, restoreInfo.versionName); + session_->SetBundleDataSize(bundleNameIndexInfo, restoreInfo.spaceOccupied); + session_->SetBackupExtName(bundleNameIndexInfo, restoreInfo.extensionName); + if (BundleMgrAdapter::IsUser0BundleName(bundleNameIndexInfo, session_->GetSessionUserId())) { + SendUserIdToApp(bundleNameIndexInfo, session_->GetSessionUserId()); } } HILOGI("End"); @@ -593,7 +597,7 @@ void Service::SetCurrentSessProperties(std::vector std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(restoreInfo.name, restoreInfo.appIndex); if ((restoreInfo.allToBackup == false && !SpecialVersion(restoreInfo.versionName)) || (restoreInfo.extensionName.empty() && !SAUtils::IsSABundleName(restoreInfo.name))) { - OnBundleStarted(BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), session_, restoreInfo.name); + OnBundleStarted(BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), session_, bundleNameIndexInfo); session_->RemoveExtInfo(bundleNameIndexInfo); continue; } @@ -626,16 +630,17 @@ void Service::SetCurrentSessProperties(std::vector } void Service::SetCurrentSessProperties(BJsonEntityCaps::BundleInfo &info, - std::map &isClearDataFlags) + std::map &isClearDataFlags, const std::string &bundleNameIndexInfo) { if (session_ == nullptr) { + HILOGE("Set currrent session properties error, session is empty"); return; } - session_->SetBundleDataSize(info.name, info.spaceOccupied); - session_->SetBackupExtName(info.name, info.extensionName); - auto iter = isClearDataFlags.find(info.name); + session_->SetBundleDataSize(bundleNameIndexInfo, info.spaceOccupied); + session_->SetBackupExtName(bundleNameIndexInfo, info.extensionName); + auto iter = isClearDataFlags.find(bundleNameIndexInfo); if (iter != isClearDataFlags.end()) { - session_->SetClearDataFlag(info.name, iter->second); + session_->SetClearDataFlag(bundleNameIndexInfo, iter->second); } } @@ -649,41 +654,45 @@ ErrCode Service::AppendBundlesBackupSession(const vector &bundleName } session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时 VerifyCaller(IServiceReverse::Scenario::BACKUP); - auto backupInfos = BundleMgrAdapter::GetBundleInfos(bundleNames, session_->GetSessionUserId()); + auto bundleDetails = MakeDetailList(bundleNames); + auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundleDetails, session_->GetSessionUserId()); session_->AppendBundles(bundleNames); - SetCurrentBackupSessProperties(bundleNames, session_->GetSessionUserId()); for (auto info : backupInfos) { - session_->SetBundleDataSize(info.name, info.spaceOccupied); - session_->SetBackupExtName(info.name, info.extensionName); + HILOGI("Current backupInfo bundleName:%{public}s, extName:%{public}s, appIndex:%{public}d", + info.name.c_str(), info.extensionName.c_str(), info.appIndex); + std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex); + session_->SetBundleDataSize(bundleNameIndexInfo, info.spaceOccupied); + session_->SetBackupExtName(bundleNameIndexInfo, info.extensionName); if (info.allToBackup == false) { session_->GetServiceReverseProxy()->BackupOnBundleStarted( - BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), info.name); - session_->RemoveExtInfo(info.name); + BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), bundleNameIndexInfo); + session_->RemoveExtInfo(bundleNameIndexInfo); } } + SetCurrentBackupSessProperties(bundleNames, session_->GetSessionUserId()); OnStartSched(); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); return BError(BError::Codes::OK); } catch (const BError &e) { + HILOGE("Failed, errCode = %{public}d", e.GetCode()); HandleExceptionOnAppendBundles(session_, bundleNames, {}); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); - HILOGE("Failed, errCode = %{public}d", e.GetCode()); return e.GetCode(); } catch (const exception &e) { + HILOGE("Catched an unexpected low-level exception %{public}s", e.what()); HandleExceptionOnAppendBundles(session_, bundleNames, {}); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); - HILOGE("Catched an unexpected low-level exception %{public}s", e.what()); return EPERM; - } catch (...) { + } catch(...) { + HILOGE("Unexpected exception"); HandleExceptionOnAppendBundles(session_, bundleNames, {}); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); - HILOGE("Unexpected exception"); return EPERM; } } ErrCode Service::AppendBundlesDetailsBackupSession(const vector &bundleNames, - const vector &bundleInfos) + const vector &bundleInfos) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); try { @@ -698,21 +707,10 @@ ErrCode Service::AppendBundlesDetailsBackupSession(const vector &bun std::map> bundleNameDetailMap = BJsonUtil::BuildBundleInfos(bundleNames, bundleInfos, bundleNamesOnly, session_->GetSessionUserId(), isClearDataFlags); - auto backupInfos = BundleMgrAdapter::GetBundleInfos(bundleNames, session_->GetSessionUserId()); + auto bundleDetails = MakeDetailList(bundleNames); + auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundleDetails, session_->GetSessionUserId()); session_->AppendBundles(bundleNames); - for (auto info : backupInfos) { - SetCurrentSessProperties(info, isClearDataFlags); - if (info.allToBackup == false) { - session_->GetServiceReverseProxy()->BackupOnBundleStarted( - BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), info.name); - session_->RemoveExtInfo(info.name); - } - BJsonUtil::BundleDetailInfo uniCastInfo; - if (BJsonUtil::FindBundleInfoByName(bundleNameDetailMap, info.name, UNICAST_TYPE, uniCastInfo)) { - HILOGI("current bundle, unicast info:%{public}s", GetAnonyString(uniCastInfo.detail).c_str()); - session_->SetBackupExtInfo(info.name, uniCastInfo.detail); - } - } + HandleCurGroupBackupInfos(backupInfos, bundleNameDetailMap, isClearDataFlags); OnStartSched(); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); return BError(BError::Codes::OK); @@ -721,11 +719,6 @@ ErrCode Service::AppendBundlesDetailsBackupSession(const vector &bun HandleExceptionOnAppendBundles(session_, bundleNames, {}); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); return e.GetCode(); - } catch (const exception &e) { - HILOGE("Catched an unexpected low-level exception %{public}s", e.what()); - HandleExceptionOnAppendBundles(session_, bundleNames, {}); - session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); - return EPERM; } catch(...) { HILOGE("Unexpected exception"); HandleExceptionOnAppendBundles(session_, bundleNames, {}); @@ -734,147 +727,26 @@ ErrCode Service::AppendBundlesDetailsBackupSession(const vector &bun } } -ErrCode Service::Finish() -{ - HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); - try { - VerifyCaller(session_->GetScenario()); - session_->Finish(); - OnAllBundlesFinished(BError(BError::Codes::OK)); - return BError(BError::Codes::OK); - } catch (const BError &e) { - ReleaseOnException(); - HILOGE("Failde to Finish"); - return e.GetCode(); - } -} - -ErrCode Service::PublishFile(const BFileInfo &fileInfo) -{ - HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); - try { - VerifyCaller(IServiceReverse::Scenario::RESTORE); - if (!fileInfo.fileName.empty()) { - HILOGE("Forbit to use publishFile with fileName for App"); - return EPERM; - } - auto backUpConnection = session_->GetExtConnection(fileInfo.owner); - if (backUpConnection == nullptr) { - HILOGE("PublishFile error, backUpConnection is empty"); - return BError(BError::Codes::SA_INVAL_ARG); - } - auto proxy = backUpConnection->GetBackupExtProxy(); - if (!proxy) { - HILOGE("PublishFile error, Extension backup Proxy is empty"); - return BError(BError::Codes::SA_INVAL_ARG); - } - ErrCode res = proxy->PublishFile(fileInfo.fileName); - if (res) { - HILOGE("Failed to publish file for backup extension"); - } - - return res; - } catch (const BError &e) { - return e.GetCode(); - } catch (const exception &e) { - HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); - return EPERM; - } catch (...) { - HILOGI("Unexpected exception"); - return EPERM; - } -} - -ErrCode Service::AppFileReady(const string &fileName, UniqueFd fd, int32_t errCode) -{ - HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); - try { - string callerName = VerifyCallerAndGetCallerName(); - HILOGD("Caller name is:%{public}s", callerName.c_str()); - if (fileName.find('/') != string::npos) { - throw BError(BError::Codes::SA_INVAL_ARG, "Filename is not valid"); - } - if (fileName == BConstants::EXT_BACKUP_MANAGE) { - fd = session_->OnBundleExtManageInfo(callerName, move(fd)); - } - - session_->GetServiceReverseProxy()->BackupOnFileReady(callerName, fileName, move(fd), errCode); - - if (session_->OnBundleFileReady(callerName, fileName)) { - auto backUpConnection = session_->GetExtConnection(callerName); - if (backUpConnection == nullptr) { - HILOGE("AppFileReady error, backUpConnection is empty"); - return BError(BError::Codes::SA_INVAL_ARG); - } - auto proxy = backUpConnection->GetBackupExtProxy(); - if (!proxy) { - HILOGE("AppFileReady error, Extension backup Proxy is empty"); - return BError(BError::Codes::SA_INVAL_ARG); - } - // 通知extension清空缓存 - proxy->HandleClear(); - // 清除Timer - session_->StopFwkTimer(callerName); - session_->StopExtTimer(callerName); - // 通知TOOL 备份完成 - session_->GetServiceReverseProxy()->BackupOnBundleFinished(BError(BError::Codes::OK), callerName); - // 断开extension - backUpConnection->DisconnectBackupExtAbility(); - ClearSessionAndSchedInfo(callerName); - } - OnAllBundlesFinished(BError(BError::Codes::OK)); - return BError(BError::Codes::OK); - } catch (const BError &e) { - return e.GetCode(); // 任意异常产生,终止监听该任务 - } catch (const exception &e) { - HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); - return EPERM; - } catch (...) { - HILOGI("Unexpected exception"); - return EPERM; - } -} - -ErrCode Service::AppDone(ErrCode errCode) +void Service::HandleCurGroupBackupInfos(std::vector &backupInfos, + std::map> &bundleNameDetailMap, + std::map &isClearDataFlags) { - HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); - try { - if (session_ == nullptr) { - HILOGE("App finish error, session info is empty"); - return BError(BError::Codes::SA_INVAL_ARG); + for (auto &info : backupInfos) { + HILOGI("Current backupInfo bundleName:%{public}s, extName:%{public}s, appIndex:%{public}d", + info.name.c_str(), info.extensionName.c_str(), info.appIndex); + std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex); + SetCurrentSessProperties(info, isClearDataFlags, bundleNameIndexInfo); + if (info.allToBackup == false) { + session_->GetServiceReverseProxy()->BackupOnBundleStarted( + BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), bundleNameIndexInfo); + session_->RemoveExtInfo(bundleNameIndexInfo); } - string callerName = VerifyCallerAndGetCallerName(); - HILOGI("Begin, callerName is: %{public}s, errCode: %{public}d", callerName.c_str(), errCode); - if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) { - auto backUpConnection = session_->GetExtConnection(callerName); - if (backUpConnection == nullptr) { - HILOGE("App finish error, backUpConnection is empty"); - return BError(BError::Codes::SA_INVAL_ARG); - } - auto proxy = backUpConnection->GetBackupExtProxy(); - if (!proxy) { - throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); - } - proxy->HandleClear(); - session_->StopFwkTimer(callerName); - session_->StopExtTimer(callerName); - backUpConnection->DisconnectBackupExtAbility(); - ClearSessionAndSchedInfo(callerName); - NotifyCallerCurAppDone(errCode, callerName); + BJsonUtil::BundleDetailInfo uniCastInfo; + if (BJsonUtil::FindBundleInfoByName(bundleNameDetailMap, bundleNameIndexInfo, UNICAST_TYPE, uniCastInfo)) { + HILOGI("current bundle:%{public}s, unicast info:%{public}s", bundleNameIndexInfo.c_str(), + GetAnonyString(uniCastInfo.detail).c_str()); + session_->SetBackupExtInfo(bundleNameIndexInfo, uniCastInfo.detail); } - OnAllBundlesFinished(BError(BError::Codes::OK)); - return BError(BError::Codes::OK); - } catch (const BError &e) { - ReleaseOnException(); - HILOGE("AppDone error, err code is: %{public}d", e.GetCode()); - return e.GetCode(); // 任意异常产生,终止监听该任务 - } catch (const exception &e) { - ReleaseOnException(); - HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); - return EPERM; - } catch (...) { - HILOGI("Unexpected exception"); - return EPERM; } } @@ -957,72 +829,6 @@ void Service::NotifyCloneBundleFinish(std::string bundleName, const BackupRestor } } -void Service::SetWant(AAFwk::Want &want, const BundleName &bundleName, const BConstants::ExtensionAction &action) -{ - BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(bundleName); - string backupExtName = session_->GetBackupExtName(bundleName); /* new device app ext name */ - HILOGI("BackupExtName: %{public}s, bundleName: %{public}s", backupExtName.data(), bundleName.data()); - string versionName = session_->GetBundleVersionName(bundleName); /* old device app version name */ - int64_t versionCode = session_->GetBundleVersionCode(bundleName); /* old device app version code */ - RestoreTypeEnum restoreType = session_->GetBundleRestoreType(bundleName); /* app restore type */ - string bundleExtInfo = session_->GetBackupExtInfo(bundleName); - HILOGI("BundleExtInfo is:%{public}s", GetAnonyString(bundleExtInfo).c_str()); - - want.SetElementName(bundleDetail.bundleName, backupExtName); - want.SetParam(BConstants::EXTENSION_ACTION_PARA, static_cast(action)); - want.SetParam(BConstants::EXTENSION_VERSION_CODE_PARA, static_cast(versionCode)); - want.SetParam(BConstants::EXTENSION_RESTORE_TYPE_PARA, static_cast(restoreType)); - want.SetParam(BConstants::EXTENSION_VERSION_NAME_PARA, versionName); - want.SetParam(BConstants::EXTENSION_RESTORE_EXT_INFO_PARA, bundleExtInfo); - want.SetParam(BConstants::EXTENSION_BACKUP_EXT_INFO_PARA, bundleExtInfo); - want.SetParam(BConstants::EXTENSION_APP_CLONE_INDEX_PARA, bundleDetail.bundleIndex); -} - -ErrCode Service::LaunchBackupExtension(const BundleName &bundleName) -{ - HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); - try { - HILOGI("begin %{public}s", bundleName.data()); - IServiceReverse::Scenario scenario = session_->GetScenario(); - BConstants::ExtensionAction action; - if (scenario == IServiceReverse::Scenario::BACKUP || scenario == IServiceReverse::Scenario::CLEAN) { - action = BConstants::ExtensionAction::BACKUP; - } else if (scenario == IServiceReverse::Scenario::RESTORE) { - action = BConstants::ExtensionAction::RESTORE; - } else { - throw BError(BError::Codes::SA_INVAL_ARG, "Failed to scenario"); - } - if (SAUtils::IsSABundleName(bundleName)) { - return LaunchBackupSAExtension(bundleName); - } - AAFwk::Want want; - SetWant(want, bundleName, action); - auto backUpConnection = session_->GetExtConnection(bundleName); - if (backUpConnection == nullptr) { - HILOGE("LaunchBackupExtension error, backUpConnection is empty"); - return BError(BError::Codes::SA_INVAL_ARG); - } - if (backUpConnection->IsExtAbilityConnected() && !backUpConnection->WaitDisconnectDone()) { - HILOGE("LaunchBackupExtension error, WaitDisconnectDone failed"); - return BError(BError::Codes::SA_INVAL_ARG); - } - ErrCode ret = backUpConnection->ConnectBackupExtAbility(want, session_->GetSessionUserId()); - if (ret) { - HILOGE("ConnectBackupExtAbility faild, bundleName:%{public}s, ret:%{public}d", bundleName.c_str(), ret); - return BError(BError::Codes::SA_BOOT_EXT_FAIL); - } - return BError(BError::Codes::OK); - } catch (const BError &e) { - return e.GetCode(); - } catch (const exception &e) { - HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); - return EPERM; - } catch (...) { - HILOGI("Unexpected exception"); - return EPERM; - } -} - ErrCode Service::LaunchBackupSAExtension(const BundleName &bundleName) { string extInfo = session_->GetBackupExtInfo(bundleName); @@ -1807,31 +1613,6 @@ ErrCode Service::AppendBundlesClearSession(const std::vector &bundle ErrCode Service::UpdateTimer(BundleName &bundleName, uint32_t timeout, bool &result) { - auto timeoutCallback = [ptr {wptr(this)}, bundleName]() { - HILOGE("Backup <%{public}s> Extension Process Timeout", bundleName.c_str()); - auto thisPtr = ptr.promote(); - if (!thisPtr) { - HILOGW("this pointer is null."); - return; - } - auto sessionPtr = ptr->session_; - if (sessionPtr == nullptr) { - HILOGW("SessionPtr is null."); - return; - } - try { - auto sessionConnection = sessionPtr->GetExtConnection(bundleName); - sessionPtr->StopFwkTimer(bundleName); - sessionPtr->StopExtTimer(bundleName); - sessionConnection->DisconnectBackupExtAbility(); - thisPtr->ClearSessionAndSchedInfo(bundleName); - thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_TIMEOUT)); - } catch (...) { - HILOGE("Unexpected exception, bundleName: %{public}s", bundleName.c_str()); - thisPtr->ClearSessionAndSchedInfo(bundleName); - thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_TIMEOUT)); - } - }; try { HILOGI("Service::UpdateTimer begin."); if (session_ == nullptr || isCleanService_.load()) { @@ -1841,6 +1622,7 @@ ErrCode Service::UpdateTimer(BundleName &bundleName, uint32_t timeout, bool &res } session_->IncreaseSessionCnt(__PRETTY_FUNCTION__); VerifyCaller(); + auto timeoutCallback = TimeOutCallback(wptr(this), bundleName); result = session_->UpdateTimer(bundleName, timeout, timeoutCallback); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); return BError(BError::Codes::OK); diff --git a/services/backup_sa/src/module_ipc/service_incremental.cpp b/services/backup_sa/src/module_ipc/service_incremental.cpp index 3d9c144dc..d69b35f3a 100644 --- a/services/backup_sa/src/module_ipc/service_incremental.cpp +++ b/services/backup_sa/src/module_ipc/service_incremental.cpp @@ -249,6 +249,15 @@ ErrCode Service::InitIncrementalBackupSession(sptr remote) } } +vector Service::GetBundleNameByDetails(const std::vector &bundlesToBackup) +{ + vector bundleNames {}; + for (auto bundle : bundlesToBackup) { + bundleNames.emplace_back(bundle.bundleName); + } + return bundleNames; +} + ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector &bundlesToBackup) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); @@ -259,25 +268,26 @@ ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vectorIncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时 VerifyCaller(IServiceReverse::Scenario::BACKUP); - vector bundleNames {}; - for (auto &bundle : bundlesToBackup) { - bundleNames.emplace_back(bundle.bundleName); - } - auto backupInfos = BundleMgrAdapter::GetBundleInfos(bundleNames, session_->GetSessionUserId()); + vector bundleNames = GetBundleNameByDetails(bundlesToBackup); + auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundlesToBackup, + session_->GetSessionUserId()); session_->AppendBundles(bundleNames); - SetCurrentBackupSessProperties(bundleNames, session_->GetSessionUserId()); for (auto info : backupInfos) { - session_->SetBundleDataSize(info.name, info.spaceOccupied); - session_->SetBackupExtName(info.name, info.extensionName); + HILOGI("Current backupInfo bundleName:%{public}s, index:%{public}d, extName:%{public}s", info.name.c_str(), + info.appIndex, info.extensionName.c_str()); + std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex); + session_->SetBundleDataSize(bundleNameIndexInfo, info.increSpaceOccupied); + session_->SetBackupExtName(bundleNameIndexInfo, info.extensionName); if (info.allToBackup == false) { session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted( - BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), info.name); - session_->RemoveExtInfo(info.name); + BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), bundleNameIndexInfo); + session_->RemoveExtInfo(bundleNameIndexInfo); } } for (auto &bundleInfo : bundlesToBackup) { session_->SetIncrementalData(bundleInfo); } + SetCurrentBackupSessProperties(bundleNames, session_->GetSessionUserId()); OnStartSched(); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); return BError(BError::Codes::OK); @@ -303,30 +313,16 @@ ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vectorIncreaseSessionCnt(__PRETTY_FUNCTION__); // BundleMgrAdapter::GetBundleInfos可能耗时 VerifyCaller(IServiceReverse::Scenario::BACKUP); - vector bundleNames {}; - for (auto &bundle : bundlesToBackup) { - bundleNames.emplace_back(bundle.bundleName); - } + vector bundleNames = GetBundleNameByDetails(bundlesToBackup); std::vector bundleNamesOnly; std::map isClearDataFlags; std::map> bundleNameDetailMap = BJsonUtil::BuildBundleInfos(bundleNames, infos, bundleNamesOnly, session_->GetSessionUserId(), isClearDataFlags); - auto backupInfos = BundleMgrAdapter::GetBundleInfos(bundleNames, session_->GetSessionUserId()); + auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundlesToBackup, + session_->GetSessionUserId()); session_->AppendBundles(bundleNames); - for (auto info : backupInfos) { - SetCurrentSessProperties(info, isClearDataFlags); - if (info.allToBackup == false) { - session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted( - BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), info.name); - session_->RemoveExtInfo(info.name); - } - BJsonUtil::BundleDetailInfo uniCastInfo; - if (BJsonUtil::FindBundleInfoByName(bundleNameDetailMap, info.name, UNICAST_TYPE, uniCastInfo)) { - HILOGI("current bundle, unicast info:%{public}s", GetAnonyString(uniCastInfo.detail).c_str()); - session_->SetBackupExtInfo(info.name, uniCastInfo.detail); - } - } + HandleCurGroupIncBackupInfos(backupInfos, bundleNameDetailMap, isClearDataFlags); for (auto &bundleInfo : bundlesToBackup) { session_->SetIncrementalData(bundleInfo); } @@ -344,6 +340,30 @@ ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vector &backupInfos, + std::map> &bundleNameDetailMap, + std::map &isClearDataFlags) +{ + for (auto &info : backupInfos) { + HILOGI("Current backupInfo bundleName:%{public}s, index:%{public}d, extName:%{public}s", info.name.c_str(), + info.appIndex, info.extensionName.c_str()); + std::string bundleNameIndexInfo = BJsonUtil::BuildBundleNameIndexInfo(info.name, info.appIndex); + SetCurrentSessProperties(info, isClearDataFlags, bundleNameIndexInfo); + session_->SetBundleDataSize(bundleNameIndexInfo, info.increSpaceOccupied); + if (info.allToBackup == false) { + session_->GetServiceReverseProxy()->IncrementalBackupOnBundleStarted( + BError(BError::Codes::SA_FORBID_BACKUP_RESTORE), bundleNameIndexInfo); + session_->RemoveExtInfo(bundleNameIndexInfo); + } + BJsonUtil::BundleDetailInfo uniCastInfo; + if (BJsonUtil::FindBundleInfoByName(bundleNameDetailMap, bundleNameIndexInfo, UNICAST_TYPE, uniCastInfo)) { + HILOGI("current bundle:%{public}s, unicast info:%{public}s", bundleNameIndexInfo.c_str(), + GetAnonyString(uniCastInfo.detail).c_str()); + session_->SetBackupExtInfo(bundleNameIndexInfo, uniCastInfo.detail); + } + } +} + ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); diff --git a/services/backup_sa/src/module_ipc/sub_service.cpp b/services/backup_sa/src/module_ipc/sub_service.cpp new file mode 100644 index 000000000..b235f1443 --- /dev/null +++ b/services/backup_sa/src/module_ipc/sub_service.cpp @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "module_ipc/service.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "ability_manager_client.h" +#include "accesstoken_kit.h" +#include "b_anony/b_anony.h" +#include "b_error/b_error.h" +#include "b_error/b_excep_utils.h" +#include "b_file_info.h" +#include "b_json/b_json_cached_entity.h" +#include "b_jsonutil/b_jsonutil.h" +#include "b_ohos/startup/backup_para.h" +#include "b_process/b_multiuser.h" +#include "b_radar/b_radar.h" +#include "b_resources/b_constants.h" +#include "b_sa/b_sa_utils.h" +#include "bundle_mgr_client.h" +#include "filemgmt_libhilog.h" +#include "hisysevent.h" +#include "hitrace_meter.h" +#include "ipc_skeleton.h" +#include "access_token.h" +#include "tokenid_kit.h" +#include "module_app_gallery/app_gallery_dispose_proxy.h" +#include "module_external/bms_adapter.h" +#include "module_external/sms_adapter.h" +#include "module_ipc/svc_backup_connection.h" +#include "module_ipc/svc_restore_deps_manager.h" +#include "module_notify/notify_work_service.h" +#include "parameter.h" +#include "parameters.h" +#include "system_ability_definition.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +vector Service::MakeDetailList(const vector &bundleNames) +{ + vector bundleDetails {}; + for (auto bundleName : bundleNames) { + bundleDetails.emplace_back(BIncrementalData {bundleName, 0}); + } + return bundleDetails; +} + +ErrCode Service::Finish() +{ + HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); + try { + VerifyCaller(session_->GetScenario()); + session_->Finish(); + OnAllBundlesFinished(BError(BError::Codes::OK)); + return BError(BError::Codes::OK); + } catch (const BError &e) { + ReleaseOnException(); + HILOGE("Failde to Finish"); + return e.GetCode(); + } +} + +ErrCode Service::PublishFile(const BFileInfo &fileInfo) +{ + HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); + try { + VerifyCaller(IServiceReverse::Scenario::RESTORE); + if (!fileInfo.fileName.empty()) { + HILOGE("Forbit to use publishFile with fileName for App"); + return EPERM; + } + auto backUpConnection = session_->GetExtConnection(fileInfo.owner); + if (backUpConnection == nullptr) { + HILOGE("PublishFile error, backUpConnection is empty"); + return BError(BError::Codes::SA_INVAL_ARG); + } + auto proxy = backUpConnection->GetBackupExtProxy(); + if (!proxy) { + HILOGE("PublishFile error, Extension backup Proxy is empty"); + return BError(BError::Codes::SA_INVAL_ARG); + } + ErrCode res = proxy->PublishFile(fileInfo.fileName); + if (res) { + HILOGE("Failed to publish file for backup extension"); + } + return res; + } catch (const BError &e) { + return e.GetCode(); + } catch (const exception &e) { + HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGI("Unexpected exception"); + return EPERM; + } +} + +ErrCode Service::AppFileReady(const string &fileName, UniqueFd fd, int32_t errCode) +{ + HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); + try { + string callerName = VerifyCallerAndGetCallerName(); + if (fileName.find('/') != string::npos) { + throw BError(BError::Codes::SA_INVAL_ARG, "Filename is not valid"); + } + if (fileName == BConstants::EXT_BACKUP_MANAGE) { + fd = session_->OnBundleExtManageInfo(callerName, move(fd)); + } + session_->GetServiceReverseProxy()->BackupOnFileReady(callerName, fileName, move(fd), errCode); + if (session_->OnBundleFileReady(callerName, fileName)) { + auto backUpConnection = session_->GetExtConnection(callerName); + if (backUpConnection == nullptr) { + HILOGE("AppFileReady error, backUpConnection is empty"); + return BError(BError::Codes::SA_INVAL_ARG); + } + auto proxy = backUpConnection->GetBackupExtProxy(); + if (!proxy) { + HILOGE("AppFileReady error, Extension backup Proxy is empty"); + return BError(BError::Codes::SA_INVAL_ARG); + } + // 通知extension清空缓存 + proxy->HandleClear(); + // 清除Timer + session_->StopFwkTimer(callerName); + session_->StopExtTimer(callerName); + // 通知TOOL 备份完成 + session_->GetServiceReverseProxy()->BackupOnBundleFinished(BError(BError::Codes::OK), callerName); + // 断开extension + backUpConnection->DisconnectBackupExtAbility(); + ClearSessionAndSchedInfo(callerName); + } + OnAllBundlesFinished(BError(BError::Codes::OK)); + return BError(BError::Codes::OK); + } catch (const BError &e) { + return e.GetCode(); // 任意异常产生,终止监听该任务 + } catch (const exception &e) { + HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGI("Unexpected exception"); + return EPERM; + } +} + +ErrCode Service::AppDone(ErrCode errCode) +{ + HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); + try { + if (session_ == nullptr) { + HILOGE("App finish error, session info is empty"); + return BError(BError::Codes::SA_INVAL_ARG); + } + string callerName = VerifyCallerAndGetCallerName(); + HILOGI("Begin, callerName is: %{public}s, errCode: %{public}d", callerName.c_str(), errCode); + if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) { + auto backUpConnection = session_->GetExtConnection(callerName); + if (backUpConnection == nullptr) { + HILOGE("App finish error, backUpConnection is empty"); + return BError(BError::Codes::SA_INVAL_ARG); + } + auto proxy = backUpConnection->GetBackupExtProxy(); + if (!proxy) { + throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); + } + proxy->HandleClear(); + session_->StopFwkTimer(callerName); + session_->StopExtTimer(callerName); + backUpConnection->DisconnectBackupExtAbility(); + ClearSessionAndSchedInfo(callerName); + NotifyCallerCurAppDone(errCode, callerName); + } + OnAllBundlesFinished(BError(BError::Codes::OK)); + return BError(BError::Codes::OK); + } catch (const BError &e) { + ReleaseOnException(); + HILOGE("AppDone error, err code is: %{public}d", e.GetCode()); + return e.GetCode(); // 任意异常产生,终止监听该任务 + } catch (const exception &e) { + ReleaseOnException(); + HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGI("Unexpected exception"); + return EPERM; + } +} + +ErrCode Service::LaunchBackupExtension(const BundleName &bundleName) +{ + HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); + try { + HILOGI("begin %{public}s", bundleName.data()); + IServiceReverse::Scenario scenario = session_->GetScenario(); + BConstants::ExtensionAction action; + if (scenario == IServiceReverse::Scenario::BACKUP || scenario == IServiceReverse::Scenario::CLEAN) { + action = BConstants::ExtensionAction::BACKUP; + } else if (scenario == IServiceReverse::Scenario::RESTORE) { + action = BConstants::ExtensionAction::RESTORE; + } else { + throw BError(BError::Codes::SA_INVAL_ARG, "Failed to scenario"); + } + if (SAUtils::IsSABundleName(bundleName)) { + return LaunchBackupSAExtension(bundleName); + } + AAFwk::Want want; + SetWant(want, bundleName, action); + auto backUpConnection = session_->GetExtConnection(bundleName); + if (backUpConnection == nullptr) { + HILOGE("LaunchBackupExtension error, backUpConnection is empty"); + return BError(BError::Codes::SA_INVAL_ARG); + } + if (backUpConnection->IsExtAbilityConnected() && !backUpConnection->WaitDisconnectDone()) { + HILOGE("LaunchBackupExtension error, WaitDisconnectDone failed"); + return BError(BError::Codes::SA_INVAL_ARG); + } + ErrCode ret = backUpConnection->ConnectBackupExtAbility(want, session_->GetSessionUserId()); + if (ret) { + HILOGE("ConnectBackupExtAbility faild, bundleName:%{public}s, ret:%{public}d", bundleName.c_str(), ret); + return BError(BError::Codes::SA_BOOT_EXT_FAIL); + } + return BError(BError::Codes::OK); + } catch (const BError &e) { + return e.GetCode(); + } catch (const exception &e) { + HILOGI("Catched an unexpected low-level exception %{public}s", e.what()); + return EPERM; + } catch (...) { + HILOGI("Unexpected exception"); + return EPERM; + } +} + +void Service::SetWant(AAFwk::Want &want, const BundleName &bundleName, const BConstants::ExtensionAction &action) +{ + BJsonUtil::BundleDetailInfo bundleDetail = BJsonUtil::ParseBundleNameIndexStr(bundleName); + string backupExtName = session_->GetBackupExtName(bundleName); /* new device app ext name */ + HILOGI("BackupExtName: %{public}s, bundleName: %{public}s", backupExtName.data(), bundleName.data()); + string versionName = session_->GetBundleVersionName(bundleName); /* old device app version name */ + int64_t versionCode = session_->GetBundleVersionCode(bundleName); /* old device app version code */ + RestoreTypeEnum restoreType = session_->GetBundleRestoreType(bundleName); /* app restore type */ + string bundleExtInfo = session_->GetBackupExtInfo(bundleName); + HILOGI("BundleExtInfo is:%{public}s", GetAnonyString(bundleExtInfo).c_str()); + want.SetElementName(bundleDetail.bundleName, backupExtName); + want.SetParam(BConstants::EXTENSION_ACTION_PARA, static_cast(action)); + want.SetParam(BConstants::EXTENSION_VERSION_CODE_PARA, static_cast(versionCode)); + want.SetParam(BConstants::EXTENSION_RESTORE_TYPE_PARA, static_cast(restoreType)); + want.SetParam(BConstants::EXTENSION_VERSION_NAME_PARA, versionName); + want.SetParam(BConstants::EXTENSION_RESTORE_EXT_INFO_PARA, bundleExtInfo); + want.SetParam(BConstants::EXTENSION_BACKUP_EXT_INFO_PARA, bundleExtInfo); + want.SetParam(BConstants::EXTENSION_APP_CLONE_INDEX_PARA, bundleDetail.bundleIndex); +} +} \ No newline at end of file diff --git a/services/backup_sa/src/module_ipc/svc_backup_connection.cpp b/services/backup_sa/src/module_ipc/svc_backup_connection.cpp index f9dc891c6..53413cc90 100644 --- a/services/backup_sa/src/module_ipc/svc_backup_connection.cpp +++ b/services/backup_sa/src/module_ipc/svc_backup_connection.cpp @@ -47,7 +47,8 @@ void SvcBackupConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &el } isConnected_.store(true); string bundleName = element.GetBundleName(); - HILOGI("%{public}s, OnAbilityConnectDone", bundleName.c_str()); + HILOGI("bundleName:%{public}s, OnAbilityConnectDone, bundleNameIndexInfo:%{public}s", bundleName.c_str(), + bundleNameIndexInfo_.c_str()); auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); auto ms = std::chrono::duration_cast(now.time_since_epoch()); @@ -68,7 +69,8 @@ void SvcBackupConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &el bundleNameIndexInfo_.c_str(), bundleName.c_str()); return; } - callConnected_(move(bundleNameIndexInfo_)); + bundleName = bundleNameIndexInfo_; + callConnected_(move(bundleName)); HILOGI("called end"); } @@ -78,6 +80,14 @@ void SvcBackupConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName isConnected_.store(false); backupProxy_ = nullptr; string bundleName = element.GetBundleName(); + HILOGI("bundleName:%{public}s, OnAbilityDisconnectDone, bundleNameIndexInfo:%{public}s", bundleName.c_str(), + bundleNameIndexInfo_.c_str()); + if (bundleNameIndexInfo_.find(bundleName) == string::npos) { + HILOGE("Current bundle name is wrong, bundleNameIndexInfo:%{public}s, bundleName:%{public}s", + bundleNameIndexInfo_.c_str(), bundleName.c_str()); + return; + } + bundleName = bundleNameIndexInfo_; if (isConnectedDone_ == false) { isConnectedDone_.store(true); HILOGE("It's error that the backup extension dies before the backup sa. name : %{public}s", bundleName.data()); diff --git a/tests/unittests/backup_sa/module_ipc/BUILD.gn b/tests/unittests/backup_sa/module_ipc/BUILD.gn index 6a395d44a..620789a39 100644 --- a/tests/unittests/backup_sa/module_ipc/BUILD.gn +++ b/tests/unittests/backup_sa/module_ipc/BUILD.gn @@ -96,6 +96,7 @@ ohos_unittest("backup_service_test") { "${path_backup}/services/backup_sa/src/module_ipc/service.cpp", "${path_backup}/services/backup_sa/src/module_ipc/service_incremental.cpp", "${path_backup}/services/backup_sa/src/module_ipc/svc_restore_deps_manager.cpp", + "${path_backup}/services/backup_sa/src/module_ipc/sub_service.cpp", "${path_backup}/services/backup_sa/src/module_notify/notify_work_service.cpp", "service_test.cpp", ] @@ -160,6 +161,7 @@ ohos_unittest("backup_service_throw_test") { "${path_backup}/services/backup_sa/src/module_ipc/service.cpp", "${path_backup}/services/backup_sa/src/module_ipc/service_incremental.cpp", "${path_backup}/services/backup_sa/src/module_ipc/svc_restore_deps_manager.cpp", + "${path_backup}/services/backup_sa/src/module_ipc/sub_service.cpp", "${path_backup}/services/backup_sa/src/module_notify/notify_work_service.cpp", "service_throw_test.cpp", ] @@ -343,6 +345,7 @@ ohos_unittest("backup_restore_deps_manager_test") { "${path_backup}/services/backup_sa/src/module_ipc/service.cpp", "${path_backup}/services/backup_sa/src/module_ipc/service_incremental.cpp", "${path_backup}/services/backup_sa/src/module_ipc/svc_restore_deps_manager.cpp", + "${path_backup}/services/backup_sa/src/module_ipc/sub_service.cpp", "${path_backup}/services/backup_sa/src/module_notify/notify_work_service.cpp", "svc_restore_deps_manager_test.cpp", ] diff --git a/utils/include/b_resources/b_constants.h b/utils/include/b_resources/b_constants.h index 849f07ecf..51907a8ae 100644 --- a/utils/include/b_resources/b_constants.h +++ b/utils/include/b_resources/b_constants.h @@ -90,6 +90,7 @@ constexpr uint32_t TIMEOUT_INVALID = UINT32_MAX; constexpr int CALL_APP_ON_PROCESS_TIME_INTERVAL = 5; // 框架每隔5s去调用应用的onProcess constexpr int APP_ON_PROCESS_MAX_TIMEOUT = 1000; // 应用的onProcess接口最大超时时间为1秒 +constexpr int FIRST_CALL_APP_ON_PROCESS_MAX_TIMEOUT = 15000; // 首次调用应用的onProcess接口最大超时时间为15秒 constexpr int APP_ON_PROCESS_TIMEOUT_MAX_COUNT = 3; // 应用的onProcess接口超时的上限次数 // backup.para内配置项的名称,该配置项值为true时可在不更新hap包的情况下,可以读取包管理元数据配置文件的内容 -- Gitee