• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef UI_MODEL_H
17 #define UI_MODEL_H
18 
19 #include <vector>
20 #include <sstream>
21 #include "common_utilities_hpp.h"
22 #include "frontend_api_handler.h"
23 #include "json.hpp"
24 
25 namespace OHOS::uitest {
26     using namespace std;
27     using namespace nlohmann;
28     const std::string ROOT_HIERARCHY = "ROOT";
29     /**Enumerates the supported string value match rules.*/
30     enum ValueMatchPattern : uint8_t { EQ, CONTAINS, STARTS_WITH, ENDS_WITH };
31 
32     /**Enumerates the supported UiComponent attributes.*/
33     enum UiAttr : uint8_t {
34         ACCESSIBILITY_ID,
35         ID,
36         TEXT,
37         KEY,
38         DESCRIPTION,
39         TYPE,
40         BOUNDS,
41         ENABLED,
42         FOCUSED,
43         SELECTED,
44         CLICKABLE,
45         LONG_CLICKABLE,
46         SCROLLABLE,
47         CHECKABLE,
48         CHECKED,
49         HOST_WINDOW_ID,
50         ORIGBOUNDS,
51         ZINDEX,
52         OPACITY,
53         BACKGROUNDCOLOR,
54         BACKGROUNDIMAGE,
55         BLUR,
56         HITTESTBEHAVIOR,
57         // inner used attributes
58         HIERARCHY,
59         HASHCODE,
60         BOUNDSCENTER,
61         VISIBLE,
62         ABILITYNAME,
63         BUNDLENAME,
64         PAGEPATH,
65         DUMMY_ATTRNAME_SELECTION,
66         HINT,
67         MAX, // mark the max length
68     };
69 
70     /**Supported UiComponent attribute names. Ordered by <code>UiAttr</code> definition.*/
71     constexpr std::string_view ATTR_NAMES[] = {
72         "accessibilityId", // ACCESSIBILITY_ID
73         "id",            // ID
74         "text",          // TEXT
75         "key",           // KEY
76         "description",   // DESCRIPTION
77         "type",          // TYPE
78         "bounds",        // BOUNDS
79         "enabled",       // ENABLED
80         "focused",       // FOCUSED
81         "selected",      // SELECTED
82         "clickable",     // CLICKABLE
83         "longClickable", // LONG_CLICKABLE
84         "scrollable",    // SCROLLABLE
85         "checkable",     // CHECKABLE
86         "checked",       // CHECKED
87         "hostWindowId",  // HOST_WINDOW_ID
88         "origBounds",    // ORIGBOUNDS
89         "zIndex",        // ZINDEX
90         "opacity",       //OPACITY
91         "backgroundColor",   // BACKGROUNDCOLOR
92         "backgroundImage",   // BACKGROUNDIMAGE
93         "blur",          //BLUR
94         "hitTestBehavior",   // HITTESTBEHAVIOR
95         "hierarchy",     // HIERARCHY
96         "hashcode",      // HASHCODE
97         "boundsCenter",  // BOUNDSCENTER
98         "visible",       // VISIBLE
99         "abilityName",   // ABILITYNAME
100         "bundleName",    // BUNDLENAME
101         "pagePath",      // PAGEPATH
102         "dummyAttrnameSelection", // DUMMY_ATTRNAME_SELECTION
103         "hint", // HINT
104     };
105 
106     const std::set<std::string> CONTAINER_TYPE = {
107         "List",          "Grid",   "WaterFlow", "GridCol",  "GridRow",    "Scroll",     "Flex",
108         "ListItemGroup", "Swiper", "DecorBar",  "_Common_", "TabContent", "WindowScene"};
109     struct Point {
PointPoint110         Point() : px_(0), py_(0){};
PointPoint111         Point(int32_t px, int32_t py) : px_(px), py_(py){};
112         int32_t px_;
113         int32_t py_;
114     };
115 
116     /**Represents a reasonable rectangle area.*/
117     struct Rect {
RectRect118         Rect(int32_t left, int32_t right, int32_t top, int32_t bottom)
119             : left_(left), right_(right), top_(top), bottom_(bottom)
120         {
121             DCHECK(right_ >= left_ && bottom_ >= top_);
122         };
RectRect123         Rect()
124         {
125             left_ = 0;
126             right_ = 0;
127             top_ = 0;
128             bottom_ = 0;
129         };
130         int32_t left_;
131         int32_t right_;
132         int32_t top_;
133         int32_t bottom_;
134 
GetCenterXRect135         FORCE_INLINE int32_t GetCenterX() const
136         {
137             return (left_ + right_) / TWO;
138         }
139 
GetCenterYRect140         FORCE_INLINE int32_t GetCenterY() const
141         {
142             return (top_ + bottom_) / TWO;
143         }
144 
GetWidthRect145         FORCE_INLINE int32_t GetWidth() const
146         {
147             return right_ - left_;
148         }
149 
GetHeightRect150         FORCE_INLINE int32_t GetHeight() const
151         {
152             return bottom_ - top_;
153         }
154 
DescribeRect155         std::string Describe() const
156         {
157             std::stringstream ss;
158             ss << "Rect {left:" << left_ << ",right:" << right_ << ",top:" << top_ << ",bottom:" << bottom_ << "}";
159             return ss.str();
160         }
161     };
162 
163     struct WidgetMatchModel {
WidgetMatchModelWidgetMatchModel164         WidgetMatchModel(UiAttr name, string value, ValueMatchPattern matchPattern)
165             : attrName(name), attrValue(value), pattern(matchPattern)
166         {
167         }
WidgetMatchModelWidgetMatchModel168         WidgetMatchModel() {}
DescribeWidgetMatchModel169         std::string Describe() const
170         {
171             stringstream ss;
172             ss << "{";
173             ss << "attrName:" << ATTR_NAMES[attrName].data() << "; value:" << attrValue
174                << "; Pattern:" << to_string(pattern);
175             ss << "}";
176             return ss.str();
177         }
178         UiAttr attrName;
179         string attrValue;
180         ValueMatchPattern pattern;
181     };
182 
183     /**Algorithm of rectangle.*/
184     class RectAlgorithm {
185     public:
186         FORCE_INLINE static bool CheckEqual(const Rect &ra, const Rect &rb);
187         FORCE_INLINE static bool CheckIntersectant(const Rect &ra, const Rect &rb);
188         FORCE_INLINE static bool IsInnerPoint(const Rect &rect, const Point &point);
189         FORCE_INLINE static bool IsPointOnEdge(const Rect &rect, const Point &point);
190         static bool ComputeIntersection(const Rect &ra, const Rect &rb, Rect &result);
191         static bool ComputeMaxVisibleRegion(const Rect &rect, const std::vector<Rect> &overlays, Rect &out);
192     };
193 
CheckEqual(const Rect & ra,const Rect & rb)194     FORCE_INLINE bool RectAlgorithm::CheckEqual(const Rect &ra, const Rect &rb)
195     {
196         return ra.left_ == rb.left_ && ra.right_ == rb.right_ && ra.top_ == rb.top_ && ra.bottom_ == rb.bottom_;
197     }
198 
CheckIntersectant(const Rect & ra,const Rect & rb)199     FORCE_INLINE bool RectAlgorithm::CheckIntersectant(const Rect &ra, const Rect &rb)
200     {
201         if (ra.left_ >= rb.right_ || ra.right_ <= rb.left_) {
202             return false;
203         }
204         if (ra.top_ >= rb.bottom_ || ra.bottom_ <= rb.top_) {
205             return false;
206         }
207         return true;
208     }
209 
IsInnerPoint(const Rect & rect,const Point & point)210     FORCE_INLINE bool RectAlgorithm::IsInnerPoint(const Rect &rect, const Point& point)
211     {
212         if (point.px_ <= rect.left_ || point.px_ >= rect.right_
213             || point.py_ <= rect.top_ || point.py_ >= rect.bottom_) {
214             return false;
215         }
216         return true;
217     }
218 
IsPointOnEdge(const Rect & rect,const Point & point)219     FORCE_INLINE bool RectAlgorithm::IsPointOnEdge(const Rect &rect, const Point& point)
220     {
221         if ((point.px_ == rect.left_ || point.px_ == rect.right_)
222             && point.py_ >= rect.top_ && point.py_ <= rect.bottom_) {
223             return true;
224         }
225         if ((point.py_ == rect.top_ || point.py_ == rect.bottom_)
226             && point.px_ >= rect.left_ && point.px_ <= rect.right_) {
227             return true;
228         }
229         return false;
230     }
231 
232     class Widget : public BackendClass {
233     public:
234         // disable default constructor, copy constructor and assignment operator
Widget(std::string_view hierarchy)235         explicit Widget(std::string_view hierarchy) : hierarchy_(hierarchy)
236         {
237             attributeVec_[UiAttr::HIERARCHY] = hierarchy;
238         };
239 
~Widget()240         ~Widget() override {}
241 
GetFrontendClassDef()242         const FrontEndClassDef &GetFrontendClassDef() const override
243         {
244             return COMPONENT_DEF;
245         }
246 
GetBounds()247         Rect GetBounds() const
248         {
249             return bounds_;
250         }
251 
GetHierarchy()252         std::string GetHierarchy() const
253         {
254             return hierarchy_;
255         }
256 
257         void SetBounds(const Rect &bounds);
258 
259         std::string ToStr() const;
260 
261         std::unique_ptr<Widget> Clone(std::string_view hierarchy) const;
262 
263         std::vector<std::string> GetAttrVec() const;
264 
IsVisible()265         bool IsVisible() const
266         {
267             return GetAttr(UiAttr::VISIBLE) == "true";
268         }
269 
270         void SetAttr(UiAttr attrId, string value);
271 
272         std::string GetAttr(UiAttr attrId) const;
273 
274         bool MatchAttr(const WidgetMatchModel& matchModel) const;
275 
276         void SetHierarchy(const std::string& hierarch);
277 
278         void WrapperWidgetToJson(nlohmann::json& out);
279     private:
280         std::string hierarchy_;
281         std::vector<string> attributeVec_ = std::vector<string>(UiAttr::MAX + 1);
282         Rect bounds_ = {0, 0, 0, 0};
283     };
284 
285     // ensure Widget is movable, since we need to move a constructed Widget object into WidgetTree
286     static_assert(std::is_move_constructible<Widget>::value, "Widget need to be movable");
287 
288     /**Enumerates the supported UiComponent attributes.*/
289     enum WindowMode : uint8_t { UNKNOWN, FULLSCREEN, SPLIT_PRIMARY, SPLIT_SECONDARY, FLOATING, PIP };
290 
291     // Represents a UI window on screen.
292     class Window : public BackendClass {
293     public:
Window(int32_t id)294         explicit Window(int32_t id) : id_(id) {};
295 
~Window()296         ~Window() override {}
297 
GetFrontendClassDef()298         const FrontEndClassDef &GetFrontendClassDef() const override
299         {
300             return UI_WINDOW_DEF;
301         }
302 
303         // plain properties, make them public for easy access
304         int32_t id_ = 0;
305         int32_t windowLayer_ = 0;
306         std::string bundleName_ = "";
307         std::string title_ = "";
308         bool focused_ = false;
309         bool actived_ = false;
310         bool decoratorEnabled_ = false;
311         Rect bounds_ = {0, 0, 0, 0};
312         Rect visibleBounds_ = {0, 0, 0, 0};
313         std::vector<Rect> invisibleBoundsVec_;
314         std::string abilityName_ = "";
315         std::string pagePath_ = "";
316         WindowMode mode_ = UNKNOWN;
317     };
318 
319     class DumpHandler {
320     public:
321         static void AddExtraAttrs(nlohmann::json &root, const map<int32_t, string_view> &elementTrees, size_t index);
322         static void DumpWindowInfoToJson(vector<Widget> &allWidget, nlohmann::json &root);
323     };
324 
325     class WidgetHierarchyBuilder {
326     public:
327         static string Build(string_view parentWidgetHierarchy, uint32_t childIndex);
328 
329         static string GetParentWidgetHierarchy(string_view hierarchy);
330 
331         static string GetChildHierarchy(string_view hierarchy, uint32_t childIndex);
332 
333     private:
334         static constexpr auto HIERARCHY_SEPARATOR = ",";
335     };
336 } // namespace OHOS::uitest
337 
338 #endif