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#include "display_manager_proxy.h" 17#include "window_test_utils.h" 18#include <ability_context.h> 19#include "window_helper.h" 20#include "wm_common_inner.h" 21#include "wm_common.h" 22namespace OHOS { 23namespace Rosen { 24namespace { 25constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowTestUtils"}; 26constexpr uint32_t EDGE_INTERVAL = 48; 27constexpr uint32_t MID_INTERVAL = 24; 28} 29 30Rect WindowTestUtils::displayRect_ = {0, 0, 0, 0}; 31Rect WindowTestUtils::statusBarRect_ = {0, 0, 0, 0}; 32Rect WindowTestUtils::naviBarRect_ = {0, 0, 0, 0}; 33Rect WindowTestUtils::customAppRect_ = {0, 0, 0, 0}; 34Rect WindowTestUtils::limitDisplayRect_ = {0, 0, 0, 0}; 35Rect WindowTestUtils::dockWindowRect_ = {0, 0, 0, 0}; 36SplitRects WindowTestUtils::splitRects_ = { 37 .primaryRect = {0, 0, 0, 0}, 38 .secondaryRect = {0, 0, 0, 0}, 39 .dividerRect = {0, 0, 0, 0}, 40}; 41Rect WindowTestUtils::singleTileRect_ = {0, 0, 0, 0}; 42std::vector<Rect> WindowTestUtils::doubleTileRects_ = std::vector<Rect>(2); 43std::vector<Rect> WindowTestUtils::tripleTileRects_ = std::vector<Rect>(3); 44AvoidArea WindowTestUtils::systemAvoidArea_ = {}; 45 46bool WindowTestUtils::isVerticalDisplay_ = false; 47 48sptr<Window> WindowTestUtils::CreateTestWindow(const TestWindowInfo& info) 49{ 50 sptr<WindowOption> option = new WindowOption(); 51 option->SetWindowRect(info.rect); 52 option->SetWindowType(info.type); 53 option->SetWindowMode(info.mode); 54 option->SetFocusable(info.focusable_); 55 option->SetRequestedOrientation(info.orientation_); 56 if (info.parentId != INVALID_WINDOW_ID) { 57 option->SetParentId(info.parentId); 58 } 59 if (info.needAvoid) { 60 option->AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID); 61 } else { 62 option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID); 63 } 64 if (info.parentLimit) { 65 option->AddWindowFlag(WindowFlag::WINDOW_FLAG_PARENT_LIMIT); 66 } else { 67 option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_PARENT_LIMIT); 68 } 69 if (info.forbidSplitMove) { 70 option->AddWindowFlag(WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE); 71 } else { 72 option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE); 73 } 74 if (info.showWhenLocked) { 75 option->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED); 76 } else { 77 option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED); 78 } 79 sptr<Window> window = Window::Create(info.name, option); 80 return window; 81} 82 83sptr<Window> WindowTestUtils::CreateDockWindow() 84{ 85 TestWindowInfo info = { 86 .name = "dockWindow", 87 .rect = dockWindowRect_, 88 .type = WindowType::WINDOW_TYPE_LAUNCHER_DOCK, 89 .mode = WindowMode::WINDOW_MODE_FLOATING, 90 .needAvoid = false, 91 .parentLimit = false, 92 .parentId = INVALID_WINDOW_ID, 93 }; 94 return CreateTestWindow(info); 95} 96 97sptr<Window> WindowTestUtils::CreateStatusBarWindow() 98{ 99 TestWindowInfo info = { 100 .name = "statusBar", 101 .rect = statusBarRect_, 102 .type = WindowType::WINDOW_TYPE_STATUS_BAR, 103 .mode = WindowMode::WINDOW_MODE_FLOATING, 104 .needAvoid = false, 105 .parentLimit = false, 106 .parentId = INVALID_WINDOW_ID, 107 }; 108 return CreateTestWindow(info); 109} 110 111sptr<Window> WindowTestUtils::CreateNavigationBarWindow() 112{ 113 TestWindowInfo info = { 114 .name = "naviBar", 115 .rect = naviBarRect_, 116 .type = WindowType::WINDOW_TYPE_NAVIGATION_BAR, 117 .mode = WindowMode::WINDOW_MODE_FLOATING, 118 .needAvoid = false, 119 .parentLimit = false, 120 .parentId = INVALID_WINDOW_ID, 121 }; 122 return CreateTestWindow(info); 123} 124 125sptr<WindowScene> WindowTestUtils::CreateWindowScene() 126{ 127 sptr<IWindowLifeCycle> listener = nullptr; 128 std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext = nullptr; 129 130 sptr<WindowScene> scene = new WindowScene(); 131 scene->Init(0, abilityContext, listener); 132 return scene; 133} 134 135Rect WindowTestUtils::GetDefaultFloatingRect(const sptr<Window>& window, bool avoid) 136{ 137 limitDisplayRect_ = displayRect_; 138 if (avoid) { 139 UpdateSplitRects(window); 140 } 141 constexpr uint32_t half = 2; 142 constexpr float ratio = DEFAULT_ASPECT_RATIO; // 0.67: default height/width ratio 143 float vpr = GetVirtualPixelRatio(0); 144 145 /* 146 * Calculate default width and height, if width or height is 147 * smaller than minWidth or minHeight, use the minimum limits 148 */ 149 uint32_t defaultW = std::max(static_cast<uint32_t>(displayRect_.width_ * ratio), 150 static_cast<uint32_t>(MIN_FLOATING_WIDTH * vpr)); 151 uint32_t defaultH = std::max(static_cast<uint32_t>(displayRect_.height_ * ratio), 152 static_cast<uint32_t>(MIN_FLOATING_HEIGHT * vpr)); 153 // calculate default x and y 154 Rect resRect = {0, 0, defaultW, defaultH}; 155 if (defaultW <= limitDisplayRect_.width_ && defaultH <= limitDisplayRect_.height_) { 156 resRect.posX_ = limitDisplayRect_.posX_ + static_cast<int32_t>((limitDisplayRect_.width_ - defaultW) / half); 157 resRect.posY_ = limitDisplayRect_.posY_ + static_cast<int32_t>((limitDisplayRect_.height_ - defaultH) / half); 158 } 159 160 return resRect; 161} 162 163Rect WindowTestUtils::CalcLimitedRect(const Rect& rect, float virtualPixelRatio) 164{ 165 constexpr uint32_t maxLimitLen = 2560; 166 constexpr int32_t maxPosRemain = 48; 167 uint32_t minFloatingW = static_cast<uint32_t>(MIN_FLOATING_WIDTH * virtualPixelRatio); 168 uint32_t minFloatingH = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * virtualPixelRatio); 169 Rect resRect = { 170 std::min(std::max(rect.posX_, maxPosRemain - static_cast<int32_t>(rect.width_)), 171 static_cast<int32_t>(displayRect_.width_) - maxPosRemain), 172 std::min(std::max(rect.posY_, maxPosRemain), static_cast<int32_t>(displayRect_.height_) - maxPosRemain), 173 std::min(std::max(minFloatingW, rect.width_), maxLimitLen), 174 std::min(std::max(minFloatingH, rect.height_), maxLimitLen), 175 }; 176 return resRect; 177} 178 179Rect WindowTestUtils::GetFloatingLimitedRect(const Rect& rect, float virtualPixelRatio) 180{ 181 uint32_t minFloatingW = static_cast<uint32_t>(MIN_FLOATING_WIDTH * virtualPixelRatio); 182 uint32_t minFloatingH = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * virtualPixelRatio); 183 Rect resRect = { 184 rect.posX_, 185 rect.posY_, 186 std::max(minFloatingW, rect.width_), 187 std::max(minFloatingH, rect.height_), 188 }; 189 return resRect; 190} 191 192Rect WindowTestUtils::GetDecorateRect(const Rect& rect, float virtualPixelRatio) 193{ 194 uint32_t winFrameW = static_cast<uint32_t>(WINDOW_FRAME_WIDTH * virtualPixelRatio); 195 uint32_t winTitleBarH = static_cast<uint32_t>(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); 196 197 Rect resRect; 198 resRect.posX_ = rect.posX_; 199 resRect.posY_ = rect.posY_; 200 resRect.width_ = rect.width_ + winFrameW + winFrameW; 201 resRect.height_ = rect.height_ + winTitleBarH + winFrameW; 202 return resRect; 203} 204 205void WindowTestUtils::InitByDisplayRect(const Rect& displayRect) 206{ 207 const float barRatio = 0.07; 208 const float spaceRation = 0.125; 209 displayRect_ = displayRect; 210 limitDisplayRect_ = displayRect; 211 if (displayRect_.width_ < displayRect_.height_) { 212 isVerticalDisplay_ = true; 213 } 214 statusBarRect_ = {0, 0, displayRect_.width_, displayRect_.height_ * barRatio}; 215 naviBarRect_ = {0, displayRect_.height_ * (1 - barRatio), displayRect_.width_, displayRect_.height_ * barRatio}; 216 dockWindowRect_ = {0, displayRect_.height_ * (1 - barRatio), displayRect_.width_, displayRect_.height_ * barRatio}; 217 customAppRect_ = { 218 displayRect_.width_ * spaceRation, 219 displayRect_.height_ * spaceRation, 220 displayRect_.width_ * DEFAULT_ASPECT_RATIO, 221 displayRect_.height_ * DEFAULT_ASPECT_RATIO 222 }; 223} 224 225std::shared_ptr<MMI::PointerEvent> WindowTestUtils::CreatePointerEvent(int32_t posX, int32_t posY, uint32_t pointerId, 226 int32_t pointerAction) 227{ 228 MMI::PointerEvent::PointerItem pointerItem; 229 pointerItem.SetPointerId(pointerId); 230 pointerItem.SetDisplayX(posX); 231 pointerItem.SetDisplayY(posY); 232 233 std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create(); 234 pointerEvent->AddPointerItem(pointerItem); 235 pointerEvent->SetPointerId(pointerId); 236 pointerEvent->SetPointerAction(pointerAction); 237 pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN); 238 return pointerEvent; 239} 240 241uint32_t WindowTestUtils::GetMaxTileWinNum() 242{ 243 float virtualPixelRatio = GetVirtualPixelRatio(0); 244 constexpr uint32_t half = 2; 245 uint32_t edgeIntervalVp = static_cast<uint32_t>(EDGE_INTERVAL * half * virtualPixelRatio); 246 uint32_t midIntervalVp = static_cast<uint32_t>(MID_INTERVAL * virtualPixelRatio); 247 uint32_t minFloatingW = static_cast<uint32_t>(MIN_FLOATING_WIDTH * virtualPixelRatio); 248 uint32_t drawableW = limitDisplayRect_.width_ - edgeIntervalVp + midIntervalVp; 249 uint32_t maxNum = static_cast<uint32_t>(drawableW / (minFloatingW + midIntervalVp)); 250 WLOGI("maxNum: %{public}d", maxNum); 251 return maxNum; 252} 253 254void WindowTestUtils::InitTileWindowRects(const sptr<Window>& window, bool avoid) 255{ 256 float virtualPixelRatio = GetVirtualPixelRatio(0); 257 uint32_t edgeInterval = static_cast<uint32_t>(EDGE_INTERVAL * virtualPixelRatio); // 48 is edge interval 258 uint32_t midInterval = static_cast<uint32_t>(MID_INTERVAL * virtualPixelRatio); // 24 is mid interval 259 constexpr float ratio = DEFAULT_ASPECT_RATIO; 260 constexpr int half = 2; 261 limitDisplayRect_ = displayRect_; 262 if (avoid) { 263 UpdateSplitRects(window); 264 } 265 266 uint32_t minFloatingW = static_cast<uint32_t>(MIN_FLOATING_WIDTH * virtualPixelRatio); 267 uint32_t minFloatingH = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * virtualPixelRatio); 268 uint32_t w = std::max(static_cast<uint32_t>(displayRect_.width_ * ratio), minFloatingW); 269 uint32_t h = std::max(static_cast<uint32_t>(displayRect_.height_ * ratio), minFloatingH); 270 w = w > limitDisplayRect_.width_ ? limitDisplayRect_.width_ : w; 271 h = h > limitDisplayRect_.height_ ? limitDisplayRect_.height_ : h; 272 int x = limitDisplayRect_.posX_ + ((limitDisplayRect_.width_ - w) / half); 273 int y = limitDisplayRect_.posY_ + ((limitDisplayRect_.height_ - h) / half); 274 singleTileRect_ = { x, y, w, h }; 275 WLOGI("singleRect_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h); 276 x = edgeInterval; 277 w = (limitDisplayRect_.width_ - edgeInterval * half - midInterval) / half; 278 // calc doubleRect 279 doubleTileRects_[0] = {x, y, w, h}; 280 doubleTileRects_[1] = {x + w + midInterval, y, w, h}; 281 WLOGI("doubleRects_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h); 282 // calc tripleRect 283 w = (limitDisplayRect_.width_ - edgeInterval * half - midInterval * half) / 3; // 3 is triple rects num 284 tripleTileRects_[0] = {x, y, w, h}; 285 tripleTileRects_[1] = {x + w + midInterval, y, w, h}; 286 tripleTileRects_[2] = {x + w * half + midInterval * half, y, w, h}; // 2 is third index 287 WLOGI("tripleRects_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h); 288} 289 290bool WindowTestUtils::RectEqualTo(const sptr<Window>& window, const Rect& r) 291{ 292 usleep(100000); // 100000us 293 Rect l = window->GetRect(); 294 bool res = ((l.posX_ == r.posX_) && (l.posY_ == r.posY_) && (l.width_ == r.width_) && (l.height_ == r.height_)); 295 if (!res) { 296 WLOGFE("GetLayoutRect: %{public}d %{public}d %{public}d %{public}d, " \ 297 "Expect: %{public}d %{public}d %{public}d %{public}d", l.posX_, l.posY_, l.width_, l.height_, 298 r.posX_, r.posY_, r.width_, r.height_); 299 } 300 return res; 301} 302 303bool WindowTestUtils::RectEqualToRect(const Rect& l, const Rect& r) 304{ 305 bool res = ((l.posX_ == r.posX_) && (l.posY_ == r.posY_) && (l.width_ == r.width_) && (l.height_ == r.height_)); 306 if (!res) { 307 WLOGFE("GetLayoutRect: %{public}d %{public}d %{public}d %{public}d, " \ 308 "Expect: %{public}d %{public}d %{public}d %{public}d", l.posX_, l.posY_, l.width_, l.height_, 309 r.posX_, r.posY_, r.width_, r.height_); 310 } 311 return res; 312} 313 314AvoidPosType WindowTestUtils::GetAvoidPosType(const Rect& rect) 315{ 316 auto display = DisplayManager::GetInstance().GetDisplayById(0); 317 if (display == nullptr) { 318 WLOGFE("GetAvoidPosType fail. Get display fail. displayId: 0"); 319 return AvoidPosType::AVOID_POS_UNKNOWN; 320 } 321 auto displayInfo = display->GetDisplayInfo(); 322 Rect displayRect = {displayInfo->GetOffsetX(), displayInfo->GetOffsetY(), displayInfo->GetWidth(), 323 displayInfo->GetHeight()}; 324 return WindowHelper::GetAvoidPosType(rect, displayRect); 325} 326 327bool WindowTestUtils::InitSplitRects() 328{ 329 auto display = DisplayManager::GetInstance().GetDisplayById(0); 330 if (display == nullptr) { 331 WLOGFE("GetDefaultDisplay: failed!"); 332 return false; 333 } 334 WLOGI("GetDefaultDisplay: id %{public}" PRIu64", w %{public}d, h %{public}d, fps %{public}u", 335 display->GetId(), display->GetWidth(), display->GetHeight(), display->GetRefreshRate()); 336 337 Rect displayRect = {0, 0, display->GetWidth(), display->GetHeight()}; 338 displayRect_ = displayRect; 339 limitDisplayRect_ = displayRect; 340 341 float virtualPixelRatio = WindowTestUtils::GetVirtualPixelRatio(0); 342 uint32_t dividerWidth = static_cast<uint32_t>(DIVIDER_WIDTH * virtualPixelRatio); 343 344 if (displayRect_.width_ < displayRect_.height_) { 345 isVerticalDisplay_ = true; 346 } 347 if (isVerticalDisplay_) { 348 splitRects_.dividerRect = { 0, 349 static_cast<uint32_t>((displayRect_.height_ - dividerWidth) * DEFAULT_SPLIT_RATIO), 350 displayRect_.width_, 351 dividerWidth, }; 352 } else { 353 splitRects_.dividerRect = { static_cast<uint32_t>((displayRect_.width_ - dividerWidth) * DEFAULT_SPLIT_RATIO), 354 0, 355 dividerWidth, 356 displayRect_.height_ }; 357 } 358 return true; 359} 360 361void WindowTestUtils::UpdateSplitRects(const sptr<Window>& window) 362{ 363 std::unique_ptr<WindowTestUtils> testUtils = std::make_unique<WindowTestUtils>(); 364 testUtils->avoidArea_ = systemAvoidArea_; 365 testUtils->UpdateLimitDisplayRect(testUtils->avoidArea_.leftRect_); 366 testUtils->UpdateLimitDisplayRect(testUtils->avoidArea_.topRect_); 367 testUtils->UpdateLimitDisplayRect(testUtils->avoidArea_.rightRect_); 368 testUtils->UpdateLimitDisplayRect(testUtils->avoidArea_.bottomRect_); 369 370 if (isVerticalDisplay_) { 371 splitRects_.dividerRect.posY_ = limitDisplayRect_.posY_ + 372 static_cast<uint32_t>((limitDisplayRect_.height_ - splitRects_.dividerRect.height_) * DEFAULT_SPLIT_RATIO); 373 testUtils->UpdateLimitSplitRects(splitRects_.dividerRect.posY_); 374 } else { 375 splitRects_.dividerRect.posX_ = limitDisplayRect_.posX_ + 376 static_cast<uint32_t>((limitDisplayRect_.width_ - splitRects_.dividerRect.width_) * DEFAULT_SPLIT_RATIO); 377 testUtils->UpdateLimitSplitRects(splitRects_.dividerRect.posX_); 378 } 379} 380 381void WindowTestUtils::UpdateLimitDisplayRect(const Rect& avoidRect) 382{ 383 if (((avoidRect.posX_ == 0) && (avoidRect.posY_ == 0) && 384 (avoidRect.width_ == 0) && (avoidRect.height_ == 0))) { 385 return; 386 } 387 auto avoidPosType = GetAvoidPosType(avoidRect); 388 int32_t offsetH = 0; 389 int32_t offsetW = 0; 390 switch (avoidPosType) { 391 case AvoidPosType::AVOID_POS_TOP: 392 offsetH = avoidRect.posY_ + avoidRect.height_ - limitDisplayRect_.posY_; 393 limitDisplayRect_.posY_ += offsetH; 394 limitDisplayRect_.height_ -= offsetH; 395 break; 396 case AvoidPosType::AVOID_POS_BOTTOM: 397 offsetH = limitDisplayRect_.posY_ + limitDisplayRect_.height_ - avoidRect.posY_; 398 limitDisplayRect_.height_ -= offsetH; 399 break; 400 case AvoidPosType::AVOID_POS_LEFT: 401 offsetW = avoidRect.posX_ + avoidRect.width_ - limitDisplayRect_.posX_; 402 limitDisplayRect_.posX_ += offsetW; 403 limitDisplayRect_.width_ -= offsetW; 404 break; 405 case AvoidPosType::AVOID_POS_RIGHT: 406 offsetW = limitDisplayRect_.posX_ + limitDisplayRect_.width_ - avoidRect.posX_; 407 limitDisplayRect_.width_ -= offsetW; 408 break; 409 default: 410 WLOGFE("invalid avoidPosType: %{public}d", avoidPosType); 411 } 412} 413 414void WindowTestUtils::UpdateLimitSplitRects(int32_t divPos) 415{ 416 std::unique_ptr<WindowTestUtils> testUtils = std::make_unique<WindowTestUtils>(); 417 if (isVerticalDisplay_) { 418 splitRects_.dividerRect.posY_ = divPos; 419 420 splitRects_.primaryRect.posX_ = displayRect_.posX_; 421 splitRects_.primaryRect.posY_ = displayRect_.posY_; 422 splitRects_.primaryRect.height_ = divPos; 423 splitRects_.primaryRect.width_ = displayRect_.width_; 424 425 splitRects_.secondaryRect.posX_ = displayRect_.posX_; 426 splitRects_.secondaryRect.posY_ = splitRects_.dividerRect.posY_ + splitRects_.dividerRect.height_; 427 splitRects_.secondaryRect.height_ = displayRect_.height_ - splitRects_.secondaryRect.posY_; 428 splitRects_.secondaryRect.width_ = displayRect_.width_; 429 } else { 430 splitRects_.dividerRect.posX_ = divPos; 431 432 splitRects_.primaryRect.posX_ = displayRect_.posX_; 433 splitRects_.primaryRect.posY_ = displayRect_.posY_; 434 splitRects_.primaryRect.width_ = divPos; 435 splitRects_.primaryRect.height_ = displayRect_.height_; 436 437 splitRects_.secondaryRect.posX_ = splitRects_.dividerRect.posX_ + splitRects_.dividerRect.width_; 438 splitRects_.secondaryRect.posY_ = displayRect_.posY_; 439 splitRects_.secondaryRect.width_ = displayRect_.width_ - splitRects_.secondaryRect.posX_; 440 splitRects_.secondaryRect.height_ = displayRect_.height_; 441 } 442 443 testUtils->UpdateLimitSplitRect(splitRects_.primaryRect); 444 testUtils->UpdateLimitSplitRect(splitRects_.secondaryRect); 445} 446 447void WindowTestUtils::UpdateLimitSplitRect(Rect& limitSplitRect) 448{ 449 Rect curLimitRect = limitSplitRect; 450 limitSplitRect.posX_ = std::max(limitDisplayRect_.posX_, curLimitRect.posX_); 451 limitSplitRect.posY_ = std::max(limitDisplayRect_.posY_, curLimitRect.posY_); 452 limitSplitRect.width_ = std::min(limitDisplayRect_.posX_ + limitDisplayRect_.width_, 453 curLimitRect.posX_ + curLimitRect.width_) - 454 limitSplitRect.posX_; 455 limitSplitRect.height_ = std::min(limitDisplayRect_.posY_ + limitDisplayRect_.height_, 456 curLimitRect.posY_ + curLimitRect.height_) - 457 limitSplitRect.posY_; 458} 459 460float WindowTestUtils::GetVirtualPixelRatio(DisplayId displayId) 461{ 462 auto display = DisplayManager::GetInstance().GetDisplayById(displayId); 463 if (display == nullptr) { 464 WLOGFE("GetVirtualPixel fail. Get display fail. displayId:%{public}" PRIu64", use Default vpr:1.0", displayId); 465 return 1.0; // Use DefaultVPR 1.0 466 } 467 468 float virtualPixelRatio = display->GetVirtualPixelRatio(); 469 if (virtualPixelRatio == 0.0) { 470 WLOGFE("GetVirtualPixel fail. vpr is 0.0. displayId:%{public}" PRIu64", use Default vpr:1.0", displayId); 471 return 1.0; // Use DefaultVPR 1.0 472 } 473 474 WLOGI("GetVirtualPixel success. displayId:%{public}" PRIu64", vpr:%{public}f", displayId, virtualPixelRatio); 475 return virtualPixelRatio; 476} 477} // namespace ROSEN 478} // namespace OHOS 479