• 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 "nlohmann/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, REG_EXP, REG_EXP_ICASE };
31 
32     enum AamsWorkMode : uint8_t { NORMAL, FASTGETNODE, END };
33 
34     /**Enumerates the supported UiComponent attributes.*/
35     enum UiAttr : uint8_t {
36         ACCESSIBILITY_ID,
37         ID,
38         TEXT,
39         KEY,
40         DESCRIPTION,
41         TYPE,
42         BOUNDS,
43         ENABLED,
44         FOCUSED,
45         SELECTED,
46         CLICKABLE,
47         LONG_CLICKABLE,
48         SCROLLABLE,
49         CHECKABLE,
50         CHECKED,
51         HOST_WINDOW_ID,
52         DISPLAY_ID,
53         ORIGBOUNDS,
54         ZINDEX,
55         OPACITY,
56         BACKGROUNDCOLOR,
57         BACKGROUNDIMAGE,
58         BLUR,
59         HITTESTBEHAVIOR,
60         CLIP,
61         // inner used attributes
62         HIERARCHY,
63         HASHCODE,
64         BOUNDSCENTER,
65         VISIBLE,
66         ABILITYNAME,
67         BUNDLENAME,
68         PAGEPATH,
69         DUMMY_ATTRNAME_SELECTION,
70         HINT,
71         MAX, // mark the max length
72     };
73 
74     /**Supported UiComponent attribute names. Ordered by <code>UiAttr</code> definition.*/
75     constexpr std::string_view ATTR_NAMES[] = {
76         "accessibilityId", // ACCESSIBILITY_ID
77         "id",            // ID
78         "text",          // TEXT
79         "key",           // KEY
80         "description",   // DESCRIPTION
81         "type",          // TYPE
82         "bounds",        // BOUNDS
83         "enabled",       // ENABLED
84         "focused",       // FOCUSED
85         "selected",      // SELECTED
86         "clickable",     // CLICKABLE
87         "longClickable", // LONG_CLICKABLE
88         "scrollable",    // SCROLLABLE
89         "checkable",     // CHECKABLE
90         "checked",       // CHECKED
91         "hostWindowId",  // HOST_WINDOW_ID
92         "displayId",     // DISPLAY_ID
93         "origBounds",    // ORIGBOUNDS
94         "zIndex",        // ZINDEX
95         "opacity",       //OPACITY
96         "backgroundColor",   // BACKGROUNDCOLOR
97         "backgroundImage",   // BACKGROUNDIMAGE
98         "blur",          //BLUR
99         "hitTestBehavior",   // HITTESTBEHAVIOR
100         "clip", // CLIP
101         "hierarchy",     // HIERARCHY
102         "hashcode",      // HASHCODE
103         "boundsCenter",  // BOUNDSCENTER
104         "visible",       // VISIBLE
105         "abilityName",   // ABILITYNAME
106         "bundleName",    // BUNDLENAME
107         "pagePath",      // PAGEPATH
108         "dummyAttrnameSelection", // DUMMY_ATTRNAME_SELECTION
109         "hint", // HINT
110     };
111 
112     struct Point {
PointPoint113         Point() : px_(0), py_(0), displayId_(-1) {};
px_Point114         Point(int32_t px, int32_t py, int32_t displayId = -1) : px_(px), py_(py), displayId_(displayId) {};
115         int32_t px_;
116         int32_t py_;
117         int32_t displayId_;
118     };
119 
120     /**Represents a reasonable rectangle area.*/
121     struct Rect {
122         Rect(int32_t left, int32_t right, int32_t top, int32_t bottom, int32_t displayId = -1)
left_Rect123             : left_(left), right_(right), top_(top), bottom_(bottom), displayId_(displayId) {};
RectRect124         Rect()
125         {
126             left_ = 0;
127             right_ = 0;
128             top_ = 0;
129             bottom_ = 0;
130             displayId_ = -1;
131         };
132         int32_t left_;
133         int32_t right_;
134         int32_t top_;
135         int32_t bottom_;
136         int32_t displayId_;
137 
GetCenterXRect138         FORCE_INLINE int32_t GetCenterX() const
139         {
140             return (left_ + right_) / TWO;
141         }
142 
GetCenterYRect143         FORCE_INLINE int32_t GetCenterY() const
144         {
145             return (top_ + bottom_) / TWO;
146         }
147 
GetWidthRect148         FORCE_INLINE int32_t GetWidth() const
149         {
150             return right_ - left_;
151         }
152 
GetHeightRect153         FORCE_INLINE int32_t GetHeight() const
154         {
155             return bottom_ - top_;
156         }
157 
DescribeRect158         std::string Describe() const
159         {
160             std::stringstream ss;
161             ss << "Rect {left:" << left_ << ",right:" << right_ << ",top:" << top_ << ",bottom:" << bottom_ << "}";
162             return ss.str();
163         }
164     };
165 
166     struct WidgetMatchModel {
WidgetMatchModelWidgetMatchModel167         WidgetMatchModel(UiAttr name, string value, ValueMatchPattern matchPattern)
168             : attrName(name), attrValue(value), pattern(matchPattern)
169         {
170         }
WidgetMatchModelWidgetMatchModel171         WidgetMatchModel() {}
DescribeWidgetMatchModel172         std::string Describe() const
173         {
174             stringstream ss;
175             ss << "{";
176             ss << "attrName:" << ATTR_NAMES[attrName].data() << "; value:" << attrValue
177                << "; Pattern:" << to_string(pattern);
178             ss << "}";
179             return ss.str();
180         }
181         UiAttr attrName;
182         string attrValue;
183         ValueMatchPattern pattern;
184     };
185 
186     /**Algorithm of rectangle.*/
187     class RectAlgorithm {
188     public:
189         FORCE_INLINE static bool CheckEqual(const Rect &ra, const Rect &rb);
190         FORCE_INLINE static bool CheckIntersectant(const Rect &ra, const Rect &rb);
191         FORCE_INLINE static bool IsInnerPoint(const Rect &rect, const Point &point);
192         FORCE_INLINE static bool IsPointOnEdge(const Rect &rect, const Point &point);
193         static bool ComputeIntersection(const Rect &ra, const Rect &rb, Rect &result);
194         static bool ComputeMaxVisibleRegion(const Rect &rect, const std::vector<Rect> &overlays, Rect &out);
195     };
196 
CheckEqual(const Rect & ra,const Rect & rb)197     FORCE_INLINE bool RectAlgorithm::CheckEqual(const Rect &ra, const Rect &rb)
198     {
199         return ra.left_ == rb.left_ && ra.right_ == rb.right_ && ra.top_ == rb.top_ && ra.bottom_ == rb.bottom_;
200     }
201 
CheckIntersectant(const Rect & ra,const Rect & rb)202     FORCE_INLINE bool RectAlgorithm::CheckIntersectant(const Rect &ra, const Rect &rb)
203     {
204         if (ra.left_ >= rb.right_ || ra.right_ <= rb.left_) {
205             return false;
206         }
207         if (ra.top_ >= rb.bottom_ || ra.bottom_ <= rb.top_) {
208             return false;
209         }
210         return true;
211     }
212 
IsInnerPoint(const Rect & rect,const Point & point)213     FORCE_INLINE bool RectAlgorithm::IsInnerPoint(const Rect &rect, const Point& point)
214     {
215         if (point.px_ <= rect.left_ || point.px_ >= rect.right_
216             || point.py_ <= rect.top_ || point.py_ >= rect.bottom_) {
217             return false;
218         }
219         return true;
220     }
221 
IsPointOnEdge(const Rect & rect,const Point & point)222     FORCE_INLINE bool RectAlgorithm::IsPointOnEdge(const Rect &rect, const Point& point)
223     {
224         if ((point.px_ == rect.left_ || point.px_ == rect.right_)
225             && point.py_ >= rect.top_ && point.py_ <= rect.bottom_) {
226             return true;
227         }
228         if ((point.py_ == rect.top_ || point.py_ == rect.bottom_)
229             && point.px_ >= rect.left_ && point.px_ <= rect.right_) {
230             return true;
231         }
232         return false;
233     }
234 
235     class Widget : public BackendClass {
236     public:
237         // disable default constructor, copy constructor and assignment operator
Widget(std::string_view hierarchy)238         explicit Widget(std::string_view hierarchy) : hierarchy_(hierarchy)
239         {
240             attributeVec_[UiAttr::HIERARCHY] = hierarchy;
241         };
242 
~Widget()243         ~Widget() override {}
244 
GetFrontendClassDef()245         const FrontEndClassDef &GetFrontendClassDef() const override
246         {
247             return COMPONENT_DEF;
248         }
249 
GetBounds()250         Rect GetBounds() const
251         {
252             return bounds_;
253         }
254 
GetHierarchy()255         std::string GetHierarchy() const
256         {
257             return hierarchy_;
258         }
259 
GetDisplayId()260         int32_t GetDisplayId() const
261         {
262             return displayId_;
263         }
264 
SetDisplayId(const int32_t id)265         void SetDisplayId(const int32_t id)
266         {
267             displayId_ = id;
268             attributeVec_[UiAttr::DISPLAY_ID] = to_string(id);
269         }
270 
271         void SetBounds(const Rect &bounds);
272 
273         std::string ToStr() const;
274 
275         std::unique_ptr<Widget> Clone(std::string_view hierarchy) const;
276 
277         std::vector<std::string> GetAttrVec() const;
278 
IsVisible()279         bool IsVisible() const
280         {
281             return GetAttr(UiAttr::VISIBLE) == "true";
282         }
283 
284         void SetAttr(UiAttr attrId, string value);
285 
286         std::string GetAttr(UiAttr attrId) const;
287 
288         bool MatchAttr(const WidgetMatchModel& matchModel) const;
289 
290         void SetHierarchy(const std::string& hierarch);
291 
292         void WrapperWidgetToJson(nlohmann::json& out);
293     private:
294         std::string hierarchy_;
295         std::vector<string> attributeVec_ = std::vector<string>(UiAttr::MAX + 1);
296         Rect bounds_ = {0, 0, 0, 0};
297         std::int32_t displayId_ = 0;
298     };
299 
300     // ensure Widget is movable, since we need to move a constructed Widget object into WidgetTree
301     static_assert(std::is_move_constructible<Widget>::value, "Widget need to be movable");
302 
303     /**Enumerates the supported UiComponent attributes.*/
304     enum WindowMode : uint8_t { UNKNOWN, FULLSCREEN, SPLIT_PRIMARY, SPLIT_SECONDARY, FLOATING, PIP };
305 
306     // Represents a UI window on screen.
307     class Window : public BackendClass {
308     public:
Window(int32_t id)309         explicit Window(int32_t id) : id_(id) {};
310 
~Window()311         ~Window() override {}
312 
GetFrontendClassDef()313         const FrontEndClassDef &GetFrontendClassDef() const override
314         {
315             return UI_WINDOW_DEF;
316         }
317 
318         // plain properties, make them public for easy access
319         int32_t id_ = 0;
320         int32_t windowLayer_ = 0;
321         std::string bundleName_ = "";
322         std::string title_ = "";
323         bool focused_ = false;
324         bool actived_ = false;
325         bool decoratorEnabled_ = false;
326         Rect bounds_ = {0, 0, 0, 0};
327         Rect visibleBounds_ = {0, 0, 0, 0};
328         std::vector<Rect> invisibleBoundsVec_;
329         std::string abilityName_ = "";
330         std::string pagePath_ = "";
331         WindowMode mode_ = UNKNOWN;
332         int32_t displayId_ = 0;
333         std::vector<Rect> touchHotAreas_;
334         Point offset_ = {0, 0};
335     };
336 
337     class DumpHandler {
338     public:
339         static void AddExtraAttrs(nlohmann::json &root, const map<int32_t, string_view> &elementTrees, size_t index);
340         static void DumpWindowInfoToJson(vector<Widget> &allWidget, nlohmann::json &root);
341     };
342 
343     class WidgetHierarchyBuilder {
344     public:
345         static string Build(string_view parentWidgetHierarchy, uint32_t childIndex);
346 
347         static string GetParentWidgetHierarchy(string_view hierarchy);
348 
349         static string GetChildHierarchy(string_view hierarchy, uint32_t childIndex);
350 
351     private:
352         static constexpr auto HIERARCHY_SEPARATOR = ",";
353     };
354 
355     struct DumpOption {
356         string savePath_ = "";
357         bool listWindows_ = false;
358         bool addExternAttr_ = false;
359         string bundleName_ = "";
360         string windowId_ = "";
361         bool notMergeWindow_ = false;
362         int32_t displayId_ = 0;
363     };
364 } // namespace OHOS::uitest
365 
366 #endif