From 336eb45759d945532efa318d1c1d2e70283dbd04 Mon Sep 17 00:00:00 2001 From: xhz-sz Date: Tue, 3 Mar 2026 19:55:20 +0800 Subject: [PATCH] add api Signed-off-by: xhz-sz Co-Authored-By: Agent --- frameworks/ets/ani/ability_manager/BUILD.gn | 1 + .../src/ets_ability_manager.cpp | 15 + .../ets/@ohos.app.ability.abilityManager.ets | 5 + frameworks/js/napi/ability_manager/BUILD.gn | 6 +- .../ability_manager/js_ability_manager.cpp | 17 + ..._extension_ability_manager_second_test.cpp | 325 ++++++++++++++++++ 6 files changed, 368 insertions(+), 1 deletion(-) diff --git a/frameworks/ets/ani/ability_manager/BUILD.gn b/frameworks/ets/ani/ability_manager/BUILD.gn index c2dcc6dbc4..8d83c60345 100644 --- a/frameworks/ets/ani/ability_manager/BUILD.gn +++ b/frameworks/ets/ani/ability_manager/BUILD.gn @@ -63,6 +63,7 @@ ohos_shared_library("ability_manager_ani_kit") { "${ability_runtime_native_path}/ability/native:abilitykit_native", "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common", + "${ability_runtime_services_path}/common:app_util", ] external_deps = [ diff --git a/frameworks/ets/ani/ability_manager/src/ets_ability_manager.cpp b/frameworks/ets/ani/ability_manager/src/ets_ability_manager.cpp index a6c005e591..eb0b9084bc 100644 --- a/frameworks/ets/ani/ability_manager/src/ets_ability_manager.cpp +++ b/frameworks/ets/ani/ability_manager/src/ets_ability_manager.cpp @@ -31,6 +31,7 @@ #include "ani_common_want.h" #include "ani_enum_convert.h" #include "app_mgr_interface.h" +#include "app_utils.h" #include "application_context.h" #include "ets_ability_foreground_state_observer.h" #include "ets_ability_manager_utils.h" @@ -126,6 +127,7 @@ public: static void CheckSystemApp(ani_env *env); static void GetTopAbilityCheck(ani_env *env); static void GetAbilityRunningInfos(ani_env *env, ani_object callback); + static ani_boolean IsEmbeddedUIExtensionSupported(ani_env *env); static void IsEmbeddedOpenAllowed(ani_env *env, ani_object contextObj, ani_string aniAppId, ani_object callbackObj); static void IsEmbeddedOpenAllowedCheck(ani_env *env, ani_object contextObj); static void NativeOn(ani_env *env, ani_string aniType, ani_object aniObserver); @@ -362,6 +364,17 @@ void EtsAbilityManager::IsEmbeddedOpenAllowedCheck(ani_env *env, ani_object cont } } +ani_boolean EtsAbilityManager::IsEmbeddedUIExtensionSupported(ani_env *env) +{ + TAG_LOGD(AAFwkTag::ABILITYMGR, "IsEmbeddedUIExtensionSupported"); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null env"); + return ANI_FALSE; + } + bool result = AAFwk::AppUtils::GetInstance().IsMultiProcessModel(); + return result ? ANI_TRUE : ANI_FALSE; +} + void EtsAbilityManager::IsEmbeddedOpenAllowed(ani_env *env, ani_object contextObj, ani_string aniAppId, ani_object callbackObj) { @@ -1119,6 +1132,8 @@ void EtsAbilityManagerRegistryInit(ani_env *env) reinterpret_cast(EtsAbilityManager::GetAbilityRunningInfos) }, ani_native_function { "nativeGetExtensionRunningInfos", "iC{utils.AbilityUtils.AsyncCallbackWrapper}:", reinterpret_cast(EtsAbilityManager::GetExtensionRunningInfos) }, + ani_native_function { "nativeIsEmbeddedUIExtensionSupported", ":z", + reinterpret_cast(EtsAbilityManager::IsEmbeddedUIExtensionSupported) }, ani_native_function { "nativeIsEmbeddedOpenAllowed", "C{application.Context.Context}C{std.core.String}C{utils.AbilityUtils.AsyncCallbackWrapper}:", reinterpret_cast(EtsAbilityManager::IsEmbeddedOpenAllowed) }, diff --git a/frameworks/ets/ets/@ohos.app.ability.abilityManager.ets b/frameworks/ets/ets/@ohos.app.ability.abilityManager.ets index 3989675e92..2fe6602b09 100644 --- a/frameworks/ets/ets/@ohos.app.ability.abilityManager.ets +++ b/frameworks/ets/ets/@ohos.app.ability.abilityManager.ets @@ -39,6 +39,7 @@ export default namespace abilityManager { export native function nativeCheckPreloadUIExtensionAbilityPermission() : void; export native function nativeGetTopAbilityCheck() : void; export native function nativeGetAbilityRunningInfos(callback:AsyncCallbackWrapper>) : void; + export native function nativeIsEmbeddedUIExtensionSupported() : boolean; export native function nativeIsEmbeddedOpenAllowed(context: Context, appId: string, callback:AsyncCallbackWrapper) : void; export native function nativeIsEmbeddedOpenAllowedCheck(context: Context): void; export native function nativeOn(type:string, observer: AbilityForegroundStateObserver): void; @@ -134,6 +135,10 @@ export default namespace abilityManager { }); } + function isEmbeddedUIExtensionSupported(): boolean { + return abilityManager.nativeIsEmbeddedUIExtensionSupported(); + } + function isEmbeddedOpenAllowed(context: Context, appId: string): Promise { abilityManager.nativeIsEmbeddedOpenAllowedCheck(context); return new Promise((resolve:(data:boolean)=>void, reject:(err: BusinessError)=>void):void => { diff --git a/frameworks/js/napi/ability_manager/BUILD.gn b/frameworks/js/napi/ability_manager/BUILD.gn index 23ac0138d2..f9d967724e 100644 --- a/frameworks/js/napi/ability_manager/BUILD.gn +++ b/frameworks/js/napi/ability_manager/BUILD.gn @@ -33,7 +33,10 @@ template("abilitymanager") { "js_preload_ui_extension_callback_client.cpp", ] - include_dirs = [ "./" ] + include_dirs = [ + "./", + "${ability_runtime_services_path}/common/include", + ] deps = [ "${ability_runtime_innerkits_path}/ability_manager:ability_manager", @@ -46,6 +49,7 @@ template("abilitymanager") { "${ability_runtime_native_path}/ability/native:ability_business_error", "${ability_runtime_native_path}/ability/native:abilitykit_native", "${ability_runtime_native_path}/appkit:app_context", + "${ability_runtime_services_path}/common:app_util", ] external_deps = [ diff --git a/frameworks/js/napi/ability_manager/js_ability_manager.cpp b/frameworks/js/napi/ability_manager/js_ability_manager.cpp index 6241e4205c..04a57e8a88 100644 --- a/frameworks/js/napi/ability_manager/js_ability_manager.cpp +++ b/frameworks/js/napi/ability_manager/js_ability_manager.cpp @@ -21,6 +21,7 @@ #include #include "ability_business_error.h" +#include "app_utils.h" #include "ability_manager_client.h" #include "accesstoken_kit.h" #include "acquire_share_data_callback_stub.h" @@ -125,6 +126,11 @@ public: GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnOff); } + static napi_value IsEmbeddedUIExtensionSupported(napi_env env, napi_callback_info info) + { + GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnIsEmbeddedUIExtensionSupported); + } + static napi_value IsEmbeddedOpenAllowed(napi_env env, napi_callback_info info) { GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnIsEmbeddedOpenAllowed); @@ -696,6 +702,15 @@ private: return handleEscape.Escape(result); } + napi_value OnIsEmbeddedUIExtensionSupported(napi_env env, NapiCallbackInfo& info) + { + TAG_LOGD(AAFwkTag::ABILITYMGR, "called"); + HandleEscape handleEscape(env); + bool isSupported = AAFwk::AppUtils::GetInstance().IsMultiProcessModel(); + napi_value result = CreateJsValue(env, isSupported); + return handleEscape.Escape(result); + } + napi_value OnIsEmbeddedOpenAllowed(napi_env env, NapiCallbackInfo& info) { TAG_LOGD(AAFwkTag::ABILITYMGR, "called"); @@ -1197,6 +1212,8 @@ napi_value JsAbilityManagerInit(napi_env env, napi_value exportObj) BindNativeFunction(env, exportObj, "on", moduleName, JsAbilityManager::On); BindNativeFunction(env, exportObj, "off", moduleName, JsAbilityManager::Off); BindNativeFunction(env, exportObj, "isEmbeddedOpenAllowed", moduleName, JsAbilityManager::IsEmbeddedOpenAllowed); + BindNativeFunction( + env, exportObj, "isEmbeddedUIExtensionSupported", moduleName, JsAbilityManager::IsEmbeddedUIExtensionSupported); BindNativeFunction( env, exportObj, "restartSelfAtomicService", moduleName, JsAbilityManager::RestartSelfAtomicService); BindNativeFunction( diff --git a/test/unittest/ui_extension_ability_manager_second_test/ui_extension_ability_manager_second_test.cpp b/test/unittest/ui_extension_ability_manager_second_test/ui_extension_ability_manager_second_test.cpp index 4f6d534c11..d01c1f19ee 100644 --- a/test/unittest/ui_extension_ability_manager_second_test/ui_extension_ability_manager_second_test.cpp +++ b/test/unittest/ui_extension_ability_manager_second_test/ui_extension_ability_manager_second_test.cpp @@ -1287,5 +1287,330 @@ HWTEST_F(UIExtensionAbilityManagerSecondTest, TerminateOrCacheAbility_001, TestS TAG_LOGI(AAFwkTag::TEST, "TerminateOrCacheAbility_001 end"); } +/* + * Feature: UIExtensionAbilityManager + * Function: DoForegroundUIExtension + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DoForegroundUIExtension with ability already in FOREGROUND state + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DoForegroundUIExtension_008, TestSize.Level1) +{ + TAG_LOGI(AAFwkTag::TEST, "DoForegroundUIExtension_008 start"); + std::shared_ptr connectManager = std::make_shared(0); + EXPECT_NE(connectManager, nullptr); + + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SYS_COMMON_UI; + abilityRequest.abilityInfo.bundleName = "com.test.uiextension"; + abilityRequest.abilityInfo.name = "TestUIExtension"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + EXPECT_NE(abilityRecord, nullptr); + + Rosen::SessionInfo info; + sptr sessionInfo(new SessionInfo()); + sessionInfo->sessionToken = sptr(new Rosen::Session(info)); + abilityRequest.sessionInfo = sessionInfo; + abilityRecord->sessionInfo_ = sessionInfo; + abilityRecord->SetAbilityState(AbilityState::FOREGROUND); + abilityRecord->abilityWindowStateMap_.clear(); // Window ready + + connectManager->DoForegroundUIExtension(abilityRecord, abilityRequest); + TAG_LOGI(AAFwkTag::TEST, "DoForegroundUIExtension_008 end"); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchForeground + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchForeground with UIExtension type and valid token + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchForeground_002, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SYS_COMMON_UI; + abilityRequest.abilityInfo.bundleName = "com.example.uiextension"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + Rosen::SessionInfo info; + sptr sessionInfo(new SessionInfo()); + sessionInfo->sessionToken = sptr(new Rosen::Session(info)); + abilityRecord->sessionInfo_ = sessionInfo; + sptr token = abilityRecord->GetToken(); + + auto ret = connectManager->DispatchForeground(abilityRecord, token); + EXPECT_EQ(ret, ERR_OK); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchForeground + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchForeground with non-UIExtension type + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchForeground_003, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SERVICE; + abilityRequest.abilityInfo.bundleName = "com.example.service"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + sptr token = abilityRecord->GetToken(); + + auto ret = connectManager->DispatchForeground(abilityRecord, token); + EXPECT_EQ(ret, ERR_OK); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchBackground + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchBackground with UIExtension type and valid token + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchBackground_001, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SYS_COMMON_UI; + abilityRequest.abilityInfo.bundleName = "com.example.uiextension"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + Rosen::SessionInfo info; + sptr sessionInfo(new SessionInfo()); + sessionInfo->sessionToken = sptr(new Rosen::Session(info)); + abilityRecord->sessionInfo_ = sessionInfo; + sptr token = abilityRecord->GetToken(); + + auto ret = connectManager->DispatchBackground(abilityRecord, token); + EXPECT_EQ(ret, ERR_OK); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchBackground + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchBackground with non-UIExtension type + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchBackground_002, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SERVICE; + abilityRequest.abilityInfo.bundleName = "com.example.service"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + sptr token = abilityRecord->GetToken(); + + auto ret = connectManager->DispatchBackground(abilityRecord, token); + EXPECT_EQ(ret, ERR_OK); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchBackground + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchBackground with null abilityRecord + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchBackground_003, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + auto ret = connectManager->DispatchBackground(nullptr, nullptr); + EXPECT_EQ(ret, ERR_INVALID_VALUE); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchInactive + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchInactive with CreateByConnect mode + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchInactive_006, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SYS_COMMON_UI; + abilityRequest.abilityInfo.bundleName = "com.example.uiextension"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + abilityRecord->SetCreateByConnectMode(true); + abilityRecord->SetAbilityState(AbilityState::INACTIVATING); + Rosen::SessionInfo info; + sptr sessionInfo(new SessionInfo()); + sessionInfo->sessionToken = sptr(new Rosen::Session(info)); + abilityRecord->sessionInfo_ = sessionInfo; + sptr token = abilityRecord->GetToken(); + + auto ret = connectManager->DispatchInactive(abilityRecord, + static_cast(AbilityState::INACTIVATING), token); + EXPECT_EQ(ret, ERR_OK); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchInactive + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchInactive with Preload mode + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchInactive_007, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SYS_COMMON_UI; + abilityRequest.abilityInfo.bundleName = "com.example.uiextension"; + abilityRequest.want.SetParam(IS_PRELOAD_UIEXTENSION_ABILITY, true); + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + abilityRecord->SetAbilityState(AbilityState::INACTIVATING); + Rosen::SessionInfo info; + sptr sessionInfo(new SessionInfo()); + sessionInfo->sessionToken = sptr(new Rosen::Session(info)); + abilityRecord->sessionInfo_ = sessionInfo; + sptr token = abilityRecord->GetToken(); + + auto ret = connectManager->DispatchInactive(abilityRecord, + static_cast(AbilityState::INACTIVATING), token); + EXPECT_EQ(ret, ERR_OK); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchInactive + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchInactive with normal mode + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchInactive_008, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SYS_COMMON_UI; + abilityRequest.abilityInfo.bundleName = "com.example.uiextension"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + abilityRecord->SetAbilityState(AbilityState::INACTIVATING); + Rosen::SessionInfo info; + sptr sessionInfo(new SessionInfo()); + sessionInfo->sessionToken = sptr(new Rosen::Session(info)); + abilityRecord->sessionInfo_ = sessionInfo; + sptr token = abilityRecord->GetToken(); + + auto ret = connectManager->DispatchInactive(abilityRecord, + static_cast(AbilityState::INACTIVATING), token); + EXPECT_EQ(ret, ERR_OK); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchInactive + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchInactive with wrong abilityState + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchInactive_009, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SYS_COMMON_UI; + abilityRequest.abilityInfo.bundleName = "com.example.uiextension"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + abilityRecord->SetAbilityState(AbilityState::BACKGROUNDING); // Wrong state + Rosen::SessionInfo info; + sptr sessionInfo(new SessionInfo()); + sessionInfo->sessionToken = sptr(new Rosen::Session(info)); + abilityRecord->sessionInfo_ = sessionInfo; + sptr token = abilityRecord->GetToken(); + + auto ret = connectManager->DispatchInactive(abilityRecord, + static_cast(AbilityState::INACTIVATING), token); + EXPECT_EQ(ret, ERR_INVALID_VALUE); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: DispatchInactive + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify DispatchInactive with null abilityRecord + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, DispatchInactive_005, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + auto ret = connectManager->DispatchInactive(nullptr, + static_cast(AbilityState::INACTIVATING), nullptr); + EXPECT_EQ(ret, ERR_INVALID_VALUE); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: TerminateAbilityInner + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify TerminateAbilityInner with record from terminatingMap + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, TerminateAbilityInner_003, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SYS_COMMON_UI; + abilityRequest.abilityInfo.bundleName = "com.example.uiextension"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + Rosen::SessionInfo info; + sptr sessionInfo(new SessionInfo()); + sessionInfo->sessionToken = sptr(new Rosen::Session(info)); + abilityRecord->sessionInfo_ = sessionInfo; + sptr token = abilityRecord->GetToken(); + + // Add record to serviceMap (simulating a normal record) + std::string serviceKey = "com.example.uiextension#MainUIExtension#entry"; + connectManager->serviceMap_[serviceKey] = abilityRecord; + + auto ret = connectManager->TerminateAbilityInner(token); + EXPECT_EQ(ret, ERR_OK); +} + +/* + * Feature: UIExtensionAbilityManager + * Function: TerminateAbilityInner + * SubFunction: NA + * FunctionPoints: NA + * EnvConditions: NA + * CaseDescription: Verify TerminateAbilityInner with UIExtension having connections + */ +HWTEST_F(UIExtensionAbilityManagerSecondTest, TerminateAbilityInner_002, TestSize.Level1) +{ + auto connectManager = std::make_shared(0); + AbilityRequest abilityRequest; + abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SYS_COMMON_UI; + abilityRequest.abilityInfo.bundleName = "com.example.uiextension"; + auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest); + Rosen::SessionInfo info; + sptr sessionInfo(new SessionInfo()); + sessionInfo->sessionToken = sptr(new Rosen::Session(info)); + abilityRecord->sessionInfo_ = sessionInfo; + sptr token = abilityRecord->GetToken(); + + // Add connection to record (simulating UIExtension with connections) + auto callback = new AbilityConnectCallback(); + abilityRecord->connRecordList_.push_back( + std::make_shared(token, abilityRecord, callback, nullptr)); + connectManager->serviceMap_["test"] = abilityRecord; + + auto ret = connectManager->TerminateAbilityInner(token); + EXPECT_EQ(ret, ERR_OK); // Should not actually terminate because of connections +} } // namespace AAFwk } // namespace OHOS