1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16// gtest
17#include <gtest/gtest.h>
18#include "window_test_utils.h"
19
20#include "display_manager.h"
21#include "display_manager_proxy.h"
22#include "future.h"
23#include "screen_manager.h"
24#include "window_manager.h"
25#include "window_accessibility_controller.h"
26#include "window_impl.h"
27#include "wm_common.h"
28
29using namespace testing;
30using namespace testing::ext;
31
32namespace OHOS {
33namespace Rosen {
34using Utils = WindowTestUtils;
35class DisplayListener : public DisplayManager::IDisplayListener {
36public:
37    virtual void OnCreate(DisplayId) override;
38    virtual void OnDestroy(DisplayId) override;
39    virtual void OnChange(DisplayId) override;
40    RunnableFuture<DisplayId> changeFuture_;
41};
42
43class ScreenListener : public ScreenManager::IScreenListener {
44public:
45    virtual void OnConnect(ScreenId) override;
46    virtual void OnDisconnect(ScreenId) override;
47    virtual void OnChange(ScreenId) override;
48    RunnableFuture<ScreenId> changeFuture_;
49};
50
51class WindowRotationTest : public testing::Test {
52public:
53    static void SetUpTestCase();
54    static void TearDownTestCase();
55    virtual void SetUp() override;
56    virtual void TearDown() override;
57    std::vector<sptr<Window>> activeWindows_;
58    Utils::TestWindowInfo fullInfo_;
59    sptr<DisplayListener> displayListener_;
60    sptr<ScreenListener> screenListener_;
61private:
62    static constexpr uint32_t SPLIT_TEST_SLEEP_S = 1;
63    static constexpr long FUTURE_GET_RESULT_TIMEOUT = 1000;
64    static constexpr uint32_t WAIT_SYNC_IN_NS = 200000;
65};
66
67void DisplayListener::OnCreate(DisplayId displayId)
68{
69}
70
71void DisplayListener::OnDestroy(DisplayId displayId)
72{
73}
74
75void DisplayListener::OnChange(DisplayId displayId)
76{
77    changeFuture_.SetValue(displayId);
78}
79
80void ScreenListener::OnConnect(ScreenId screenId)
81{
82}
83
84void ScreenListener::OnDisconnect(ScreenId screenId)
85{
86}
87
88void ScreenListener::OnChange(ScreenId screenId)
89{
90    changeFuture_.SetValue(screenId);
91}
92
93void WindowRotationTest::SetUpTestCase()
94{
95}
96
97void WindowRotationTest::TearDownTestCase()
98{
99}
100
101void WindowRotationTest::SetUp()
102{
103    fullInfo_ = {
104            .name = "",
105            .rect = Utils::customAppRect_,
106            .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
107            .mode = WindowMode::WINDOW_MODE_FULLSCREEN,
108            .needAvoid = true,
109            .parentLimit = false,
110            .showWhenLocked = true,
111            .parentId = INVALID_WINDOW_ID,
112    };
113
114    activeWindows_.clear();
115    displayListener_ = new DisplayListener();
116    DisplayManager::GetInstance().RegisterDisplayListener(displayListener_);
117    screenListener_ = new ScreenListener();
118    ScreenManager::GetInstance().RegisterScreenListener(screenListener_);
119}
120
121void WindowRotationTest::TearDown()
122{
123    while (!activeWindows_.empty()) {
124        ASSERT_EQ(WMError::WM_OK, activeWindows_.back()->Destroy());
125        activeWindows_.pop_back();
126    }
127    DisplayManager::GetInstance().UnregisterDisplayListener(displayListener_);
128    ScreenManager::GetInstance().UnregisterScreenListener(screenListener_);
129    usleep(WAIT_SYNC_IN_NS);
130}
131
132namespace {
133/**
134* @tc.name: WindowRotationTest1
135* @tc.desc: create window and SetRequestedOrientation.
136* @tc.type: FUNC
137*/
138HWTEST_F(WindowRotationTest, WindowRotationTest1, Function | MediumTest | Level3)
139{
140    fullInfo_.name  = "fullscreen.1";
141    fullInfo_.orientation_ = Orientation::UNSPECIFIED;
142    const sptr<Window>& fullWindow = Utils::CreateTestWindow(fullInfo_);
143    if (fullWindow == nullptr) {
144        return;
145    }
146    activeWindows_.push_back(fullWindow);
147    ASSERT_EQ(WMError::WM_OK, fullWindow->Show());
148    ASSERT_EQ(WindowMode::WINDOW_MODE_FULLSCREEN, fullWindow->GetMode());
149    sleep(SPLIT_TEST_SLEEP_S);
150
151    fullWindow->SetRequestedOrientation(Orientation::REVERSE_HORIZONTAL);
152    sleep(SPLIT_TEST_SLEEP_S);
153    ASSERT_EQ(Orientation::REVERSE_HORIZONTAL, fullWindow->GetRequestedOrientation());
154    DisplayId displayId = displayListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT);
155    displayListener_->changeFuture_.Reset(-1);
156    ScreenId screenId = screenListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT);
157    screenListener_->changeFuture_.Reset(-1);
158    auto screen = ScreenManager::GetInstance().GetScreenById(screenId);
159    auto display = DisplayManager::GetInstance().GetDisplayById(displayId);
160    ASSERT_EQ(Orientation::REVERSE_HORIZONTAL, screen->GetOrientation());
161    ASSERT_EQ(Orientation::REVERSE_HORIZONTAL, display->GetOrientation());
162    sleep(SPLIT_TEST_SLEEP_S);
163
164    ASSERT_EQ(WMError::WM_OK, fullWindow->Hide());
165    sleep(SPLIT_TEST_SLEEP_S);
166    ASSERT_EQ(Rotation::ROTATION_0, screen->GetRotation());
167}
168
169/**
170* @tc.name: WindowRotationTest2
171* @tc.desc: create window with orientation property.
172* @tc.type: FUNC
173*/
174HWTEST_F(WindowRotationTest, WindowRotationTest2, Function | MediumTest | Level3)
175{
176    fullInfo_.name  = "fullscreen.2";
177    fullInfo_.orientation_ = Orientation::REVERSE_HORIZONTAL;
178    const sptr<Window>& fullWindow = Utils::CreateTestWindow(fullInfo_);
179    if (fullWindow == nullptr) {
180        return;
181    }
182    activeWindows_.push_back(fullWindow);
183
184    ASSERT_EQ(WMError::WM_OK, fullWindow->Show());
185    ASSERT_EQ(WindowMode::WINDOW_MODE_FULLSCREEN, fullWindow->GetMode());
186    sleep(SPLIT_TEST_SLEEP_S);
187
188    ASSERT_EQ(Orientation::REVERSE_HORIZONTAL, fullWindow->GetRequestedOrientation());
189    sleep(SPLIT_TEST_SLEEP_S);
190    DisplayId displayId = displayListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT);
191    ScreenId screenId = screenListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT);
192    auto screen = ScreenManager::GetInstance().GetScreenById(screenId);
193    auto display = DisplayManager::GetInstance().GetDisplayById(displayId);
194    ASSERT_EQ(Orientation::REVERSE_HORIZONTAL, screen->GetOrientation());
195    ASSERT_EQ(Orientation::REVERSE_HORIZONTAL, display->GetOrientation());
196    sleep(SPLIT_TEST_SLEEP_S);
197
198    ASSERT_EQ(WMError::WM_OK, fullWindow->Hide());
199    sleep(SPLIT_TEST_SLEEP_S);
200    screen->SetOrientation(Orientation::UNSPECIFIED);
201    displayListener_->changeFuture_.Reset(-1);
202    screenListener_->changeFuture_.Reset(-1);
203    sleep(SPLIT_TEST_SLEEP_S);
204}
205
206/**
207* @tc.name: WindowRotationTest3
208* @tc.desc: create floating window with orientation property
209* @tc.type: FUNC
210*/
211HWTEST_F(WindowRotationTest, WindowRotationTest3, Function | MediumTest | Level3)
212{
213    auto display = DisplayManager::GetInstance().GetDefaultDisplay();
214    ASSERT_NE(display, nullptr);
215    auto curDisplayOrientation = display->GetOrientation();
216
217    fullInfo_.name  = "fullscreen.3";
218    fullInfo_.orientation_ = Orientation::REVERSE_HORIZONTAL;
219    fullInfo_.mode = WindowMode::WINDOW_MODE_FLOATING;
220    const sptr<Window>& fullWindow = Utils::CreateTestWindow(fullInfo_);
221    if (fullWindow == nullptr) {
222        return;
223    }
224    activeWindows_.push_back(fullWindow);
225    ASSERT_EQ(WMError::WM_OK, fullWindow->Show());
226    ASSERT_EQ(WindowMode::WINDOW_MODE_FLOATING, fullWindow->GetMode());
227    sleep(SPLIT_TEST_SLEEP_S);
228
229    ASSERT_EQ(Orientation::REVERSE_HORIZONTAL, fullWindow->GetRequestedOrientation());
230    sleep(SPLIT_TEST_SLEEP_S);
231    ASSERT_EQ(curDisplayOrientation, display->GetOrientation());
232    sleep(SPLIT_TEST_SLEEP_S);
233
234    curDisplayOrientation = display->GetOrientation();
235    ASSERT_EQ(WMError::WM_OK, fullWindow->Hide());
236    sleep(SPLIT_TEST_SLEEP_S);
237    ASSERT_EQ(curDisplayOrientation, display->GetOrientation());
238    sleep(SPLIT_TEST_SLEEP_S);
239}
240
241
242/**
243* @tc.name: WindowRotationTest4
244* @tc.desc: create window with orientation after setting screen default orientation.
245* @tc.type: FUNC
246*/
247HWTEST_F(WindowRotationTest, WindowRotationTest4, Function | MediumTest | Level3)
248{
249    auto displayDefault = DisplayManager::GetInstance().GetDefaultDisplay();
250    ASSERT_NE(displayDefault, nullptr);
251    ScreenId defaultScreenId = displayDefault->GetScreenId();
252    auto defaultScreen = ScreenManager::GetInstance().GetScreenById(defaultScreenId);
253    defaultScreen->SetOrientation(Orientation::REVERSE_HORIZONTAL);
254    sleep(SPLIT_TEST_SLEEP_S);
255
256    fullInfo_.name  = "fullscreen.4";
257    fullInfo_.orientation_ = Orientation::HORIZONTAL;
258    const sptr<Window>& fullWindow = Utils::CreateTestWindow(fullInfo_);
259    if (fullWindow == nullptr) {
260        return;
261    }
262    activeWindows_.push_back(fullWindow);
263    ASSERT_EQ(WMError::WM_OK, fullWindow->Show());
264    ASSERT_EQ(WindowMode::WINDOW_MODE_FULLSCREEN, fullWindow->GetMode());
265    sleep(SPLIT_TEST_SLEEP_S);
266
267    ASSERT_EQ(Orientation::HORIZONTAL, fullWindow->GetRequestedOrientation());
268    DisplayId displayId = displayListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT);
269    displayListener_->changeFuture_.Reset(-1);
270    ScreenId screenId = screenListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT);
271    screenListener_->changeFuture_.Reset(-1);
272    auto screen = ScreenManager::GetInstance().GetScreenById(screenId);
273    auto display = DisplayManager::GetInstance().GetDisplayById(displayId);
274    sleep(SPLIT_TEST_SLEEP_S);
275    ASSERT_EQ(Orientation::HORIZONTAL, screen->GetOrientation());
276    ASSERT_EQ(Orientation::HORIZONTAL, display->GetOrientation());
277
278    ASSERT_EQ(WMError::WM_OK, fullWindow->Hide());
279    sleep(SPLIT_TEST_SLEEP_S);
280    defaultScreen->SetOrientation(Orientation::UNSPECIFIED);
281    sleep(SPLIT_TEST_SLEEP_S);
282}
283
284/**
285* @tc.name: WindowRotationTest5
286* @tc.desc: create window with orientation after setting screen default orientation, and toggle shown state for all app
287*           windows.
288* @tc.type: FUNC
289*/
290HWTEST_F(WindowRotationTest, WindowRotationTest5, Function | MediumTest | Level3)
291{
292    auto displayDefault = DisplayManager::GetInstance().GetDefaultDisplay();
293    ASSERT_NE(displayDefault, nullptr);
294    ScreenId defaultScreenId = displayDefault->GetScreenId();
295    auto defaultScreen = ScreenManager::GetInstance().GetScreenById(defaultScreenId);
296    defaultScreen->SetOrientation(Orientation::REVERSE_HORIZONTAL);
297    sleep(SPLIT_TEST_SLEEP_S);
298
299    fullInfo_.name  = "fullscreen.5";
300    fullInfo_.orientation_ = Orientation::HORIZONTAL;
301    const sptr<Window>& fullWindow = Utils::CreateTestWindow(fullInfo_);
302    if (fullWindow == nullptr) {
303        return;
304    }
305    activeWindows_.push_back(fullWindow);
306    ASSERT_EQ(WMError::WM_OK, fullWindow->Show());
307    ASSERT_EQ(WindowMode::WINDOW_MODE_FULLSCREEN, fullWindow->GetMode());
308    sleep(SPLIT_TEST_SLEEP_S);
309
310    ASSERT_EQ(Orientation::HORIZONTAL, fullWindow->GetRequestedOrientation());
311    sleep(SPLIT_TEST_SLEEP_S);
312    DisplayId displayId = displayListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT);
313    displayListener_->changeFuture_.Reset(-1);
314    ScreenId screenId = screenListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT);
315    screenListener_->changeFuture_.Reset(-1);
316    auto screen = ScreenManager::GetInstance().GetScreenById(screenId);
317    auto display = DisplayManager::GetInstance().GetDisplayById(displayId);
318    ASSERT_EQ(Orientation::HORIZONTAL, display->GetOrientation());
319
320    WindowManager::GetInstance().ToggleShownStateForAllAppWindows();
321    sleep(SPLIT_TEST_SLEEP_S);
322    ASSERT_EQ(WMError::WM_OK, fullWindow->Hide());
323    sleep(SPLIT_TEST_SLEEP_S);
324
325    WindowManager::GetInstance().ToggleShownStateForAllAppWindows();
326    sleep(SPLIT_TEST_SLEEP_S);
327
328    ASSERT_EQ(WMError::WM_OK, fullWindow->Hide());
329    sleep(SPLIT_TEST_SLEEP_S);
330    defaultScreen->SetOrientation(Orientation::UNSPECIFIED);
331    sleep(SPLIT_TEST_SLEEP_S);
332}
333}
334} // namespace Rosen
335} // namespace OHOS
336