diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index ec76b769c76a71a1674a1abec900d24a4202ad3a..eaa6a4d25dc7aca077832846012245ac4abd687a 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -165,6 +165,7 @@ enum class WindowType : uint32_t { SYSTEM_SUB_WINDOW_BASE = 2500, WINDOW_TYPE_SYSTEM_SUB_WINDOW = SYSTEM_SUB_WINDOW_BASE, + WINDOW_TYPE_SCB_SUB_WINDOW, SYSTEM_SUB_WINDOW_END, SYSTEM_WINDOW_END = SYSTEM_SUB_WINDOW_END, diff --git a/utils/include/string_util.h b/utils/include/string_util.h index 96c5eb161bee250e3ae833fa529045d7be5c6883..241044c432dd756296160889b43594f5446dbe33 100644 --- a/utils/include/string_util.h +++ b/utils/include/string_util.h @@ -16,6 +16,7 @@ #ifndef WM_STRING_UTIL_H #define WM_STRING_UTIL_H +#include #include namespace OHOS { @@ -23,6 +24,25 @@ namespace Rosen { class StringUtil { public: static std::string Trim(std::string s); + + static inline bool ConvertStringToInt32(const std::string& str, int32_t& num) + { + auto res = std::from_chars(str.data(), str.data() + str.size(), num); + if (res.ec != std::errc()) { + return false; + } + return true; + } + + static inline bool ConvertStringToBool(const std::string& str) + { + std::string tmp = str; + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + if (tmp == "true" || tmp == "1") { + return true; + } + return false; + } }; } // Rosen } // OHOS diff --git a/window_scene/common/include/window_session_property.h b/window_scene/common/include/window_session_property.h index 4a5dc4d6f54910a59c92a5e66039b7f1d4959170..46ebf02a974aaaa4fded45f73bcde7c0816e0d51 100755 --- a/window_scene/common/include/window_session_property.h +++ b/window_scene/common/include/window_session_property.h @@ -801,6 +801,9 @@ struct SystemSessionConfig : public Parcelable { bool supportPreloadStartingWindow_ = false; bool supportCreateFloatWindow_ = false; float defaultCornerRadius_ = 0.0f; // default corner radius of window set by system config + bool supportUIExtensionSubWindow_ = false; + + void ConvertSupportUIExtensionSubWindow(const std::string& itemValue); virtual bool Marshalling(Parcel& parcel) const override { diff --git a/window_scene/common/src/window_session_property.cpp b/window_scene/common/src/window_session_property.cpp index c7010cc9922eab19fd41cc08dcfd3815fc7a0067..761ba1ae983ed8657876089fbbafd3132bc73fb9 100755 --- a/window_scene/common/src/window_session_property.cpp +++ b/window_scene/common/src/window_session_property.cpp @@ -14,6 +14,7 @@ */ #include "common/include/window_session_property.h" +#include "string_util.h" #include "window_manager_hilog.h" #include "wm_common.h" #include "window_helper.h" @@ -1589,6 +1590,10 @@ void WindowSessionProperty::CopyFrom(const sptr& property isPcAppInpadOrientationLandscape_ = property->isPcAppInpadOrientationLandscape_; isPcAppInpadCompatibleMode_ = property->isPcAppInpadCompatibleMode_; ancoRealBundleName_ = property->ancoRealBundleName_; + { + std::lock_guard lock(missionInfoMutex_); + missionInfo_ = property->missionInfo_; + } } bool WindowSessionProperty::Write(Parcel& parcel, WSPropertyChangeAction action) @@ -2580,5 +2585,10 @@ void WindowSessionProperty::UnmarshallingShadowsInfo(Parcel& parcel, WindowSessi } property->SetWindowShadows(*shadowsInfo); } + +void SystemSessionConfig::ConvertSupportUIExtensionSubWindow(const std::string& itemValue) +{ + supportUIExtensionSubWindow_ = StringUtil::ConvertStringToBool(itemValue); +} } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp index be06d1d20e2e9c0be85223fc5470550a4945d331..e9dff81a97f418746ab42f3e2a99910600aa1971 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp @@ -326,6 +326,8 @@ napi_value JsSceneSessionManager::Init(napi_env env, napi_value exportObj) JsSceneSessionManager::SetPiPSettingSwitchStatus); BindNativeFunction(env, exportObj, "UpdateSystemDecorEnable", moduleName, JsSceneSessionManager::UpdateSystemDecorEnable); + BindNativeFunction(env, exportObj, "applyFeatureConfig", moduleName, + JsSceneSessionManager::ApplyFeatureConfig); return NapiGetUndefined(env); } @@ -1455,6 +1457,35 @@ napi_value JsSceneSessionManager::SetSupportFunctionType(napi_env env, napi_call return (me != nullptr) ? me->OnSetSupportFunctionType(env, info) : nullptr; } +napi_value JsSceneSessionManager::ApplyFeatureConfig(napi_env env, napi_callback_info info) +{ + TLOGI(WmsLogTag::WMS_MAIN, "[NAPI]"); + JsSceneSessionManager* me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnApplyFeatureConfig(env, info) : nullptr; +} + +napi_value JsSceneSessionManager::OnApplyFeatureConfig(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_ONE; + napi_value argv[ARGC_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (argc < ARGC_ONE) { + TLOGE(WmsLogTag::WMS_MAIN, "Argc is invalid: %{public}zu", argc); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return NapiGetUndefined(env); + } + std::unordered_map configMap; + if (!ConvertStringMapFromJs(env, argv[ARG_INDEX_ZERO], configMap)) { + TLOGE(WmsLogTag::WMS_MAIN, "Failed to convert parameter to configMap"); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return NapiGetUndefined(env); + } + SceneSessionManager::GetInstance().ApplyFeatureConfig(configMap); + return NapiGetUndefined(env); +} + bool JsSceneSessionManager::IsCallbackRegistered(napi_env env, const std::string& type, napi_value jsListenerObject) { HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "JsSceneSessionManager::IsCallbackRegistered[%s]", type.c_str()); diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h index bf82225a4bbc5d46603ddcfee8d1d16e6c8541ab..8e0172a96c6f91a22b94f62db6e3239cb8146190 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h @@ -135,6 +135,7 @@ public: static napi_value GetApplicationInfo(napi_env env, napi_callback_info info); static napi_value SetUIEffectControllerAliveInUI(napi_env env, napi_callback_info info); static napi_value SupportCreateFloatWindow(napi_env env, napi_callback_info info); + static napi_value ApplyFeatureConfig(napi_env env, napi_callback_info info); /* * PC Window @@ -257,6 +258,7 @@ private: napi_value OnSupportZLevel(napi_env env, napi_callback_info info); napi_value OnSetSupportFunctionType(napi_env env, napi_callback_info info); napi_value OnUpdateRecentMainSessionInfos(napi_env env, napi_callback_info info); + napi_value OnApplyFeatureConfig(napi_env env, napi_callback_info info); /* * PC Window diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index 8b4c5cd78685f26085f1f9d0a6b6cfe3647217ea..38df580f4d6898bee60bd20592206d82c72e1bc3 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -169,6 +169,7 @@ using NotifySessionRecoverStateChangeFunc = std::function; using FindScenePanelRsNodeByZOrderFunc = std::function(DisplayId screenId, uint32_t targetZOrder)>; +using ConvertSystemConfigFunc = std::function; class AppAnrListener : public IRemoteStub { public: @@ -239,6 +240,7 @@ public: void SetDumpUITreeFunc(const DumpUITreeFunc& func); void SetFindScenePanelRsNodeByZOrderFunc(FindScenePanelRsNodeByZOrderFunc&& func); const AppWindowSceneConfig& GetWindowSceneConfig() const; + void ApplyFeatureConfig(const std::unordered_map& configMap); /* * Window Recover @@ -808,6 +810,7 @@ protected: private: std::atomic enterRecent_ { false }; bool isKeyboardPanelEnabled_ = false; + std::unordered_map convertConfigMap_; static sptr CreateInstance(); static inline bool isNotCurrentScreen(sptr sceneSession, ScreenId screenId) { diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index 46143f8f5a74e088ba3daf59e6c3f4fc31cee8dc..d6d21f0c4a20528001125266c3f465213e8141f9 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -3743,6 +3743,10 @@ WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptrSetSubWindowLevel(parentProperty->GetSubWindowLevel() + 1); + if (parentSession->GetSessionInfo().isSystem_ && property->GetIsUIExtFirstSubWindow() && + systemConfig_.supportUIExtensionSubWindow_) { + property->SetWindowType(WindowType::WINDOW_TYPE_SCB_SUB_WINDOW); + } } auto initClientDisplayId = UpdateSpecificSessionClientDisplayId(property); bool shouldBlock = false; @@ -10846,6 +10850,29 @@ static void FillUnreliableWindowInfo(const sptr& sceneSession, TLOGD(WmsLogTag::WMS_MAIN, "wid=%{public}d", info->windowId_); } +void SceneSessionManager::ApplyFeatureConfig(const std::unordered_map& configMap) +{ + auto task = [this, where = __func__, &configMap] { + if (convertConfigMap_.empty()) { + convertConfigMap_ = { + {"supportUIExtensionSubWindow", std::bind(&SystemSessionConfig::ConvertSupportUIExtensionSubWindow, + &systemConfig_, std::placeholders::_1)}, + }; + } + for (const auto& [configName, configValue] : configMap) { + TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, configEntry is %{public}s: %{public}s", + where, configName.c_str(), configValue.c_str()); + auto convertIter = convertConfigMap_.find(configName); + if (convertIter != convertConfigMap_.end()) { + auto convertFunc = convertIter->second; + convertFunc(configValue); + } + } + return WMError::WM_OK; + }; + taskScheduler_->PostSyncTask(task, "ApplyFeatureConfig"); +} + WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId, std::vector>& infos) { diff --git a/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp b/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp index cae8eb38fac14ca0cf0983e4d9bfffb1001e9a3b..e607ca393f5697c160f4c805c01a7f20b5d632eb 100644 --- a/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp +++ b/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp @@ -105,6 +105,12 @@ WSError SceneSessionManagerProxy::CreateAndConnectSpecificSession(const sptrGetDisplayId() != VIRTUAL_DISPLAY_ID) { property->SetDisplayId(displayId); } + uint32_t windowType = 0; + if (!reply.ReadUint32(windowType)) { + TLOGE(WmsLogTag::WMS_LIFE, "Read windowType failed"); + return WSError::WS_ERROR_IPC_FAILED; + } + property->SetWindowType(static_cast(windowType)); int32_t ret = reply.ReadInt32(); return static_cast(ret); } diff --git a/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp b/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp index aab739f17e2ebaf1204c7296904c84dcd9715bb1..c3a79f753257390ceca1abe845729adf4b6c02a4 100644 --- a/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp +++ b/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp @@ -304,6 +304,7 @@ int SceneSessionManagerStub::HandleCreateAndConnectSpecificSession(MessageParcel reply.WriteParcelable(&systemConfig); reply.WriteUint32(property->GetSubWindowLevel()); reply.WriteUint64(property->GetDisplayId()); + reply.WriteUint32(static_cast(property->GetWindowType())); reply.WriteUint32(static_cast(WSError::WS_OK)); return ERR_NONE; } diff --git a/window_scene/test/unittest/scene_session_manager_test12.cpp b/window_scene/test/unittest/scene_session_manager_test12.cpp index c1776be98d1b67af813fb8ec493820a443a75980..470112c7484aa9bc74ed473cc6e08a223a3a6d55 100644 --- a/window_scene/test/unittest/scene_session_manager_test12.cpp +++ b/window_scene/test/unittest/scene_session_manager_test12.cpp @@ -631,6 +631,77 @@ HWTEST_F(SceneSessionManagerTest12, CreateAndConnectSpecificSession03, TestSize. EXPECT_EQ(WSError::WS_DO_NOTHING, res); } +/** + * @tc.name: CreateAndConnectSpecificSession + * @tc.desc: CreateAndConnectSpecificSession + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerTest12, CreateAndConnectSpecificSession04, TestSize.Level1) +{ + sptr sessionStage; + sptr eventChannel; + std::shared_ptr node = nullptr; + sptr property = sptr::MakeSptr(); + sptr session; + SystemSessionConfig systemConfig; + sptr token; + int32_t id = 0; + ASSERT_NE(ssm_, nullptr); + + SessionInfo info; + info.abilityName_ = "test1"; + info.bundleName_ = "test2"; + sptr parentSession = sptr::MakeSptr(info, nullptr); + parentSession->GetSessionProperty()->SetWindowType(WindowType::WINDOW_TYPE_GLOBAL_SEARCH); + ssm_->sceneSessionMap_.insert({ parentSession->GetPersistentId(), parentSession }); + + // Create UI_EXTENSION_SUB_WINDOW success + property->SetWindowType(WindowType::WINDOW_TYPE_FLOAT); + property->SetParentPersistentId(parentSession->GetPersistentId()); + property->SetIsUIExtFirstSubWindow(true); + ssm_->systemConfig_.supportUIExtensionSubWindow_ = true; + ssm_->CreateAndConnectSpecificSession(sessionStage, eventChannel, node, property, id, session, + systemConfig, token); + EXPECT_EQ(property->GetWindowType(), WindowType::WINDOW_TYPE_SCB_SUB_WINDOW); + + // Create UI_EXTENSION_SUB_WINDOW failed + property->SetWindowType(WindowType::WINDOW_TYPE_FLOAT); + ssm_->systemConfig_.supportUIExtensionSubWindow_ = false; + ssm_->CreateAndConnectSpecificSession(sessionStage, eventChannel, node, property, id, session, + systemConfig, token); + EXPECT_NE(property->GetWindowType(), WindowType::WINDOW_TYPE_SCB_SUB_WINDOW); + + // Create UI_EXTENSION_SUB_WINDOW failed + property->SetWindowType(WindowType::WINDOW_TYPE_FLOAT); + property->SetIsUIExtFirstSubWindow(false); + ssm_->CreateAndConnectSpecificSession(sessionStage, eventChannel, node, property, id, session, + systemConfig, token); + EXPECT_NE(property->GetWindowType(), WindowType::WINDOW_TYPE_SCB_SUB_WINDOW); + + // Create UI_EXTENSION_SUB_WINDOW failed + property->SetWindowType(WindowType::WINDOW_TYPE_FLOAT); + parentSession->GetSessionProperty()->SetWindowType(WindowType::APP_MAIN_WINDOW_BASE); + ssm_->CreateAndConnectSpecificSession(sessionStage, eventChannel, node, property, id, session, + systemConfig, token); + EXPECT_NE(property->GetWindowType(), WindowType::WINDOW_TYPE_SCB_SUB_WINDOW); +} + +/** + * @tc.name: ApplyFeatureConfig + * @tc.desc: ApplyFeatureConfig + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerTest12, ApplyFeatureConfig, TestSize.Level1) +{ + ASSERT_NE(ssm_, nullptr); + std::unordered_map configMap = { + {"testKey", "testVal"}, + {"supportUIExtensionSubWindow", "true"} + }; + ssm_->ApplyFeatureConfig(configMap); + EXPECT_TRUE(ssm_->systemConfig_.supportUIExtensionSubWindow_); +} + /** * @tc.name: SetCreateKeyboardSessionListener * @tc.desc: SetCreateKeyboardSessionListener diff --git a/wm/src/window_scene_session_impl.cpp b/wm/src/window_scene_session_impl.cpp index 117d76fb874a8b204641918ec31c1dd321e452ca..d94364ef8a7894eafa95e608db5f4ed909f49057 100644 --- a/wm/src/window_scene_session_impl.cpp +++ b/wm/src/window_scene_session_impl.cpp @@ -663,7 +663,7 @@ WMError WindowSceneSessionImpl::Create(const std::shared_ptrGetWindowName().c_str(), property_->GetPersistentId(), state_, GetWindowMode(), isEnableDefaultDensityWhenCreate_, property_->GetDisplayId());