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