diff --git a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp index 70d2e006ab..7136816ab6 100644 --- a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp +++ b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp @@ -145,6 +145,22 @@ ErrCode AbilityContextImpl::StartAbility(const AAFwk::Want& want, int requestCod { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); HILOG_DEBUG("StartAbility"); + int32_t screenMode = want.GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::IDLE_SCREEN_MODE); + if (screenMode == AAFwk::HALF_SCREEN_MODE) { + auto uiContent = GetUIContent(); + if (uiContent == nullptr) { + HILOG_ERROR("uiContent is nullptr"); + return ERR_INVALID_VALUE; + } + Ace::ModalUIExtensionCallbacks callback; + Ace::ModalUIExtensionConfig config; + int32_t sessionId = uiContent->CreateModalUIExtension(want, callback, config); + if (sessionId == 0) { + HILOG_ERROR("CreateModalUIExtension failed"); + return ERR_INVALID_VALUE; + } + return ERR_OK; + } ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, requestCode); if (err != ERR_OK) { HILOG_ERROR("StartAbility. ret=%{public}d", err); diff --git a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp index 26cda9d581..9525faa198 100755 --- a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension.cpp @@ -588,8 +588,15 @@ bool JsUIExtension::HandleSessionCreate(const AAFwk::Want &want, const sptr(reinterpret_cast(ref))); - napi_value argv[] = {napiWant, nativeContentSession}; - CallObjectMethod("onSessionCreate", argv, ARGC_TWO); + int32_t screenMode = want.GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::IDLE_SCREEN_MODE); + if (screenMode == AAFwk::HALF_SCREEN_MODE) { + screenMode_ = AAFwk::HALF_SCREEN_MODE; + napi_value argv[] = {nullptr}; + CallObjectMethod("onWindowStageCreate", argv, ARGC_ONE); + } else { + napi_value argv[] = {napiWant, nativeContentSession}; + CallObjectMethod("onSessionCreate", argv, ARGC_TWO); + } uiWindowMap_[componentId] = uiWindow; if (context->GetWindow() == nullptr) { context->SetWindow(uiWindow); @@ -650,8 +657,13 @@ void JsUIExtension::DestroyWindow(const sptr &sessionInfo) } if (contentSessions_.find(componentId) != contentSessions_.end() && contentSessions_[componentId] != nullptr) { HandleScope handleScope(jsRuntime_); - napi_value argv[] = {contentSessions_[componentId]->GetNapiValue()}; - CallObjectMethod("onSessionDestroy", argv, ARGC_ONE); + if (screenMode_ == AAFwk::HALF_SCREEN_MODE) { + screenMode_ = AAFwk::IDLE_SCREEN_MODE; + CallObjectMethod("onWindowStageDestroy"); + } else { + napi_value argv[] = {contentSessions_[componentId]->GetNapiValue()}; + CallObjectMethod("onSessionDestroy", argv, ARGC_ONE); + } } auto& uiWindow = uiWindowMap_[componentId]; if (uiWindow) { diff --git a/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension.h b/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension.h index a3580130d4..960379e66a 100755 --- a/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension.h +++ b/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension.h @@ -210,6 +210,7 @@ private: std::set foregroundWindows_; std::map> contentSessions_; std::shared_ptr abilityResultListeners_ = nullptr; + int32_t screenMode_ = AAFwk::IDLE_SCREEN_MODE; }; } // namespace AbilityRuntime } // namespace OHOS diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 2f0a56169d..cc9959d2b2 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -1713,6 +1713,9 @@ private: void AppRecoverKill(pid_t pid, int32_t reason); + int32_t GenerateEmbeddableUIAbilityRequest(const Want &want, AbilityRequest &request, + const sptr &callerToken, int32_t userId); + /** * Check if Caller is allowed to start ServiceAbility(FA) or ServiceExtension(Stage) or DataShareExtension(Stage). * diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 94b7609ce8..31b842f189 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -230,6 +230,7 @@ const std::string NEED_STARTINGWINDOW = "ohos.ability.NeedStartingWindow"; const std::string PERMISSIONMGR_BUNDLE_NAME = "com.ohos.permissionmanager"; const std::string PERMISSIONMGR_ABILITY_NAME = "com.ohos.permissionmanager.GrantAbility"; const std::string IS_CALL_BY_SCB = "isCallBySCB"; +const std::string PROCESS_SUFFIX = "embeddable"; const int DEFAULT_DMS_MISSION_ID = -1; const std::map AbilityManagerService::dumpMap = { std::map::value_type("--all", KEY_DUMP_ALL), @@ -2387,7 +2388,7 @@ int AbilityManagerService::StartUIExtensionAbility(const sptr &exte abilityRequest.Voluation(extensionSessionInfo->want, DEFAULT_INVAL_VALUE, callerToken); abilityRequest.callType = AbilityCallType::START_EXTENSION_TYPE; abilityRequest.sessionInfo = extensionSessionInfo; - result = GenerateExtensionAbilityRequest(extensionSessionInfo->want, abilityRequest, callerToken, validUserId); + result = GenerateEmbeddableUIAbilityRequest(extensionSessionInfo->want, abilityRequest, callerToken, validUserId); CHECK_POINTER_AND_RETURN(abilityRequest.sessionInfo, ERR_INVALID_VALUE); abilityRequest.sessionInfo->uiExtensionComponentId = ( static_cast(callerRecord->GetRecordId()) << OFFSET) | @@ -9450,5 +9451,26 @@ void AbilityManagerService::RemoveLauncherDeathRecipient(int32_t userId) } connectManager->RemoveLauncherDeathRecipient(); } + +int32_t AbilityManagerService::GenerateEmbeddableUIAbilityRequest( + const Want &want, AbilityRequest &request, const sptr &callerToken, int32_t userId) +{ + int32_t screenMode = want.GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::IDLE_SCREEN_MODE); + int32_t result = ERR_OK; + if (screenMode == AAFwk::HALF_SCREEN_MODE) { + result = GenerateAbilityRequest(want, -1, request, callerToken, userId); + request.abilityInfo.isModuleJson = true; + request.abilityInfo.isStageBasedModel = true; + request.abilityInfo.type = AppExecFwk::AbilityType::EXTENSION; + request.abilityInfo.extensionAbilityType = AppExecFwk::ExtensionAbilityType::UI; + struct timespec time = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &time); + int64_t times = static_cast(time.tv_sec); + request.abilityInfo.process = request.abilityInfo.bundleName + PROCESS_SUFFIX + std::to_string(times); + } else { + result = GenerateExtensionAbilityRequest(want, request, callerToken, userId); + } + return result; +} } // namespace AAFwk } // namespace OHOS diff --git a/test/unittest/ability_manager_service_first_test/ability_manager_service_first_test.cpp b/test/unittest/ability_manager_service_first_test/ability_manager_service_first_test.cpp index 31388bf077..3482fea714 100644 --- a/test/unittest/ability_manager_service_first_test/ability_manager_service_first_test.cpp +++ b/test/unittest/ability_manager_service_first_test/ability_manager_service_first_test.cpp @@ -1484,5 +1484,40 @@ HWTEST_F(AbilityManagerServiceFirstTest, GetForegroundUIAbilities_001, TestSize. auto res = abilityMs_->GetForegroundUIAbilities(list); EXPECT_EQ(res, CHECK_PERMISSION_FAILED); } + +/* + * Feature: AbilityManagerService + * Function: GenerateEmbeddableUIAbilityRequest + * SubFunction: NA + * FunctionPoints: AbilityManagerService GenerateEmbeddableUIAbilityRequest + */ +HWTEST_F(AbilityManagerServiceFirstTest, GenerateEmbeddableUIAbilityRequest_001, TestSize.Level1) +{ + HILOG_INFO("AbilityManagerServiceSecondTest GenerateEmbeddableUIAbilityRequest_001 start"); + auto abilityMs_ = std::make_shared(); + Want want; + want.SetParam("ScreenMode", 1); + AbilityRequest request; + auto res = abilityMs_->GenerateEmbeddableUIAbilityRequest(want, request, nullptr, USER_ID_U100); + EXPECT_EQ(res, RESOLVE_ABILITY_ERR); + HILOG_INFO("AbilityManagerServiceSecondTest GenerateEmbeddableUIAbilityRequest_001 end"); +} + +/* + * Feature: AbilityManagerService + * Function: GenerateEmbeddableUIAbilityRequest + * SubFunction: NA + * FunctionPoints: AbilityManagerService GenerateEmbeddableUIAbilityRequest + */ +HWTEST_F(AbilityManagerServiceFirstTest, GenerateEmbeddableUIAbilityRequest_002, TestSize.Level1) +{ + HILOG_INFO("AbilityManagerServiceSecondTest GenerateEmbeddableUIAbilityRequest_002 start"); + auto abilityMs_ = std::make_shared(); + Want want; + AbilityRequest request; + auto res = abilityMs_->GenerateEmbeddableUIAbilityRequest(want, request, nullptr, USER_ID_U100); + EXPECT_EQ(res, RESOLVE_ABILITY_ERR); + HILOG_INFO("AbilityManagerServiceSecondTest GenerateEmbeddableUIAbilityRequest_002 end"); +} } // namespace AAFwk } // namespace OHOS diff --git a/test/unittest/frameworks_kits_ability_ability_runtime_test/ability_context_impl_test.cpp b/test/unittest/frameworks_kits_ability_ability_runtime_test/ability_context_impl_test.cpp index 6bee5dfcf2..f3cc680d91 100644 --- a/test/unittest/frameworks_kits_ability_ability_runtime_test/ability_context_impl_test.cpp +++ b/test/unittest/frameworks_kits_ability_ability_runtime_test/ability_context_impl_test.cpp @@ -556,6 +556,20 @@ HWTEST_F(AbilityContextImplTest, Ability_Context_Impl_StartAbility_0400, Functio EXPECT_EQ(ret, ERR_OK); } +/** + * @tc.number: Ability_Context_Impl_StartAbility_0500 + * @tc.name: StartAbility + * @tc.desc: Start Ability + */ +HWTEST_F(AbilityContextImplTest, Ability_Context_Impl_StartAbility_0500, Function | MediumTest | Level1) +{ + AAFwk::Want want; + want.SetParam("ScreenMode", 1); + int32_t requestCode = 1; + auto ret = context_->StartAbility(want, requestCode); + EXPECT_EQ(ret, ERR_INVALID_VALUE); +} + /** * @tc.number: Ability_Context_Impl_OnAbilityResult_0100 * @tc.name: OnAbilityResult