diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index 3e175b9e4b22a481429138327074aeace124e447..5b0fa4c78dab974281fdda0f34dfb9057d6d17ee 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); @@ -300,7 +300,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_; @@ -309,7 +309,10 @@ private: std::mutex onStartTimeLock_; AppRadar::DoRestoreInfo radarRestoreInfo_ { 0 }; OHOS::ThreadPool onProcessTaskPool_; - BackupRestoreScenario curScenario_; + 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 4101f56ecaebfebc2924e3361e67c37f0b04d165..933a174ece1c762f92cf797e14b1dc6f40b8b0eb 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 027216afec711a3d02b3a8d4491d79a0f572ddbd..21b78cac54a155c8a4adf4ea2f63b8250d0b7591 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_ipc/service.h b/services/backup_sa/include/module_ipc/service.h index b9126cea68f3bad0c6b61204325f84b518ad4c15..1329df10d21d2d3616cd858e5fa460f1a314b7bd 100644 --- a/services/backup_sa/include/module_ipc/service.h +++ b/services/backup_sa/include/module_ipc/service.h @@ -376,7 +376,8 @@ 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 @@ -466,6 +467,14 @@ private: 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 981c6cc863892fadbf78f9dd1559e9dc9c2150d7..e1f415e89dfa100823f36734360d015f3d1f25f8 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) { diff --git a/services/backup_sa/src/module_ipc/service.cpp b/services/backup_sa/src/module_ipc/service.cpp index 498043c8f4d6ad02c771f3d8d9bc9f3b51549d68..3df17771707f8da191ab3eb5fc309ab953768eb4 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; @@ -502,26 +503,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"); @@ -591,7 +595,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; } @@ -624,27 +628,20 @@ 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); } } -vector Service::MakeDetailList(const vector &bundleNames) -{ - vector bundleDetails {}; - for (auto bundleName : bundleNames) { - bundleDetails.emplace_back(BIncrementalData {bundleName, 0}); - } - return bundleDetails; -} ErrCode Service::AppendBundlesBackupSession(const vector &bundleNames) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); @@ -658,14 +655,15 @@ ErrCode Service::AppendBundlesBackupSession(const vector &bundleName auto backupInfos = BundleMgrAdapter::GetBundleInfosForAppend(bundleDetails, session_->GetSessionUserId()); session_->AppendBundles(bundleNames); for (auto info : backupInfos) { - HILOGI("Current backupInfo bundleName:%{public}s, extName:%{public}s", info.name.c_str(), - info.extensionName.c_str()); - 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()); @@ -682,7 +680,7 @@ ErrCode Service::AppendBundlesBackupSession(const vector &bundleName HandleExceptionOnAppendBundles(session_, bundleNames, {}); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); return EPERM; - } catch (...) { + } catch(...) { HILOGE("Unexpected exception"); HandleExceptionOnAppendBundles(session_, bundleNames, {}); session_->DecreaseSessionCnt(__PRETTY_FUNCTION__); @@ -691,7 +689,7 @@ ErrCode Service::AppendBundlesBackupSession(const vector &bundleName } ErrCode Service::AppendBundlesDetailsBackupSession(const vector &bundleNames, - const vector &bundleInfos) + const vector &bundleInfos) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); try { @@ -709,19 +707,7 @@ ErrCode Service::AppendBundlesDetailsBackupSession(const vector &bun 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); @@ -730,11 +716,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, {}); @@ -743,147 +724,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; } } @@ -966,72 +826,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); @@ -1816,31 +1610,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()) { @@ -1850,6 +1619,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 ea29fe6a04d402f7824e6c9d636190c67d1e92d5..d69b35f3a8dc74146795a71919202024a6ff643b 100644 --- a/services/backup_sa/src/module_ipc/service_incremental.cpp +++ b/services/backup_sa/src/module_ipc/service_incremental.cpp @@ -273,14 +273,15 @@ ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vectorGetSessionUserId()); session_->AppendBundles(bundleNames); for (auto info : backupInfos) { - HILOGI("Current backupInfo bundleName:%{public}s, extName:%{public}s", info.name.c_str(), - info.extensionName.c_str()); - 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) { @@ -321,20 +322,7 @@ ErrCode Service::AppendBundlesIncrementalBackupSession(const std::vectorGetSessionUserId()); session_->AppendBundles(bundleNames); - for (auto info : backupInfos) { - SetCurrentSessProperties(info, isClearDataFlags); - session_->SetBundleDataSize(info.name, info.increSpaceOccupied); - 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); } @@ -352,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 0000000000000000000000000000000000000000..b235f14433bbbf08e2083628b0ca9072f78844fa --- /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 f9dc891c68e4e3a66a3c688717c2df9aab531e34..53413cc907d7a00e4cd04e6861db36ae5cd73fa4 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 f4c0009c2c2a62971816fb81c0981c7a415ca3e4..302ff1ee38530c1b440f90fbbbdeee67944d4faf 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_mock}/timer/timer_mock.cpp", "${path_backup}/services/backup_sa/src/module_ipc/sa_backup_connection.cpp", "${path_backup}/services/backup_sa/src/module_ipc/service_incremental.cpp", + "${path_backup}/services/backup_sa/src/module_ipc/sub_service.cpp", "${path_backup}/services/backup_sa/src/module_ipc/svc_restore_deps_manager.cpp", "${path_backup}/services/backup_sa/src/module_notify/notify_work_service.cpp", "service_test.cpp", @@ -172,6 +173,7 @@ ohos_unittest("backup_service_throw_test") { "${path_backup}/services/backup_sa/src/module_ipc/sa_backup_connection.cpp", "${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/sub_service.cpp", "${path_backup}/services/backup_sa/src/module_ipc/svc_restore_deps_manager.cpp", "${path_backup}/services/backup_sa/src/module_notify/notify_work_service.cpp", "service_throw_test.cpp", @@ -357,6 +359,7 @@ ohos_unittest("backup_restore_deps_manager_test") { "${path_backup}/services/backup_sa/src/module_ipc/sa_backup_connection.cpp", "${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/sub_service.cpp", "${path_backup}/services/backup_sa/src/module_ipc/svc_restore_deps_manager.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 849f07ecf4a44f2f7fb61d54bfc9961a8ac6035f..51907a8aee9109b0114438b3094244f7b26e2cd0 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包的情况下,可以读取包管理元数据配置文件的内容