diff --git a/interfaces/innerkits/extension/extension_business_info.h b/interfaces/innerkits/extension/extension_business_info.h new file mode 100644 index 0000000000000000000000000000000000000000..efc0c4b577052fcdeeeffafeef00ac5120be361a --- /dev/null +++ b/interfaces/innerkits/extension/extension_business_info.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ROSEN_EXTENSION_BUSINESS_INFO_H +#define OHOS_ROSEN_EXTENSION_BUSINESS_INFO_H + +#include + +namespace OHOS::Rosen::Extension { +constexpr const char* const WINDOW_MODE_FIELD = "windowMode"; + +enum class Businesscode : uint8_t { + SYNC_HOST_WINDOW_MODE = 0, // Synchronize the host's window mode +}; +} // namespace OHOS::Rosen::Extension + +#endif // OHOS_ROSEN_EXTENSION_BUSINESS_INFO_H \ No newline at end of file diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index 7d28807b4ddd56e17563a73af6e25f07b4857898..3c52bb582b4518aaed4bd42eb44afd2b484c597c 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -139,7 +139,8 @@ enum class WindowMode : uint32_t { WINDOW_MODE_SPLIT_PRIMARY = 100, WINDOW_MODE_SPLIT_SECONDARY, WINDOW_MODE_FLOATING, - WINDOW_MODE_PIP + WINDOW_MODE_PIP, + END = WINDOW_MODE_PIP, }; /** diff --git a/wm/include/window_extension_session_impl.h b/wm/include/window_extension_session_impl.h index 4e61a8bc32806b108fc1f91db5d8e97d06b5c391..cc33567a4fc4de255f6773994f4f8145ac8736aa 100644 --- a/wm/include/window_extension_session_impl.h +++ b/wm/include/window_extension_session_impl.h @@ -52,6 +52,8 @@ public: void TriggerBindModalUIExtension() override; std::shared_ptr GetExtensionDataHandler() const override; void NotifyExtensionDataConsumer(MessageParcel& data, MessageParcel& reply) override; + WindowMode GetMode() const override; + WMError SetWindowMode(WindowMode mode) override; /* * Window Privacy @@ -156,8 +158,10 @@ private: void ReportModalUIExtensionMayBeCovered(bool byLoadContent) const; WMError SetUIContentInner(const std::string& contentInfo, napi_env env, napi_value storage, sptr token, AppExecFwk::Ability* ability, bool initByName = false); + void RegisterDataConsumer(); std::shared_ptr dataHandler_; + std::unordered_map dataConsumers_; // Read only after init sptr abilityToken_ { nullptr }; std::atomic isDensityFollowHost_ { false }; std::optional> hostDensityValue_ = std::nullopt; diff --git a/wm/src/window_extension_session_impl.cpp b/wm/src/window_extension_session_impl.cpp index 3c016b5dfa6142bc5308af2665bab6abff5d8d6e..c73646596be0eb5b0b1e468dccfbc283f43d5ffe 100644 --- a/wm/src/window_extension_session_impl.cpp +++ b/wm/src/window_extension_session_impl.cpp @@ -15,21 +15,24 @@ #include "window_extension_session_impl.h" +#include +#include #include #include + #ifdef IMF_ENABLE #include #endif -#include "window_manager_hilog.h" + #include "display_info.h" -#include "parameters.h" -#include "hitrace_meter.h" +#include "extension/extension_business_info.h" +#include "input_transfer_station.h" #include "perform_reporter.h" #include "session_permission.h" #include "singleton_container.h" -#include "window_adapter.h" -#include "input_transfer_station.h" #include "ui_extension/provider_data_handler.h" +#include "window_adapter.h" +#include "window_manager_hilog.h" namespace OHOS { namespace Rosen { @@ -67,6 +70,7 @@ WindowExtensionSessionImpl::WindowExtensionSessionImpl(const sptr& TLOGI(WmsLogTag::WMS_UIEXT, "UIExtension usage=%{public}u, the default state of hideNonSecureWindows is %{public}d", property_->GetUIExtensionUsage(), extensionWindowFlags_.hideNonSecureWindowsFlag); dataHandler_ = std::make_shared(); + RegisterDataConsumer(); } WindowExtensionSessionImpl::~WindowExtensionSessionImpl() @@ -1355,5 +1359,55 @@ void WindowExtensionSessionImpl::NotifyExtensionDataConsumer(MessageParcel& data TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d", GetPersistentId()); dataHandler_->NotifyDataConsumer(data, reply); } + +WindowMode WindowExtensionSessionImpl::GetMode() const +{ + return property_->GetWindowMode(); +} + +WMError WindowExtensionSessionImpl::SetWindowMode(WindowMode mode) +{ + property_->SetWindowMode(mode); + TLOGNI(WmsLogTag::WMS_UIEXT, "windowMode:%{public}u", GetMode()); + return WMError::WM_OK; +} + +void WindowExtensionSessionImpl::RegisterDataConsumer() +{ + auto windowModeConsumer = [this](SubSystemId id, uint32_t customId, AAFwk::Want&& data, + std::optional& reply) -> int32_t { + auto windowMode = data.GetIntParam(Extension::WINDOW_MODE_FIELD, 0); + if (windowMode < static_cast(WindowMode::WINDOW_MODE_UNDEFINED) || + windowMode > static_cast(WindowMode::END)) { + TLOGNE(WmsLogTag::WMS_UIEXT, "invalid window mode, windowMode:%{public}d", windowMode); + return static_cast(DataHandlerErr::INVALID_PARAMETER); + } + + static_cast(SetWindowMode(static_cast(windowMode))); + return static_cast(DataHandlerErr::OK); + }; + dataConsumers_.emplace(static_cast(Extension::Businesscode::SYNC_HOST_WINDOW_MODE), + std::move(windowModeConsumer)); + + auto consumersEntry = [this](SubSystemId id, uint32_t customId, AAFwk::Want&& data, + std::optional& reply) -> int32_t { + auto itr = dataConsumers_.find(customId); + if (itr == dataConsumers_.end()) { + TLOGNE(WmsLogTag::WMS_UIEXT, "no consumer for %{public}u", customId); + return static_cast(DataHandlerErr::NO_CONSUME_CALLBACK); + } + + const auto& func = itr->second; + if (!func) { + TLOGNE(WmsLogTag::WMS_UIEXT, "not callable for %{public}u", customId); + return static_cast(DataHandlerErr::INVALID_CALLBACK); + } + + auto ret = func(id, customId, std::move(data), reply); + TLOGNI(WmsLogTag::WMS_UIEXT, "customId:%{public}u, ret:%{public}d", customId, ret); + return static_cast(DataHandlerErr::OK); + }; + dataHandler_->RegisterDataConsumer(SubSystemId::WM_UIEXT, std::move(consumersEntry)); +} } // namespace Rosen } // namespace OHOS diff --git a/wm/test/unittest/ui_extension/window_extension_session_impl_test.cpp b/wm/test/unittest/ui_extension/window_extension_session_impl_test.cpp index 5845c50f9d52f65a4fdad69f7884120a25741284..b4d5d5b46aa7edccdad26616a3cc6d64260c7ebb 100644 --- a/wm/test/unittest/ui_extension/window_extension_session_impl_test.cpp +++ b/wm/test/unittest/ui_extension/window_extension_session_impl_test.cpp @@ -14,20 +14,19 @@ */ #include -#include "session_proxy.h" +#include +#include #include -#include "ability_context_impl.h" -#include "mock_session.h" -#include "display_info.h" + #include "accessibility_event_info.h" -#include "window_manager_hilog.h" -#include "window_impl.h" -#include "native_engine.h" -#include "window_extension_session_impl.h" -#include "mock_uicontent.h" -#include "context_impl.h" +#include "display_info.h" +#include "extension/extension_business_info.h" +#include "extension_data_handler.h" #include "iremote_object_mocker.h" +#include "mock_session.h" +#include "mock_uicontent.h" +#include "window_extension_session_impl.h" using namespace testing; using namespace testing::ext; @@ -2190,6 +2189,40 @@ HWTEST_F(WindowExtensionSessionImplTest, UpdateConfigurationSyncForAll, Function window_->UpdateConfigurationSyncForAll(configuration); window_->windowExtensionSessionSet_.erase(window_); } + +/** + * @tc.name: NotifyExtensionDataConsumer01 + * @tc.desc: Test NotifyExtensionDataConsumer with valid window mode data + * @tc.type: FUNC + */ +HWTEST_F(WindowExtensionSessionImplTest, NotifyExtensionDataConsumer01, Function | SmallTest | Level3) +{ + // Prepare and write config + MessageParcel data; + MessageParcel reply; + Extension::DataTransferConfig config; + config.subSystemId = SubSystemId::WM_UIEXT; + config.customId = static_cast(Extension::Businesscode::SYNC_HOST_WINDOW_MODE); + config.needReply = false; + config.needSyncSend = true; + ASSERT_TRUE(data.WriteParcelable(&config)); + + // Prepare and write want data + AAFwk::Want want; + want.SetParam(Extension::WINDOW_MODE_FIELD, static_cast(WindowMode::WINDOW_MODE_FLOATING)); + ASSERT_TRUE(data.WriteParcelable(&want)); + + // Call NotifyExtensionDataConsumer + window_->NotifyExtensionDataConsumer(data, reply); + + // Verify reply contains success code + uint32_t replyCode; + ASSERT_TRUE(reply.ReadUint32(replyCode)); + ASSERT_EQ(static_cast(DataHandlerErr::OK), replyCode); + + // Verify window mode was updated + ASSERT_EQ(WindowMode::WINDOW_MODE_FLOATING, window_->GetMode()); +} } } // namespace Rosen } // namespace OHOS \ No newline at end of file