diff --git a/frameworks/core/components/web/resource/web_delegate.cpp b/frameworks/core/components/web/resource/web_delegate.cpp index d2e8aa9c041d96590d5bd857cfbc84170da25e77..69d04b7ba74ce57e51f0d91433a6e8631f81aa18 100644 --- a/frameworks/core/components/web/resource/web_delegate.cpp +++ b/frameworks/core/components/web/resource/web_delegate.cpp @@ -968,6 +968,7 @@ WebDelegate::~WebDelegate() UnregisterSurfacePositionChangedCallback(); UnregisterAvoidAreaChangeListener(instanceId_); UnRegisterConfigObserver(); + UnregisterFreeMultiWindowListener(); } void WebDelegate::ReleasePlatformResource() @@ -8375,6 +8376,7 @@ void WebDelegate::OnDetachContext() { UnRegisterScreenLockFunction(); UnregisterSurfacePositionChangedCallback(); + UnregisterFreeMultiWindowListener(); auto context = context_.Upgrade(); CHECK_NULL_VOID(context); auto pipelineContext = DynamicCast(context); @@ -8393,6 +8395,7 @@ void WebDelegate::OnAttachContext(const RefPtr &context) instanceId_ = context->GetInstanceId(); context_ = context; RegisterSurfacePositionChangedCallback(); + RegisterFreeMultiWindowListener(); if (nweb_) { auto screenLockCallback = std::make_shared(context); nweb_->RegisterScreenLockFunction(instanceId_, screenLockCallback); @@ -9189,4 +9192,88 @@ void WebDelegate::OnSafeBrowsingCheckFinish(int threat_type) std::make_shared(threat_type)); } } + +bool WebDelegate::IsPcMode() +{ + auto container = AceType::DynamicCast(Container::Current()); + CHECK_NULL_RETURN(container, false); + int32_t instanceId = container->GetInstanceId(); + auto window = Platform::AceContainer::GetUIWindow(instanceId); + CHECK_NULL_RETURN(window, false); + return window->IsPcWindow(); +} + +class WebFreeMultiWindowListener : public OHOS::Rosen::ISwitchFreeMultiWindowListener { +public: + explicit WebFreeMultiWindowListener(WeakPtr webDelegate) : webDelegate_(webDelegate) {} + ~WebFreeMultiWindowListener() = default; + + void OnSwitchFreeMultiWindow(bool enable) override + { + auto webDelegate = webDelegate_.Upgrade(); + CHECK_NULL_VOID(webDelegate); + webDelegate->OnSwitchFreeMultiWindow(enable); + } +private: + WeakPtr webDelegate_; +}; + +void WebDelegate::OnSwitchFreeMultiWindow(bool enable) +{ + TAG_LOGI(AceLogTag::ACE_WEB, "WebDelegate::OnSwitchFreeMultiWindow, freeMultiWindow is %{public}d", enable); + if (enable) { + return; + } + auto context = context_.Upgrade(); + CHECK_NULL_VOID(context); + context->GetTaskExecutor()->PostTask( + [weak = WeakClaim(this)]() { + auto delegate = weak.Upgrade(); + CHECK_NULL_VOID(delegate); + auto webPattern = delegate->webPattern_.Upgrade(); + CHECK_NULL_VOID(webPattern); + webPattern->WindowMaximize(NG::WebWindowMaximizeReason::EXIT_FREE_MULTI_MODE); + }, + TaskExecutor::TaskType::PLATFORM, "ArkUIWebMaximizeResize"); +} + +void WebDelegate::RegisterFreeMultiWindowListener() +{ + TAG_LOGD(AceLogTag::ACE_WEB, "WebDelegate::RegisterFreeMultiWindowListener in, webId: %{public}d", GetWebId()); + if (freeMultiWindowListener_) { + TAG_LOGE(AceLogTag::ACE_WEB, "WebDelegate::RegisterFreeMultiWindowListener, already register"); + return; + } + auto container = AceType::DynamicCast(Container::Current()); + CHECK_NULL_VOID(container); + int32_t instanceId = container->GetInstanceId(); + auto window = Platform::AceContainer::GetUIWindow(instanceId); + CHECK_NULL_VOID(window); + freeMultiWindowListener_ = new WebFreeMultiWindowListener(AceType::WeakClaim(this)); + OHOS::Rosen::WMError result = window->RegisterSwitchFreeMultiWindowListener(freeMultiWindowListener_); + if (OHOS::Rosen::WMError::WM_OK == result) { + TAG_LOGD(AceLogTag::ACE_WEB, "RegisterSwitchFreeMultiWindowListener ok, webId: %{public}d", GetWebId()); + } else { + TAG_LOGE(AceLogTag::ACE_WEB, "RegisterSwitchFreeMultiWindowListener failed, webId: %{public}d", GetWebId()); + freeMultiWindowListener_ = nullptr; + } +} + +void WebDelegate::UnregisterFreeMultiWindowListener() +{ + TAG_LOGD(AceLogTag::ACE_WEB, "WebDelegate::UnregisterFreeMultiWindowListener in, webId: %{public}d", GetWebId()); + CHECK_NULL_VOID(freeMultiWindowListener_); + auto container = AceType::DynamicCast(Container::Current()); + CHECK_NULL_VOID(container); + int32_t instanceId = container->GetInstanceId(); + auto window = Platform::AceContainer::GetUIWindow(instanceId); + CHECK_NULL_VOID(window); + OHOS::Rosen::WMError result = window->UnregisterSwitchFreeMultiWindowListener(freeMultiWindowListener_); + if (OHOS::Rosen::WMError::WM_OK == result) { + TAG_LOGD(AceLogTag::ACE_WEB, "UnregisterSwitchFreeMultiWindowListener ok, webId: %{public}d", GetWebId()); + freeMultiWindowListener_ = nullptr; + } else { + TAG_LOGE(AceLogTag::ACE_WEB, "UnregisterSwitchFreeMultiWindowListener failed, webId: %{public}d", GetWebId()); + } +} } // namespace OHOS::Ace diff --git a/frameworks/core/components/web/resource/web_delegate.h b/frameworks/core/components/web/resource/web_delegate.h index 20a7fad28c0b7d6a2fb4e0953296148e9f0e6e51..01e4b83ff4e10d8e882dd3626a88031998e34744 100644 --- a/frameworks/core/components/web/resource/web_delegate.h +++ b/frameworks/core/components/web/resource/web_delegate.h @@ -1412,6 +1412,8 @@ public: void SetForceEnableZoom(bool isEnabled); bool IsShowHandle(); void OnSafeBrowsingCheckFinish(int threat_type); + bool IsPcMode(); + void OnSwitchFreeMultiWindow(bool enable); private: void InitWebEvent(); void RegisterWebEvent(); @@ -1502,6 +1504,8 @@ private: const MouseInfo& mouseInfo, std::string embedId, const RefPtr& delegate); void HandleNativeMouseToTouch(const std::shared_ptr& result, const MouseInfo& mouseInfo, std::string embedId, const RefPtr& delegate); + void RegisterFreeMultiWindowListener(); + void UnregisterFreeMultiWindowListener(); #endif WeakPtr webComponent_; @@ -1656,6 +1660,8 @@ private: double density_ = 0.0; bool isVisible_ = false; + + sptr freeMultiWindowListener_ = nullptr; #endif }; diff --git a/frameworks/core/components_ng/pattern/web/web_pattern.cpp b/frameworks/core/components_ng/pattern/web/web_pattern.cpp index dd1f15ece457f2219492173770c8b94c6e337bed..64ad85147b805a36f938031581dbaacebd1cd3db 100644 --- a/frameworks/core/components_ng/pattern/web/web_pattern.cpp +++ b/frameworks/core/components_ng/pattern/web/web_pattern.cpp @@ -6276,7 +6276,7 @@ void WebPattern::OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeCh CHECK_NULL_VOID(delegate_); TAG_LOGD(AceLogTag::ACE_WEB, "WindowSizeChangeReason type: %{public}d ", type); if (type == WindowSizeChangeReason::MAXIMIZE) { - WindowMaximize(); + WindowMaximize(WebWindowMaximizeReason::MAXIMIZE); return; } AdjustRotationRenderFit(type); @@ -6371,16 +6371,12 @@ void WebPattern::WindowDrag(int32_t width, int32_t height) } } -void WebPattern::WindowMaximize() +void WebPattern::WindowMaximize(WebWindowMaximizeReason reason) { if (!SystemProperties::GetWebDebugMaximizeResizeOptimize()) { TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::WindowMaximize not enabled"); return; } - WebInfoType webInfoType = GetWebInfoType(); - if (webInfoType != WebInfoType::TYPE_2IN1) { - return; - } if (layoutMode_ != WebLayoutMode::NONE || renderMode_ != RenderMode::ASYNC_RENDER) { TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::WindowMaximize not support"); return; @@ -6388,11 +6384,15 @@ void WebPattern::WindowMaximize() if (!isAttachedToMainTree_ || !isVisible_) { return; } - TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::WindowMaximize, webId: %{public}d", GetWebId()); - if (renderContextForSurface_) { - renderContextForSurface_->SetRenderFit(RenderFit::RESIZE_FILL); - } - if (delegate_) { + CHECK_NULL_VOID(delegate_); + WebInfoType webInfoType = GetWebInfoType(); + if (webInfoType == WebInfoType::TYPE_2IN1 || + (webInfoType == WebInfoType::TYPE_TABLET && delegate_->IsNWebEx() && + (delegate_->IsPcMode() || reason == WebWindowMaximizeReason::EXIT_FREE_MULTI_MODE))) { + TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::WindowMaximize, webId: %{public}d", GetWebId()); + if (renderContextForSurface_) { + renderContextForSurface_->SetRenderFit(RenderFit::RESIZE_FILL); + } delegate_->MaximizeResize(); } } diff --git a/frameworks/core/components_ng/pattern/web/web_pattern.h b/frameworks/core/components_ng/pattern/web/web_pattern.h index fb4e95f338967106a73c84757628afe8bea942d7..3b8d9948fa11439fe79c16f28ed7ffb76db98379 100644 --- a/frameworks/core/components_ng/pattern/web/web_pattern.h +++ b/frameworks/core/components_ng/pattern/web/web_pattern.h @@ -125,6 +125,11 @@ struct PipInfo { int height; }; +enum class WebWindowMaximizeReason : uint32_t { + MAXIMIZE = 0, + EXIT_FREE_MULTI_MODE, +}; + using CursorStyleInfo = std::tuple>; class WebPattern : public NestableScrollContainer, public TextBase, @@ -904,6 +909,7 @@ public: std::string GetAllTextInfo() const; void GetHandleInfo(SelectOverlayInfo& infoHandle); void HandleOnAIWrite(); + void WindowMaximize(WebWindowMaximizeReason reason); protected: void ModifyWebSrc(const std::string& webSrc) @@ -1021,7 +1027,6 @@ private: void OnNativeVideoPlayerConfigUpdate(const std::tuple& config); void DragResizeNoMoveTimer(); void WindowDrag(int32_t width, int32_t height); - void WindowMaximize(); void OnOverlayScrollbarEnabledUpdate(bool enable); void OnKeyboardAvoidModeUpdate(const WebKeyboardAvoidMode& mode); void OnEnabledHapticFeedbackUpdate(bool enable); diff --git a/test/unittest/core/pattern/web/mock_web_delegate.cpp b/test/unittest/core/pattern/web/mock_web_delegate.cpp index d6fe75b81e4922af0cc97357453d7022cd2de9c5..5f2a881aa500cc79c20c50c0a3889aedf41554a0 100644 --- a/test/unittest/core/pattern/web/mock_web_delegate.cpp +++ b/test/unittest/core/pattern/web/mock_web_delegate.cpp @@ -1414,4 +1414,11 @@ void WebDelegate::SetBorderRadiusFromWeb(double borderRadiusTopLeft, double bord double borderRadiusBottomLeft, double borderRadiusBottomRight) {} void WebDelegate::SetForceEnableZoom(bool isEnabled) {} bool WebDelegate::IsShowHandle() { return false; } +bool WebDelegate::IsPcMode() +{ + return g_setReturnStatus == STATUS_TRUE; +} +void WebDelegate::OnSwitchFreeMultiWindow(bool enable) {} +void WebDelegate::RegisterFreeMultiWindowListener() {} +void WebDelegate::UnregisterFreeMultiWindowListener() {} } // namespace OHOS::Ace diff --git a/test/unittest/core/pattern/web/web_pattern_test_ng.cpp b/test/unittest/core/pattern/web/web_pattern_test_ng.cpp index e250ee670c538f56d43873e4c3b7f07d7e00090c..11e47dd610cb9d969f4806f47a5fa4a529f7d7bc 100755 --- a/test/unittest/core/pattern/web/web_pattern_test_ng.cpp +++ b/test/unittest/core/pattern/web/web_pattern_test_ng.cpp @@ -2789,7 +2789,7 @@ HWTEST_F(WebPatternTestNg, WindowMaximize_001, TestSize.Level1) webPattern->isAttachedToMainTree_ = true; webPattern->isVisible_ = true; webPattern->renderContextForSurface_ = RenderContext::Create(); - webPattern->WindowMaximize(); + webPattern->WindowMaximize(WebWindowMaximizeReason::MAXIMIZE); #endif } @@ -2814,7 +2814,7 @@ HWTEST_F(WebPatternTestNg, WindowMaximize_002, TestSize.Level1) OHOS::Ace::SetReturnStatus("-1"); auto webInfoType = webPattern->GetWebInfoType(); EXPECT_EQ(webInfoType, WebInfoType::TYPE_UNKNOWN); - webPattern->WindowMaximize(); + webPattern->WindowMaximize(WebWindowMaximizeReason::MAXIMIZE); #endif } @@ -2841,7 +2841,7 @@ HWTEST_F(WebPatternTestNg, WindowMaximize_003, TestSize.Level1) EXPECT_EQ(webInfoType, WebInfoType::TYPE_2IN1); webPattern->layoutMode_ = WebLayoutMode::FIT_CONTENT; webPattern->renderMode_ = RenderMode::ASYNC_RENDER; - webPattern->WindowMaximize(); + webPattern->WindowMaximize(WebWindowMaximizeReason::MAXIMIZE); #endif } @@ -2868,7 +2868,7 @@ HWTEST_F(WebPatternTestNg, WindowMaximize_004, TestSize.Level1) EXPECT_EQ(webInfoType, WebInfoType::TYPE_2IN1); webPattern->layoutMode_ = WebLayoutMode::NONE; webPattern->renderMode_ = RenderMode::SYNC_RENDER; - webPattern->WindowMaximize(); + webPattern->WindowMaximize(WebWindowMaximizeReason::MAXIMIZE); #endif } @@ -2897,7 +2897,7 @@ HWTEST_F(WebPatternTestNg, WindowMaximize_005, TestSize.Level1) webPattern->renderMode_ = RenderMode::ASYNC_RENDER; webPattern->isAttachedToMainTree_ = false; webPattern->isVisible_ = true; - webPattern->WindowMaximize(); + webPattern->WindowMaximize(WebWindowMaximizeReason::MAXIMIZE); #endif } @@ -2926,7 +2926,7 @@ HWTEST_F(WebPatternTestNg, WindowMaximize_006, TestSize.Level1) webPattern->renderMode_ = RenderMode::ASYNC_RENDER; webPattern->isAttachedToMainTree_ = true; webPattern->isVisible_ = false; - webPattern->WindowMaximize(); + webPattern->WindowMaximize(WebWindowMaximizeReason::MAXIMIZE); #endif } @@ -2956,7 +2956,36 @@ HWTEST_F(WebPatternTestNg, WindowMaximize_007, TestSize.Level1) webPattern->isAttachedToMainTree_ = true; webPattern->isVisible_ = true; webPattern->renderContextForSurface_ = nullptr; - webPattern->WindowMaximize(); + webPattern->WindowMaximize(WebWindowMaximizeReason::MAXIMIZE); +#endif +} + +/** + * @tc.name: WindowMaximize_008 + * @tc.desc: WindowMaximize. + * @tc.type: FUNC + */ +HWTEST_F(WebPatternTestNg, WindowMaximize_008, TestSize.Level1) +{ +#ifdef OHOS_STANDARD_SYSTEM + auto* stack = ViewStackProcessor::GetInstance(); + ASSERT_NE(stack, nullptr); + auto nodeId = stack->ClaimNodeId(); + auto frameNode = + FrameNode::GetOrCreateFrameNode(V2::WEB_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr(); }); + stack->Push(frameNode); + auto webPattern = frameNode->GetPattern(); + ASSERT_NE(webPattern, nullptr); + webPattern->OnModifyDone(); + ASSERT_NE(webPattern->delegate_, nullptr); + OHOS::Ace::SetReturnStatus("4"); + auto webInfoType = webPattern->GetWebInfoType(); + EXPECT_EQ(webInfoType, WebInfoType::TYPE_TABLET); + webPattern->layoutMode_ = WebLayoutMode::NONE; + webPattern->renderMode_ = RenderMode::ASYNC_RENDER; + webPattern->isAttachedToMainTree_ = true; + webPattern->isVisible_ = true; + webPattern->WindowMaximize(WebWindowMaximizeReason::EXIT_FREE_MULTI_MODE); #endif }