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 "ability_context_impl.h"
19 #include "ipc_skeleton.h"
20 #include "window.h"
21 #include "window_manager.h"
22 #include "window_option.h"
23 #include "window_scene.h"
24 #include "window_test_utils.h"
25 #include "wm_common.h"
26 
27 using namespace testing;
28 using namespace testing::ext;
29 
30 namespace OHOS {
31 namespace Rosen {
32 namespace {
33 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowAppFloatingWindowTest"};
34 }
35 
36 class TestCameraFloatWindowChangedListener : public ICameraFloatWindowChangedListener {
37 public:
38     uint32_t accessTokenId_ = 0;
39     bool isShowing_ = false;
40     void OnCameraFloatWindowChange(uint32_t accessTokenId, bool isShowing) override;
41 };
42 
43 class WindowAppFloatingWindowTest : public testing::Test {
44 public:
45     static void SetUpTestCase();
46     static void TearDownTestCase();
47     virtual void SetUp() override;
48     virtual void TearDown() override;
49 
50     static inline float virtualPixelRatio_ = 1.0;
51     static inline Rect displayRect_ {0, 0, 0, 0};
52     static inline std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext_ = nullptr;
53     static sptr<TestCameraFloatWindowChangedListener> testCameraFloatWindowChangedListener_;
54 };
55 
56 sptr<TestCameraFloatWindowChangedListener> WindowAppFloatingWindowTest::testCameraFloatWindowChangedListener_ =
57     new TestCameraFloatWindowChangedListener();
58 
OnCameraFloatWindowChange(uint32_t accessTokenId,bool isShowing)59 void TestCameraFloatWindowChangedListener::OnCameraFloatWindowChange(uint32_t accessTokenId, bool isShowing)
60 {
61     WLOGI("TestCameraFloatWindowChangedListener [%{public}u, %{public}u]", accessTokenId, isShowing);
62     accessTokenId_ = accessTokenId;
63     isShowing_ = isShowing;
64 }
65 
SetUpTestCase()66 void WindowAppFloatingWindowTest::SetUpTestCase()
67 {
68     auto display = DisplayManager::GetInstance().GetDisplayById(0);
69     ASSERT_TRUE((display != nullptr));
70     displayRect_.width_ = display->GetWidth();
71     displayRect_.height_ = display->GetHeight();
72     WindowTestUtils::InitByDisplayRect(displayRect_);
73     virtualPixelRatio_ = WindowTestUtils::GetVirtualPixelRatio(0);
74 }
75 
TearDownTestCase()76 void WindowAppFloatingWindowTest::TearDownTestCase()
77 {
78 }
79 
SetUp()80 void WindowAppFloatingWindowTest::SetUp()
81 {
82 }
83 
TearDown()84 void WindowAppFloatingWindowTest::TearDown()
85 {
86 }
87 
CreateWindowScene()88 static sptr<WindowScene> CreateWindowScene()
89 {
90     sptr<IWindowLifeCycle> listener = nullptr;
91     WindowAppFloatingWindowTest::abilityContext_ = std::make_shared<AbilityRuntime::AbilityContextImpl>();
92 
93     sptr<WindowScene> scene = new WindowScene();
94     scene->Init(0, WindowAppFloatingWindowTest::abilityContext_, listener);
95     return scene;
96 }
97 
CreateAppFloatingWindow(WindowType type,Rect rect,std::string name="")98 static sptr<Window> CreateAppFloatingWindow(WindowType type, Rect rect, std::string name = "")
99 {
100     sptr<WindowOption> option = new WindowOption();
101     option->SetWindowType(type);
102     option->SetWindowRect(rect);
103 
104     static int cnt = 0;
105     std::string winName = (name == "") ? "FloatingWindowTest" + std::to_string(cnt++) : name;
106 
107     return Window::Create(winName, option, WindowAppFloatingWindowTest::abilityContext_);
108 }
109 
GetRectWithVpr(int32_t x,int32_t y,uint32_t w,uint32_t h)110 static inline Rect GetRectWithVpr(int32_t x, int32_t y, uint32_t w, uint32_t h)
111 {
112     auto vpr = WindowAppFloatingWindowTest::virtualPixelRatio_;
113     return {x, y, static_cast<uint32_t>(w * vpr), static_cast<uint32_t>(h * vpr)};
114 }
115 
116 /**
117  * @tc.name: AppFloatingWindow01
118  * @tc.desc: AppFloatingWindow life cycle
119  * @tc.type: FUNC
120  */
121 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow01, Function | MediumTest | Level2)
122 {
123     sptr<WindowScene> scene = CreateWindowScene();
124     ASSERT_NE(nullptr, scene);
125 
126     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
127     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT, fltWindRect);
128     ASSERT_NE(nullptr, fltWin);
129     if (scene->GoForeground() == WMError::WM_OK) {
130         ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
131     }
132 
133     ASSERT_EQ(WMError::WM_OK, fltWin->Show());
134 
135     ASSERT_EQ(WMError::WM_OK, fltWin->Hide());
136     if (scene->GoForeground() == WMError::WM_OK) {
137         ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
138     } else {
139         ASSERT_NE(WMError::WM_OK, scene->GoForeground());
140     }
141 
142     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
143 
144     if (scene->GoDestroy() == WMError::WM_OK) {
145         ASSERT_EQ(WMError::WM_ERROR_NULLPTR, scene->GoDestroy());
146     } else {
147         ASSERT_NE(WMError::WM_OK, scene->GoDestroy());
148     }
149 }
150 
151 /**
152  * @tc.name: AppFloatingWindow02
153  * @tc.desc: AppFloatingWindow life cycle, main window hide first
154  * @tc.type: FUNC
155  */
156 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow02, Function | MediumTest | Level3)
157 {
158     sptr<WindowScene> scene = CreateWindowScene();
159     ASSERT_NE(nullptr, scene);
160 
161     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
162     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT, fltWindRect);
163     if (fltWin == nullptr) {
164         return;
165     }
166     ASSERT_NE(nullptr, fltWin);
167     if (scene->GoForeground() == WMError::WM_OK) {
168         ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
169     } else {
170         ASSERT_NE(WMError::WM_OK, scene->GoForeground());
171     }
172 
173     ASSERT_EQ(WMError::WM_OK, fltWin->Show());
174 
175     if (scene->GoForeground() == WMError::WM_OK) {
176         ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
177     } else {
178         ASSERT_NE(WMError::WM_OK, scene->GoForeground());
179     }
180 
181     if (scene->GetMainWindow() == nullptr) {
182         return;
183     }
184     ASSERT_EQ(true, scene->GetMainWindow()->GetWindowState() == WindowState::STATE_SHOWN);
185     ASSERT_EQ(true, fltWin->GetWindowState() == WindowState::STATE_SHOWN);
186     ASSERT_EQ(WMError::WM_OK, fltWin->Hide());
187 
188     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
189     ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
190 }
191 
192 /**
193  * @tc.name: AppFloatingWindow03
194  * @tc.desc: AppFloatingWindow life cycle, app floating window hide first
195  * @tc.type: FUNC
196  */
197 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow03, Function | MediumTest | Level3)
198 {
199     sptr<WindowScene> scene = CreateWindowScene();
200     ASSERT_NE(nullptr, scene);
201 
202     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
203     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT, fltWindRect);
204     if (fltWin == nullptr) {
205         return;
206     }
207     ASSERT_NE(nullptr, fltWin);
208     if (scene->GoForeground() == WMError::WM_OK) {
209         ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
210     } else {
211         ASSERT_NE(WMError::WM_OK, scene->GoForeground());
212     }
213 
214     ASSERT_EQ(WMError::WM_OK, fltWin->Show());
215 
216     ASSERT_EQ(WMError::WM_OK, fltWin->Hide());
217     ASSERT_EQ(false, fltWin->GetWindowState() == WindowState::STATE_SHOWN);
218     if (scene->GetMainWindow() == nullptr) {
219         return;
220     }
221     ASSERT_EQ(true, scene->GetMainWindow()->GetWindowState() == WindowState::STATE_SHOWN);
222     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
223 
224     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
225     ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
226 }
227 
228 /**
229  * @tc.name: AppFloatingWindow04
230  * @tc.desc: AppFloatingWindow life cycle, main window destroy first
231  * @tc.type: FUNC
232  */
233 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow04, Function | MediumTest | Level3)
234 {
235     sptr<WindowScene> scene = CreateWindowScene();
236     ASSERT_NE(nullptr, scene);
237 
238     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
239     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT, fltWindRect);
240     if (fltWin == nullptr) {
241         return;
242     }
243     ASSERT_NE(nullptr, fltWin);
244 
245     if (scene->GoForeground() == WMError::WM_OK) {
246         ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
247         ASSERT_EQ(WMError::WM_OK, fltWin->Show());
248         ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
249     } else {
250         ASSERT_NE(WMError::WM_OK, scene->GoForeground());
251     }
252 
253     if (scene->GetMainWindow() == nullptr) {
254         return;
255     }
256     ASSERT_EQ(nullptr, scene->GetMainWindow());
257     ASSERT_EQ(false, fltWin->GetWindowState() == WindowState::STATE_SHOWN);
258     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
259 }
260 
261 /**
262  * @tc.name: AppFloatingWindow05
263  * @tc.desc: Camera AppFloatingWindow life cycle
264  * @tc.type: FUNC
265  * @tc.require: issueI5NEHO
266  */
267 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow05, Function | MediumTest | Level2)
268 {
269     sptr<WindowScene> scene = CreateWindowScene();
270     ASSERT_NE(nullptr, scene);
271 
272     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
273     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT_CAMERA, fltWindRect);
274     if (fltWin == nullptr) {
275         return;
276     }
277     ASSERT_NE(nullptr, fltWin);
278 
279     if (scene->GoForeground() == WMError::WM_OK) {
280         ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
281         ASSERT_EQ(WMError::WM_OK, fltWin->Show());
282         ASSERT_EQ(WMError::WM_OK, fltWin->Hide());
283         ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
284         ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
285         ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
286     } else {
287         ASSERT_NE(WMError::WM_OK, scene->GoForeground());
288     }
289 }
290 
291 /**
292  * @tc.name: AppFloatingWindow06
293  * @tc.desc: Camera AppFloatingWindow life cycle, main window hide first
294  * @tc.type: FUNC
295  * @tc.require: issueI5NEHO
296  */
297 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow06, Function | MediumTest | Level3)
298 {
299     sptr<WindowScene> scene = CreateWindowScene();
300     ASSERT_NE(nullptr, scene);
301 
302     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
303     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT_CAMERA, fltWindRect);
304     if (fltWin == nullptr) {
305         return;
306     }
307     ASSERT_NE(nullptr, fltWin);
308 
309     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
310     ASSERT_EQ(WMError::WM_OK, fltWin->Show());
311 
312     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
313     if (scene->GetMainWindow() == nullptr) {
314         return;
315     }
316     ASSERT_EQ(false, scene->GetMainWindow()->GetWindowState() == WindowState::STATE_SHOWN);
317     ASSERT_EQ(true, fltWin->GetWindowState() == WindowState::STATE_SHOWN);
318     ASSERT_EQ(WMError::WM_OK, fltWin->Hide());
319 
320     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
321     ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
322 }
323 
324 /**
325  * @tc.name: AppFloatingWindow07
326  * @tc.desc: Camera AppFloatingWindow life cycle, app floating window hide first
327  * @tc.type: FUNC
328  * @tc.require: issueI5NEHO
329  */
330 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow07, Function | MediumTest | Level3)
331 {
332     sptr<WindowScene> scene = CreateWindowScene();
333     ASSERT_NE(nullptr, scene);
334 
335     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
336     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT_CAMERA, fltWindRect);
337     if (fltWin == nullptr) {
338         return;
339     }
340     ASSERT_NE(nullptr, fltWin);
341 
342     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
343     ASSERT_EQ(WMError::WM_OK, fltWin->Show());
344 
345     ASSERT_EQ(WMError::WM_OK, fltWin->Hide());
346     ASSERT_EQ(false, fltWin->GetWindowState() == WindowState::STATE_SHOWN);
347     if (scene->GetMainWindow() == nullptr) {
348         return;
349     }
350     ASSERT_EQ(true, scene->GetMainWindow()->GetWindowState() == WindowState::STATE_SHOWN);
351     ASSERT_EQ(WMError::WM_OK, scene->GoBackground());
352 
353     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
354     ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
355 }
356 
357 /**
358  * @tc.name: AppFloatingWindow08
359  * @tc.desc: Camera AppFloatingWindow life cycle, main window destroy first
360  * @tc.type: FUNC
361  * @tc.require: issueI5NEHO
362  */
363 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow08, Function | MediumTest | Level3)
364 {
365     sptr<WindowScene> scene = CreateWindowScene();
366     ASSERT_NE(nullptr, scene);
367 
368     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
369     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT_CAMERA, fltWindRect);
370     if (fltWin == nullptr) {
371         return;
372     }
373     ASSERT_NE(nullptr, fltWin);
374 
375     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
376     ASSERT_EQ(WMError::WM_OK, fltWin->Show());
377 
378     ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
379 
380     ASSERT_EQ(nullptr, scene->GetMainWindow());
381     ASSERT_EQ(false, fltWin->GetWindowState() == WindowState::STATE_SHOWN);
382     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
383 }
384 
385 /**
386  * @tc.name: AppFloatingWindow09
387  * @tc.desc: Camera AppFloatingWindow rect check
388  * @tc.type: FUNC
389  * @tc.require: issueI5NEHO
390  */
391 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow09, Function | MediumTest | Level3)
392 {
393     sptr<WindowScene> scene = CreateWindowScene();
394     ASSERT_NE(nullptr, scene);
395 
396     Rect fltWindRect = GetRectWithVpr(10, 20, 10, 10);
397     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT_CAMERA, fltWindRect);
398     if (fltWin == nullptr) {
399         return;
400     }
401     ASSERT_NE(nullptr, fltWin);
402 
403     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
404     ASSERT_EQ(WMError::WM_OK, fltWin->Show());
405 
406     Rect exceptRect = {10, 20, 0, 0};
407     uint32_t smallWidth = displayRect_.height_ <= displayRect_.width_ ? displayRect_.height_ : displayRect_.width_;
408     float hwRatio = static_cast<float>(displayRect_.height_) / static_cast<float>(displayRect_.width_);
409     if (smallWidth <= static_cast<uint32_t>(600 * virtualPixelRatio_)) { // sw <= 600dp
410         if (displayRect_.width_ <= displayRect_.height_) {
411             exceptRect.width_= static_cast<uint32_t>(smallWidth * 0.3);
412         } else {
413             exceptRect.width_ = static_cast<uint32_t>(smallWidth * 0.5);
414         }
415     } else {
416         if (displayRect_.width_ <= displayRect_.height_) {
417             exceptRect.width_ = static_cast<uint32_t>(smallWidth * 0.12);
418         } else {
419             exceptRect.width_ = static_cast<uint32_t>(smallWidth * 0.3);
420         }
421     }
422     exceptRect.height_ = static_cast<uint32_t>(exceptRect.width_ * hwRatio);
423     ASSERT_TRUE(WindowTestUtils::RectEqualTo(fltWin, exceptRect));
424 
425     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
426     ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
427 }
428 
429 /**
430  * @tc.name: AppFloatingWindow10
431  * @tc.desc: Camera AppFloatingWindow multi create
432  * @tc.type: FUNC
433  * @tc.require: issueI5NEHO
434  */
435 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow10, Function | MediumTest | Level3)
436 {
437     sptr<WindowScene> scene = CreateWindowScene();
438     ASSERT_NE(nullptr, scene);
439 
440     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
441     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT_CAMERA, fltWindRect);
442     if (fltWin == nullptr) {
443         return;
444     }
445     ASSERT_NE(nullptr, fltWin);
446 
447     sptr<Window> fltWin2 = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT_CAMERA, fltWindRect);
448     ASSERT_EQ(nullptr, fltWin2);
449 
450     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
451     sptr<Window> fltWin3 = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT_CAMERA, fltWindRect);
452     ASSERT_NE(nullptr, fltWin3);
453 
454     ASSERT_EQ(WMError::WM_OK, fltWin3->Destroy());
455     ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
456 }
457 
458 /**
459  * @tc.name: AppFloatingWindow11
460  * @tc.desc: Camera AppFloatingWindow listener
461  * @tc.type: FUNC
462  * @tc.require: issueI5NEHR
463  */
464 HWTEST_F(WindowAppFloatingWindowTest, AppFloatingWindow11, Function | MediumTest | Level2)
465 {
466     uint32_t tokenId = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID());
467     WindowManager::GetInstance().RegisterCameraFloatWindowChangedListener(testCameraFloatWindowChangedListener_);
468     sptr<WindowScene> scene = CreateWindowScene();
469     ASSERT_NE(nullptr, scene);
470 
471     Rect fltWindRect = GetRectWithVpr(0, 0, 400, 600);
472     sptr<Window> fltWin = CreateAppFloatingWindow(WindowType::WINDOW_TYPE_FLOAT_CAMERA, fltWindRect);
473     if (fltWin == nullptr) {
474         return;
475     }
476     ASSERT_NE(nullptr, fltWin);
477 
478     ASSERT_EQ(WMError::WM_OK, scene->GoForeground());
479     ASSERT_EQ(WMError::WM_OK, fltWin->Show());
480 
481     usleep(500000); // 500000us = 0.5s
482     ASSERT_EQ(tokenId, testCameraFloatWindowChangedListener_->accessTokenId_);
483     ASSERT_EQ(true, testCameraFloatWindowChangedListener_->isShowing_);
484 
485     ASSERT_EQ(WMError::WM_OK, fltWin->Hide());
486 
487     usleep(500000); // 500000us = 0.5s
488     ASSERT_EQ(tokenId, testCameraFloatWindowChangedListener_->accessTokenId_);
489     ASSERT_EQ(false, testCameraFloatWindowChangedListener_->isShowing_);
490 
491     ASSERT_EQ(WMError::WM_OK, fltWin->Destroy());
492     ASSERT_EQ(WMError::WM_OK, scene->GoDestroy());
493 
494     WindowManager::GetInstance().UnregisterCameraFloatWindowChangedListener(testCameraFloatWindowChangedListener_);
495 }
496 } // namespace Rosen
497 } // namespace OHOS
498