0de1c62d3fc63e557278b43773b4de7cc79dcfe9
[platform/core/uifw/aurum.git] / libaurum / src / AccessibleNode.cc
1 #include "AccessibleNode.h"
2 #include <string.h>
3 #include <iostream>
4
5 #include "loguru.hpp"
6 #include "config.h"
7
8 std::map<AtspiAccessible *, AccessibleNode *> AccessibleNode::mNodeMap{};
9
10 AccessibleNode::~AccessibleNode()
11 {
12
13 }
14
15 AccessibleNode::AccessibleNode() : AccessibleNode(nullptr)
16 {
17     // No meaning without AtspiAccessbile object
18     // prohibited to create this object with this constructor
19 }
20
21 AccessibleNode::AccessibleNode(AtspiAccessible *node)
22     : mNode(make_gobj_ref_unique(node)), mBoundingBox{0,0,0,0}, mSupportingIfaces(0), mFeatureProperty(0), mIsAlive(true)
23 {
24     // prohibited to create this object this constructor
25     // better to use AccessibleNode::get factory method.
26
27     LOG_SCOPE_F(1, "AccessibleNode constructor %p", mNode.get());
28     GArray *ifaces = atspi_accessible_get_interfaces(mNode.get());
29     if (ifaces) {
30         for (unsigned int i = 0; i < ifaces->len; i++) {
31             char *iface = g_array_index(ifaces, char *, i);
32             if (!strcmp(iface, "Action"))
33                 mSupportingIfaces |=
34                     static_cast<int>(AccessibleNodeInterface::ACTION);
35             else if (!strcmp(iface, "Collection"))
36                 mSupportingIfaces |=
37                     static_cast<int>(AccessibleNodeInterface::COLLECTION);
38             else if (!strcmp(iface, "Component"))
39                 mSupportingIfaces |=
40                     static_cast<int>(AccessibleNodeInterface::COMPONENT);
41             else if (!strcmp(iface, "Document"))
42                 mSupportingIfaces |=
43                     static_cast<int>(AccessibleNodeInterface::DOCUMENT);
44             else if (!strcmp(iface, "EditableText"))
45                 mSupportingIfaces |=
46                     static_cast<int>(AccessibleNodeInterface::EDITABLETEXT);
47             else if (!strcmp(iface, "Hypertext"))
48                 mSupportingIfaces |=
49                     static_cast<int>(AccessibleNodeInterface::HYPERTEXT);
50             else if (!strcmp(iface, "Image"))
51                 mSupportingIfaces |=
52                     static_cast<int>(AccessibleNodeInterface::IMAGE);
53             else if (!strcmp(iface, "Selection"))
54                 mSupportingIfaces |=
55                     static_cast<int>(AccessibleNodeInterface::SELECTION);
56             else if (!strcmp(iface, "Text"))
57                 mSupportingIfaces |=
58                     static_cast<int>(AccessibleNodeInterface::TEXT);
59             else if (!strcmp(iface, "Value"))
60                 mSupportingIfaces |=
61                     static_cast<int>(AccessibleNodeInterface::VALUE);
62             else if (!strcmp(iface, "Accessible"))
63                 mSupportingIfaces |=
64                     static_cast<int>(AccessibleNodeInterface::ACCESSIBLE);
65             else if (!strcmp(iface, "Table"))
66                 mSupportingIfaces |=
67                     static_cast<int>(AccessibleNodeInterface::TABLE);
68             else if (!strcmp(iface, "TableCell"))
69                 mSupportingIfaces |=
70                     static_cast<int>(AccessibleNodeInterface::TABLECELL);
71             else
72                 LOG_F(WARNING, "Not Supported interface found %s", iface);
73         }
74     }
75     this->refresh();
76 }
77
78 std::unique_ptr<AccessibleNode> AccessibleNode::get(AtspiAccessible *node)
79 {
80     return std::make_unique<AccessibleNode>(node);
81 }
82
83 void AccessibleNode::refresh() const
84 {
85     gchar *rolename = atspi_accessible_get_role_name(mNode.get(), NULL);
86     if (rolename) {
87         mRole = rolename;
88         g_free(rolename);
89     }
90
91 #ifdef GBS_BUILD
92     gchar *uID = atspi_accessible_get_unique_id(mNode.get(), NULL);
93     if (uID) {
94         mRes = uID;
95         g_free(uID);
96     }
97 #else
98     mRes = "Not_Supported";
99 #endif
100
101     /*
102         GHashTable *attributes = atspi_accessible_get_attributes(mNode, NULL);
103         char *t = (char*)g_hash_table_lookup(attributes, "type");
104         char *s = (char*)g_hash_table_lookup(attributes, "style");
105
106         //LOG_F(INFO, "%s %s", t, s);
107
108         if (t) mType =  std::string(t);
109         if (s) mStyle = std::string(s);
110
111         free(t);
112         free(s);
113
114         g_hash_table_unref(attributes);
115     */
116 }
117
118 int AccessibleNode::getChildCount() const
119 {
120     return atspi_accessible_get_child_count(mNode.get(), NULL);
121 }
122
123 std::unique_ptr<AccessibleNode> AccessibleNode::getChildAt(int index) const
124 {
125     AtspiAccessible *child =
126         atspi_accessible_get_child_at_index(mNode.get(), index, NULL);
127     if (child) {
128         auto node = AccessibleNode::get(child);
129         g_object_unref(child);
130         return node;
131     }
132     return AccessibleNode::get(nullptr);
133 }
134
135 std::unique_ptr<AccessibleNode> AccessibleNode::getParent() const
136 {
137     AtspiAccessible *parent = atspi_accessible_get_parent(mNode.get(), NULL);
138     auto node = AccessibleNode::get(parent);
139     if (parent) g_object_unref(parent);
140     return node;
141 }
142
143 void AccessibleNode::print(int d, int m) const
144 {
145     if (m <= 0 || d > m) return;
146
147     int             n = 0;
148     this->print(d);
149     n = getChildCount();
150
151     for (int i = 0; i < n; i++) {
152         auto child = getChildAt(i);
153         if (child) child->print(d + 1, m);
154     }
155 }
156
157 void AccessibleNode::print(int d) const
158 {
159     char *name = atspi_accessible_get_name(mNode.get(), NULL);
160     char *role = atspi_accessible_get_role_name(mNode.get(), NULL);
161     LOG_F(INFO, "%s - %p(%s)  /  role:%s, pkg:%s, text:%s",
162           std::string(d, ' ').c_str(), mNode.get(), name, role, getPkg().c_str(),
163           getText().c_str());
164     free(name);
165     free(role);
166 }
167
168 bool AccessibleNode::isSupporting(AccessibleNodeInterface thisIface) const
169 {
170     return (mSupportingIfaces & static_cast<int>(thisIface)) != 0;
171 }
172
173 bool AccessibleNode::hasFeatureProperty(NodeFeatureProperties prop) const
174 {
175     return (mFeatureProperty & static_cast<int>(prop)) != 0;
176 }
177
178 void AccessibleNode::setFeatureProperty(NodeFeatureProperties prop, bool has)
179 {
180     if (has)
181         mFeatureProperty |= static_cast<int>(prop);
182     else
183         mFeatureProperty &= ~static_cast<int>(prop);
184 }
185
186 std::string AccessibleNode::getDesc() const
187 {
188     return mDesc;
189 }
190
191 std::string AccessibleNode::getText() const
192 {
193     gchar *name = atspi_accessible_get_name(mNode.get(), NULL);
194     mText = name;
195     mPkg = name;
196     g_free(name);
197
198     return mText;
199 }
200
201 std::string AccessibleNode::getPkg() const
202 {
203     return mPkg;
204 }
205
206 std::string AccessibleNode::getRes() const
207 {
208     return mRes;
209 }
210 std::string AccessibleNode::getType() const
211 {
212     return mType;
213 }
214 Rect<int> AccessibleNode::getBoundingBox() const
215 {
216     AtspiComponent *component = atspi_accessible_get_component_iface(mNode.get());
217     if (component) {
218         AtspiRect *extent = atspi_component_get_extents(
219             component, ATSPI_COORD_TYPE_SCREEN, NULL);
220         if (extent) {
221             mBoundingBox =
222                 Rect<int>{extent->x, extent->y, extent->x + extent->width,
223                           extent->y + extent->height};
224             g_free(extent);
225         }
226         g_object_unref(component);
227     }
228
229     return mBoundingBox;
230 }
231
232 bool AccessibleNode::isCheckable() const
233 {
234     return hasFeatureProperty(NodeFeatureProperties::CHECKABLE);
235 }
236
237 bool AccessibleNode::isChecked() const
238 {
239     return hasFeatureProperty(NodeFeatureProperties::CHECKED);
240 }
241
242 bool AccessibleNode::isClickable() const
243 {
244     return hasFeatureProperty(NodeFeatureProperties::CLICKABLE);
245 }
246
247 bool AccessibleNode::isEnabled() const
248 {
249     return hasFeatureProperty(NodeFeatureProperties::ENABLED);
250 }
251
252 bool AccessibleNode::isFocusable() const
253 {
254     return hasFeatureProperty(NodeFeatureProperties::FOCUSABLE);
255 }
256
257 bool AccessibleNode::isFocused() const
258 {
259     return hasFeatureProperty(NodeFeatureProperties::FOCUSED);
260 }
261
262 bool AccessibleNode::isLongClickable() const
263 {
264     return hasFeatureProperty(NodeFeatureProperties::LONGCLICKABLE);
265 }
266
267 bool AccessibleNode::isScrollable() const
268 {
269     return hasFeatureProperty(NodeFeatureProperties::SCROLLABLE);
270 }
271
272 bool AccessibleNode::isSelectable() const
273 {
274     return hasFeatureProperty(NodeFeatureProperties::SELECTABLE);
275 }
276
277 bool AccessibleNode::isSelected() const
278 {
279     return hasFeatureProperty(NodeFeatureProperties::SELECTED);
280 }
281
282 bool AccessibleNode::isVisible() const
283 {
284     return hasFeatureProperty(NodeFeatureProperties::VISIBILITY);
285 }
286
287 AtspiAccessible *AccessibleNode::getAccessible() const
288 {
289     return mNode.get();
290 }
291
292 void AccessibleNode::setValue(std::string &text) const
293 {
294     AtspiEditableText *iface = atspi_accessible_get_editable_text(mNode.get());
295     if (iface) {
296         atspi_editable_text_insert_text(iface, 0, text.c_str(), text.length(),
297                                         NULL);
298     }
299 }