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 "window.h"
20 #include "window_option.h"
21 #include "window_scene.h"
22 #include "wm_common.h"
23 
24 using namespace testing;
25 using namespace testing::ext;
26 
27 namespace OHOS {
28 namespace Rosen {
29 class WindowSubWindowTest : public testing::Test {
30 public:
31     static void SetUpTestCase();
32     static void TearDownTestCase();
33     virtual void SetUp() override;
34     virtual void TearDown() override;
35 };
36 
SetUpTestCase()37 void WindowSubWindowTest::SetUpTestCase()
38 {
39 }
40 
TearDownTestCase()41 void WindowSubWindowTest::TearDownTestCase()
42 {
43 }
44 
SetUp()45 void WindowSubWindowTest::SetUp()
46 {
47 }
48 
TearDown()49 void WindowSubWindowTest::TearDown()
50 {
51 }
52 
CreateWindowScene()53 static sptr<WindowScene> CreateWindowScene()
54 {
55     sptr<IWindowLifeCycle> listener = nullptr;
56     std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext = nullptr;
57 
58     sptr<WindowScene> scene = new WindowScene();
59     scene->Init(0, abilityContext, listener);
60     return scene;
61 }
62 
CreateSubWindow(sptr<WindowScene> scene,WindowType type,struct Rect rect,uint32_t flags,std::string name="")63 static sptr<Window> CreateSubWindow(sptr<WindowScene> scene, WindowType type,
64     struct Rect rect, uint32_t flags, std::string name = "")
65 {
66     sptr<WindowOption> subOp = new WindowOption();
67     subOp->SetWindowType(type);
68     subOp->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
69     subOp->SetWindowRect(rect);
70     subOp->SetWindowFlags(flags);
71 
72     static int cnt = 0;
73     std::string subWinName = (name == "") ? "SubWindow" + std::to_string(cnt++) : name;
74 
75     return scene->CreateWindow(subWinName, subOp);
76 }
77 
78 /**
79  * @tc.name: SubWindow01
80  * @tc.desc: FullScreen Main Window + Floating SubWindow
81  * @tc.type: FUNC
82  */
83 HWTEST_F(WindowSubWindowTest, SubWindow01, Function | MediumTest | Level2)
84 {
85     sptr<WindowScene> scene = CreateWindowScene();
86 
87     struct Rect rect = {0, 0, 100, 200};
88     uint32_t flags = 0;
89     sptr<Window> subWindow = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, flags);
90     if (subWindow == nullptr) {
91         return;
92     }
93     ASSERT_NE(nullptr, subWindow);
94 
95     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
96     ASSERT_EQ(WMError::WM_OK, subWindow->Show());
97 
98     ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
99     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
100     sleep(1);
101 
102     subWindow->Destroy();
103     scene->GoDestroy();
104 }
105 
106 /**
107  * @tc.name: SubWindow02
108  * @tc.desc: FullScreen Main Window + Floating SubWindow & Parent Limit work
109  * @tc.type: FUNC
110  */
111 HWTEST_F(WindowSubWindowTest, SubWindow02, Function | MediumTest | Level2)
112 {
113     sptr<WindowScene> scene = CreateWindowScene();
114 
115     struct Rect rect = {0, 0, 100, 200};
116     uint32_t flags = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
117     sptr<Window> subWindow = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, flags);
118     if (subWindow == nullptr) {
119         return;
120     }
121     ASSERT_NE(nullptr, subWindow);
122 
123     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
124     ASSERT_EQ(WMError::WM_OK, subWindow->Show());
125 
126     ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
127     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
128     sleep(1);
129 
130     subWindow->Destroy();
131     scene->GoDestroy();
132 }
133 
134 /**
135  * @tc.name: SubWindow03
136  * @tc.desc: FullScreen Main Window + Floating MediaWindow
137  * @tc.type: FUNC
138  */
139 HWTEST_F(WindowSubWindowTest, SubWindow03, Function | MediumTest | Level2)
140 {
141     sptr<WindowScene> scene = CreateWindowScene();
142 
143     struct Rect rect = {0, 2000, 100, 200};
144     uint32_t flags = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
145     sptr<Window> subWindow = CreateSubWindow(scene, WindowType::WINDOW_TYPE_MEDIA, rect, flags);
146     if (subWindow == nullptr) {
147         return;
148     }
149     ASSERT_NE(nullptr, subWindow);
150 
151     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
152     ASSERT_EQ(WMError::WM_OK, subWindow->Show());
153 
154     ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
155     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
156     sleep(1);
157 
158     subWindow->Destroy();
159     scene->GoDestroy();
160 }
161 
162 /**
163  * @tc.name: SubWindow04
164  * @tc.desc: FullScreen Main Window + Floating MediaWindow
165  * @tc.type: FUNC
166  */
167 HWTEST_F(WindowSubWindowTest, SubWindow04, Function | MediumTest | Level2)
168 {
169     sptr<WindowScene> scene = CreateWindowScene();
170 
171     struct Rect rect = {0, 2000, 3000, 2000};
172     uint32_t flags = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
173     sptr<Window> subWindow = CreateSubWindow(scene, WindowType::WINDOW_TYPE_MEDIA, rect, flags);
174     if (subWindow == nullptr) {
175         return;
176     }
177     ASSERT_NE(nullptr, subWindow);
178 
179     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
180     ASSERT_EQ(WMError::WM_OK, subWindow->Show());
181 
182     ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
183     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
184     sleep(1);
185 
186     subWindow->Destroy();
187     scene->GoDestroy();
188 }
189 
190 /**
191  * @tc.name: SubWindow05
192  * @tc.desc: FullScreen Main Window + Floating MediaWindow + Floating SubWindow
193  * @tc.type: FUNC
194  */
195 HWTEST_F(WindowSubWindowTest, SubWindow05, Function | MediumTest | Level3)
196 {
197     sptr<WindowScene> scene = CreateWindowScene();
198 
199     struct Rect rect = {0, 0, 100, 200};
200     uint32_t flags = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
201     sptr<Window> subWindow = CreateSubWindow(scene, WindowType::WINDOW_TYPE_MEDIA, rect, flags);
202     if (subWindow == nullptr) {
203         return;
204     }
205     ASSERT_NE(nullptr, subWindow);
206 
207     sptr<Window> subWindow2 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, flags);
208     ASSERT_NE(nullptr, subWindow2);
209 
210     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
211     ASSERT_EQ(WMError::WM_OK, subWindow->Show());
212     ASSERT_EQ(WMError::WM_OK, subWindow2->Show());
213 
214     ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
215     ASSERT_EQ(WMError::WM_OK, subWindow2->Hide());
216     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
217     sleep(1);
218 
219     subWindow->Destroy();
220     subWindow2->Destroy();
221     scene->GoDestroy();
222 }
223 
224 /**
225  * @tc.name: SubWindow06
226  * @tc.desc: FullScreen Main Window + 2 SubWindows
227  * @tc.type: FUNC
228  */
229 HWTEST_F(WindowSubWindowTest, SubWindow06, Function | MediumTest | Level3)
230 {
231     sptr<WindowScene> scene = CreateWindowScene();
232 
233     struct Rect rect = {0, 0, 100, 200};
234     sptr<Window> subWindow0 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0);
235     if (subWindow0 == nullptr) {
236         return;
237     }
238     ASSERT_NE(nullptr, subWindow0);
239 
240     sptr<Window> subWindow1 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0);
241     ASSERT_NE(nullptr, subWindow1);
242 
243     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
244     ASSERT_EQ(WMError::WM_OK, subWindow0->Show());
245     ASSERT_EQ(WMError::WM_OK, subWindow1->Show());
246 
247     ASSERT_EQ(WMError::WM_OK, subWindow0->Hide());
248     ASSERT_EQ(WMError::WM_OK, subWindow1->Hide());
249     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
250     sleep(1);
251 
252     subWindow0->Destroy();
253     subWindow1->Destroy();
254     scene->GoDestroy();
255 }
256 
257 /**
258  * @tc.name: SubWindow07
259  * @tc.desc: FullScreen Main Window + Floating SubWindow & MainWindow First GoBackground
260  * @tc.type: FUNC
261  */
262 HWTEST_F(WindowSubWindowTest, SubWindow07, Function | MediumTest | Level4)
263 {
264     sptr<WindowScene> scene = CreateWindowScene();
265 
266     struct Rect rect = {0, 0, 100, 200};
267     uint32_t flags = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
268     sptr<Window> subWindow = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, flags);
269     if (subWindow == nullptr) {
270         return;
271     }
272     ASSERT_NE(nullptr, subWindow);
273 
274     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
275     ASSERT_EQ(WMError::WM_OK, subWindow->Show());
276 
277     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
278     ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
279     sleep(1);
280 
281     subWindow->Destroy();
282     scene->GoDestroy();
283 }
284 
285 /**
286  * @tc.name: SubWindow08
287  * @tc.desc: FullScreen Main Window + Floating SubWindow & only show SubWindow
288  * @tc.type: FUNC
289  */
290 HWTEST_F(WindowSubWindowTest, SubWindow08, Function | MediumTest | Level4)
291 {
292     sptr<WindowScene> scene = CreateWindowScene();
293 
294     struct Rect rect = {0, 0, 100, 200};
295     uint32_t flags = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
296     sptr<Window> subWindow = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, flags);
297     if (subWindow == nullptr) {
298         return;
299     }
300     ASSERT_NE(nullptr, subWindow);
301 
302     ASSERT_EQ(WMError::WM_ERROR_INVALID_PARAM, subWindow->Show());
303 }
304 
305 /**
306  * @tc.name: SubWindow09
307  * @tc.desc: FullScreen Main Window + Floating SubWindow & first destroy SubWindow, then destroy MainWindow
308  * @tc.type: FUNC
309  */
310 HWTEST_F(WindowSubWindowTest, SubWindow09, Function | MediumTest | Level2)
311 {
312     sptr<WindowScene> scene = CreateWindowScene();
313 
314     struct Rect rect = {0, 0, 100, 200};
315     uint32_t flags = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
316     sptr<Window> subWindow = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, flags);
317     if (subWindow == nullptr) {
318         return;
319     }
320     ASSERT_NE(nullptr, subWindow);
321 
322     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
323     ASSERT_EQ(WMError::WM_OK, subWindow->Show());
324 
325     ASSERT_EQ(WMError::WM_OK, subWindow->Hide());
326     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
327     sleep(1);
328 
329     ASSERT_EQ(WMError::WM_OK, subWindow->Destroy());
330 
331     subWindow->Destroy();
332     scene->GoDestroy();
333 }
334 
335 /**
336  * @tc.name: SubWindow10
337  * @tc.desc: FullScreen Main Window + Floating SubWindow & first destroy MainWindow, then destroy SubWindow
338  * @tc.type: FUNC
339  */
340 HWTEST_F(WindowSubWindowTest, SubWindow10, Function | MediumTest | Level2)
341 {
342     sptr<WindowScene> scene = CreateWindowScene();
343 
344     struct Rect rect = {0, 0, 100, 200};
345     uint32_t flags = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
346     sptr<Window> subWindow = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, flags);
347     if (subWindow == nullptr) {
348         return;
349     }
350     ASSERT_NE(nullptr, subWindow);
351 
352     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
353     ASSERT_EQ(WMError::WM_OK, subWindow->Show());
354     sleep(1);
355 
356     sptr<Window> mainWindow = scene->GetMainWindow();
357     ASSERT_EQ(WMError::WM_OK, mainWindow->Destroy());
358     ASSERT_EQ(WMError::WM_OK, subWindow->Destroy());
359 
360     scene->GoDestroy();
361 }
362 
363 /**
364  * @tc.name: SubWindow11
365  * @tc.desc: FullScreen Main Window + 5 subWindows
366  * @tc.type: FUNC
367  */
368 HWTEST_F(WindowSubWindowTest, SubWindow11, Function | MediumTest | Level3)
369 {
370     sptr<WindowScene> scene = CreateWindowScene();
371 
372     struct Rect rect = {0, 0, 100, 200};
373     sptr<Window> subWindow0 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0);
374     if (subWindow0 == nullptr) {
375         return;
376     }
377     ASSERT_NE(nullptr, subWindow0);
378 
379     sptr<Window> subWindow1 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0);
380     if (subWindow1 == nullptr) {
381         return;
382     }
383     ASSERT_NE(nullptr, subWindow1);
384 
385     sptr<Window> subWindow2 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0);
386     if (subWindow2 == nullptr) {
387         return;
388     }
389     ASSERT_NE(nullptr, subWindow2);
390 
391     sptr<Window> subWindow3 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0);
392     if (subWindow3 == nullptr) {
393         return;
394     }
395     ASSERT_NE(nullptr, subWindow3);
396 
397     sptr<Window> subWindow4 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0);
398     if (subWindow4 == nullptr) {
399         return;
400     }
401     ASSERT_NE(nullptr, subWindow4);
402     if (scene->GoForeground() == WMError::WM_OK) {
403         ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
404     }
405 
406     ASSERT_EQ(WMError::WM_OK, subWindow0->Show());
407     ASSERT_EQ(WMError::WM_OK, subWindow1->Show());
408     ASSERT_EQ(WMError::WM_OK, subWindow2->Show());
409     ASSERT_EQ(WMError::WM_OK, subWindow3->Show());
410     ASSERT_EQ(WMError::WM_OK, subWindow4->Show());
411 
412     ASSERT_EQ(WMError::WM_OK, subWindow0->Hide());
413     ASSERT_EQ(WMError::WM_OK, subWindow1->Hide());
414     ASSERT_EQ(WMError::WM_OK, subWindow2->Hide());
415     ASSERT_EQ(WMError::WM_OK, subWindow3->Hide());
416     ASSERT_EQ(WMError::WM_OK, subWindow4->Hide());
417     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
418     sleep(1);
419 
420     subWindow0->Destroy();
421     subWindow1->Destroy();
422     subWindow2->Destroy();
423     subWindow3->Destroy();
424     subWindow4->Destroy();
425     scene->GoDestroy();
426 }
427 
428 /**
429  * @tc.name: SubWindow12
430  * @tc.desc: FullScreen Main Window + 2 SubWindows with the same name
431  * @tc.type: FUNC
432  */
433 HWTEST_F(WindowSubWindowTest, SubWindow12, Function | MediumTest | Level3)
434 {
435     sptr<WindowScene> scene = CreateWindowScene();
436 
437     struct Rect rect = {0, 0, 100, 200};
438     sptr<Window> subWindow0 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0, "sub0");
439     sptr<Window> subWindow1 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0, "sub0");
440     if (subWindow0 == nullptr) {
441         return;
442     }
443     if (subWindow1 == nullptr) {
444         return;
445     }
446     ASSERT_NE(nullptr, subWindow0);
447     ASSERT_EQ(nullptr, subWindow1);
448 
449     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
450     ASSERT_EQ(WMError::WM_OK, subWindow0->Show());
451 
452     ASSERT_EQ(WMError::WM_OK, subWindow0->Hide());
453     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
454     sleep(1);
455 
456     subWindow0->Destroy();
457     scene->GoDestroy();
458 }
459 
460 /**
461  * @tc.name: SubWindow13
462  * @tc.desc: FullScreen Main Window + 2 subwindows with the same name but one create after another destroyed
463  * @tc.type: FUNC
464  */
465 HWTEST_F(WindowSubWindowTest, SubWindow13, Function | MediumTest | Level3)
466 {
467     sptr<WindowScene> scene = CreateWindowScene();
468     if (scene->GoForeground() == WMError::WM_OK) {
469         ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
470     }
471 
472     struct Rect rect = {0, 0, 100, 200};
473     sptr<Window> subWindow0 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0, "sub1");
474     if (subWindow0 == nullptr) {
475         return;
476     }
477     ASSERT_NE(nullptr, subWindow0);
478     ASSERT_EQ(WMError::WM_OK, subWindow0->Show());
479     ASSERT_EQ(WMError::WM_OK, subWindow0->Destroy());
480 
481     sptr<Window> subWindow1 = CreateSubWindow(scene, WindowType::WINDOW_TYPE_APP_SUB_WINDOW, rect, 0, "sub1");
482     if (subWindow1 == nullptr) {
483         return;
484     }
485     ASSERT_NE(nullptr, subWindow1);
486     ASSERT_EQ(WMError::WM_OK, subWindow1->Show());
487     ASSERT_EQ(WMError::WM_OK, subWindow1->Destroy());
488 
489     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
490     sleep(1);
491     scene->GoDestroy();
492 }
493 } // namespace Rosen
494 } // namespace OHOS
495