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#include <gtest/gtest.h> 16#include <transaction/rs_transaction.h> 17#include <ui/rs_surface_node.h> 18#include "display_test_utils.h" 19#include "display.h" 20#include "display_manager_proxy.h" 21#include "screen.h" 22#include "surface_draw.h" 23#include "wm_common.h" 24#include "wm_common_inner.h" 25#include "window.h" 26#include "window_option.h" 27#include "window_manager_hilog.h" 28#include "display_manager_agent_controller.h" 29 30using namespace testing; 31using namespace testing::ext; 32 33namespace OHOS::Rosen { 34namespace { 35constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DisplayManagerTest"}; 36const int WAIT_FOR_SYNC_US = 1; // 1s 37} 38 39class DisplayChangeEventListener : public DisplayManager::IDisplayListener { 40public: 41 virtual void OnCreate(DisplayId displayId) {} 42 43 virtual void OnDestroy(DisplayId displayId) {} 44 45 virtual void OnChange(DisplayId displayId) {} 46}; 47 48class DisplayManagerTest : public testing::Test { 49public: 50 static void SetUpTestCase(); 51 static void TearDownTestCase(); 52 virtual void SetUp() override; 53 virtual void TearDown() override; 54 55 sptr<Window> CreateWindow(std::string name, WindowMode mode, Rect rect, uint32_t color = 0xff000000); 56 bool DrawWindowColor(const sptr<Window>& window, uint32_t color, int32_t width, int32_t height); 57 static inline DisplayId displayId_; 58 static inline int32_t displayWidth_; 59 static inline int32_t displayHeight_; 60}; 61 62void DisplayManagerTest::SetUpTestCase() 63{ 64 displayId_ = DisplayManager::GetInstance().GetDefaultDisplayId(); 65 sptr<Display> display = DisplayManager::GetInstance().GetDefaultDisplay(); 66 if (display == nullptr) { 67 return; 68 } 69 displayWidth_ = display->GetWidth(); 70 displayHeight_ = display->GetHeight(); 71} 72 73void DisplayManagerTest::TearDownTestCase() 74{ 75} 76 77void DisplayManagerTest::SetUp() 78{ 79} 80 81void DisplayManagerTest::TearDown() 82{ 83} 84 85sptr<Window> DisplayManagerTest::CreateWindow(std::string name, 86 WindowMode mode, Rect rect, uint32_t color) 87{ 88 sptr<WindowOption> option = new WindowOption(); 89 option->SetDisplayId(displayId_); 90 option->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); 91 int32_t width = 0; 92 int32_t height = 0; 93 if (mode != WindowMode::WINDOW_MODE_FULLSCREEN) { 94 option->SetWindowRect(rect); 95 } else { 96 width = displayWidth_; 97 height = displayHeight_; 98 } 99 option->SetWindowMode(mode); 100 option->SetWindowName(name); 101 sptr<Window> window = Window::Create(option->GetWindowName(), option); 102 if (window == nullptr) { 103 return nullptr; 104 } 105 window->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED); 106 window->Show(); 107 sleep(WAIT_FOR_SYNC_US); // wait for rect updated 108 width = window->GetRect().width_; 109 height = window->GetRect().height_; 110 DrawWindowColor(window, color, width, height); // 0x66000000 color_black 111 RSTransaction::FlushImplicitTransaction(); 112 return window; 113} 114 115bool DisplayManagerTest::DrawWindowColor(const sptr<Window>& window, uint32_t color, int32_t width, int32_t height) 116{ 117 auto surfaceNode = window->GetSurfaceNode(); 118 if (surfaceNode == nullptr) { 119 WLOGFE("Failed to GetSurfaceNode!"); 120 return false; 121 } 122 SurfaceDraw::DrawColor(surfaceNode, width, height, color); 123 surfaceNode->SetAbilityBGAlpha(255); // 255 is alpha 124 return true; 125} 126 127namespace { 128/** 129 * @tc.name: HasPrivateWindow 130 * @tc.desc: Check whether there is a private window in the current display 131 * @tc.type: FUNC 132 * @tc.require issueI5HF6V 133 */ 134HWTEST_F(DisplayManagerTest, HasPrivateWindow, Function | SmallTest | Level2) 135{ 136 sptr<Window> window = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); 137 if (window == nullptr) { 138 return; 139 } 140 ASSERT_NE(nullptr, window); 141 window->SetPrivacyMode(true); 142 sleep(WAIT_FOR_SYNC_US); 143 bool hasPrivateWindow = false; 144 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); 145 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); 146 147 window->SetPrivacyMode(false); 148 sleep(WAIT_FOR_SYNC_US); 149 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); 150 window->Destroy(); 151 ASSERT_TRUE(!hasPrivateWindow); 152} 153 154/** 155 * @tc.name: HasPrivateWindowCovered 156 * @tc.desc: The private window is covered 157 * @tc.type: FUNC 158 * @tc.require issueI5HF6V 159 */ 160HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered, Function | SmallTest | Level2) 161{ 162 auto displayWidth = DisplayManagerTest::displayWidth_; 163 auto displayHeight = DisplayManagerTest::displayHeight_; 164 165 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); 166 if (window1 == nullptr) { 167 return; 168 } 169 ASSERT_NE(nullptr, window1); 170 // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height 171 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, 172 Rect{0, 0, 300, 300}, 0xffff0000); 173 ASSERT_NE(nullptr, window2); 174 window2->SetPrivacyMode(true); 175 // The window shadows is too large to cover. so, set a special position for cover window easily. 176 sleep(WAIT_FOR_SYNC_US); 177 window2->MoveTo(displayWidth * 0.53, displayHeight * 0.66); 178 sleep(WAIT_FOR_SYNC_US); 179 180 // 10:rect.posX_, 110:rect.posY_, 650:rect.width, 500:rect.height 181 sptr<Window> window3 = CreateWindow("covered", WindowMode::WINDOW_MODE_FLOATING, 182 Rect{0, 0, displayWidth, displayHeight}, 0xff00ff00); 183 ASSERT_NE(nullptr, window3); 184 sleep(WAIT_FOR_SYNC_US); 185 window3->MoveTo(45, 115); 186 sleep(WAIT_FOR_SYNC_US); 187 188 bool hasPrivateWindow = false; 189 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); 190 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); 191 window1->Destroy(); 192 window2->Destroy(); 193 window3->Destroy(); 194 if (!hasPrivateWindow) { 195 ASSERT_TRUE(!hasPrivateWindow); 196 } 197} 198 199/** 200 * @tc.name: HasPrivateWindowCovered01 201 * @tc.desc: The private window is partially covered 202 * @tc.type: FUNC 203 * @tc.require issueI5HF6V 204 */ 205HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered01, Function | SmallTest | Level2) 206{ 207 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect{0, 0, 0, 0}); 208 209 // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height 210 if (window1 == nullptr) 211 { 212 return; 213 } 214 ASSERT_NE(nullptr, window1); 215 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, 216 Rect{10, 120, 650, 500}, 0xffff0000); 217 ASSERT_NE(nullptr, window2); 218 window2->SetPrivacyMode(true); 219 // 5:rect.posX_, 110:rect.posY_, 650:rect.width, 500:rect.height 220 sptr<Window> window3 = CreateWindow("covered", WindowMode::WINDOW_MODE_FLOATING, 221 Rect{5, 110, 650, 500}, 0xff00ff00); 222 ASSERT_NE(nullptr, window3); 223 224 sleep(WAIT_FOR_SYNC_US); 225 bool hasPrivateWindow = false; 226 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); 227 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); 228 window1->Destroy(); 229 window2->Destroy(); 230 window3->Destroy(); 231 if (hasPrivateWindow) 232 { 233 ASSERT_TRUE(hasPrivateWindow); 234 } 235} 236 237/** 238 * @tc.name: HasPrivateWindowCovered02 239 * @tc.desc: The private window is covered 240 * @tc.type: FUNC 241 * @tc.require issueI5HF6V 242 */ 243HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered02, Function | SmallTest | Level2) 244{ 245 auto displayWidth = DisplayManagerTest::displayWidth_; 246 auto displayHeight = DisplayManagerTest::displayHeight_; 247 248 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); 249 if (window1 == nullptr) { 250 return; 251 } 252 ASSERT_NE(nullptr, window1); 253 // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height 254 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, 255 Rect {0, 0, 300, 300}, 0xffff0000); 256 ASSERT_NE(nullptr, window2); 257 window2->SetPrivacyMode(true); 258 // The window shadows is too large to cover. so, set a special position for cover window easily. 259 sleep(WAIT_FOR_SYNC_US); 260 window2->MoveTo(displayWidth * 0.53, displayHeight * 0.66); 261 sleep(WAIT_FOR_SYNC_US); 262 263 // 5:rect.posX_, 110:rect.posY_, 655:rect.width, 500:rect.height 264 sptr<Window> window3 = CreateWindow("covered1", WindowMode::WINDOW_MODE_FLOATING, 265 Rect { 0, 0, displayWidth, displayHeight / 2}, 0xff00ff00); 266 ASSERT_NE(nullptr, window3); 267 sleep(WAIT_FOR_SYNC_US); 268 window3->MoveTo(45, 115); 269 sleep(WAIT_FOR_SYNC_US); 270 271 // 5:rect.posX_, 300:rect.posY_, 655:rect.width, 500:rect.height 272 sptr<Window> window4 = CreateWindow("covered2", WindowMode::WINDOW_MODE_FLOATING, 273 Rect { 0, 0, displayWidth, displayHeight / 2 + 200 }, 0xff00ff00); 274 ASSERT_NE(nullptr, window4); 275 window4->MoveTo(45, displayHeight / 2 - 95); 276 277 sleep(WAIT_FOR_SYNC_US); 278 bool hasPrivateWindow = false; 279 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); 280 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); 281 window1->Destroy(); 282 window2->Destroy(); 283 window3->Destroy(); 284 window4->Destroy(); 285 if (!hasPrivateWindow) { 286 ASSERT_TRUE(!hasPrivateWindow); 287 } 288} 289 290/** 291 * @tc.name: HasPrivateWindowCovered03 292 * @tc.desc: The private window is partially covered 293 * @tc.type: FUNC 294 * @tc.require issueI5HF6V 295 */ 296HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered03, Function | SmallTest | Level2) 297{ 298 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); 299 300 if (window1 == nullptr) { 301 return; 302 } 303 ASSERT_NE(nullptr, window1); 304 // 10:rect.posX_, 120:rect.pos_Y, rect.width_:650, rect.height_:700 305 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, 306 Rect{10, 120, 650, 700}, 0xffff0000); 307 ASSERT_NE(nullptr, window2); 308 window2->SetPrivacyMode(true); 309 // 5:rect.posX_, 110:rect.pos_Y, rect.width_:655, rect.height_:500 310 sptr<Window> window3 = CreateWindow("covered1", WindowMode::WINDOW_MODE_FLOATING, 311 Rect{5, 110, 655, 500}, 0xff00ff00); 312 ASSERT_NE(nullptr, window3); 313 // 5:rect.posX_, 700:rect.pos_Y, rect.width_:655, rect.height_:500 314 sptr<Window> window4 = CreateWindow("covered2", WindowMode::WINDOW_MODE_FLOATING, 315 Rect{5, 700, 655, 500}, 0xff00ff00); 316 ASSERT_NE(nullptr, window4); 317 318 sleep(WAIT_FOR_SYNC_US); 319 bool hasPrivateWindow = false; 320 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); 321 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); 322 window1->Destroy(); 323 window2->Destroy(); 324 window3->Destroy(); 325 window4->Destroy(); 326 if (hasPrivateWindow) { 327 ASSERT_TRUE(hasPrivateWindow); 328 } 329} 330 331/** 332 * @tc.name: HasPrivateWindowSkipSnapShot 333 * @tc.desc: set snap shot skip 334 * @tc.type: FUNC 335 * @tc.require issueI5HF6V 336 */ 337HWTEST_F(DisplayManagerTest, HasPrivateWindowSkipSnapShot, Function | SmallTest | Level2) 338{ 339 sptr<Window> window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); 340 if (window1 == nullptr) { 341 return; 342 } 343 ASSERT_NE(nullptr, window1); 344 // 10:rect.posX_, 120:rect.posY_, 650:rect.width, 500:rect.height 345 sptr<Window> window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, 346 Rect {10, 120, 650, 500}, 0xffff0000); 347 ASSERT_NE(nullptr, window2); 348 window2->SetSnapshotSkip(true); 349 sleep(WAIT_FOR_SYNC_US); 350 bool hasPrivateWindow = false; 351 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); 352 DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); 353 window1->Destroy(); 354 window2->Destroy(); 355 if (hasPrivateWindow) { 356 ASSERT_TRUE(hasPrivateWindow); 357 } 358} 359 360/** 361 * @tc.name: AddSurfaceNodeToDisplay | RemoveSurfaceNodeFromDisplay 362 * @tc.desc: add/remove surfaceNode to/from display 363 * @tc.type: FUNC 364 */ 365HWTEST_F(DisplayManagerTest, AddAndRemoveSurfaceNode, Function | SmallTest | Level2) 366{ 367 RSSurfaceNodeConfig config; 368 config.SurfaceNodeName = "TestSurfaceNode"; 369 auto surfaceNode = RSSurfaceNode::Create(config); 370 DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); 371 ASSERT_EQ(DMError::DM_OK, DisplayManager::GetInstance().AddSurfaceNodeToDisplay(id, surfaceNode)); 372 sleep(2); 373 ASSERT_EQ(DMError::DM_OK, DisplayManager::GetInstance().RemoveSurfaceNodeFromDisplay(id, surfaceNode)); 374} 375 376/** 377 * @tc.name: AddSurfaceNodeToDisplay | RemoveSurfaceNodeFromDisplay 378 * @tc.desc: add/remove surfaceNode to/from display 379 * @tc.type: FUNC 380 */ 381HWTEST_F(DisplayManagerTest, SetVirtualScreenSecurityExemption, Function | SmallTest | Level2) 382{ 383 ScreenId id = 0; 384 uint32_t pid = 0; 385 std::vector<uint64_t> windowList; 386 auto ret = DisplayManager::GetInstance().SetVirtualScreenSecurityExemption(id, pid, windowList); 387 ASSERT_NE(DMError::DM_OK, ret); // not virtual screen for id 0 388 sleep(2); 389} 390 391} 392} // namespace OHOS::Rosen 393