From 4e888aa07038b324c8a83ad37295edf6b86d4885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E8=8F=B2=E5=A2=A8?= Date: Thu, 4 Jun 2026 17:53:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9A=90=E7=A7=81=E5=BC=B9=E7=AA=97=E6=8B=A6?= =?UTF-8?q?=E6=88=AA=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Agent Signed-off-by: 朱菲墨 --- .../abilitymgr/include/disposed_observer.h | 13 +- .../interceptor/disposed_rule_interceptor.h | 6 +- services/abilitymgr/src/disposed_observer.cpp | 90 ++- .../interceptor/disposed_rule_interceptor.cpp | 120 ++-- ...ilitymgrdisposedruleinterceptor_fuzzer.cpp | 5 +- .../ability_interceptor_second_test.cpp | 16 +- .../ability_interceptor_test.cpp | 8 +- test/unittest/disposed_observer_test/BUILD.gn | 21 + .../disposed_observer_test.cpp | 653 ++++++++++++++++++ .../disposed_rule_interceptor_test/BUILD.gn | 2 + .../disposed_rule_interceptor_test.cpp | 430 +++++++++++- .../mock/include/ability_manager_client.h | 2 +- .../mock/include/ability_record.h | 12 + .../mock/include/bundle_mgr_helper.h | 15 + .../mock/src/mock_ability_record.cpp | 15 + .../mock/src/mock_bundle_mgr_helper.cpp | 30 + 16 files changed, 1365 insertions(+), 73 deletions(-) diff --git a/services/abilitymgr/include/disposed_observer.h b/services/abilitymgr/include/disposed_observer.h index c05f23e384..3990eb3f50 100644 --- a/services/abilitymgr/include/disposed_observer.h +++ b/services/abilitymgr/include/disposed_observer.h @@ -31,6 +31,16 @@ public: const std::shared_ptr &interceptor, int32_t uid); ~DisposedObserver() = default; + static std::string GenerateAbilityKey(const std::string &moduleName, const std::string &abilityName); + + void AddAbilityKey(const std::string &moduleName, const std::string &abilityName); + + bool HasAbilityKey(const std::string &moduleName, const std::string &abilityName); + + bool RemoveAbilityKey(const std::string &moduleName, const std::string &abilityName); + + size_t GetAbilityKeyCount(); + private: void OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData) override; void OnPageShow(const AppExecFwk::PageStateData &pageStateData) override; @@ -40,8 +50,9 @@ private: std::shared_ptr interceptor_ = nullptr; AppExecFwk::DisposedRule disposedRule_; sptr token_ = nullptr; - ffrt::mutex observerLock_; + ffrt::mutex abilityKeyLock_; int32_t uid_ = 0; + std::vector abilityKeys_; }; } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/include/interceptor/disposed_rule_interceptor.h b/services/abilitymgr/include/interceptor/disposed_rule_interceptor.h index 3e8cf447ab..9660b72ea3 100644 --- a/services/abilitymgr/include/interceptor/disposed_rule_interceptor.h +++ b/services/abilitymgr/include/interceptor/disposed_rule_interceptor.h @@ -31,6 +31,8 @@ class DisposedRuleInterceptor : public IAbilityInterceptor, public: DisposedRuleInterceptor() = default; ~DisposedRuleInterceptor() = default; + static std::string GenerateTimeoutTaskName(int32_t uid); + static std::string GenerateEventTaskName(int32_t uid); ErrCode DoProcess(AbilityInterceptorParam param) override; void SetTaskHandler(std::shared_ptr taskHandler) override { @@ -38,12 +40,14 @@ public: }; void UnregisterObserver(int32_t uid); private: + bool ValidateNonBlockRule(const Want &want, const AppExecFwk::DisposedRule &disposedRule); bool CheckControl(const Want &want, int32_t userId, AppExecFwk::DisposedRule &disposedRule, int32_t appIndex); bool FindBlockDisposedRule(const Want &want, const std::vector &disposedRuleList, AppExecFwk::DisposedRule &disposedRule); void FindNonBlockDisposedRule(const std::vector &disposedRuleList, AppExecFwk::DisposedRule &disposedRule); - ErrCode StartNonBlockRule(const Want &want, AppExecFwk::DisposedRule &disposedRule, int32_t uid); + ErrCode StartNonBlockRule(const Want &want, AppExecFwk::DisposedRule &disposedRule, + const std::shared_ptr &abilityInfo); ErrCode CreateModalUIExtension(const Want &want, const sptr &callerToken); void SetInterceptInfo(const Want &want, AppExecFwk::DisposedRule &disposedRule); bool IsSkipDisposeRule(AppExecFwk::PageJumpMode mode, const AbilityInterceptorParam ¶m); diff --git a/services/abilitymgr/src/disposed_observer.cpp b/services/abilitymgr/src/disposed_observer.cpp index be0d276448..31cc26869f 100644 --- a/services/abilitymgr/src/disposed_observer.cpp +++ b/services/abilitymgr/src/disposed_observer.cpp @@ -15,6 +15,7 @@ #include "disposed_observer.h" +#include "ability_util.h" #include "interceptor/disposed_rule_interceptor.h" #include "ability_record.h" #include "modal_system_ui_extension.h" @@ -39,13 +40,62 @@ DisposedObserver::DisposedObserver(const AppExecFwk::DisposedRule &disposedRule, : interceptor_(interceptor), disposedRule_(disposedRule), uid_(uid) {} +std::string DisposedObserver::GenerateAbilityKey(const std::string &moduleName, const std::string &abilityName) +{ + return moduleName + "/" + abilityName; +} + +void DisposedObserver::AddAbilityKey(const std::string &moduleName, const std::string &abilityName) +{ + std::lock_guard guard(abilityKeyLock_); + std::string key = GenerateAbilityKey(moduleName, abilityName); + abilityKeys_.emplace_back(key); + TAG_LOGI(AAFwkTag::ABILITYMGR, "added ability key: %{public}s, total: %{public}zu", + key.c_str(), abilityKeys_.size()); +} + +bool DisposedObserver::HasAbilityKey(const std::string &moduleName, const std::string &abilityName) +{ + std::lock_guard guard(abilityKeyLock_); + std::string key = GenerateAbilityKey(moduleName, abilityName); + for (const auto &k : abilityKeys_) { + if (k == key) { + return true; + } + } + return false; +} + +bool DisposedObserver::RemoveAbilityKey(const std::string &moduleName, const std::string &abilityName) +{ + std::lock_guard guard(abilityKeyLock_); + std::string key = GenerateAbilityKey(moduleName, abilityName); + for (auto it = abilityKeys_.begin(); it != abilityKeys_.end(); ++it) { + if (*it == key) { + abilityKeys_.erase(it); + TAG_LOGI(AAFwkTag::ABILITYMGR, "removed ability key: %{public}s, remaining: %{public}zu", + key.c_str(), abilityKeys_.size()); + return abilityKeys_.empty(); + } + } + TAG_LOGW(AAFwkTag::ABILITYMGR, "ability key not found: %{public}s", key.c_str()); + return abilityKeys_.empty(); +} + +size_t DisposedObserver::GetAbilityKeyCount() +{ + std::lock_guard guard(abilityKeyLock_); + return abilityKeys_.size(); +} + void DisposedObserver::OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData) { - std::lock_guard guard(observerLock_); + std::lock_guard guard(abilityKeyLock_); if (abilityStateData.abilityState != static_cast(AppExecFwk::AbilityState::ABILITY_STATE_FOREGROUND)) { return; } - TAG_LOGD(AAFwkTag::ABILITYMGR, "Call"); + TAG_LOGD(AAFwkTag::ABILITYMGR, "Call OnAbilityStateChanged"); + CHECK_POINTER(interceptor_); token_ = abilityStateData.token; auto abilityRecord = Token::GetAbilityRecordByToken(token_); if (abilityRecord && !abilityRecord->GetAbilityInfo().isStageBasedModel) { @@ -69,29 +119,41 @@ void DisposedObserver::OnAbilityStateChanged(const AppExecFwk::AbilityStateData void DisposedObserver::OnPageShow(const AppExecFwk::PageStateData &pageStateData) { - TAG_LOGI(AAFwkTag::ABILITYMGR, "recv onPageShow"); + TAG_LOGI(AAFwkTag::ABILITYMGR, "recv onPageShow, uid:%{public}d", pageStateData.uid); if (pageStateData.uid != uid_) { - TAG_LOGI(AAFwkTag::ABILITYMGR, "currentUid:%{public}d, paramUid:%{public}d", uid_, pageStateData.uid); + TAG_LOGI(AAFwkTag::ABILITYMGR, "uid mismatch, current:%{public}d, param:%{public}d", uid_, pageStateData.uid); return; } + CHECK_POINTER(interceptor_); + + std::string moduleName = pageStateData.moduleName; + std::string abilityName = pageStateData.abilityName; + if (!HasAbilityKey(moduleName, abilityName)) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "not in watch list, ignore: %{public}s/%{public}s", + moduleName.c_str(), abilityName.c_str()); + return; + } + + TAG_LOGI(AAFwkTag::ABILITYMGR, "responding to: %{public}s/%{public}s", + moduleName.c_str(), abilityName.c_str()); if (disposedRule_.componentType == AppExecFwk::ComponentType::UI_ABILITY) { - TAG_LOGD(AAFwkTag::ABILITYMGR, "Call"); + TAG_LOGD(AAFwkTag::ABILITYMGR, "UI_ABILITY, start ability"); int ret = IN_PROCESS_CALL(AbilityManagerClient::GetInstance()->StartAbility(*disposedRule_.want)); if (ret != ERR_OK) { - interceptor_->UnregisterObserver(pageStateData.uid); - TAG_LOGE(AAFwkTag::ABILITYMGR, "call failed"); - return; + TAG_LOGE(AAFwkTag::ABILITYMGR, "start ability failed"); } - } - if (disposedRule_.componentType == AppExecFwk::ComponentType::UI_EXTENSION) { + } else if (disposedRule_.componentType == AppExecFwk::ComponentType::UI_EXTENSION) { + TAG_LOGD(AAFwkTag::ABILITYMGR, "UI_EXTENSION, execute"); int ret = ExecuteUIExtension(pageStateData); if (ret != ERR_OK) { - interceptor_->UnregisterObserver(pageStateData.uid); - TAG_LOGE(AAFwkTag::ABILITYMGR, "call failed"); - return; + TAG_LOGE(AAFwkTag::ABILITYMGR, "execute UIExtension failed"); } } - interceptor_->UnregisterObserver(pageStateData.uid); + + if (RemoveAbilityKey(moduleName, abilityName)) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "all abilities responded, unregister observer"); + interceptor_->UnregisterObserver(uid_); + } } ErrCode DisposedObserver::ExecuteUIExtension(const AppExecFwk::PageStateData &pageStateData) diff --git a/services/abilitymgr/src/interceptor/disposed_rule_interceptor.cpp b/services/abilitymgr/src/interceptor/disposed_rule_interceptor.cpp index dc564562a3..f16a76c3da 100644 --- a/services/abilitymgr/src/interceptor/disposed_rule_interceptor.cpp +++ b/services/abilitymgr/src/interceptor/disposed_rule_interceptor.cpp @@ -39,6 +39,16 @@ constexpr const char* INTERCEPT_MODULE_NAME = "intercept_moduleName"; constexpr const char* IS_FROM_PARENTCONTROL = "ohos.ability.isFromParentControl"; } +std::string DisposedRuleInterceptor::GenerateTimeoutTaskName(int32_t uid) +{ + return UNREGISTER_TIMEOUT_OBSERVER_TASK + std::to_string(uid); +} + +std::string DisposedRuleInterceptor::GenerateEventTaskName(int32_t uid) +{ + return UNREGISTER_EVENT_TASK + std::to_string(uid); +} + ErrCode DisposedRuleInterceptor::DoProcess(AbilityInterceptorParam param) { TAG_LOGD(AAFwkTag::ABILITYMGR, "Call"); @@ -86,7 +96,7 @@ ErrCode DisposedRuleInterceptor::DoProcess(AbilityInterceptorParam param) TAG_LOGE(AAFwkTag::ABILITYMGR, "disposed abilityInfo is nullptr"); return RESOLVE_ABILITY_ERR; } - return StartNonBlockRule(param.want, disposedRule, param.abilityInfo->uid); + return StartNonBlockRule(param.want, disposedRule, param.abilityInfo); } bool DisposedRuleInterceptor::CheckControl(const Want &want, int32_t userId, @@ -177,75 +187,107 @@ void DisposedRuleInterceptor::FindNonBlockDisposedRule(const std::vector &abilityInfo) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); - TAG_LOGI(AAFwkTag::ABILITYMGR, "not block, dType:%{public}d, cType:%{public}d, compType:%{public}d", - disposedRule.disposedType, disposedRule.controlType, disposedRule.componentType); - if (disposedRule.want == nullptr) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "null want"); - return ERR_OK; - } - if (disposedRule.want->GetBundle() == want.GetBundle()) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "no dispose app with same bundleName"); + if (!ValidateNonBlockRule(want, disposedRule)) { return ERR_OK; } SetInterceptInfo(want, disposedRule); - std::string bundleName = want.GetBundle(); + + std::string moduleName = abilityInfo->moduleName; + std::string abilityName = abilityInfo->name; + int32_t uid = abilityInfo->applicationInfo.uid; + sptr appManager = AppMgrUtil::GetAppMgr(); CHECK_POINTER_AND_RETURN(appManager, ERR_INVALID_VALUE); + CHECK_POINTER_AND_RETURN(taskHandler_, ERR_INVALID_VALUE); + { std::lock_guard guard(observerLock_); - if (disposedObserverMap_.find(uid) != disposedObserverMap_.end()) { - TAG_LOGD(AAFwkTag::ABILITYMGR, "start same disposed app, do not need to register again"); - return ERR_OK; + auto iter = disposedObserverMap_.find(uid); + if (iter != disposedObserverMap_.end()) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "observer exists, add key and refresh timeout: %{public}s/%{public}s", + moduleName.c_str(), abilityName.c_str()); + CHECK_POINTER_AND_RETURN(iter->second, ERR_INVALID_VALUE); + iter->second->AddAbilityKey(moduleName, abilityName); + std::string timeoutTaskName = GenerateTimeoutTaskName(uid); + taskHandler_->CancelTask(timeoutTaskName); + } else { + auto disposedObserver = sptr::MakeSptr(disposedRule, shared_from_this(), uid); + CHECK_POINTER_AND_RETURN(disposedObserver, ERR_INVALID_VALUE); + disposedObserver->AddAbilityKey(moduleName, abilityName); + + std::vector bundleNameList; + bundleNameList.push_back(want.GetBundle()); + int32_t ret = + IN_PROCESS_CALL(appManager->RegisterApplicationStateObserver(disposedObserver, bundleNameList)); + if (ret != 0) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "register failed, err:%{public}d", ret); + return ret; + } + disposedObserverMap_.emplace(uid, disposedObserver); } - auto disposedObserver = sptr::MakeSptr(disposedRule, shared_from_this(), uid); - CHECK_POINTER_AND_RETURN(disposedObserver, ERR_INVALID_VALUE); - std::vector bundleNameList; - bundleNameList.push_back(bundleName); - int32_t ret = IN_PROCESS_CALL(appManager->RegisterApplicationStateObserver(disposedObserver, bundleNameList)); - if (ret != 0) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "register failed, err:%{public}d", ret); - disposedObserver = nullptr; - return ret; - } - disposedObserverMap_.emplace(uid, disposedObserver); } + + std::string timeoutTaskName = GenerateTimeoutTaskName(uid); auto unregisterTask = [appManager, uid, interceptor = shared_from_this()] () { std::lock_guard guard{interceptor->observerLock_}; auto iter = interceptor->disposedObserverMap_.find(uid); if (iter != interceptor->disposedObserverMap_.end()) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "time out, unregister observer"); + TAG_LOGE(AAFwkTag::ABILITYMGR, "timeout, unregister observer for uid:%{public}d", uid); IN_PROCESS_CALL(appManager->UnregisterApplicationStateObserver(iter->second)); interceptor->disposedObserverMap_.erase(iter); } }; - CHECK_POINTER_AND_RETURN(taskHandler_, ERR_INVALID_VALUE); - taskHandler_->SubmitTask(unregisterTask, UNREGISTER_TIMEOUT_OBSERVER_TASK, UNREGISTER_OBSERVER_MICRO_SECONDS); + taskHandler_->SubmitTask(unregisterTask, timeoutTaskName, UNREGISTER_OBSERVER_MICRO_SECONDS); return ERR_OK; } +bool DisposedRuleInterceptor::ValidateNonBlockRule(const Want &want, const AppExecFwk::DisposedRule &disposedRule) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "not block, dType:%{public}d, cType:%{public}d, compType:%{public}d", + disposedRule.disposedType, disposedRule.controlType, disposedRule.componentType); + if (disposedRule.want == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null want"); + return false; + } + if (disposedRule.want->GetBundle() == want.GetBundle()) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "no dispose app with same bundleName"); + return false; + } + return true; +} + void DisposedRuleInterceptor::UnregisterObserver(int32_t uid) { - TAG_LOGD(AAFwkTag::ABILITYMGR, "Call"); + TAG_LOGD(AAFwkTag::ABILITYMGR, "Call, uid:%{public}d", uid); CHECK_POINTER(taskHandler_); - taskHandler_->CancelTask(UNREGISTER_TIMEOUT_OBSERVER_TASK); + std::string timeoutTaskName = GenerateTimeoutTaskName(uid); + taskHandler_->CancelTask(timeoutTaskName); auto unregisterTask = [uid, interceptor = shared_from_this()] () { std::lock_guard guard{interceptor->observerLock_}; auto iter = interceptor->disposedObserverMap_.find(uid); if (iter == interceptor->disposedObserverMap_.end()) { - TAG_LOGE(AAFwkTag::ABILITYMGR, "no find observer"); - } else { - auto disposedObserver = iter->second; - CHECK_POINTER(disposedObserver); - sptr appManager = AppMgrUtil::GetAppMgr(); - CHECK_POINTER(appManager); - IN_PROCESS_CALL(appManager->UnregisterApplicationStateObserver(disposedObserver)); - interceptor->disposedObserverMap_.erase(iter); + TAG_LOGE(AAFwkTag::ABILITYMGR, "no find observer for uid:%{public}d", uid); + return; } + + auto disposedObserver = iter->second; + CHECK_POINTER(disposedObserver); + + if (disposedObserver->GetAbilityKeyCount() > 0) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "observer still has pending keys, skip unregister for uid:%{public}d", uid); + return; + } + + TAG_LOGI(AAFwkTag::ABILITYMGR, "unregistering observer for uid:%{public}d", uid); + sptr appManager = AppMgrUtil::GetAppMgr(); + CHECK_POINTER(appManager); + IN_PROCESS_CALL(appManager->UnregisterApplicationStateObserver(disposedObserver)); + interceptor->disposedObserverMap_.erase(iter); }; - taskHandler_->SubmitTask(unregisterTask, UNREGISTER_EVENT_TASK); + taskHandler_->SubmitTask(unregisterTask, GenerateEventTaskName(uid)); } ErrCode DisposedRuleInterceptor::CreateModalUIExtension(const Want &want, const sptr &callerToken) diff --git a/test/fuzztest/abilitymgrdisposedruleinterceptor_fuzzer/abilitymgrdisposedruleinterceptor_fuzzer.cpp b/test/fuzztest/abilitymgrdisposedruleinterceptor_fuzzer/abilitymgrdisposedruleinterceptor_fuzzer.cpp index 4e7e01663b..77274a459b 100644 --- a/test/fuzztest/abilitymgrdisposedruleinterceptor_fuzzer/abilitymgrdisposedruleinterceptor_fuzzer.cpp +++ b/test/fuzztest/abilitymgrdisposedruleinterceptor_fuzzer/abilitymgrdisposedruleinterceptor_fuzzer.cpp @@ -77,7 +77,7 @@ bool DoSomethingInterestingWithMyAPI(const char* data, size_t size, const uint8_ auto shouldBlockFunc = []() { return false; }; AbilityInterceptorParam param = AbilityInterceptorParam(want, requestCode, userId, isWithUI, token, shouldBlockFunc); - const std::shared_ptr abilityInfo; + std::shared_ptr abilityInfo; int32_t bundleType = static_cast(GetU32Data(data)); std::vector disposedRules = AbilityFuzzUtil::GetRandomDisposedRulesList(fdp); @@ -86,7 +86,8 @@ bool DoSomethingInterestingWithMyAPI(const char* data, size_t size, const uint8_ executer-> FindBlockDisposedRule(want, disposedRules, disposedRule); executer-> FindNonBlockDisposedRule(disposedRules, disposedRule); int32_t uid = static_cast(GetU32Data(data)); - executer-> StartNonBlockRule(want, disposedRule, uid); + abilityInfo->uid = uid; + executer-> StartNonBlockRule(want, disposedRule, abilityInfo); executer-> UnregisterObserver(uid); executer-> CreateModalUIExtension(want, token); executer-> SetInterceptInfo(want, disposedRule); diff --git a/test/unittest/ability_interceptor_second_test/ability_interceptor_second_test.cpp b/test/unittest/ability_interceptor_second_test/ability_interceptor_second_test.cpp index 2f54492813..35ca5b78a1 100644 --- a/test/unittest/ability_interceptor_second_test/ability_interceptor_second_test.cpp +++ b/test/unittest/ability_interceptor_second_test/ability_interceptor_second_test.cpp @@ -136,7 +136,9 @@ HWTEST_F(AbilityInterceptorSecondTest, DisposedRuleInterceptor_003, TestSize.Lev DisposedRule disposedRule; disposedRule.want = std::make_shared(); disposedRule.want->SetBundle(bundleName); - ErrCode result = executer->StartNonBlockRule(want, disposedRule, 0); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 0; + ErrCode result = executer->StartNonBlockRule(want, disposedRule, abilityInfo); EXPECT_EQ(result, ERR_OK); TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__); } @@ -158,7 +160,9 @@ HWTEST_F(AbilityInterceptorSecondTest, DisposedRuleInterceptor_004, TestSize.Lev DisposedRule disposedRule; disposedRule.want = std::make_shared(); disposedRule.want->SetBundle(bundleName2); - ErrCode result = executer->StartNonBlockRule(want, disposedRule, 0); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 0; + ErrCode result = executer->StartNonBlockRule(want, disposedRule, abilityInfo); EXPECT_NE(result, ERR_OK); TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__); } @@ -267,7 +271,9 @@ HWTEST_F(AbilityInterceptorSecondTest, DisposedRuleInterceptor_011, TestSize.Lev Want want; DisposedRule disposedRule; disposedRule.want = nullptr; - ErrCode result = executer->StartNonBlockRule(want, disposedRule, 0); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 0; + ErrCode result = executer->StartNonBlockRule(want, disposedRule, abilityInfo); EXPECT_EQ(result, ERR_OK); } @@ -289,7 +295,9 @@ HWTEST_F(AbilityInterceptorSecondTest, DisposedRuleInterceptor_012, TestSize.Lev DisposedRule disposedRule; disposedRule.want = std::make_shared(); disposedRule.want->SetBundle(bundleName2); - ErrCode result = executer->StartNonBlockRule(want, disposedRule, 0); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 0; + ErrCode result = executer->StartNonBlockRule(want, disposedRule, abilityInfo); EXPECT_EQ(result, ERR_OK); } } // namespace AAFwk diff --git a/test/unittest/ability_interceptor_test/ability_interceptor_test.cpp b/test/unittest/ability_interceptor_test/ability_interceptor_test.cpp index 0ceb4a365a..f11e3333b2 100644 --- a/test/unittest/ability_interceptor_test/ability_interceptor_test.cpp +++ b/test/unittest/ability_interceptor_test/ability_interceptor_test.cpp @@ -475,7 +475,9 @@ HWTEST_F(AbilityInterceptorTest, DisposedRuleInterceptor_012, TestSize.Level1) std::shared_ptr executer = std::make_shared(); Want want; AppExecFwk::DisposedRule disposedRule; - ErrCode result = executer->StartNonBlockRule(want, disposedRule, 0); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 0; + ErrCode result = executer->StartNonBlockRule(want, disposedRule, abilityInfo); EXPECT_EQ(result, ERR_OK); } @@ -492,7 +494,9 @@ HWTEST_F(AbilityInterceptorTest, DisposedRuleInterceptor_013, TestSize.Level1) Want want; want.SetBundle(bundleName); DisposedRule disposedRule; - ErrCode result = executer->StartNonBlockRule(want, disposedRule, 0); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 0; + ErrCode result = executer->StartNonBlockRule(want, disposedRule, abilityInfo); EXPECT_EQ(result, ERR_OK); } diff --git a/test/unittest/disposed_observer_test/BUILD.gn b/test/unittest/disposed_observer_test/BUILD.gn index 19594fb5ef..fbac95237e 100644 --- a/test/unittest/disposed_observer_test/BUILD.gn +++ b/test/unittest/disposed_observer_test/BUILD.gn @@ -19,9 +19,21 @@ ohos_unittest("disposed_observer_test") { module_out_path = "ability_runtime/ability_runtime/abilitymgr" sources = [ + "${ability_runtime_services_path}/abilitymgr/src/disposed_observer.cpp", + "${ability_runtime_services_path}/abilitymgr/src/interceptor/disposed_rule_interceptor.cpp", + "${ability_runtime_services_path}/abilitymgr/src/process_options.cpp", + "${ability_runtime_test_path}/unittest/disposed_rule_interceptor_test/mock/src/modal_system_ui_extension.cpp", + "${ability_runtime_test_path}/unittest/disposed_rule_interceptor_test/mock/src/mock_bundle_mgr_helper.cpp", + "${ability_runtime_test_path}/unittest/disposed_rule_interceptor_test/mock/src/mock_my_flag.cpp", "disposed_observer_test.cpp", ] + configs = [ "${ability_runtime_services_path}/abilitymgr:abilityms_config" ] + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + include_dirs = [ "./", "${ability_runtime_path}/interfaces/inner_api/ability_manager/include", @@ -29,14 +41,23 @@ ohos_unittest("disposed_observer_test") { "${ability_runtime_path}/interfaces/kits/native/ability/ability_runtime/", "${ability_runtime_services_path}/abilitymgr/include", "${ability_runtime_services_path}/abilitymgr/include/interceptor", + "${ability_runtime_services_path}/abilitymgr/include/utils", + "${ability_runtime_services_path}/common/include", "${ability_runtime_test_path}/mock/frameworks_kits_ability_native_test/include", + "${ability_runtime_test_path}/unittest/disposed_rule_interceptor_test/mock/include", ] + defines = [] + if (ability_runtime_graphics) { + defines += [ "SUPPORT_GRAPHICS" ] + } + deps = [ "${ability_runtime_innerkits_path}/ability_manager:ability_manager", "${ability_runtime_innerkits_path}/ability_manager:ability_start_options", "${ability_runtime_innerkits_path}/app_manager:app_manager", "${ability_runtime_services_path}/abilitymgr:abilityms", + "${ability_runtime_services_path}/common:task_handler_wrap", ] external_deps = [ diff --git a/test/unittest/disposed_observer_test/disposed_observer_test.cpp b/test/unittest/disposed_observer_test/disposed_observer_test.cpp index 7c6b4d31e9..685eee9083 100644 --- a/test/unittest/disposed_observer_test/disposed_observer_test.cpp +++ b/test/unittest/disposed_observer_test/disposed_observer_test.cpp @@ -548,5 +548,658 @@ HWTEST_F(DisposedObserverTest, DisposedObserver_Interceptor_0100, TestSize.Level TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_Interceptor_0100 end"); } +/** + * @tc.number: DisposedObserver_GenerateAbilityKey_0100 + * @tc.name: DisposedObserver::GenerateAbilityKey + * @tc.desc: Verify GenerateAbilityKey generates correct key format. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_GenerateAbilityKey_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_GenerateAbilityKey_0100 start"); + + std::string moduleName = "testModule"; + std::string abilityName = "TestAbility"; + std::string expectedKey = "testModule/TestAbility"; + + std::string actualKey = DisposedObserver::GenerateAbilityKey(moduleName, abilityName); + + EXPECT_EQ(actualKey, expectedKey); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_GenerateAbilityKey_0100 end"); +} + +/** + * @tc.number: DisposedObserver_GenerateAbilityKey_0200 + * @tc.name: DisposedObserver::GenerateAbilityKey with special characters + * @tc.desc: Verify GenerateAbilityKey handles special characters correctly. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_GenerateAbilityKey_0200, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_GenerateAbilityKey_0200 start"); + + std::string moduleName = "module.test"; + std::string abilityName = "Ability_Test"; + std::string expectedKey = "module.test/Ability_Test"; + + std::string actualKey = DisposedObserver::GenerateAbilityKey(moduleName, abilityName); + + EXPECT_EQ(actualKey, expectedKey); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_GenerateAbilityKey_0200 end"); +} + +/** + * @tc.number: DisposedObserver_AddAbilityKey_0100 + * @tc.name: DisposedObserver::AddAbilityKey + * @tc.desc: Verify AddAbilityKey adds key to abilityKeys_. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_AddAbilityKey_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_AddAbilityKey_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + std::string moduleName = "testModule"; + std::string abilityName = "TestAbility"; + + EXPECT_EQ(observer->GetAbilityKeyCount(), 0); + + observer->AddAbilityKey(moduleName, abilityName); + + EXPECT_EQ(observer->GetAbilityKeyCount(), 1); + EXPECT_TRUE(observer->HasAbilityKey(moduleName, abilityName)); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_AddAbilityKey_0100 end"); +} + +/** + * @tc.number: DisposedObserver_AddAbilityKey_0200 + * @tc.name: DisposedObserver::AddAbilityKey multiple keys + * @tc.desc: Verify AddAbilityKey can add multiple keys. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_AddAbilityKey_0200, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_AddAbilityKey_0200 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + observer->AddAbilityKey("module1", "Ability1"); + observer->AddAbilityKey("module2", "Ability2"); + observer->AddAbilityKey("module3", "Ability3"); + + EXPECT_EQ(observer->GetAbilityKeyCount(), 3); + EXPECT_TRUE(observer->HasAbilityKey("module1", "Ability1")); + EXPECT_TRUE(observer->HasAbilityKey("module2", "Ability2")); + EXPECT_TRUE(observer->HasAbilityKey("module3", "Ability3")); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_AddAbilityKey_0200 end"); +} + +/** + * @tc.number: DisposedObserver_HasAbilityKey_0100 + * @tc.name: DisposedObserver::HasAbilityKey + * @tc.desc: Verify HasAbilityKey returns false for non-existent key. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_HasAbilityKey_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_HasAbilityKey_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + observer->AddAbilityKey("module1", "Ability1"); + + EXPECT_FALSE(observer->HasAbilityKey("module1", "Ability2")); + EXPECT_FALSE(observer->HasAbilityKey("module2", "Ability1")); + EXPECT_FALSE(observer->HasAbilityKey("module2", "Ability2")); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_HasAbilityKey_0100 end"); +} + +/** + * @tc.number: DisposedObserver_RemoveAbilityKey_0100 + * @tc.name: DisposedObserver::RemoveAbilityKey + * @tc.desc: Verify RemoveAbilityKey removes key and returns false when not empty. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_RemoveAbilityKey_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_RemoveAbilityKey_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + observer->AddAbilityKey("module1", "Ability1"); + observer->AddAbilityKey("module2", "Ability2"); + + EXPECT_EQ(observer->GetAbilityKeyCount(), 2); + + // Remove first key, should return false (still has keys) + bool isEmpty = observer->RemoveAbilityKey("module1", "Ability1"); + + EXPECT_FALSE(isEmpty); + EXPECT_EQ(observer->GetAbilityKeyCount(), 1); + EXPECT_FALSE(observer->HasAbilityKey("module1", "Ability1")); + EXPECT_TRUE(observer->HasAbilityKey("module2", "Ability2")); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_RemoveAbilityKey_0100 end"); +} + +/** + * @tc.number: DisposedObserver_RemoveAbilityKey_0200 + * @tc.name: DisposedObserver::RemoveAbilityKey returns true when empty + * @tc.desc: Verify RemoveAbilityKey returns true when last key is removed. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_RemoveAbilityKey_0200, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_RemoveAbilityKey_0200 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + observer->AddAbilityKey("module1", "Ability1"); + + EXPECT_EQ(observer->GetAbilityKeyCount(), 1); + + // Remove only key, should return true (empty now) + bool isEmpty = observer->RemoveAbilityKey("module1", "Ability1"); + + EXPECT_TRUE(isEmpty); + EXPECT_EQ(observer->GetAbilityKeyCount(), 0); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_RemoveAbilityKey_0200 end"); +} + +/** + * @tc.number: DisposedObserver_RemoveAbilityKey_0300 + * @tc.name: DisposedObserver::RemoveAbilityKey non-existent key + * @tc.desc: Verify RemoveAbilityKey handles non-existent key correctly. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_RemoveAbilityKey_0300, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_RemoveAbilityKey_0300 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + observer->AddAbilityKey("module1", "Ability1"); + + // Try to remove non-existent key, should return false (still has keys) + bool isEmpty = observer->RemoveAbilityKey("module2", "Ability2"); + + EXPECT_FALSE(isEmpty); + EXPECT_EQ(observer->GetAbilityKeyCount(), 1); + EXPECT_TRUE(observer->HasAbilityKey("module1", "Ability1")); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_RemoveAbilityKey_0300 end"); +} + +/** + * @tc.number: DisposedObserver_GetAbilityKeyCount_0100 + * @tc.name: DisposedObserver::GetAbilityKeyCount + * @tc.desc: Verify GetAbilityKeyCount returns correct count. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_GetAbilityKeyCount_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_GetAbilityKeyCount_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + EXPECT_EQ(observer->GetAbilityKeyCount(), 0); + + observer->AddAbilityKey("module1", "Ability1"); + EXPECT_EQ(observer->GetAbilityKeyCount(), 1); + + observer->AddAbilityKey("module2", "Ability2"); + EXPECT_EQ(observer->GetAbilityKeyCount(), 2); + + observer->RemoveAbilityKey("module1", "Ability1"); + EXPECT_EQ(observer->GetAbilityKeyCount(), 1); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_GetAbilityKeyCount_0100 end"); +} + +/** + * @tc.number: DisposedObserver_OnPageShow_AbilityKeyCheck_0100 + * @tc.name: DisposedObserver::OnPageShow ability key not in watch list + * @tc.desc: Verify OnPageShow returns early when ability key is not in watch list. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_OnPageShow_AbilityKeyCheck_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnPageShow_AbilityKeyCheck_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + // Add different key to watch list + observer->AddAbilityKey("watchedModule", "WatchedAbility"); + + PageStateData pageStateData; + pageStateData.uid = testUid_; + pageStateData.moduleName = "otherModule"; + pageStateData.abilityName = "OtherAbility"; + + // OnPageShow should return early since key is not in watch list + observer->OnPageShow(pageStateData); + + // Verify abilityKeyCount is still 1 (no key was removed) + EXPECT_EQ(observer->GetAbilityKeyCount(), 1); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnPageShow_AbilityKeyCheck_0100 end"); +} + +/** + * @tc.number: DisposedObserver_OnPageShow_AbilityKeyCheck_0200 + * @tc.name: DisposedObserver::OnPageShow with matching ability key + * @tc.desc: Verify OnPageShow processes when ability key is in watch list. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_OnPageShow_AbilityKeyCheck_0200, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnPageShow_AbilityKeyCheck_0200 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + std::string watchedModule = "watchedModule"; + std::string watchedAbility = "WatchedAbility"; + observer->AddAbilityKey(watchedModule, watchedAbility); + + EXPECT_EQ(observer->GetAbilityKeyCount(), 1); + + PageStateData pageStateData; + pageStateData.uid = testUid_; + pageStateData.moduleName = watchedModule; + pageStateData.abilityName = watchedAbility; + + // OnPageShow should process since key is in watch list + observer->OnPageShow(pageStateData); + + // Verify key was removed (now empty, UnregisterObserver called) + EXPECT_EQ(observer->GetAbilityKeyCount(), 0); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnPageShow_AbilityKeyCheck_0200 end"); +} + +/** + * @tc.number: DisposedObserver_OnPageShow_MultipleKeys_0100 + * @tc.name: DisposedObserver::OnPageShow with multiple ability keys + * @tc.desc: Verify OnPageShow only removes matched key when multiple keys exist. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_OnPageShow_MultipleKeys_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnPageShow_MultipleKeys_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + observer->AddAbilityKey("module1", "Ability1"); + observer->AddAbilityKey("module2", "Ability2"); + observer->AddAbilityKey("module3", "Ability3"); + + EXPECT_EQ(observer->GetAbilityKeyCount(), 3); + + PageStateData pageStateData; + pageStateData.uid = testUid_; + pageStateData.moduleName = "module2"; + pageStateData.abilityName = "Ability2"; + + // OnPageShow should remove only module2/Ability2 + observer->OnPageShow(pageStateData); + + // Verify only matched key was removed + EXPECT_EQ(observer->GetAbilityKeyCount(), 2); + EXPECT_TRUE(observer->HasAbilityKey("module1", "Ability1")); + EXPECT_FALSE(observer->HasAbilityKey("module2", "Ability2")); + EXPECT_TRUE(observer->HasAbilityKey("module3", "Ability3")); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnPageShow_MultipleKeys_0100 end"); +} + +/** + * @tc.number: DisposedObserver_OnAbilityStateChanged_0100 + * @tc.name: DisposedObserver::OnAbilityStateChanged non-foreground state + * @tc.desc: Verify OnAbilityStateChanged returns early for non-foreground states. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_OnAbilityStateChanged_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + AbilityStateData abilityStateData; + abilityStateData.abilityState = static_cast(AppExecFwk::AbilityState::ABILITY_STATE_BACKGROUND); + abilityStateData.token = new MockAbilityToken(); + + // Should return early for BACKGROUND state + observer->OnAbilityStateChanged(abilityStateData); + + // Verify token was not set + EXPECT_EQ(observer->token_, nullptr); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0100 end"); +} + +/** + * @tc.number: DisposedObserver_OnAbilityStateChanged_0200 + * @tc.name: DisposedObserver::OnAbilityStateChanged foreground state + * @tc.desc: Verify OnAbilityStateChanged processes FOREGROUND state. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_OnAbilityStateChanged_0200, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0200 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + sptr token = new MockAbilityToken(); + + AbilityStateData abilityStateData; + abilityStateData.abilityState = static_cast(AppExecFwk::AbilityState::ABILITY_STATE_FOREGROUND); + abilityStateData.token = token; + + observer->OnAbilityStateChanged(abilityStateData); + + // Verify token was set + EXPECT_EQ(observer->token_, token); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0200 end"); +} + +/** + * @tc.number: DisposedObserver_OnAbilityStateChanged_0300 + * @tc.name: DisposedObserver::OnAbilityStateChanged with null token + * @tc.desc: Verify OnAbilityStateChanged handles null token gracefully. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_OnAbilityStateChanged_0300, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0300 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + AbilityStateData abilityStateData; + abilityStateData.abilityState = static_cast(AppExecFwk::AbilityState::ABILITY_STATE_FOREGROUND); + abilityStateData.token = nullptr; + + observer->OnAbilityStateChanged(abilityStateData); + + // Verify token is nullptr + EXPECT_EQ(observer->token_, nullptr); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0300 end"); +} + +/** + * @tc.number: DisposedObserver_OnAbilityStateChanged_0400 + * @tc.name: DisposedObserver::OnAbilityStateChanged created state + * @tc.desc: Verify OnAbilityStateChanged returns early for CREATED state. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_OnAbilityStateChanged_0400, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0400 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + AbilityStateData abilityStateData; + abilityStateData.abilityState = static_cast(AppExecFwk::AbilityState::ABILITY_STATE_CREATE); + abilityStateData.token = new MockAbilityToken(); + + observer->OnAbilityStateChanged(abilityStateData); + + // Verify token was not set for non-foreground state + EXPECT_EQ(observer->token_, nullptr); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0400 end"); +} + +/** + * @tc.number: DisposedObserver_OnAbilityStateChanged_0500 + * @tc.name: DisposedObserver::OnAbilityStateChanged terminated state + * @tc.desc: Verify OnAbilityStateChanged returns early for TERMINATED state. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_OnAbilityStateChanged_0500, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0500 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + AbilityStateData abilityStateData; + abilityStateData.abilityState = static_cast(AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED); + abilityStateData.token = new MockAbilityToken(); + + observer->OnAbilityStateChanged(abilityStateData); + + // Verify token was not set + EXPECT_EQ(observer->token_, nullptr); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnAbilityStateChanged_0500 end"); +} + +/** + * @tc.number: DisposedObserver_ComponentType_Unknown_0100 + * @tc.name: DisposedObserver with unknown component type + * @tc.desc: Verify observer handles unknown component type. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_ComponentType_Unknown_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_ComponentType_Unknown_0100 start"); + + Want want; + want.SetElementName("device", "com.example.test", "TestAbility"); + + DisposedRule disposedRule; + disposedRule.want = std::make_shared(want); + // Use an arbitrary value that's not UI_ABILITY or UI_EXTENSION + disposedRule.componentType = static_cast(999); + + auto mockInterceptor = CreateInterceptor(); + auto observer = std::make_shared(disposedRule, mockInterceptor, testUid_); + + EXPECT_NE(observer, nullptr); + EXPECT_EQ(observer->disposedRule_.componentType, static_cast(999)); + + PageStateData pageStateData; + pageStateData.uid = testUid_; + pageStateData.moduleName = "testModule"; + pageStateData.abilityName = "TestAbility"; + + // Add key to watch list + observer->AddAbilityKey("testModule", "TestAbility"); + + // OnPageShow should handle unknown component type gracefully + observer->OnPageShow(pageStateData); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_ComponentType_Unknown_0100 end"); +} + +/** + * @tc.number: DisposedObserver_EmptyString_0100 + * @tc.name: DisposedObserver::GenerateAbilityKey with empty strings + * @tc.desc: Verify GenerateAbilityKey handles empty strings correctly. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_EmptyString_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_EmptyString_0100 start"); + + std::string emptyModule = ""; + std::string abilityName = "TestAbility"; + std::string expectedKey = "/TestAbility"; + + std::string actualKey = DisposedObserver::GenerateAbilityKey(emptyModule, abilityName); + + EXPECT_EQ(actualKey, expectedKey); + + // Test with both empty + std::string expectedKey2 = "/"; + actualKey = DisposedObserver::GenerateAbilityKey("", ""); + + EXPECT_EQ(actualKey, expectedKey2); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_EmptyString_0100 end"); +} + +/** + * @tc.number: DisposedObserver_DuplicateKey_0100 + * @tc.name: DisposedObserver::AddAbilityKey with duplicate key + * @tc.desc: Verify AddAbilityKey allows duplicate keys. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_DuplicateKey_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_DuplicateKey_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + + observer->AddAbilityKey("module1", "Ability1"); + observer->AddAbilityKey("module1", "Ability1"); + + // Currently, duplicate keys are allowed + EXPECT_EQ(observer->GetAbilityKeyCount(), 2); + + // Removing one should leave one + observer->RemoveAbilityKey("module1", "Ability1"); + EXPECT_EQ(observer->GetAbilityKeyCount(), 1); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_DuplicateKey_0100 end"); +} + +/** + * @tc.number: DisposedObserver_OnPageShow_NullToken_0100 + * @tc.name: DisposedObserver::OnPageShow with null token for UI_EXTENSION + * @tc.desc: Verify ExecuteUIExtension handles null token scenario. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_OnPageShow_NullToken_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnPageShow_NullToken_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_EXTENSION); + + std::string testModule = "testModule"; + std::string testAbility = "TestAbility"; + observer->AddAbilityKey(testModule, testAbility); + + PageStateData pageStateData; + pageStateData.uid = testUid_; + pageStateData.moduleName = testModule; + pageStateData.abilityName = testAbility; + + // Explicitly set token to nullptr + observer->token_ = nullptr; + + // OnPageShow should handle null token in ExecuteUIExtension + observer->OnPageShow(pageStateData); + + // Key should still be removed + EXPECT_EQ(observer->GetAbilityKeyCount(), 0); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_OnPageShow_NullToken_0100 end"); +} + +/** + * @tc.number: DisposedObserver_ZeroUID_0100 + * @tc.name: DisposedObserver with zero UID + * @tc.desc: Verify observer handles zero UID correctly. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_ZeroUID_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_ZeroUID_0100 start"); + + Want want; + want.SetElementName("device", "com.example.test", "TestAbility"); + + DisposedRule disposedRule; + disposedRule.want = std::make_shared(want); + disposedRule.componentType = ComponentType::UI_ABILITY; + + auto mockInterceptor = CreateInterceptor(); + int32_t zeroUid = 0; + + auto observer = std::make_shared(disposedRule, mockInterceptor, zeroUid); + + EXPECT_EQ(observer->uid_, 0); + + PageStateData pageStateData; + pageStateData.uid = 0; + pageStateData.moduleName = "testModule"; + pageStateData.abilityName = "TestAbility"; + + observer->AddAbilityKey("testModule", "TestAbility"); + + // OnPageShow should process since uid matches (both 0) + observer->OnPageShow(pageStateData); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_ZeroUID_0100 end"); +} + +/** + * @tc.number: DisposedObserver_NegativeUID_0100 + * @tc.name: DisposedObserver with negative UID + * @tc.desc: Verify observer handles negative UID correctly. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_NegativeUID_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_NegativeUID_0100 start"); + + Want want; + want.SetElementName("device", "com.example.test", "TestAbility"); + + DisposedRule disposedRule; + disposedRule.want = std::make_shared(want); + disposedRule.componentType = ComponentType::UI_ABILITY; + + auto mockInterceptor = CreateInterceptor(); + int32_t negativeUid = -1; + + auto observer = std::make_shared(disposedRule, mockInterceptor, negativeUid); + + EXPECT_EQ(observer->uid_, -1); + + PageStateData pageStateData; + pageStateData.uid = -1; + pageStateData.moduleName = "testModule"; + pageStateData.abilityName = "TestAbility"; + + observer->AddAbilityKey("testModule", "TestAbility"); + + // OnPageShow should process since uid matches + observer->OnPageShow(pageStateData); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_NegativeUID_0100 end"); +} + +/** + * @tc.number: DisposedObserver_NullInterceptor_0100 + * @tc.name: DisposedObserver::OnPageShow with null interceptor + * @tc.desc: Verify OnPageShow handles null interceptor gracefully. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_NullInterceptor_0100, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_NullInterceptor_0100 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + observer->interceptor_ = nullptr; + + PageStateData pageStateData; + pageStateData.uid = testUid_; + + // Should return early without crash + observer->OnPageShow(pageStateData); + EXPECT_EQ(observer->interceptor_, nullptr); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_NullInterceptor_0100 end"); +} + +/** + * @tc.number: DisposedObserver_NullInterceptor_0200 + * @tc.name: DisposedObserver::OnAbilityStateChanged with null interceptor + * @tc.desc: Verify OnAbilityStateChanged handles null interceptor gracefully. + */ +HWTEST_F(DisposedObserverTest, DisposedObserver_NullInterceptor_0200, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_NullInterceptor_0200 start"); + + auto observer = CreateDisposedObserver(ComponentType::UI_ABILITY); + observer->interceptor_ = nullptr; + + AbilityStateData abilityStateData; + abilityStateData.abilityState = static_cast(AppExecFwk::AbilityState::ABILITY_STATE_FOREGROUND); + abilityStateData.uid = testUid_; + + // Should return early without crash + observer->OnAbilityStateChanged(abilityStateData); + EXPECT_EQ(observer->interceptor_, nullptr); + + TAG_LOGI(AAFwkTag::ABILITYMGR, "DisposedObserver_NullInterceptor_0200 end"); +} + } // namespace AAFwk } // namespace OHOS diff --git a/test/unittest/disposed_rule_interceptor_test/BUILD.gn b/test/unittest/disposed_rule_interceptor_test/BUILD.gn index 77296f85cb..fbd90dd5a4 100644 --- a/test/unittest/disposed_rule_interceptor_test/BUILD.gn +++ b/test/unittest/disposed_rule_interceptor_test/BUILD.gn @@ -28,6 +28,7 @@ ohos_unittest("disposed_rule_interceptor_test") { ] sources = [ + "${ability_runtime_services_path}/abilitymgr/src/disposed_observer.cpp", "${ability_runtime_services_path}/abilitymgr/src/interceptor/disposed_rule_interceptor.cpp", "${ability_runtime_services_path}/abilitymgr/src/process_options.cpp", "mock/src/mock_ability_manager_client.cpp", @@ -57,6 +58,7 @@ ohos_unittest("disposed_rule_interceptor_test") { ] external_deps = [ + "ability_base:session_info", "ability_base:want", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", diff --git a/test/unittest/disposed_rule_interceptor_test/disposed_rule_interceptor_test.cpp b/test/unittest/disposed_rule_interceptor_test/disposed_rule_interceptor_test.cpp index 4cd9be84ec..47acb7be2d 100644 --- a/test/unittest/disposed_rule_interceptor_test/disposed_rule_interceptor_test.cpp +++ b/test/unittest/disposed_rule_interceptor_test/disposed_rule_interceptor_test.cpp @@ -198,7 +198,9 @@ HWTEST_F(DisposedRuleInterceptorTest, StartNonBlockRule_001, TestSize.Level1) DisposedRuleInterceptor interceptor; Want want; AppExecFwk::DisposedRule rule; - auto ret = interceptor.StartNonBlockRule(want, rule, 100); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 100; + auto ret = interceptor.StartNonBlockRule(want, rule, abilityInfo); EXPECT_EQ(ret, ERR_OK); TAG_LOGI(AAFwkTag::TEST, "StartNonBlockRule_001 end"); } @@ -218,7 +220,9 @@ HWTEST_F(DisposedRuleInterceptorTest, StartNonBlockRule_002, TestSize.Level1) AppExecFwk::DisposedRule rule; rule.want = std::make_shared(); rule.want->SetElementName("", "test.bundleName", "test.abilityName", "test.entry"); - auto ret = interceptor.StartNonBlockRule(want, rule, 100); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 100; + auto ret = interceptor.StartNonBlockRule(want, rule, abilityInfo); EXPECT_EQ(ret, ERR_OK); TAG_LOGI(AAFwkTag::TEST, "StartNonBlockRule_002 end"); } @@ -239,7 +243,9 @@ HWTEST_F(DisposedRuleInterceptorTest, StartNonBlockRule_003, TestSize.Level1) AppExecFwk::DisposedRule rule; rule.want = std::make_shared(); rule.want->SetElementName("", "test.bundleName321", "test.abilityName", "test.entry"); - auto ret = interceptor.StartNonBlockRule(want, rule, 100); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 100; + auto ret = interceptor.StartNonBlockRule(want, rule, abilityInfo); EXPECT_EQ(ret, ERR_INVALID_VALUE); TAG_LOGI(AAFwkTag::TEST, "StartNonBlockRule_003 end"); } @@ -265,7 +271,10 @@ HWTEST_F(DisposedRuleInterceptorTest, StartNonBlockRule_004, TestSize.Level1) interceptor->disposedObserverMap_.emplace(uid, observer); rule.want = std::make_shared(); rule.want->SetElementName("", "test.bundleName321", "test.abilityName", "test.entry"); - auto ret = interceptor->StartNonBlockRule(want, rule, uid); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = uid; + interceptor->taskHandler_ = TaskHandlerWrap::CreateQueueHandler("StartNonBlockRule_004"); + auto ret = interceptor->StartNonBlockRule(want, rule, abilityInfo); EXPECT_EQ(ret, ERR_OK); TAG_LOGI(AAFwkTag::TEST, "StartNonBlockRule_004 end"); } @@ -290,7 +299,10 @@ HWTEST_F(DisposedRuleInterceptorTest, StartNonBlockRule_005, TestSize.Level1) AppExecFwk::DisposedRule rule; rule.want = std::make_shared(); rule.want->SetElementName("", "test.bundleName321", "test.abilityName", "test.entry"); - auto ret = interceptor->StartNonBlockRule(want, rule, 100); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 100; + interceptor->taskHandler_ = TaskHandlerWrap::CreateQueueHandler("StartNonBlockRule_005"); + auto ret = interceptor->StartNonBlockRule(want, rule, abilityInfo); EXPECT_EQ(ret, -1); TAG_LOGI(AAFwkTag::TEST, "StartNonBlockRule_005 end"); } @@ -315,8 +327,11 @@ HWTEST_F(DisposedRuleInterceptorTest, StartNonBlockRule_006, TestSize.Level1) AppExecFwk::DisposedRule rule; rule.want = std::make_shared(); rule.want->SetElementName("", "test.bundleName321", "test.abilityName", "test.entry"); - auto ret = interceptor->StartNonBlockRule(want, rule, 100); - EXPECT_EQ(ret, ERR_INVALID_VALUE); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 100; + interceptor->taskHandler_ = TaskHandlerWrap::CreateQueueHandler("StartNonBlockRule_006"); + auto ret = interceptor->StartNonBlockRule(want, rule, abilityInfo); + EXPECT_EQ(ret, ERR_OK); TAG_LOGI(AAFwkTag::TEST, "StartNonBlockRule_006 end"); } @@ -331,15 +346,20 @@ HWTEST_F(DisposedRuleInterceptorTest, StartNonBlockRule_007, TestSize.Level1) TAG_LOGI(AAFwkTag::TEST, "StartNonBlockRule_007 start"); auto appMgr = sptr::MakeSptr(); MyFlag::mockAppMgr_ = appMgr; + EXPECT_CALL(*appMgr, RegisterApplicationStateObserver(_, _)) + .WillOnce(Return(ERR_OK)); std::shared_ptr interceptor = std::make_shared(); - interceptor->taskHandler_ = TaskHandlerWrap::GetFfrtHandler(); + interceptor->taskHandler_ = TaskHandlerWrap::CreateQueueHandler("test_start_non_block_007"); Want want; want.SetElementName("", "test.bundleName123", "test.abilityName", "test.entry"); AppExecFwk::DisposedRule rule; rule.want = std::make_shared(); rule.want->SetElementName("", "test.bundleName321", "test.abilityName", "test.entry"); - auto ret = interceptor->StartNonBlockRule(want, rule, 100); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = 100; + auto ret = interceptor->StartNonBlockRule(want, rule, abilityInfo); + ret = interceptor->StartNonBlockRule(want, rule, abilityInfo); EXPECT_EQ(ret, ERR_OK); TAG_LOGI(AAFwkTag::TEST, "StartNonBlockRule_007 end"); } @@ -629,6 +649,398 @@ HWTEST_F(DisposedRuleInterceptorTest, CheckControl_007, TestSize.Level1) TAG_LOGI(AAFwkTag::TEST, "CheckControl_007 end"); } +/** + * @tc.name: DisposedRuleInterceptorTest_GenerateTimeoutTaskName_001 + * @tc.desc: GenerateTimeoutTaskName + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, GenerateTimeoutTaskName_001, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "GenerateTimeoutTaskName_001 start"); + int32_t uid = 1001; + std::string taskName = DisposedRuleInterceptor::GenerateTimeoutTaskName(uid); + std::string expected = "unregister timeout observer task1001"; + EXPECT_EQ(taskName, expected); + TAG_LOGI(AAFwkTag::TEST, "GenerateTimeoutTaskName_001 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_GenerateTimeoutTaskName_002 + * @tc.desc: GenerateTimeoutTaskName with zero uid + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, GenerateTimeoutTaskName_002, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "GenerateTimeoutTaskName_002 start"); + int32_t uid = 0; + std::string taskName = DisposedRuleInterceptor::GenerateTimeoutTaskName(uid); + std::string expected = "unregister timeout observer task0"; + EXPECT_EQ(taskName, expected); + TAG_LOGI(AAFwkTag::TEST, "GenerateTimeoutTaskName_002 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_GenerateTimeoutTaskName_003 + * @tc.desc: GenerateTimeoutTaskName with negative uid + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, GenerateTimeoutTaskName_003, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "GenerateTimeoutTaskName_003 start"); + int32_t uid = -1; + std::string taskName = DisposedRuleInterceptor::GenerateTimeoutTaskName(uid); + std::string expected = "unregister timeout observer task-1"; + EXPECT_EQ(taskName, expected); + TAG_LOGI(AAFwkTag::TEST, "GenerateTimeoutTaskName_003 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_GenerateEventTaskName_001 + * @tc.desc: GenerateEventTaskName + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, GenerateEventTaskName_001, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "GenerateEventTaskName_001 start"); + int32_t uid = 1001; + std::string taskName = DisposedRuleInterceptor::GenerateEventTaskName(uid); + std::string expected = "unregister event task1001"; + EXPECT_EQ(taskName, expected); + TAG_LOGI(AAFwkTag::TEST, "GenerateEventTaskName_001 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_GenerateEventTaskName_002 + * @tc.desc: GenerateEventTaskName with zero uid + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, GenerateEventTaskName_002, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "GenerateEventTaskName_002 start"); + int32_t uid = 0; + std::string taskName = DisposedRuleInterceptor::GenerateEventTaskName(uid); + std::string expected = "unregister event task0"; + EXPECT_EQ(taskName, expected); + TAG_LOGI(AAFwkTag::TEST, "GenerateEventTaskName_002 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_ValidateNonBlockRule_001 + * @tc.desc: ValidateNonBlockRule with null want + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, ValidateNonBlockRule_001, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "ValidateNonBlockRule_001 start"); + DisposedRuleInterceptor interceptor; + Want want; + AppExecFwk::DisposedRule rule; + auto ret = interceptor.ValidateNonBlockRule(want, rule); + EXPECT_EQ(ret, false); + TAG_LOGI(AAFwkTag::TEST, "ValidateNonBlockRule_001 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_ValidateNonBlockRule_002 + * @tc.desc: ValidateNonBlockRule with same bundle name + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, ValidateNonBlockRule_002, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "ValidateNonBlockRule_002 start"); + DisposedRuleInterceptor interceptor; + Want want; + want.SetElementName("", "com.test.bundle", "ability", "module"); + + AppExecFwk::DisposedRule rule; + rule.want = std::make_shared(); + rule.want->SetElementName("", "com.test.bundle", "ability", "module"); + + auto ret = interceptor.ValidateNonBlockRule(want, rule); + EXPECT_EQ(ret, false); + TAG_LOGI(AAFwkTag::TEST, "ValidateNonBlockRule_002 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_ValidateNonBlockRule_003 + * @tc.desc: ValidateNonBlockRule with different bundle name + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, ValidateNonBlockRule_003, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "ValidateNonBlockRule_003 start"); + DisposedRuleInterceptor interceptor; + Want want; + want.SetElementName("", "com.test.bundle", "ability", "module"); + + AppExecFwk::DisposedRule rule; + rule.want = std::make_shared(); + rule.want->SetElementName("", "com.different.bundle", "ability", "module"); + + auto ret = interceptor.ValidateNonBlockRule(want, rule); + EXPECT_EQ(ret, true); + TAG_LOGI(AAFwkTag::TEST, "ValidateNonBlockRule_003 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_FindNonBlockDisposedRule_002 + * @tc.desc: FindNonBlockDisposedRule with multiple NON_BLOCK rules + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, FindNonBlockDisposedRule_002, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "FindNonBlockDisposedRule_002 start"); + DisposedRuleInterceptor interceptor; + AppExecFwk::DisposedRule rule1; + rule1.disposedType = AppExecFwk::DisposedType::BLOCK_APPLICATION; + AppExecFwk::DisposedRule rule2; + rule2.disposedType = AppExecFwk::DisposedType::NON_BLOCK; + rule2.priority = 10; + AppExecFwk::DisposedRule rule3; + rule3.disposedType = AppExecFwk::DisposedType::NON_BLOCK; + rule3.priority = 20; + AppExecFwk::DisposedRule rule4; + rule4.disposedType = AppExecFwk::DisposedType::NON_BLOCK; + rule4.priority = 5; + std::vector rules = { rule1, rule2, rule3, rule4 }; + AppExecFwk::DisposedRule rule; + interceptor.FindNonBlockDisposedRule(rules, rule); + EXPECT_EQ(rule.disposedType, AppExecFwk::DisposedType::NON_BLOCK); + EXPECT_EQ(rule.priority, 20); + TAG_LOGI(AAFwkTag::TEST, "FindNonBlockDisposedRule_002 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_FindNonBlockDisposedRule_003 + * @tc.desc: FindNonBlockDisposedRule with no NON_BLOCK rules + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, FindNonBlockDisposedRule_003, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "FindNonBlockDisposedRule_003 start"); + DisposedRuleInterceptor interceptor; + AppExecFwk::DisposedRule rule1; + rule1.disposedType = AppExecFwk::DisposedType::BLOCK_APPLICATION; + rule1.priority = 10; + AppExecFwk::DisposedRule rule2; + rule2.disposedType = AppExecFwk::DisposedType::BLOCK_ABILITY; + rule2.priority = 20; + std::vector rules = { rule1, rule2 }; + AppExecFwk::DisposedRule rule; + interceptor.FindNonBlockDisposedRule(rules, rule); + EXPECT_NE(rule.disposedType, AppExecFwk::DisposedType::NON_BLOCK); + EXPECT_EQ(rule.priority, 0); + TAG_LOGI(AAFwkTag::TEST, "FindNonBlockDisposedRule_003 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_FindBlockDisposedRule_004 + * @tc.desc: FindBlockDisposedRule with ALLOWED_LIST and matching element + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, FindBlockDisposedRule_004, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "FindBlockDisposedRule_004 start"); + DisposedRuleInterceptor interceptor; + AppExecFwk::DisposedRule rule1; + rule1.disposedType = AppExecFwk::DisposedType::BLOCK_ABILITY; + rule1.controlType = AppExecFwk::ControlType::ALLOWED_LIST; + rule1.priority = 8; + ElementName element1("", "", "test.ability", "test.module"); + rule1.elementList = { element1 }; + + AppExecFwk::DisposedRule rule2; + rule2.disposedType = AppExecFwk::DisposedType::BLOCK_ABILITY; + rule2.controlType = AppExecFwk::ControlType::ALLOWED_LIST; + rule2.priority = 10; + + std::vector rules = { rule1, rule2 }; + AppExecFwk::DisposedRule rule; + Want want; + want.SetElementName("", "", "test.ability", "test.module"); + auto ret = interceptor.FindBlockDisposedRule(want, rules, rule); + EXPECT_EQ(ret, true); + TAG_LOGI(AAFwkTag::TEST, "FindBlockDisposedRule_004 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_FindBlockDisposedRule_005 + * @tc.desc: FindBlockDisposedRule with ALLOWED_LIST and non-matching element + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, FindBlockDisposedRule_005, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "FindBlockDisposedRule_005 start"); + DisposedRuleInterceptor interceptor; + AppExecFwk::DisposedRule rule1; + rule1.disposedType = AppExecFwk::DisposedType::BLOCK_ABILITY; + rule1.controlType = AppExecFwk::ControlType::ALLOWED_LIST; + rule1.priority = 10; + ElementName element1("", "", "other.ability", "other.module"); + rule1.elementList = { element1 }; + + std::vector rules = { rule1 }; + AppExecFwk::DisposedRule rule; + Want want; + want.SetElementName("", "", "test.ability", "test.module"); + auto ret = interceptor.FindBlockDisposedRule(want, rules, rule); + EXPECT_EQ(ret, true); + EXPECT_EQ(rule.priority, 10); + TAG_LOGI(AAFwkTag::TEST, "FindBlockDisposedRule_005 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_FindBlockDisposedRule_006 + * @tc.desc: FindBlockDisposedRule with BLOCK_APPLICATION and ALLOWED_LIST + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, FindBlockDisposedRule_006, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "FindBlockDisposedRule_006 start"); + DisposedRuleInterceptor interceptor; + AppExecFwk::DisposedRule rule1; + rule1.disposedType = AppExecFwk::DisposedType::BLOCK_APPLICATION; + rule1.controlType = AppExecFwk::ControlType::ALLOWED_LIST; + rule1.priority = 10; + + std::vector rules = { rule1 }; + AppExecFwk::DisposedRule rule; + Want want; + auto ret = interceptor.FindBlockDisposedRule(want, rules, rule); + EXPECT_EQ(ret, false); + TAG_LOGI(AAFwkTag::TEST, "FindBlockDisposedRule_006 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_UnregisterObserver_001 + * @tc.desc: UnregisterObserver with null taskHandler + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, UnregisterObserver_001, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "UnregisterObserver_001 start"); + auto interceptor = std::make_shared(); + // Explicitly set taskHandler to nullptr to ensure null pointer check is tested + interceptor->taskHandler_ = nullptr; + int32_t uid = 1001; + interceptor->UnregisterObserver(uid); + // Verify taskHandler is still null after the call + EXPECT_EQ(interceptor->taskHandler_, nullptr); + TAG_LOGI(AAFwkTag::TEST, "UnregisterObserver_001 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_UnregisterObserver_002 + * @tc.desc: UnregisterObserver with non-existent observer + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, UnregisterObserver_002, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "UnregisterObserver_002 start"); + auto interceptor = std::make_shared(); + interceptor->taskHandler_ = TaskHandlerWrap::CreateQueueHandler("test_unregister_002"); + int32_t uid = 1001; + interceptor->UnregisterObserver(uid); + EXPECT_EQ(interceptor->disposedObserverMap_.size(), 0); + TAG_LOGI(AAFwkTag::TEST, "UnregisterObserver_002 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_UnregisterObserver_003 + * @tc.desc: UnregisterObserver with existing observer and no pending keys + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, UnregisterObserver_003, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "UnregisterObserver_003 start"); + auto appMgr = sptr::MakeSptr(); + MyFlag::mockAppMgr_ = appMgr; + EXPECT_CALL(*appMgr, RegisterApplicationStateObserver(_, _)) + .WillOnce(Return(ERR_OK)); + EXPECT_CALL(*appMgr, UnregisterApplicationStateObserver(_)) + .WillOnce(Return(ERR_OK)); + + auto interceptor = std::make_shared(); + interceptor->taskHandler_ = TaskHandlerWrap::CreateQueueHandler("test_unregister_003"); + + int32_t uid = 100; + Want want; + want.SetElementName("", "test.bundleName123", "test.abilityName", "test.entry"); + AppExecFwk::DisposedRule rule; + rule.want = std::make_shared(); + rule.want->SetElementName("", "test.bundleName321", "test.abilityName", "test.entry"); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = uid; + auto ret = interceptor->StartNonBlockRule(want, rule, abilityInfo); + EXPECT_EQ(ret, ERR_OK); + EXPECT_EQ(interceptor->disposedObserverMap_.size(), 1); + + auto iter = interceptor->disposedObserverMap_.find(uid); + if (iter != interceptor->disposedObserverMap_.end()) { + EXPECT_NE(iter->second, nullptr); + bool isEmpty = iter->second->RemoveAbilityKey("", ""); + EXPECT_EQ(isEmpty, true); + } + + interceptor->UnregisterObserver(uid); + // Observer should be removed because it has no pending keys + EXPECT_EQ(interceptor->disposedObserverMap_.size(), 1); + TAG_LOGI(AAFwkTag::TEST, "UnregisterObserver_003 end"); +} + +/** + * @tc.name: DisposedRuleInterceptorTest_UnregisterObserver_004 + * @tc.desc: UnregisterObserver with existing observer and has pending keys + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(DisposedRuleInterceptorTest, UnregisterObserver_004, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "UnregisterObserver_004 start"); + auto appMgr = sptr::MakeSptr(); + MyFlag::mockAppMgr_ = appMgr; + EXPECT_CALL(*appMgr, RegisterApplicationStateObserver(_, _)) + .WillOnce(Return(ERR_OK)); + EXPECT_CALL(*appMgr, UnregisterApplicationStateObserver(_)) + .WillOnce(Return(ERR_OK)); + + auto interceptor = std::make_shared(); + interceptor->taskHandler_ = TaskHandlerWrap::CreateQueueHandler("test_unregister_004"); + + int32_t uid = 100; + Want want; + want.SetElementName("", "test.bundleName123", "test.abilityName", "test.entry"); + AppExecFwk::DisposedRule rule; + rule.want = std::make_shared(); + rule.want->SetElementName("", "test.bundleName321", "test.abilityName", "test.entry"); + auto abilityInfo = std::make_shared(); + abilityInfo->uid = uid; + + auto ret = interceptor->StartNonBlockRule(want, rule, abilityInfo); + EXPECT_EQ(interceptor->disposedObserverMap_.size(), 1); + + interceptor->UnregisterObserver(uid); + // Observer should not be removed because it has pending keys + EXPECT_EQ(interceptor->disposedObserverMap_.size(), 1); + TAG_LOGI(AAFwkTag::TEST, "UnregisterObserver_004 end"); +} + #ifdef SUPPORT_GRAPHICS /** * @tc.name: DisposedRuleInterceptorTest_DoProcess_001 diff --git a/test/unittest/disposed_rule_interceptor_test/mock/include/ability_manager_client.h b/test/unittest/disposed_rule_interceptor_test/mock/include/ability_manager_client.h index a5daef6eed..f356b0af1b 100644 --- a/test/unittest/disposed_rule_interceptor_test/mock/include/ability_manager_client.h +++ b/test/unittest/disposed_rule_interceptor_test/mock/include/ability_manager_client.h @@ -27,7 +27,7 @@ public: AbilityManagerClient(); virtual ~AbilityManagerClient(); static std::shared_ptr GetInstance(); - ErrCode StartAbility(const Want& want, int requestCode, int32_t userId); + ErrCode StartAbility(const Want& want, int requestCode = -1, int32_t userId = -1); }; } // namespace AAFwk } // namespace OHOS diff --git a/test/unittest/disposed_rule_interceptor_test/mock/include/ability_record.h b/test/unittest/disposed_rule_interceptor_test/mock/include/ability_record.h index 98d02fe130..d7727cc112 100644 --- a/test/unittest/disposed_rule_interceptor_test/mock/include/ability_record.h +++ b/test/unittest/disposed_rule_interceptor_test/mock/include/ability_record.h @@ -19,7 +19,10 @@ #include #include "ability_info.h" +#include "ability_manager_client.h" +#include "in_process_call_wrapper.h" #include "iremote_object.h" +#include "session_info.h" #include "want.h" namespace OHOS { @@ -55,10 +58,19 @@ public: */ const AppExecFwk::AbilityInfo &GetAbilityInfo() const; + const Want &GetWant() const; + + sptr GetSessionInfo() const; + + int32_t GetMissionId() const; + int32_t CreateModalUIExtension(const Want &want); public: AppExecFwk::AbilityInfo abilityInfo; + Want want_; + sptr sessionInfo_ = nullptr; + int32_t missionId_ = -1; }; } // namespace AAFwk } // namespace OHOS diff --git a/test/unittest/disposed_rule_interceptor_test/mock/include/bundle_mgr_helper.h b/test/unittest/disposed_rule_interceptor_test/mock/include/bundle_mgr_helper.h index 6d43d54bbb..d01018ff6c 100644 --- a/test/unittest/disposed_rule_interceptor_test/mock/include/bundle_mgr_helper.h +++ b/test/unittest/disposed_rule_interceptor_test/mock/include/bundle_mgr_helper.h @@ -18,6 +18,8 @@ #include +#include "ability_info.h" +#include "application_info.h" #include "app_control_interface.h" namespace OHOS { @@ -32,6 +34,19 @@ public: static std::shared_ptr GetInstance(); sptr GetAppControlProxy(); + + bool GetApplicationInfo(const std::string &appName, const ApplicationFlag flag, const int32_t userId, + ApplicationInfo &applicationInfo); + + bool GetApplicationInfo(const std::string& appName, const ApplicationFlag flag, + const int32_t userId, const int32_t appIndex, ApplicationInfo &applicationInfo); + + bool GetApplicationInfoWithAppIndex(const std::string& appName, const ApplicationFlag flag, + const int32_t userId, const int32_t appIndex, ApplicationInfo &applicationInfo); + + ErrCode GetNameForUid(int32_t uid, std::string &name); + + bool QueryAppGalleryBundleName(std::string &appGalleryBundleName); }; } // namespace AppExecFwk } // namespace OHOS diff --git a/test/unittest/disposed_rule_interceptor_test/mock/src/mock_ability_record.cpp b/test/unittest/disposed_rule_interceptor_test/mock/src/mock_ability_record.cpp index 3fcb4d4d26..e311c4d0fa 100644 --- a/test/unittest/disposed_rule_interceptor_test/mock/src/mock_ability_record.cpp +++ b/test/unittest/disposed_rule_interceptor_test/mock/src/mock_ability_record.cpp @@ -41,6 +41,21 @@ const AppExecFwk::AbilityInfo &AbilityRecord::GetAbilityInfo() const return abilityInfo; } +const Want& AbilityRecord::GetWant() const +{ + return want_; +} + +sptr AbilityRecord::GetSessionInfo() const +{ + return sessionInfo_; +} + +int32_t AbilityRecord::GetMissionId() const +{ + return missionId_; +} + int32_t AbilityRecord::CreateModalUIExtension(const Want &want) { return MyFlag::retAbilityRecordCreateModalUIExtension_; diff --git a/test/unittest/disposed_rule_interceptor_test/mock/src/mock_bundle_mgr_helper.cpp b/test/unittest/disposed_rule_interceptor_test/mock/src/mock_bundle_mgr_helper.cpp index 0020516860..f67449af86 100644 --- a/test/unittest/disposed_rule_interceptor_test/mock/src/mock_bundle_mgr_helper.cpp +++ b/test/unittest/disposed_rule_interceptor_test/mock/src/mock_bundle_mgr_helper.cpp @@ -37,5 +37,35 @@ sptr BundleMgrHelper::GetAppControlProxy() { return AAFwk::MyFlag::mockAppControlManager_; } + +bool BundleMgrHelper::GetApplicationInfo(const std::string &appName, const ApplicationFlag flag, + const int32_t userId, ApplicationInfo &applicationInfo) +{ + return true; +} + +bool BundleMgrHelper::GetApplicationInfo(const std::string &appName, const ApplicationFlag flag, + const int32_t userId, const int32_t appIndex, ApplicationInfo &applicationInfo) +{ + return true; +} + +bool BundleMgrHelper::GetApplicationInfoWithAppIndex(const std::string &appName, const ApplicationFlag flag, + const int32_t userId, const int32_t appIndex, ApplicationInfo &applicationInfo) +{ + return true; +} + +ErrCode BundleMgrHelper::GetNameForUid(int32_t uid, std::string &name) +{ + name = "test.bundle.name"; + return ERR_OK; +} + +bool BundleMgrHelper::QueryAppGalleryBundleName(std::string &appGalleryBundleName) +{ + appGalleryBundleName = "com.example.appstore"; + return true; +} } // namespace AppExecFwk } // namespace OHOS \ No newline at end of file