1/*
2 * Copyright (c) 2021-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 <ability_context.h>
19#include "common_test_utils.h"
20#include "window_test_utils.h"
21#include "window.h"
22#include "window_option.h"
23#include "window_scene.h"
24#include "wm_common.h"
25
26using namespace testing;
27using namespace testing::ext;
28
29namespace OHOS {
30namespace Rosen {
31class WindowSystemSubWindowTest : public testing::Test {
32public:
33    static void SetUpTestCase();
34    static void TearDownTestCase();
35    virtual void SetUp() override;
36    virtual void TearDown() override;
37    // define windowTypes_ for SystemSubWindow02
38    std::vector<WindowType> windowTypes_ = {
39        WindowType::WINDOW_TYPE_APP_LAUNCHING,
40        WindowType::WINDOW_TYPE_DOCK_SLICE,
41        WindowType::WINDOW_TYPE_INCOMING_CALL,
42        WindowType::WINDOW_TYPE_SEARCHING_BAR,
43        WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW,
44        WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT,
45        WindowType::WINDOW_TYPE_FLOAT,
46        WindowType::WINDOW_TYPE_TOAST,
47        WindowType::WINDOW_TYPE_STATUS_BAR,
48        WindowType::WINDOW_TYPE_PANEL,
49        WindowType::WINDOW_TYPE_VOLUME_OVERLAY,
50        WindowType::WINDOW_TYPE_NAVIGATION_BAR,
51        WindowType::WINDOW_TYPE_DRAGGING_EFFECT,
52        WindowType::WINDOW_TYPE_POINTER,
53        WindowType::WINDOW_TYPE_LAUNCHER_RECENT,
54        WindowType::WINDOW_TYPE_LAUNCHER_DOCK,
55        WindowType::WINDOW_TYPE_BOOT_ANIMATION,
56        WindowType::WINDOW_TYPE_FREEZE_DISPLAY,
57        WindowType::WINDOW_TYPE_VOICE_INTERACTION,
58        WindowType::WINDOW_TYPE_FLOAT_CAMERA,
59        WindowType::WINDOW_TYPE_PLACEHOLDER,
60        WindowType::WINDOW_TYPE_SCREENSHOT,
61        WindowType::WINDOW_TYPE_GLOBAL_SEARCH,
62    };
63};
64
65void WindowSystemSubWindowTest::SetUpTestCase()
66{
67}
68
69void WindowSystemSubWindowTest::TearDownTestCase()
70{
71}
72
73void WindowSystemSubWindowTest::SetUp()
74{
75}
76
77void WindowSystemSubWindowTest::TearDown()
78{
79}
80
81static sptr<Window> CreateBaseWindow(WindowType type, struct Rect rect, uint32_t flags)
82{
83    sptr<WindowOption> baseOp = new WindowOption();
84    baseOp->SetWindowType(type);
85    baseOp->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
86    baseOp->SetWindowRect(rect);
87    baseOp->SetWindowFlags(flags);
88
89    static int baseCount = 0;
90    std::string baseWindowName = "BaseWindow" + std::to_string(baseCount++);
91    sptr<Window> window = Window::Create(baseWindowName, baseOp, nullptr);
92    return window;
93}
94
95static sptr<Window> CreateAppSubWindow(sptr<Window> parentWindow, WindowType type, struct Rect rect,
96    uint32_t flags, std::string name = "")
97{
98    sptr<WindowOption> subOp = new WindowOption();
99    subOp->SetWindowType(type);
100    subOp->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
101    subOp->SetWindowRect(rect);
102    subOp->SetWindowFlags(flags);
103    subOp->SetParentId(parentWindow->GetWindowId());
104
105    static int cnt = 0;
106    std::string subWinName = (name == "") ? "AppSubWindow" + std::to_string(cnt++) : name;
107    sptr<Window> window = Window::Create(subWinName, subOp);
108    return window;
109}
110
111static sptr<Window> CreateSystemSubWindow(sptr<Window> parentWindow, struct Rect rect,
112    uint32_t flags, std::string name = "")
113{
114    sptr<WindowOption> subOp = new WindowOption();
115    subOp->SetWindowType(WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW);
116    subOp->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
117    subOp->SetWindowRect(rect);
118    subOp->SetWindowFlags(flags);
119    subOp->SetParentId(parentWindow->GetWindowId());
120
121    static int cnt = 0;
122    std::string subWinName = (name == "") ? "SystemSubWindow" + std::to_string(cnt++) : name;
123    sptr<Window> window = Window::Create(subWinName, subOp);
124    return window;
125}
126
127/**
128 * @tc.name: SystemSubWindow01
129 * @tc.desc: create sub windows with below system Windows
130 * @tc.type: FUNC
131 */
132HWTEST_F(WindowSystemSubWindowTest, SystemSubWindow01, Function | MediumTest | Level2)
133{
134    std::vector<WindowType> windowTypes = {
135        WindowType::WINDOW_TYPE_WALLPAPER,
136        WindowType::WINDOW_TYPE_DESKTOP,
137    };
138    for (auto itor = windowTypes.begin(); itor != windowTypes.end(); itor++) {
139        struct Rect baseRect = {0, 0, 100, 200};
140        uint32_t baseFlags = 0;
141        sptr<Window> baseWindow = CreateBaseWindow(static_cast<WindowType>(*itor), baseRect, baseFlags);
142        if (baseWindow == nullptr) {
143            continue;
144        }
145        struct Rect rect = {0, 0, 100, 200};
146        uint32_t flags = 0;
147        sptr<Window> subWindow = CreateSystemSubWindow(baseWindow, rect, flags);
148        if (subWindow == nullptr) {
149            return;
150        }
151
152        ASSERT_NE(nullptr, subWindow);
153
154        ASSERT_EQ(WMError::WM_OK, baseWindow->Show());
155        ASSERT_EQ(WMError::WM_OK, subWindow->Show());
156
157        ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
158        ASSERT_EQ(WMError::WM_OK, baseWindow->Hide());
159
160        ASSERT_EQ(WMError::WM_OK, subWindow->Destroy());
161        ASSERT_EQ(WMError::WM_OK, baseWindow->Destroy());
162    }
163}
164
165/**
166 * @tc.name: SystemSubWindow02
167 * @tc.desc: create sub windows with above system Windows except WINDOW_TYPE_DIALOG
168 * @tc.type: FUNC
169 */
170HWTEST_F(WindowSystemSubWindowTest, SystemSubWindow02, Function | MediumTest | Level2)
171{
172    for (auto itor = windowTypes_.begin(); itor != windowTypes_.end(); itor++) {
173        if (static_cast<WindowType>(*itor) == WindowType::WINDOW_TYPE_FLOAT) {
174            CommonTestUtils::GuaranteeFloatWindowPermission("wms_window_systemsubwindow_test");
175        }
176        struct Rect baseRect = {0, 0, 100, 200};
177        uint32_t baseFlags = 0;
178        sptr<Window> baseWindow = CreateBaseWindow(static_cast<WindowType>(*itor), baseRect, baseFlags);
179        if (baseWindow == nullptr) {
180            continue;
181        }
182
183        struct Rect rect = {0, 0, 100, 200};
184        uint32_t flags = 0;
185        sptr<Window> subWindow = CreateSystemSubWindow(baseWindow, rect, flags);
186        if (subWindow == nullptr) {
187            return;
188        }
189        ASSERT_NE(nullptr, subWindow);
190
191        ASSERT_EQ(WMError::WM_OK, baseWindow->Show());
192        ASSERT_EQ(WMError::WM_OK, subWindow->Show());
193
194        ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
195        ASSERT_EQ(WMError::WM_OK, baseWindow->Hide());
196
197        ASSERT_EQ(WMError::WM_OK, subWindow->Destroy());
198        ASSERT_EQ(WMError::WM_OK, baseWindow->Destroy());
199    }
200}
201
202/**
203 * @tc.name: SystemSubWindow03
204 * @tc.desc: create sub windows with app main Windows, no allow to add as app_main_window's subwindow
205 * @tc.type: FUNC
206 */
207HWTEST_F(WindowSystemSubWindowTest, SystemSubWindow03, Function | MediumTest | Level2)
208{
209
210    std::vector<WindowType> windowTypes = { WindowType::WINDOW_TYPE_APP_MAIN_WINDOW };
211    for (auto itor = windowTypes.begin(); itor != windowTypes.end(); itor++) {
212        struct Rect baseRect = {0, 0, 100, 200};
213        uint32_t baseFlags = 0;
214        sptr<Window> baseWindow = CreateBaseWindow(static_cast<WindowType>(*itor), baseRect, baseFlags);
215        if (baseWindow == nullptr) {
216            return;
217        }
218        ASSERT_NE(nullptr, baseWindow);
219
220        struct Rect rect = {0, 0, 100, 200};
221        uint32_t flags = 0;
222        sptr<Window> subWindow = CreateSystemSubWindow(baseWindow, rect, flags);
223        if (subWindow == nullptr) {
224            return;
225        }
226        ASSERT_EQ(nullptr, subWindow);
227    }
228}
229
230/**
231 * @tc.name: SystemSubWindow04
232 * @tc.desc: create sub windows with app sub Windows
233 * @tc.type: FUNC
234 */
235HWTEST_F(WindowSystemSubWindowTest, SystemSubWindow04, Function | MediumTest | Level2)
236{
237    std::vector<WindowType> windowTypes = {
238        WindowType::WINDOW_TYPE_MEDIA,
239        WindowType::WINDOW_TYPE_APP_SUB_WINDOW,
240        WindowType::WINDOW_TYPE_APP_COMPONENT,
241    };
242    for (auto itor = windowTypes.begin(); itor != windowTypes.end(); itor++) {
243        struct Rect baseRect = {0, 0, 100, 200};
244        uint32_t baseFlags = 0;
245        sptr<Window> baseWindow = CreateBaseWindow(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, baseRect, baseFlags);
246        if (baseWindow == nullptr) {
247            return;
248        }
249        ASSERT_NE(nullptr, baseWindow);
250
251        sptr<Window> appSubWindow = CreateAppSubWindow(baseWindow, static_cast<WindowType>(*itor), baseRect, baseFlags);
252        if (appSubWindow == nullptr) {
253            return;
254        }
255        ASSERT_NE(nullptr, appSubWindow);
256
257        struct Rect rect = {0, 0, 100, 200};
258        uint32_t flags = 0;
259        sptr<Window> subWindow = CreateSystemSubWindow(appSubWindow, rect, flags);
260        ASSERT_EQ(nullptr, subWindow);
261        ASSERT_EQ(WMError::WM_OK, appSubWindow->Destroy());
262        ASSERT_EQ(WMError::WM_OK, baseWindow->Destroy());
263    }
264}
265
266/**
267 * @tc.name: SystemSubWindow05
268 * @tc.desc: create sub windows with system sub Windows
269 * @tc.type: FUNC
270 */
271HWTEST_F(WindowSystemSubWindowTest, SystemSubWindow05, Function | MediumTest | Level3)
272{
273    struct Rect baseRect = {0, 0, 100, 200};
274    uint32_t baseFlags = 0;
275    sptr<Window> baseWindow = CreateBaseWindow(WindowType::WINDOW_TYPE_DOCK_SLICE, baseRect, baseFlags);
276    if (baseWindow == nullptr) {
277        return;
278    }
279    ASSERT_NE(nullptr, baseWindow);
280
281    sptr<Window> systemSubWindow = CreateSystemSubWindow(baseWindow, baseRect, baseFlags);
282    if (systemSubWindow == nullptr) {
283        return;
284    }
285    ASSERT_NE(nullptr, systemSubWindow);
286
287    struct Rect rect = {0, 0, 100, 200};
288    uint32_t flags = 0;
289    sptr<Window> subWindow = CreateSystemSubWindow(systemSubWindow, rect, flags);
290    if (subWindow == nullptr) {
291        return;
292    }
293    ASSERT_EQ(nullptr, subWindow);
294
295    ASSERT_EQ(WMError::WM_OK, baseWindow->Show());
296    ASSERT_EQ(WMError::WM_OK, systemSubWindow->Show());
297
298    ASSERT_EQ(WMError::WM_OK, systemSubWindow->Hide());
299    ASSERT_EQ(WMError::WM_OK, baseWindow->Hide());
300
301    ASSERT_EQ(WMError::WM_OK, systemSubWindow->Destroy());
302    ASSERT_EQ(WMError::WM_OK, baseWindow->Destroy());
303}
304
305/**
306 * @tc.name: SystemSubWindow06
307 * @tc.desc: FullScreen Main Window + 2 SubWindows
308 * @tc.type: FUNC
309 */
310HWTEST_F(WindowSystemSubWindowTest, SystemSubWindow06, Function | MediumTest | Level3)
311{
312    struct Rect baseRect = {0, 0, 100, 200};
313    uint32_t baseFlags = 0;
314    sptr<Window> baseWindow = CreateBaseWindow(WindowType::WINDOW_TYPE_DOCK_SLICE, baseRect, baseFlags);
315    if (baseWindow == nullptr) {
316        return;
317    }
318    ASSERT_NE(nullptr, baseWindow);
319
320    struct Rect rect = {0, 0, 100, 200};
321    uint32_t flags = 0;
322    sptr<Window> subWindow = CreateSystemSubWindow(baseWindow, rect, flags);
323    if (subWindow == nullptr) {
324        return;
325    }
326    ASSERT_NE(nullptr, subWindow);
327
328    ASSERT_EQ(WMError::WM_OK, baseWindow->Show());
329    ASSERT_EQ(WMError::WM_OK, subWindow->Show());
330
331    bool isFocus = subWindow->GetFocusable();
332    ASSERT_EQ(WMError::WM_OK, subWindow->SetFocusable(!isFocus));
333    ASSERT_EQ(WMError::WM_OK, subWindow->MoveTo(0, 0));
334    ASSERT_EQ(WMError::WM_OK, subWindow->Resize(200, 400));
335    ASSERT_EQ(WMError::WM_OK, subWindow->SetTurnScreenOn(true));
336
337    ASSERT_EQ(WMError::WM_ERROR_INVALID_TYPE, subWindow->SetBrightness(0.5f));
338    ASSERT_EQ(WMError::WM_OK, subWindow->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN));
339
340    ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
341    ASSERT_EQ(WMError::WM_OK, baseWindow->Hide());
342
343    ASSERT_EQ(WMError::WM_OK, subWindow->Destroy());
344    ASSERT_EQ(WMError::WM_OK, baseWindow->Destroy());
345}
346/**
347 * @tc.name: SystemSubWindow07
348 * @tc.desc: create sub windows with dialog
349 * @tc.type: FUNC
350 */
351HWTEST_F(WindowSystemSubWindowTest, SystemSubWindow07, Function | MediumTest | Level3)
352{
353    struct Rect baseRect = {0, 0, 100, 200};
354    uint32_t baseFlags = 0;
355    sptr<Window> baseWindow = CreateBaseWindow(WindowType::WINDOW_TYPE_DIALOG, baseRect, baseFlags);
356    if (baseWindow == nullptr) {
357        return;
358    }
359    ASSERT_NE(nullptr, baseWindow);
360
361    struct Rect rect = {0, 0, 100, 200};
362    uint32_t flags = 0;
363    sptr<Window> subWindow = CreateSystemSubWindow(baseWindow, rect, flags);
364    if (subWindow == nullptr) {
365        return;
366    }
367    ASSERT_NE(nullptr, subWindow);
368    ASSERT_EQ(WMError::WM_OK, baseWindow->Destroy());
369}
370} // namespace Rosen
371} // namespace OHOS
372