From 23a75c8795e1e3eab68d09bf45dbfe48632c7bd2 Mon Sep 17 00:00:00 2001 From: csw Date: Wed, 25 Jun 2025 17:21:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=9A=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: csw --- .../ability/native/recovery/app_recovery.cpp | 177 +++++++++++++----- .../ability/native/recovery/app_recovery.h | 23 ++- .../ability/native/recovery/recovery_param.h | 2 + 3 files changed, 158 insertions(+), 44 deletions(-) diff --git a/frameworks/native/ability/native/recovery/app_recovery.cpp b/frameworks/native/ability/native/recovery/app_recovery.cpp index 4655b2f69a6..5e15206a080 100644 --- a/frameworks/native/ability/native/recovery/app_recovery.cpp +++ b/frameworks/native/ability/native/recovery/app_recovery.cpp @@ -51,13 +51,19 @@ std::atomic g_blocked = false; const int DELAY_TIME = 1000; AppRecovery::AppRecovery() : isEnable_(false), restartFlag_(RestartFlag::ALWAYS_RESTART), - saveOccasion_(SaveOccasionFlag::SAVE_WHEN_ERROR), saveMode_(SaveModeFlag::SAVE_WITH_FILE) + saveOccasion_(SaveOccasionFlag::SAVE_WHEN_ERROR), saveMode_(SaveModeFlag::SAVE_WITH_FILE), { } AppRecovery::~AppRecovery() { } +void AppRecovery::SetEnableCrossProcess(bool isEnableCrossProcess) +{ + isEnableCrossProcess_ = isEnableCrossProcess; +} + + static void SigQuitHandler(int signal) { @@ -108,8 +114,14 @@ AppRecovery& AppRecovery::GetInstance() bool AppRecovery::InitApplicationInfo(const std::shared_ptr& mainHandler, const std::shared_ptr& applicationInfo) { - mainHandler_ = mainHandler; - applicationInfo_ = applicationInfo; + { + std::lock_guard lock(mainHandlerMutex_); + mainHandler_ = mainHandler; + } + { + std::lock_guard lock(applicationInfoMutex_); + applicationInfo_ = applicationInfo; + } return true; } @@ -120,10 +132,18 @@ bool AppRecovery::AddAbility(std::shared_ptr ability, TAG_LOGE(AAFwkTag::RECOVERY, "null abilityInfo or ability"); return false; } - - token_ = token; - mainWant_.SetElementName(abilityInfo->bundleName, abilityInfo->name); - auto handler = mainHandler_.lock(); + { + std:d::lock_guard lock(tokenMutex_); + token_ = token; + } + { + std::lock_guard lock(mainWantMutex_); + mainWant_.SetElementName(abilityInfo->bundleName, abilityInfo->name); + } + { + std::lock_guard lock(mainHandlerMutex_); + auto handler = mainHandler_.lock(); + } if (handler != nullptr) { auto task = []() { AppRecovery::GetInstance().DeleteInValidMissionFiles(); @@ -132,17 +152,30 @@ bool AppRecovery::AddAbility(std::shared_ptr ability, TAG_LOGE(AAFwkTag::RECOVERY, "DeleteInValidMissionFiles failed"); } } - - if (isEnable_ && !abilityRecoverys_.empty() && !abilityInfo->recoverable) { + bool abityRecoveryIsEmpty = false; + { + std::lock_guard lock(abilityRecoveryMutex_); + abityRecoveryIsEmpty = abilityRecovery_.empty(); + } + if (isEnable_ && !abityRecoveryIsEmpty && !abilityInfo->recoverable) { TAG_LOGE(AAFwkTag::RECOVERY, "recoverable is false"); return false; } - ability_ = ability; + { + std::lock_guard lock(abilityMutex_); + ability_ = ability; + } std::shared_ptr abilityRecovery = std::make_shared(); abilityRecovery->InitAbilityInfo(ability, abilityInfo, token); - abilityRecovery->EnableAbilityRecovery(useAppSettedValue_.load(), restartFlag_, saveOccasion_, saveMode_); + { + std::lock_guard lock(stateConfigMutex_); + abilityRecovery->EnableAbilityRecovery(useAppSettedValue_.load(), restartFlag_, saveOccasion_, saveMode_); + } ability->EnableAbilityRecovery(abilityRecovery, useAppSettedValue_.load()); - abilityRecoverys_.push_back(abilityRecovery); + { + std::lock_guard lock(abilityRecoveryMutex_); + abilityRecoverys_.push_back(abilityRecovery); + } return true; } @@ -153,6 +186,7 @@ bool AppRecovery::RemoveAbility(const sptr& tokenId) return false; } TAG_LOGD(AAFwkTag::RECOVERY, "start"); + std::lock_guard lock(abilityRecoveryMutex_); auto itr = std::find_if(abilityRecoverys_.begin(), abilityRecoverys_.end(), [&tokenId](std::shared_ptr &abilityRecovery) { return (abilityRecovery && abilityRecovery->GetToken() == tokenId); @@ -165,6 +199,7 @@ bool AppRecovery::RemoveAbility(const sptr& tokenId) void AppRecovery::SetFreezeCallback(FreezeFunction freezeCallback) { + std::lock_guard lock(callbackMutex_); if (!this->freezeCallback) { this->freezeCallback = freezeCallback; } @@ -188,12 +223,17 @@ bool AppRecovery::ScheduleSaveAppState(StateReason reason, uintptr_t ability) { TAG_LOGI(AAFwkTag::RECOVERY, "begin"); bool ret = IsNeedSaveAppState(reason); - if (!ret && this->freezeCallback == nullptr) { - return false; + { + std::lock_guard lock(callbackMutex_); + if (!ret && this->freezeCallback == nullptr) { + return false; + } } - if (reason == StateReason::APP_FREEZE) { - auto abilityPtr = ability_.lock(); + { + std::lock_guard lock(abilityMutex_); + auto abilityPtr = ability_.lock(); + } if (!abilityPtr || !abilityPtr->GetAbilityContext()) { TAG_LOGE(AAFwkTag::RECOVERY, "null ability or context"); return false; @@ -204,18 +244,24 @@ bool AppRecovery::ScheduleSaveAppState(StateReason reason, uintptr_t ability) return false; } #ifdef SUPPORT_SCREEN - OHOS::AbilityRuntime::JsUIAbility& jsAbility = static_cast(*abilityPtr); - AbilityRuntime::JsRuntime& runtime = const_cast(jsAbility.GetJsRuntime()); - panda::ecmascript::EcmaVM* vm = runtime.GetEcmaVm(); - if (!panda::JSNApi::CheckAndSetAllowCrossThreadExecution(vm)) { - TAG_LOGE(AAFwkTag::RECOVERY, "VM is in gc process"); - return false; + if (isEnableCrossProcess_) { + OHOS::AbilityRuntime::JsUIAbility& jsAbility = static_cast(*abilityPtr); + AbilityRuntime::JsRuntime& runtime = const_cast(jsAbility.GetJsRuntime()); + panda::ecmascript::EcmaVM* vm = runtime.GetEcmaVm(); + if (!panda::JSNApi::CheckAndSetAllowCrossThreadExecution(vm)) { + TAG_LOGE(AAFwkTag::RECOVERY, "VM is in gc process"); + return false; + } } #endif - if (this->freezeCallback) { - this->freezeCallback(); - TAG_LOGW(AAFwkTag::RECOVERY, "Freeze callback execution completed"); + { + std::lock_guard lock(callbackMutex_); + if (this->freezeCallback) { + this->freezeCallback(); + TAG_LOGW(AAFwkTag::RECOVERY, "Freeze callback execution completed"); + } } + if (!ret) { return false; } @@ -223,7 +269,10 @@ bool AppRecovery::ScheduleSaveAppState(StateReason reason, uintptr_t ability) return true; } - auto handler = mainHandler_.lock(); + { + std::lock_guard lock(mainHandlerMutex_); + auto handler = mainHandler_.lock(); + } if (handler == nullptr) { TAG_LOGE(AAFwkTag::RECOVERY, "null handler"); return false; @@ -247,7 +296,10 @@ void AppRecovery::SetRestartWant(std::shared_ptr want) TAG_LOGE(AAFwkTag::RECOVERY, "not enabled"); return; } - want_ = want; + { + std::lock_guard lock(wantMutex_); + want_ = want; + } } bool AppRecovery::ScheduleRecoverApp(StateReason reason) @@ -266,9 +318,12 @@ bool AppRecovery::ScheduleRecoverApp(StateReason reason) return false; } - if (abilityRecoverys_.empty()) { - TAG_LOGE(AAFwkTag::RECOVERY, "null ability"); - return false; + { + std::lock_guard lock(abilityRecoveryMutex_); + if (abilityRecoverys_.empty()) { + TAG_LOGE(AAFwkTag::RECOVERY, "null ability"); + return false; + } } if (reason == StateReason::APP_FREEZE) { @@ -276,7 +331,10 @@ bool AppRecovery::ScheduleRecoverApp(StateReason reason) return true; } - auto handler = mainHandler_.lock(); + { + std::lock_guard lock(mainHandlerMutex_); + auto handler = mainHandler_.lock(); + } if (handler == nullptr) { TAG_LOGE(AAFwkTag::RECOVERY, "null handler"); return false; @@ -312,15 +370,21 @@ bool AppRecovery::TryRecoverApp(StateReason reason) void AppRecovery::DoRecoverApp(StateReason reason) { TAG_LOGD(AAFwkTag::RECOVERY, "begin"); - if (abilityRecoverys_.empty()) { - TAG_LOGE(AAFwkTag::RECOVERY, "no ability exist"); - return; + { + std::lock_guard lock(abilityRecoveryMutex_); + if (abilityRecoverys_.empty()) { + TAG_LOGE(AAFwkTag::RECOVERY, "no ability exist"); + return; + } } AAFwk::Want *want = nullptr; - if (want_ != nullptr) { - want = want_.get(); + { + std::lock_guard lock(wantMutex_); + if (want_ != nullptr) { + want = want_.get(); + } } - + std::mutex_lock lock(abilityRecoveryMutex_); if (abilityRecoverys_.size() == 1) { if (abilityRecoverys_.front()->IsOnForeground()) { abilityRecoverys_.front()->ScheduleRecoverAbility(reason, want); @@ -339,9 +403,16 @@ void AppRecovery::DoRecoverApp(StateReason reason) void AppRecovery::DoRecoverMainApp(StateReason reason) { TAG_LOGD(AAFwkTag::RECOVERY, "DoReciverMainApp begin"); - AAFwk::Want *want = &mainWant_; + { + std::lock_guard lock(mainWantMutex_); + AAFwk::Want *want = &mainWant_; + } want->SetParam(AAFwk::Want::PARAM_ABILITY_RECOVERY_RESTART, false); - auto token = token_.promote(); + { + std::lock_guard lock(tokenMutex_); + auto token = token_.promote(); + } + if (token == nullptr) { return; } @@ -356,7 +427,11 @@ void AppRecovery::DoRecoverMainApp(StateReason reason) void AppRecovery::DoSaveAppState(StateReason reason, uintptr_t ability) { TAG_LOGD(AAFwkTag::RECOVERY, "begin"); - auto appInfo = applicationInfo_.lock(); + { + std::lock_guard lock(applicationInfoMutex_); + auto appInfo = applicationInfo_.lock(); + } + std::lock_guard lock(abilityRecoveryMutex_); if (appInfo == nullptr || abilityRecoverys_.empty()) { TAG_LOGE(AAFwkTag::RECOVERY, "not exist application or ability info"); return; @@ -379,6 +454,7 @@ void AppRecovery::DoSaveAppState(StateReason reason, uintptr_t ability) void AppRecovery::EnableAppRecovery(uint16_t restartFlag, uint16_t saveFlag, uint16_t saveMode) { + std::lock_guard lock(stateConfigMutex_); isEnable_ = true; restartFlag_ = restartFlag; saveOccasion_ = saveFlag; @@ -395,6 +471,7 @@ bool AppRecovery::ShouldSaveAppState(StateReason reason) break; case StateReason::LIFECYCLE: + std::lock_guard lock(stateConfigMutex_); if ((saveOccasion_ & SaveOccasionFlag::SAVE_WHEN_BACKGROUND) != 0) { ret = true; } @@ -403,7 +480,9 @@ bool AppRecovery::ShouldSaveAppState(StateReason reason) case StateReason::CPP_CRASH: case StateReason::JS_ERROR: case StateReason::CJ_ERROR: + case StateReason::STS_ERROR: case StateReason::APP_FREEZE: // appfreeze could not callback to js function safely. + std::lock_guard lock(stateConfigMutex_); if ((saveOccasion_ & SaveOccasionFlag::SAVE_WHEN_ERROR) != 0) { ret = true; } @@ -414,6 +493,7 @@ bool AppRecovery::ShouldSaveAppState(StateReason reason) bool AppRecovery::ShouldRecoverApp(StateReason reason) { + std::lock_guard lock(stateConfigMutex_); if (restartFlag_ == RestartFlag::NO_RESTART) { return false; } @@ -448,6 +528,11 @@ bool AppRecovery::ShouldRecoverApp(StateReason reason) } break; + case StateReason::STS_ERROR: + if (isAlwaysStart || (restartFlag_ & RestartFlag::RESTART_WHEN_STS_CRASH) != 0) { + ret = true; + } + break; case StateReason::APP_FREEZE: if (isAlwaysStart || (restartFlag_ & RestartFlag::RESTART_WHEN_APP_FREEZE) != 0) { ret = true; @@ -554,11 +639,14 @@ bool AppRecovery::GetMissionIds(std::string path, std::vector &missionI bool AppRecovery::PersistAppState() { - if (saveMode_ == SaveModeFlag::SAVE_WITH_FILE) { - return true; + { + std::lock_guard lock(stateConfigMutex_); + if (saveMode_ == SaveModeFlag::SAVE_WITH_FILE) { + return true; + } } - bool ret = true; + std::lock_guard lock(abilityRecoveryMutex_); for (auto& abilityRecovery : abilityRecoverys_) { ret = ret && abilityRecovery->PersistState(); } @@ -572,16 +660,19 @@ bool AppRecovery::IsEnabled() const uint16_t AppRecovery::GetRestartFlag() const { + std::lock_guard lock(stateConfigMutex_); return restartFlag_; } uint16_t AppRecovery::GetSaveOccasionFlag() const { + std::lock_guard lock(stateConfigMutex_); return saveOccasion_; } uint16_t AppRecovery::GetSaveModeFlag() const { + std::lock_guard lock(stateConfigMutex_); return saveMode_; } } // namespace AbilityRuntime diff --git a/interfaces/kits/native/ability/native/recovery/app_recovery.h b/interfaces/kits/native/ability/native/recovery/app_recovery.h index 75bf4baa8c9..df6850da3aa 100644 --- a/interfaces/kits/native/ability/native/recovery/app_recovery.h +++ b/interfaces/kits/native/ability/native/recovery/app_recovery.h @@ -70,19 +70,40 @@ private: void DeleteInValidMissionFileById(std::string path, int32_t missionId); bool GetMissionIds(std::string path, std::vector &missionIds); - bool isEnable_; + std::atomic isEnable_; + + std::mutex stateConfigMutex_; uint16_t restartFlag_; uint16_t saveOccasion_; uint16_t saveMode_; + + std::mutex tokenMutex_; wptr token_; + + std::mutex mainWantMutex_; AAFwk::Want mainWant_; + + std::mutex mainHandlerMutex_; std::weak_ptr mainHandler_; + + std::mutex applicationInfoMutex_; std::weak_ptr applicationInfo_; + + std::mutex abilityMutex_; std::weak_ptr ability_; + + std::mutex abilityRecoveryMutex_; std::vector> abilityRecoverys_; + + std::mutex wantMutex_; std::shared_ptr want_ = nullptr; + std::atomic useAppSettedValue_ = false; // If the value is true means app call appRecovery.enableAppRecovery + + std::mutex callbackMutex_; FreezeFunction freezeCallback = nullptr; + + std::atmoc isEnableCrossProcess_ = true; // If the value is true means appRecovery is cross process }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/interfaces/kits/native/ability/native/recovery/recovery_param.h b/interfaces/kits/native/ability/native/recovery/recovery_param.h index 67db772c8ea..1e125b90847 100644 --- a/interfaces/kits/native/ability/native/recovery/recovery_param.h +++ b/interfaces/kits/native/ability/native/recovery/recovery_param.h @@ -45,6 +45,7 @@ enum RestartFlag { RESTART_WHEN_JS_CRASH = 0x0001, RESTART_WHEN_APP_FREEZE = 0x0002, RESTART_WHEN_CJ_CRASH = 0x0004, + RESTART_WHEN_STS_CRASH = 0x0008, NO_RESTART = 0xFFFF, }; @@ -67,6 +68,7 @@ enum StateReason { JS_ERROR, APP_FREEZE, CJ_ERROR, + STS_ERROR, }; } // namespace AAFwk -- Gitee