diff --git a/frameworks/native/ability/native/ability_local_record.cpp b/frameworks/native/ability/native/ability_local_record.cpp index 6a96a6ad70..f69fd4c821 100644 --- a/frameworks/native/ability/native/ability_local_record.cpp +++ b/frameworks/native/ability/native/ability_local_record.cpp @@ -62,5 +62,15 @@ bool AbilityLocalRecord::IsHook() const { return want_ && want_->GetBoolParam(IS_HOOK, false); } + +void AbilityLocalRecord::SetSkipAbilityStageLifecycle(bool skipAbilityStageLifecycle) +{ + skipAbilityStageLifecycle_ = skipAbilityStageLifecycle; +} + +bool AbilityLocalRecord::IsSkipAbilityStageLifecycle() const +{ + return skipAbilityStageLifecycle_; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/frameworks/native/appkit/ability_runtime/app/ability_stage.cpp b/frameworks/native/appkit/ability_runtime/app/ability_stage.cpp index 3513c48d14..3d922754cf 100644 --- a/frameworks/native/appkit/ability_runtime/app/ability_stage.cpp +++ b/frameworks/native/appkit/ability_runtime/app/ability_stage.cpp @@ -157,5 +157,15 @@ void AbilityStage::MarkAbilityCreated() { isAbilityCreate_ = true; } + +void AbilityStage::SetSkipAbilityStageLifecycle(bool skipAbilityStageLifecycle) +{ + skipAbilityStageLifecycle_ = skipAbilityStageLifecycle; +} + +bool AbilityStage::IsSkipAbilityStageLifecycle() const +{ + return skipAbilityStageLifecycle_; +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index 5f24c0d540..a2ce27b375 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -186,6 +186,7 @@ constexpr const char* INHERIT_PLUGIN_NAMESPACE = "persist.sys.abilityms.inherit_ constexpr const char* PLUGIN_DEFAULT_NAMESPACE_LDDICTIONARY = "persist.sys.abilityms.plugin_default_namespace_lddictionary"; constexpr char KILL_REASON[] = "Kill Reason:Js Error"; +constexpr const char* KEY_SKIP_ABILITY_STAGE_LIFECYCLE = "ohos.ability.param.skipAbilityStageLifecycle"; const int32_t JSCRASH_TYPE = 3; const std::string JSVM_TYPE = "ARK"; @@ -825,12 +826,16 @@ void MainThread::ScheduleLaunchAbility(const AbilityInfo &info, const sptrGetBoolParam(KEY_SKIP_ABILITY_STAGE_LIFECYCLE, false); + want->RemoveParam(KEY_SKIP_ABILITY_STAGE_LIFECYCLE); AAFwk::Want newWant(*want); newWant.CloseAllFd(); } std::shared_ptr abilityInfo = std::make_shared(info); auto abilityRecord = std::make_shared(abilityInfo, token, want, abilityRecordId); + abilityRecord->SetSkipAbilityStageLifecycle(skipAbilityStageLifecycle); auto tmpWatchdog = watchdog_; if (tmpWatchdog != nullptr) { tmpWatchdog->SetBgWorkingThreadStatus(IsBgWorkingThread(info)); diff --git a/frameworks/native/appkit/app/ohos_application.cpp b/frameworks/native/appkit/app/ohos_application.cpp index 1a6aa7b8a1..8255fa9385 100644 --- a/frameworks/native/appkit/app/ohos_application.cpp +++ b/frameworks/native/appkit/app/ohos_application.cpp @@ -311,7 +311,7 @@ void OHOSApplication::OnConfigurationUpdated( } for (auto it = abilityStages_.begin(); it != abilityStages_.end(); it++) { auto abilityStage = it->second; - if (abilityStage) { + if (abilityStage && !abilityStage->IsSkipAbilityStageLifecycle()) { abilityStage->OnConfigurationUpdated(config); } } @@ -370,7 +370,7 @@ void OHOSApplication::OnMemoryLevel(int32_t level) TAG_LOGD(AAFwkTag::APPKIT, "Number of abilityStage to be notified : [%{public}zu]", abilityStages_.size()); for (auto it = abilityStages_.begin(); it != abilityStages_.end(); it++) { auto abilityStage = it->second; - if (abilityStage) { + if (abilityStage && !abilityStage->IsSkipAbilityStageLifecycle()) { abilityStage->OnMemoryLevel(level); } } @@ -399,7 +399,7 @@ void OHOSApplication::OnHyperSnapUpdate() TAG_LOGI(AAFwkTag::APPKIT, "OnHyperSnapUpdate"); AppExecFwk::AppImageObserverManager::GetInstance().NotifyApplicationUpdate(); for (auto& item : abilityStages_) { - if (item.second) { + if (item.second && !item.second->IsSkipAbilityStageLifecycle()) { item.second->OnLaunchFromHyperSnap(); } } @@ -422,8 +422,10 @@ void OHOSApplication::AddAbility(std::shared_ptr a return; } if (!abilityStage->IsAbilityCreated()) { - TAG_LOGI(AAFwkTag::APPKIT, "OnAboutToCreateAbility"); - abilityStage->OnAboutToCreateAbility(); + if (!abilityStage->IsSkipAbilityStageLifecycle()) { + TAG_LOGI(AAFwkTag::APPKIT, "OnAboutToCreateAbility"); + abilityStage->OnAboutToCreateAbility(); + } abilityStage->MarkAbilityCreated(); } abilityStage->AddAbility(token, abilityRecord); @@ -542,6 +544,7 @@ std::shared_ptr OHOSApplication::AddAbilityStage( } abilityStage->Init(stageContext, weak); + abilityStage->SetSkipAbilityStageLifecycle(abilityRecord->IsSkipAbilityStageLifecycle()); auto firstCallback = CreateFirstStartupCallbackForRecord(abilityStage, abilityRecord, *hapModuleInfo, callback); if (firstCallback != nullptr) { @@ -566,7 +569,9 @@ std::shared_ptr OHOSApplication::AddAbilityStage( } TAG_LOGD(AAFwkTag::APPKIT, "no wait startup second"); - abilityStage->OnCreate(want); + if (!abilityStage->IsSkipAbilityStageLifecycle()) { + abilityStage->OnCreate(want); + } abilityStages_[moduleName] = abilityStage; } else { abilityStage = iterator->second; @@ -886,7 +891,9 @@ void OHOSApplication::CleanAbilityStage(const sptr &token, } abilityStage->RemoveAbility(token); if (!abilityStage->ContainsAbility() && !isCacheProcess) { - abilityStage->OnDestroy(); + if (!abilityStage->IsSkipAbilityStageLifecycle()) { + abilityStage->OnDestroy(); + } abilityStages_.erase(moduleName); } } @@ -975,7 +982,7 @@ void OHOSApplication::SchedulePrepareTerminate(const std::string &moduleName, return; } callbackInfo->Push(callback); - if (!iter->second->OnPrepareTerminate(callbackInfo, isAsync)) { + if (iter->second->IsSkipAbilityStageLifecycle() || !iter->second->OnPrepareTerminate(callbackInfo, isAsync)) { TAG_LOGI(AAFwkTag::APPKIT, "not exist"); AppExecFwk::OnPrepareTerminationResult result = { 0, false }; callbackInfo->Call(result); @@ -1113,7 +1120,9 @@ void OHOSApplication::CleanEmptyAbilityStage() continue; } if (!abilityStage->ContainsAbility()) { - abilityStage->OnDestroy(); + if (!abilityStage->IsSkipAbilityStageLifecycle()) { + abilityStage->OnDestroy(); + } it = abilityStages_.erase(it); } else { containsNonEmpty = true; diff --git a/interfaces/kits/native/ability/native/ability_local_record.h b/interfaces/kits/native/ability/native/ability_local_record.h index 8fe0d9ce7d..86e68ccb2b 100644 --- a/interfaces/kits/native/ability/native/ability_local_record.h +++ b/interfaces/kits/native/ability/native/ability_local_record.h @@ -76,12 +76,17 @@ public: const std::shared_ptr &GetWant(); bool IsHook() const; + + void SetSkipAbilityStageLifecycle(bool skipAbilityStageLifecycle); + + bool IsSkipAbilityStageLifecycle() const; private: std::shared_ptr abilityInfo_ = nullptr; sptr token_ = nullptr; std::shared_ptr want_ = nullptr; int32_t abilityRecordId_ = 0; sptr abilityThread_; + bool skipAbilityStageLifecycle_ = false; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/kits/native/appkit/ability_runtime/app/ability_stage.h b/interfaces/kits/native/appkit/ability_runtime/app/ability_stage.h index 43dca09e84..f49e496187 100644 --- a/interfaces/kits/native/appkit/ability_runtime/app/ability_stage.h +++ b/interfaces/kits/native/appkit/ability_runtime/app/ability_stage.h @@ -77,6 +77,9 @@ public: bool IsAbilityCreated() const; void MarkAbilityCreated(); + void SetSkipAbilityStageLifecycle(bool skipAbilityStageLifecycle); + bool IsSkipAbilityStageLifecycle() const; + private: friend class JsAbilityStage; friend class ETSAbilityStage; @@ -84,6 +87,7 @@ private: std::map, std::shared_ptr> abilityRecords_; std::weak_ptr application_; bool isAbilityCreate_ = false; + bool skipAbilityStageLifecycle_ = false; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/services/abilitymgr/include/utils/start_ability_utils.h b/services/abilitymgr/include/utils/start_ability_utils.h index 8a30e63054..0afdff2493 100644 --- a/services/abilitymgr/include/utils/start_ability_utils.h +++ b/services/abilitymgr/include/utils/start_ability_utils.h @@ -48,6 +48,7 @@ struct StartAbilityInfo { int32_t status = ERR_OK; AppExecFwk::ExtensionProcessMode extensionProcessMode = AppExecFwk::ExtensionProcessMode::UNDEFINED; bool isTargetPlugin = false; + bool skipAbilityStageLifecycle = false; }; struct StartAbilityUtils { diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index f7b2d09247..fe2378fa17 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -360,6 +360,7 @@ constexpr uint32_t TARGET_TYPE_INIT = 100; constexpr int64_t USER_SWITCH_TIMEOUT = 3 * 1000; // 3s constexpr const char* SUPPORT_LINKAGE_SCENE = "const.window.supportLinkageScene"; constexpr const char* KEY_SPECIFIED_FLAG = "com.ohos.param.specifiedFlag"; +constexpr const char* KEY_SKIP_ABILITY_STAGE_LIFECYCLE = "ohos.ability.param.skipAbilityStageLifecycle"; const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(DelayedSingleton::GetInstance().get()); @@ -8293,6 +8294,12 @@ int AbilityManagerService::GenerateAbilityRequest(const Want &want, int requestC request.collaboratorType = GetCollaboratorType(request.abilityInfo.applicationInfo.codePath); request.isTargetPlugin = abilityInfo->isTargetPlugin; + if (request.abilityInfo.extensionAbilityType == AppExecFwk::ExtensionAbilityType::BACKUP && + !request.abilityInfo.applicationInfo.allowMultiProcess) { + request.want.SetParam(KEY_SKIP_ABILITY_STAGE_LIFECYCLE, abilityInfo->skipAbilityStageLifecycle); + TAG_LOGD(AAFwkTag::ABILITYMGR, "set skipAbilityStageLifecycle for backup extension"); + } + if (request.abilityInfo.type == AppExecFwk::AbilityType::SERVICE && request.abilityInfo.isStageBasedModel) { TAG_LOGI(AAFwkTag::ABILITYMGR, "stage mode, abilityInfo SERVICE type reset EXTENSION"); request.abilityInfo.type = AppExecFwk::AbilityType::EXTENSION; diff --git a/services/abilitymgr/src/utils/start_ability_utils.cpp b/services/abilitymgr/src/utils/start_ability_utils.cpp index 5218bda3d5..aa3256cc22 100644 --- a/services/abilitymgr/src/utils/start_ability_utils.cpp +++ b/services/abilitymgr/src/utils/start_ability_utils.cpp @@ -300,6 +300,7 @@ std::shared_ptr StartAbilityInfo::CreateStartAbilityInfo(const return request; } request->extensionProcessMode = extensionInfo.extensionProcessMode; + request->skipAbilityStageLifecycle = extensionInfo.skipAbilityStageLifecycle; // For compatibility translates to AbilityInfo AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, request->abilityInfo); } @@ -374,6 +375,7 @@ void StartAbilityInfo::FindExtensionInfo(const Want &want, int32_t flags, int32_ return; } abilityInfo->customProcess = extensionInfo.customProcess; + abilityInfo->skipAbilityStageLifecycle = extensionInfo.skipAbilityStageLifecycle; TAG_LOGD(AAFwkTag::ABILITYMGR, "extensionInfo customProcess: %{public}s", abilityInfo->customProcess.c_str()); if (AbilityRuntime::StartupUtil::IsSupportAppClone(extensionInfo.type)) { abilityInfo->extensionProcessMode = extensionInfo.extensionProcessMode; diff --git a/services/appmgr/src/app_lifecycle_deal.cpp b/services/appmgr/src/app_lifecycle_deal.cpp index edf43fa4e8..4b18d57897 100644 --- a/services/appmgr/src/app_lifecycle_deal.cpp +++ b/services/appmgr/src/app_lifecycle_deal.cpp @@ -30,6 +30,7 @@ namespace AppExecFwk { namespace { constexpr const char* REUSING_WINDOW = "ohos.ability_runtime.reusing_window"; constexpr const char* IS_HOOK = "ohos.ability_runtime.is_hook"; +constexpr const char* KEY_SKIP_ABILITY_STAGE_LIFECYCLE = "ohos.ability.param.skipAbilityStageLifecycle"; } AppLifeCycleDeal::AppLifeCycleDeal() {} @@ -111,6 +112,7 @@ void AppLifeCycleDeal::LaunchAbility(const std::shared_ptr if (ability->GetWant() != nullptr) { ability->GetWant()->RemoveParam(REUSING_WINDOW); ability->GetWant()->RemoveParam(IS_HOOK); + ability->GetWant()->RemoveParam(KEY_SKIP_ABILITY_STAGE_LIFECYCLE); } } else { TAG_LOGW(AAFwkTag::APPMGR, "null appThread or ability"); diff --git a/test/unittest/appkit/ohos_application_test/mock_ability_stage.h b/test/unittest/appkit/ohos_application_test/mock_ability_stage.h index 43d671f539..5ecd0a1f97 100644 --- a/test/unittest/appkit/ohos_application_test/mock_ability_stage.h +++ b/test/unittest/appkit/ohos_application_test/mock_ability_stage.h @@ -27,8 +27,11 @@ public: MockAbilityStage() {} ~MockAbilityStage() {} + MOCK_CONST_METHOD0(OnDestroy, void()); + MOCK_METHOD1(OnMemoryLevel, void(int)); MOCK_METHOD5(RunAutoStartupTask, int32_t(const std::function&, std::shared_ptr, bool&, const std::shared_ptr&, bool)); + MOCK_METHOD0(OnAboutToCreateAbility, void()); MOCK_METHOD0(OnLaunchFromHyperSnap, void()); }; } // namespace AbilityRuntime diff --git a/test/unittest/appkit/ohos_application_test/ohos_application_test.cpp b/test/unittest/appkit/ohos_application_test/ohos_application_test.cpp index 5009fb4a90..728db892f1 100644 --- a/test/unittest/appkit/ohos_application_test/ohos_application_test.cpp +++ b/test/unittest/appkit/ohos_application_test/ohos_application_test.cpp @@ -44,6 +44,35 @@ using namespace testing::ext; namespace OHOS { namespace AppExecFwk { +namespace { +class PrepareTerminateCountStage : public AbilityRuntime::AbilityStage { +public: + explicit PrepareTerminateCountStage(bool returnValue) : returnValue_(returnValue) {} + + bool OnPrepareTerminate( + AppExecFwk::AbilityTransactionCallbackInfo *, + bool &isAsync) const override + { + callCount_++; + isAsync = false; + return returnValue_; + } + + mutable int32_t callCount_ = 0; + bool returnValue_ = false; +}; + +class ConfigUpdateCountStage : public AbilityRuntime::AbilityStage { +public: + void OnConfigurationUpdated(const AppExecFwk::Configuration &) override + { + ++updateCount_; + } + + int32_t updateCount_ = 0; +}; +} + class OHOSApplicationTest : public testing::Test { public: static void SetUpTestCase(); @@ -399,6 +428,78 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnConfigurationUpda GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0300 end."; } +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0310 +* @tc.name: OnConfigurationUpdated +* @tc.desc: Verify calls abilityStage OnConfigurationUpdated when skipAbilityStageLifecycle is false +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0310, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0310 start."; + std::string bundleName = "test.bundleName"; + std::string moduleName = "test.moduleName"; + std::string hapPath = "/data/app/testHap"; + std::vector overlayPaths; + std::unique_ptr resConfig(Global::Resource::CreateResConfig()); + ASSERT_NE(resConfig, nullptr); + std::shared_ptr resourceManager(Global::Resource::CreateResourceManager( + bundleName, moduleName, hapPath, overlayPaths, *resConfig)); + ASSERT_NE(resourceManager, nullptr); + auto contextImpl = std::make_shared(); + contextImpl->SetResourceManager(resourceManager); + auto appContext = std::make_shared(); + appContext->AttachContextImpl(contextImpl); + ohosApplication_->SetApplicationContext(appContext); + + ohosApplication_->abilityRecordMgr_ = std::make_shared(); + ohosApplication_->configuration_ = std::make_shared(); + auto stage = std::make_shared(); + stage->SetSkipAbilityStageLifecycle(false); + ohosApplication_->abilityStages_.emplace("entry_config_false", stage); + + Configuration config; + config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, "zh"); + ohosApplication_->OnConfigurationUpdated(config); + EXPECT_EQ(stage->updateCount_, 1); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0310 end."; +} + +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0320 +* @tc.name: OnConfigurationUpdated +* @tc.desc: Verify does not call abilityStage OnConfigurationUpdated when skipAbilityStageLifecycle is true +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0320, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0320 start."; + std::string bundleName = "test.bundleName"; + std::string moduleName = "test.moduleName"; + std::string hapPath = "/data/app/testHap"; + std::vector overlayPaths; + std::unique_ptr resConfig(Global::Resource::CreateResConfig()); + ASSERT_NE(resConfig, nullptr); + std::shared_ptr resourceManager(Global::Resource::CreateResourceManager( + bundleName, moduleName, hapPath, overlayPaths, *resConfig)); + ASSERT_NE(resourceManager, nullptr); + auto contextImpl = std::make_shared(); + contextImpl->SetResourceManager(resourceManager); + auto appContext = std::make_shared(); + appContext->AttachContextImpl(contextImpl); + ohosApplication_->SetApplicationContext(appContext); + + ohosApplication_->abilityRecordMgr_ = std::make_shared(); + ohosApplication_->configuration_ = std::make_shared(); + auto stage = std::make_shared(); + stage->SetSkipAbilityStageLifecycle(true); + ohosApplication_->abilityStages_.emplace("entry_config_true", stage); + + Configuration config; + config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, "zh"); + ohosApplication_->OnConfigurationUpdated(config); + EXPECT_EQ(stage->updateCount_, 0); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnConfigurationUpdated_0320 end."; +} + /* * @tc.number: OnConfigurationUpdated_0600 * @tc.name: OnConfigurationUpdated @@ -481,6 +582,44 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0200, GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0200 end."; } +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0210 +* @tc.name: OnMemoryLevel +* @tc.desc: Verify calls abilityStage OnMemoryLevel when skipAbilityStageLifecycle is false +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0210, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0210 start."; + constexpr int32_t level = 1; + ohosApplication_->abilityRuntimeContext_ = std::make_shared(); + auto mockAbilityStage = std::make_shared(); + mockAbilityStage->SetSkipAbilityStageLifecycle(false); + ohosApplication_->abilityStages_.emplace("entry_memory_false", mockAbilityStage); + + EXPECT_CALL(*mockAbilityStage, OnMemoryLevel(level)).Times(1); + ohosApplication_->OnMemoryLevel(level); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0210 end."; +} + +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0220 +* @tc.name: OnMemoryLevel +* @tc.desc: Verify does not call abilityStage OnMemoryLevel when skipAbilityStageLifecycle is true +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0220, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0220 start."; + constexpr int32_t level = 1; + ohosApplication_->abilityRuntimeContext_ = std::make_shared(); + auto mockAbilityStage = std::make_shared(); + mockAbilityStage->SetSkipAbilityStageLifecycle(true); + ohosApplication_->abilityStages_.emplace("entry_memory_true", mockAbilityStage); + + EXPECT_CALL(*mockAbilityStage, OnMemoryLevel(level)).Times(0); + ohosApplication_->OnMemoryLevel(level); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_OnMemoryLevel_0220 end."; +} + /* * @tc.number: AppExecFwk_OHOSApplicationTest_AddAbilityStage_0100 * @tc.name: AddAbilityStage @@ -616,6 +755,58 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_AddAbilityStage_070 GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0700 end."; } +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_AddAbilityStage_0710 +* @tc.name: AddAbilityStage +* @tc.desc: Verify function AddAbilityStage skipAbilityStageLifecycle false branch +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_AddAbilityStage_0710, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0710 start."; + sptr token = new (std::nothrow) Notification::MockIRemoteObject(); + std::shared_ptr info = std::make_shared(); + info->moduleName = "entry_skip_false"; + auto abilityRecord = std::make_shared(info, token, nullptr, 0); + abilityRecord->SetSkipAbilityStageLifecycle(false); + + auto callback = [](const std::shared_ptr &) {}; + bool isAsyncCallback = false; + auto context = ohosApplication_->AddAbilityStage(abilityRecord, callback, isAsyncCallback); + + EXPECT_NE(context, nullptr); + auto it = ohosApplication_->abilityStages_.find(info->moduleName); + ASSERT_NE(it, ohosApplication_->abilityStages_.end()); + ASSERT_NE(it->second, nullptr); + EXPECT_FALSE(it->second->IsSkipAbilityStageLifecycle()); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0710 end."; +} + +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_AddAbilityStage_0720 +* @tc.name: AddAbilityStage +* @tc.desc: Verify function AddAbilityStage skipAbilityStageLifecycle true branch +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_AddAbilityStage_0720, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0720 start."; + sptr token = new (std::nothrow) Notification::MockIRemoteObject(); + std::shared_ptr info = std::make_shared(); + info->moduleName = "entry_skip_true"; + auto abilityRecord = std::make_shared(info, token, nullptr, 0); + abilityRecord->SetSkipAbilityStageLifecycle(true); + + auto callback = [](const std::shared_ptr &) {}; + bool isAsyncCallback = false; + auto context = ohosApplication_->AddAbilityStage(abilityRecord, callback, isAsyncCallback); + + EXPECT_NE(context, nullptr); + auto it = ohosApplication_->abilityStages_.find(info->moduleName); + ASSERT_NE(it, ohosApplication_->abilityStages_.end()); + ASSERT_NE(it->second, nullptr); + EXPECT_TRUE(it->second->IsSkipAbilityStageLifecycle()); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_AddAbilityStage_0720 end."; +} + /* * @tc.number: AppExecFwk_OHOSApplicationTest_AddAbilityStage_0800 * @tc.name: AddAbilityStage @@ -775,6 +966,56 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0 GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0300 end."; } +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0400 +* @tc.name: CleanAbilityStage +* @tc.desc: Verify function CleanAbilityStage calls OnDestroy when skipAbilityStageLifecycle is false +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0400, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0400 start."; + std::string moduleName = "entry_clean_destroy_false"; + std::shared_ptr abilityInfo = std::make_shared(); + abilityInfo->moduleName = moduleName; + sptr token = new (std::nothrow) Notification::MockIRemoteObject(); + auto abilityRecord = std::make_shared(abilityInfo, token, nullptr, 0); + + auto mockAbilityStage = std::make_shared(); + mockAbilityStage->SetSkipAbilityStageLifecycle(false); + mockAbilityStage->AddAbility(token, abilityRecord); + ohosApplication_->abilityStages_.emplace(moduleName, mockAbilityStage); + + EXPECT_CALL(*mockAbilityStage, OnDestroy()).Times(1); + ohosApplication_->CleanAbilityStage(token, abilityInfo, false); + EXPECT_EQ(ohosApplication_->abilityStages_.find(moduleName), ohosApplication_->abilityStages_.end()); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0400 end."; +} + +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0500 +* @tc.name: CleanAbilityStage +* @tc.desc: Verify function CleanAbilityStage does not call OnDestroy when skipAbilityStageLifecycle is true +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0500, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0500 start."; + std::string moduleName = "entry_clean_destroy_true"; + std::shared_ptr abilityInfo = std::make_shared(); + abilityInfo->moduleName = moduleName; + sptr token = new (std::nothrow) Notification::MockIRemoteObject(); + auto abilityRecord = std::make_shared(abilityInfo, token, nullptr, 0); + + auto mockAbilityStage = std::make_shared(); + mockAbilityStage->SetSkipAbilityStageLifecycle(true); + mockAbilityStage->AddAbility(token, abilityRecord); + ohosApplication_->abilityStages_.emplace(moduleName, mockAbilityStage); + + EXPECT_CALL(*mockAbilityStage, OnDestroy()).Times(0); + ohosApplication_->CleanAbilityStage(token, abilityInfo, false); + EXPECT_EQ(ohosApplication_->abilityStages_.find(moduleName), ohosApplication_->abilityStages_.end()); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_CleanAbilityStage_0500 end."; +} + /* * @tc.number: AppExecFwk_OHOSApplicationTest_GetAppContext_0100 * @tc.name: GetAppContext @@ -838,6 +1079,82 @@ HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_ScheduleAcceptWant_ GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_ScheduleAcceptWant_0100 end."; } +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0100 +* @tc.name: SchedulePrepareTerminate +* @tc.desc: Verify does not call OnPrepareTerminate when skipAbilityStageLifecycle is true +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0100, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0100 start."; + bool isAsync = true; + bool callbackCalled = false; + auto callback = [&callbackCalled](AppExecFwk::OnPrepareTerminationResult) { + callbackCalled = true; + }; + + std::string moduleName = "entry_prepare_skip_true"; + auto abilityStage = std::make_shared(true); + abilityStage->SetSkipAbilityStageLifecycle(true); + ohosApplication_->abilityStages_.emplace(moduleName, abilityStage); + + ohosApplication_->SchedulePrepareTerminate(moduleName, callback, isAsync); + EXPECT_EQ(abilityStage->callCount_, 0); + EXPECT_TRUE(callbackCalled); + EXPECT_FALSE(isAsync); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0100 end."; +} + +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0200 +* @tc.name: SchedulePrepareTerminate +* @tc.desc: Verify calls fallback callback when OnPrepareTerminate returns false +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0200, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0200 start."; + bool isAsync = false; + bool callbackCalled = false; + auto callback = [&callbackCalled](AppExecFwk::OnPrepareTerminationResult) { + callbackCalled = true; + }; + + std::string moduleName = "entry_prepare_return_false"; + auto abilityStage = std::make_shared(false); + abilityStage->SetSkipAbilityStageLifecycle(false); + ohosApplication_->abilityStages_.emplace(moduleName, abilityStage); + + ohosApplication_->SchedulePrepareTerminate(moduleName, callback, isAsync); + EXPECT_EQ(abilityStage->callCount_, 1); + EXPECT_TRUE(callbackCalled); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0200 end."; +} + +/* +* @tc.number: AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0300 +* @tc.name: SchedulePrepareTerminate +* @tc.desc: Verify does not call fallback callback when OnPrepareTerminate returns true +*/ +HWTEST_F(OHOSApplicationTest, AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0300, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0300 start."; + bool isAsync = false; + bool callbackCalled = false; + auto callback = [&callbackCalled](AppExecFwk::OnPrepareTerminationResult) { + callbackCalled = true; + }; + + std::string moduleName = "entry_prepare_return_true"; + auto abilityStage = std::make_shared(true); + abilityStage->SetSkipAbilityStageLifecycle(false); + ohosApplication_->abilityStages_.emplace(moduleName, abilityStage); + + ohosApplication_->SchedulePrepareTerminate(moduleName, callback, isAsync); + EXPECT_EQ(abilityStage->callCount_, 1); + EXPECT_FALSE(callbackCalled); + GTEST_LOG_(INFO) << "AppExecFwk_OHOSApplicationTest_SchedulePrepareTerminate_0300 end."; +} + /* * @tc.number: AppExecFwk_OHOSApplicationTest_GetConfiguration_0100 * @tc.name: GetConfiguration @@ -1625,6 +1942,26 @@ HWTEST_F(OHOSApplicationTest, OnUpdate_0100, TestSize.Level1) GTEST_LOG_(INFO) << "OnUpdate_0100 end."; } +/* + * @tc.number: OnUpdate_0200 + * @tc.name: OnUpdate + * @tc.desc: Verify skipAbilityStageLifecycle=true does not call OnLaunchFromHyperSnap + */ +HWTEST_F(OHOSApplicationTest, OnUpdate_0200, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "OnUpdate_0200 start."; + auto ohosApplication = std::make_shared(); + ASSERT_NE(ohosApplication, nullptr); + auto abilityStage = std::make_shared(); + ASSERT_NE(abilityStage, nullptr); + abilityStage->SetSkipAbilityStageLifecycle(true); + ohosApplication->abilityStages_["test_skip_true"] = abilityStage; + + EXPECT_CALL(*abilityStage, OnLaunchFromHyperSnap()).Times(0); + ohosApplication->OnHyperSnapUpdate(); + GTEST_LOG_(INFO) << "OnUpdate_0200 end."; +} + /* * @tc.number: AddAbility_ShouldDonothingWhenInputIsInvalid * @tc.name: AddAbility @@ -1678,6 +2015,31 @@ HWTEST_F(OHOSApplicationTest, AddAbility_ShouldAddAbilityToAbilityStageWhenInput GTEST_LOG_(INFO) << "AddAbility_ShouldAddAbilityToAbilityStageWhenInputIsValid end."; } +/* + * @tc.number: AddAbility_0100 + * @tc.name: AddAbility + * @tc.desc: Verify OnAboutToCreateAbility is not called when skipAbilityStageLifecycle is true + */ +HWTEST_F(OHOSApplicationTest, AddAbility_0200, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "AddAbility_0200 start."; + auto ohosApplication = std::make_shared(); + ASSERT_NE(ohosApplication, nullptr); + auto abilityStage = std::make_shared(); + ASSERT_NE(abilityStage, nullptr); + abilityStage->SetSkipAbilityStageLifecycle(true); + + sptr token = new (std::nothrow) Notification::MockIRemoteObject(); + ASSERT_NE(token, nullptr); + auto abilityRecord = std::make_shared(nullptr, token, nullptr, 0); + ASSERT_NE(abilityRecord, nullptr); + + EXPECT_CALL(*abilityStage, OnAboutToCreateAbility()).Times(0); + ohosApplication->AddAbility(abilityStage, token, abilityRecord); + EXPECT_TRUE(abilityStage->ContainsAbility()); + GTEST_LOG_(INFO) << "AddAbility_0200 end."; +} + /** * @tc.number: AppExecFwk_OHOSApplicationTest_LaunchElement_0100 * @tc.name: AddAbilityStage sets launchElement with valid Want