Signed-off-by: xhz-sz <xiehuandong@huawei.com>
Co-Authored-By: Agent
This commit is contained in:
xhz-sz
2026-03-03 19:55:20 +08:00
parent 0cfa5015aa
commit 336eb45759
6 changed files with 368 additions and 1 deletions
@@ -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 = [
@@ -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<void *>(EtsAbilityManager::GetAbilityRunningInfos) },
ani_native_function { "nativeGetExtensionRunningInfos", "iC{utils.AbilityUtils.AsyncCallbackWrapper}:",
reinterpret_cast<void *>(EtsAbilityManager::GetExtensionRunningInfos) },
ani_native_function { "nativeIsEmbeddedUIExtensionSupported", ":z",
reinterpret_cast<void *>(EtsAbilityManager::IsEmbeddedUIExtensionSupported) },
ani_native_function { "nativeIsEmbeddedOpenAllowed",
"C{application.Context.Context}C{std.core.String}C{utils.AbilityUtils.AsyncCallbackWrapper}:",
reinterpret_cast<void *>(EtsAbilityManager::IsEmbeddedOpenAllowed) },
@@ -39,6 +39,7 @@ export default namespace abilityManager {
export native function nativeCheckPreloadUIExtensionAbilityPermission() : void;
export native function nativeGetTopAbilityCheck() : void;
export native function nativeGetAbilityRunningInfos(callback:AsyncCallbackWrapper<Array<AbilityRunningInfo>>) : void;
export native function nativeIsEmbeddedUIExtensionSupported() : boolean;
export native function nativeIsEmbeddedOpenAllowed(context: Context, appId: string, callback:AsyncCallbackWrapper<boolean>) : 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<boolean> {
abilityManager.nativeIsEmbeddedOpenAllowedCheck(context);
return new Promise<boolean>((resolve:(data:boolean)=>void, reject:(err: BusinessError)=>void):void => {
+5 -1
View File
@@ -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 = [
@@ -21,6 +21,7 @@
#include <future>
#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(
@@ -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<UIExtensionAbilityManager> connectManager = std::make_shared<UIExtensionAbilityManager>(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> sessionInfo(new SessionInfo());
sessionInfo->sessionToken = sptr<Rosen::Session>(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<UIExtensionAbilityManager>(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> sessionInfo(new SessionInfo());
sessionInfo->sessionToken = sptr<Rosen::Session>(new Rosen::Session(info));
abilityRecord->sessionInfo_ = sessionInfo;
sptr<IRemoteObject> 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<UIExtensionAbilityManager>(0);
AbilityRequest abilityRequest;
abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SERVICE;
abilityRequest.abilityInfo.bundleName = "com.example.service";
auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest);
sptr<IRemoteObject> 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<UIExtensionAbilityManager>(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> sessionInfo(new SessionInfo());
sessionInfo->sessionToken = sptr<Rosen::Session>(new Rosen::Session(info));
abilityRecord->sessionInfo_ = sessionInfo;
sptr<IRemoteObject> 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<UIExtensionAbilityManager>(0);
AbilityRequest abilityRequest;
abilityRequest.abilityInfo.extensionAbilityType = ExtensionAbilityType::SERVICE;
abilityRequest.abilityInfo.bundleName = "com.example.service";
auto abilityRecord = BaseExtensionRecord::CreateBaseExtensionRecord(abilityRequest);
sptr<IRemoteObject> 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<UIExtensionAbilityManager>(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<UIExtensionAbilityManager>(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> sessionInfo(new SessionInfo());
sessionInfo->sessionToken = sptr<Rosen::Session>(new Rosen::Session(info));
abilityRecord->sessionInfo_ = sessionInfo;
sptr<IRemoteObject> token = abilityRecord->GetToken();
auto ret = connectManager->DispatchInactive(abilityRecord,
static_cast<int>(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<UIExtensionAbilityManager>(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> sessionInfo(new SessionInfo());
sessionInfo->sessionToken = sptr<Rosen::Session>(new Rosen::Session(info));
abilityRecord->sessionInfo_ = sessionInfo;
sptr<IRemoteObject> token = abilityRecord->GetToken();
auto ret = connectManager->DispatchInactive(abilityRecord,
static_cast<int>(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<UIExtensionAbilityManager>(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> sessionInfo(new SessionInfo());
sessionInfo->sessionToken = sptr<Rosen::Session>(new Rosen::Session(info));
abilityRecord->sessionInfo_ = sessionInfo;
sptr<IRemoteObject> token = abilityRecord->GetToken();
auto ret = connectManager->DispatchInactive(abilityRecord,
static_cast<int>(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<UIExtensionAbilityManager>(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> sessionInfo(new SessionInfo());
sessionInfo->sessionToken = sptr<Rosen::Session>(new Rosen::Session(info));
abilityRecord->sessionInfo_ = sessionInfo;
sptr<IRemoteObject> token = abilityRecord->GetToken();
auto ret = connectManager->DispatchInactive(abilityRecord,
static_cast<int>(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<UIExtensionAbilityManager>(0);
auto ret = connectManager->DispatchInactive(nullptr,
static_cast<int>(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<UIExtensionAbilityManager>(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> sessionInfo(new SessionInfo());
sessionInfo->sessionToken = sptr<Rosen::Session>(new Rosen::Session(info));
abilityRecord->sessionInfo_ = sessionInfo;
sptr<IRemoteObject> 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<UIExtensionAbilityManager>(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> sessionInfo(new SessionInfo());
sessionInfo->sessionToken = sptr<Rosen::Session>(new Rosen::Session(info));
abilityRecord->sessionInfo_ = sessionInfo;
sptr<IRemoteObject> token = abilityRecord->GetToken();
// Add connection to record (simulating UIExtension with connections)
auto callback = new AbilityConnectCallback();
abilityRecord->connRecordList_.push_back(
std::make_shared<ConnectionRecord>(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