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