From 104ebf7025885c03c0c7511e4fe855c8035d73cd Mon Sep 17 00:00:00 2001 From: xingyanan Date: Sun, 16 Jan 2022 18:47:51 +0800 Subject: [PATCH] Signed-off-by: xingyanan Change-Id: Ic9c83bacd701ef22f6e4827430406f7f2cef1df1 --- wm/test/systemtest/BUILD.gn | 20 +++- wm/test/systemtest/window_split_test.cpp | 140 +++++++++++++++++++++++ wmserver/include/window_node_container.h | 8 +- wmserver/src/window_inner_manager.cpp | 2 - wmserver/src/window_node_container.cpp | 47 +++++--- wmserver/src/window_root.cpp | 3 +- 6 files changed, 192 insertions(+), 28 deletions(-) create mode 100644 wm/test/systemtest/window_split_test.cpp diff --git a/wm/test/systemtest/BUILD.gn b/wm/test/systemtest/BUILD.gn index 84b5b6172a..c5c734397b 100644 --- a/wm/test/systemtest/BUILD.gn +++ b/wm/test/systemtest/BUILD.gn @@ -9,7 +9,7 @@ # 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. +# limitations under the License. import("//build/test.gni") @@ -19,6 +19,7 @@ group("systemtest") { testonly = true deps = [ + ":wm_window_split_test", ":wm_window_immersive_test", ":wm_window_layout_test", ":wm_window_multi_ability_test", @@ -35,7 +36,7 @@ ohos_systemtest("wm_window_layout_test") { deps = [ ":wm_systemtest_common" ] } -## SystemTest wm_window_layout_test }}} +## SystemTest wm_window_layout_test }}} ## SystemTest wm_window_multi_ability_test {{{ ohos_systemtest("wm_window_multi_ability_test") { @@ -46,7 +47,7 @@ ohos_systemtest("wm_window_multi_ability_test") { deps = [ ":wm_systemtest_common" ] } -## SystemTest wm_window_multi_ability_test }}} +## SystemTest wm_window_multi_ability_test }}} ## SystemTest wm_window_subwindow_test {{{ ohos_systemtest("wm_window_subwindow_test") { @@ -57,7 +58,7 @@ ohos_systemtest("wm_window_subwindow_test") { deps = [ ":wm_systemtest_common" ] } -## SystemTest wm_window_subwindow_test }}} +## SystemTest wm_window_subwindow_test }}} ## SystemTest wm_window_immersive_test {{{ ohos_systemtest("wm_window_immersive_test") { @@ -70,6 +71,17 @@ ohos_systemtest("wm_window_immersive_test") { ## SystemTest wm_window_immersive_test }}} +## SystemTest wm_window_split_test {{{ +ohos_systemtest("wm_window_split_test") { + module_out_path = module_out_path + + sources = [ "window_split_test.cpp" ] + + deps = [ ":wm_systemtest_common" ] +} + +## SystemTest wm_window_split_test }}} + ## Build wm_systemtest_common.a {{{ config("wm_systemtest_common_public_config") { include_dirs = [ diff --git a/wm/test/systemtest/window_split_test.cpp b/wm/test/systemtest/window_split_test.cpp new file mode 100644 index 0000000000..453e4a90d1 --- /dev/null +++ b/wm/test/systemtest/window_split_test.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021 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. + */ + +// gtest +#include +#include "window_test_utils.h" +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace Rosen { +using utils = WindowTestUtils; +class WindowSplitTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp() override; + virtual void TearDown() override; + std::vector> activeWindows_; +}; + +void WindowSplitTest::SetUpTestCase() +{ + +} + +void WindowSplitTest::TearDownTestCase() +{ +} + +void WindowSplitTest::SetUp() +{ + activeWindows_.clear(); +} + +void WindowSplitTest::TearDown() +{ + while (!activeWindows_.empty()) { + ASSERT_EQ(WMError::WM_OK, activeWindows_.back()->Destroy()); + activeWindows_.pop_back(); + } +} + +namespace { + +/** + * @tc.name: SplitWindow01 + * @tc.desc: one primary window and one fullscreen window + * @tc.type: FUNC + * @tc.require: AR000GGTV7 + */ +HWTEST_F(WindowSplitTest, SplitWindow01, Function | MediumTest | Level3) +{ + utils::TestWindowInfo infoFullScreen = { + .name = "fullscreen.1", + .rect = utils::defaultAppRect_, + .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, + .mode = WindowMode::WINDOW_MODE_FULLSCREEN, + .needAvoid = true, + .parentLimit = false, + .parentName = "", + }; + utils::TestWindowInfo infoPrimary = { + .name = "primary.1", + .rect = utils::defaultAppRect_, + .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, + .mode = WindowMode::WINDOW_MODE_SPLIT_PRIMARY, + .needAvoid = true, + .parentLimit = false, + .parentName = "", + }; + const sptr& windowFullScreen = utils::CreateTestWindow(infoFullScreen); + ASSERT_EQ(WMError::WM_OK, windowFullScreen->Show()); + + activeWindows_.push_back(windowFullScreen); + const sptr& windowPrimary = utils::CreateTestWindow(infoPrimary); + ASSERT_EQ(WMError::WM_OK, windowPrimary->Show()); + ASSERT_EQ(WindowMode::WINDOW_MODE_SPLIT_PRIMARY, windowPrimary->GetMode()); + activeWindows_.push_back(windowPrimary); + // show one split primary window + ASSERT_EQ(WindowMode::WINDOW_MODE_SPLIT_SECONDARY, windowFullScreen->GetMode()); + ASSERT_EQ(WMError::WM_OK, windowPrimary->Hide()); + ASSERT_EQ(WindowMode::WINDOW_MODE_FULLSCREEN, windowFullScreen->GetMode()); + ASSERT_EQ(WMError::WM_OK, windowFullScreen->Hide()); +} + +/** + * @tc.name: SplitWindow02 + * @tc.desc: one secondary window and one fullscreen window + * @tc.type: FUNC + * @tc.require: AR000GGTV7 + */ +HWTEST_F(WindowSplitTest, SplitWindow02, Function | MediumTest | Level3) +{ + utils::TestWindowInfo infoFullScreen = { + .name = "fullscreen.2", + .rect = utils::defaultAppRect_, + .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, + .mode = WindowMode::WINDOW_MODE_FULLSCREEN, + .needAvoid = true, + .parentLimit = false, + .parentName = "", + }; + utils::TestWindowInfo infoPrimary = { + .name = "secondary.2", + .rect = utils::defaultAppRect_, + .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, + .mode = WindowMode::WINDOW_MODE_SPLIT_SECONDARY, + .needAvoid = true, + .parentLimit = false, + .parentName = "", + }; + const sptr& windowFullScreen = utils::CreateTestWindow(infoFullScreen); + ASSERT_EQ(WMError::WM_OK, windowFullScreen->Show()); + activeWindows_.push_back(windowFullScreen); + const sptr& windowSecondary = utils::CreateTestWindow(infoPrimary); + ASSERT_EQ(WMError::WM_OK, windowSecondary->Show()); + ASSERT_EQ(WindowMode::WINDOW_MODE_SPLIT_SECONDARY, windowSecondary->GetMode()); + activeWindows_.push_back(windowSecondary); + // show one split primary window + ASSERT_EQ(WindowMode::WINDOW_MODE_SPLIT_PRIMARY, windowFullScreen->GetMode()); + ASSERT_EQ(WMError::WM_OK, windowFullScreen->Hide()); + ASSERT_EQ(WindowMode::WINDOW_MODE_FULLSCREEN, windowSecondary->GetMode()); + ASSERT_EQ(WMError::WM_OK, windowSecondary->Hide()); +} +} +} // namespace Rosen +} // namespace OHOS diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index c50759273b..ba9349b50e 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -52,7 +52,7 @@ public: Rect GetDisplayRect() const; sptr GetTopImmersiveNode() const; void NotifySystemBarIfChanged(); - void HandleSplitWindowModeChange(sptr& triggerNode, bool isChangeToSplit); + WMError HandleSplitWindowModeChange(sptr& triggerNode, bool isChangeToSplit); std::shared_ptr GetDisplayNode() const; void LayoutDividerWindow(sptr& node); void UpdateDisplayInfo(); @@ -87,9 +87,9 @@ private: void SendSplitScreenEvent(WindowMode mode); sptr FindSplitPairNode(sptr& node) const; - void HandleModeChangeToSplit(sptr& triggerNode); - void HandleModeChangeFromSplit(sptr& triggerNode); - void UpdateWindowPairInfo(sptr& triggerNode, sptr& pairNode); + WMError HandleModeChangeToSplit(sptr& triggerNode); + WMError HandleModeChangeFromSplit(sptr& triggerNode); + WMError UpdateWindowPairInfo(sptr& triggerNode, sptr& pairNode); sptr zorderPolicy_ = new WindowZorderPolicy(); sptr belowAppWindowNode_ = new WindowNode(); diff --git a/wmserver/src/window_inner_manager.cpp b/wmserver/src/window_inner_manager.cpp index 4f13b95c0c..29b71e7476 100644 --- a/wmserver/src/window_inner_manager.cpp +++ b/wmserver/src/window_inner_manager.cpp @@ -187,7 +187,6 @@ void WindowInnerManager::HandleMessage() void WindowInnerManager::SendMessage(InnerWMCmd cmdType, uint32_t displayId) { - std::unique_lock lk(mutex_); if (!hasInitThread_) { WLOGFI("Inner window manager thread has not been created"); return; @@ -204,7 +203,6 @@ void WindowInnerManager::SendMessage(InnerWMCmd cmdType, uint32_t displayId) void WindowInnerManager::SendMessage(InnerWMCmd cmdType, uint32_t displayId, const Rect& dividerRect) { - std::unique_lock lk(mutex_); if (!hasInitThread_) { WLOGFI("Inner window manager thread has not been created"); return; diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 210f40cc30..2f917d2aeb 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -115,9 +115,12 @@ WMError WindowNodeContainer::AddWindowNode(sptr& node, sptrparent_ = parentNode; if (node->IsSplitMode()) { - HandleSplitWindowModeChange(node, true); + WMError ret = HandleSplitWindowModeChange(node, true); + if (ret != WMError::WM_OK) { + WLOGFE("Add split window failed!"); + return ret; + } } - UpdateWindowTree(node); UpdateRSTree(node, true); AssignZOrder(); @@ -226,9 +229,12 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr& node) } if (node->IsSplitMode()) { - HandleSplitWindowModeChange(node, false); + WMError ret = HandleSplitWindowModeChange(node, false); + if (ret != WMError::WM_OK) { + WLOGFE("Remove split window failed!"); + return ret; + } } - UpdateRSTree(node, false); UpdateFocusWindow(); layoutPolicy_->RemoveWindowNode(node); @@ -589,23 +595,27 @@ sptr WindowNodeContainer::FindSplitPairNode(sptr& trigge return nullptr; } -void WindowNodeContainer::HandleModeChangeToSplit(sptr& triggerNode) +WMError WindowNodeContainer::HandleModeChangeToSplit(sptr& triggerNode) { WM_FUNCTION_TRACE(); WLOGFI("HandleModeChangeToSplit %{public}d", triggerNode->GetWindowId()); auto pairNode = FindSplitPairNode(triggerNode); if (pairNode != nullptr) { WLOGFI("Window %{public}d find pair %{public}d", triggerNode->GetWindowId(), pairNode->GetWindowId()); - UpdateWindowPairInfo(triggerNode, pairNode); + WMError ret = UpdateWindowPairInfo(triggerNode, pairNode); + if (ret != WMError::WM_OK) { + return ret; + } } else { // sent split event displayRects_->SetSplitRect(DEFAULT_SPLIT_RATIO); SendSplitScreenEvent(triggerNode->GetWindowMode()); } UpdateDisplayInfo(); + return WMError::WM_OK; } -void WindowNodeContainer::HandleModeChangeFromSplit(sptr& triggerNode) +WMError WindowNodeContainer::HandleModeChangeFromSplit(sptr& triggerNode) { WLOGFI("HandleModeChangeFromSplit %{public}d", triggerNode->GetWindowId()); if (pairedWindowMap_.find(triggerNode->GetWindowId()) != pairedWindowMap_.end()) { @@ -614,7 +624,7 @@ void WindowNodeContainer::HandleModeChangeFromSplit(sptr& triggerNod pairNode->GetWindowProperty()->ResumeLastWindowMode(); pairNode->GetWindowToken()->UpdateWindowMode(pairNode->GetWindowMode()); triggerNode->GetWindowProperty()->ResumeLastWindowMode(); - triggerNode->GetWindowToken()->UpdateWindowMode(pairNode->GetWindowMode()); + triggerNode->GetWindowToken()->UpdateWindowMode(triggerNode->GetWindowMode()); pairedWindowMap_.erase(pairNode->GetWindowId()); pairedWindowMap_.erase(triggerNode->GetWindowId()); WLOGFI("Split out, Id[%{public}d, %{public}d], Mode[%{public}d, %{public}d]", @@ -622,22 +632,21 @@ void WindowNodeContainer::HandleModeChangeFromSplit(sptr& triggerNod triggerNode->GetWindowMode(), pairNode->GetWindowMode()); } else { WLOGFE("Split out, but can not find pair in map %{public}d", triggerNode->GetWindowId()); + return WMError::WM_ERROR_INVALID_WINDOW; } if (pairedWindowMap_.empty()) { + WLOGFI("Notify devider to destroy"); SingletonContainer::Get().SendMessage(INNER_WM_DESTROY_DIVIDER, screenId_); } + return WMError::WM_OK; } -void WindowNodeContainer::HandleSplitWindowModeChange(sptr& triggerNode, bool isChangeToSplit) +WMError WindowNodeContainer::HandleSplitWindowModeChange(sptr& triggerNode, bool isChangeToSplit) { - if (isChangeToSplit) { - HandleModeChangeToSplit(triggerNode); - } else { - HandleModeChangeFromSplit(triggerNode); - } + return isChangeToSplit ? HandleModeChangeToSplit(triggerNode) : HandleModeChangeFromSplit(triggerNode); } -void WindowNodeContainer::UpdateWindowPairInfo(sptr& triggerNode, sptr& pairNode) +WMError WindowNodeContainer::UpdateWindowPairInfo(sptr& triggerNode, sptr& pairNode) { float splitRatio = DEFAULT_SPLIT_RATIO; WindowMode triggerMode = triggerNode->GetWindowMode(); @@ -647,7 +656,11 @@ void WindowNodeContainer::UpdateWindowPairInfo(sptr& triggerNode, sp WindowMode::WINDOW_MODE_SPLIT_SECONDARY : WindowMode::WINDOW_MODE_SPLIT_PRIMARY; pairNode->SetWindowMode(pairDstMode); pairNode->GetWindowToken()->UpdateWindowMode(pairDstMode); - layoutPolicy_->AddWindowNode(pairNode); + WMError ret = UpdateWindowNode(pairNode); + if (ret != WMError::WM_OK) { + WLOGFE("Update window pair info failed"); + return ret; + } WLOGFI("Pair FullScreen [%{public}d, %{public}d], Mode[%{public}d, %{public}d], splitRatio = %{public}f", triggerNode->GetWindowId(), pairNode->GetWindowId(), triggerMode, pairDstMode, splitRatio); } else { @@ -671,8 +684,10 @@ void WindowNodeContainer::UpdateWindowPairInfo(sptr& triggerNode, sp pairedWindowMap_.insert(std::pair(pairNode->GetWindowId(), {triggerNode, 1 - splitRatio})); displayRects_->SetSplitRect(splitRatio); + WLOGFI("Notify devider to create"); Rect dividerRect = displayRects_->GetDividerRect(); SingletonContainer::Get().SendMessage(INNER_WM_CREATE_DIVIDER, screenId_, dividerRect); + return WMError::WM_OK; } } } diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 5e99d2312b..2676de0530 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -192,8 +192,7 @@ WMError WindowRoot::HandleSplitWindowModeChange(sptr& node, bool isS WLOGFE("HandleSplitWindowModeChange failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; } - container->HandleSplitWindowModeChange(node, isSplitIn); - return WMError::WM_OK; + return container->HandleSplitWindowModeChange(node, isSplitIn); } WMError WindowRoot::DestroyWindow(uint32_t windowId) -- Gitee