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