Merge branch 'devel/master' into devel/graphics
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / accessibility-common.h
1 #ifndef DALI_INTERNAL_ATSPI_ACCESSIBILITY_COMMON_H
2 #define DALI_INTERNAL_ATSPI_ACCESSIBILITY_COMMON_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <iomanip>
24 #include <sstream>
25 #include <string>
26
27 // INTERNAL INCLUDES
28 #include <dali/devel-api/adaptor-framework/accessibility-impl.h>
29 #include <dali/internal/accessibility/bridge/dbus-locators.h>
30 #include <dali/internal/accessibility/bridge/dbus.h>
31 #include <dali/public-api/dali-adaptor-common.h>
32
33 #define A11yDbusName "org.a11y.Bus"
34 #define A11yDbusPath "/org/a11y/bus"
35 #define A11yDbusStatusInterface "org.a11y.Status"
36 #define AtspiDbusNameRegistry "org.a11y.atspi.Registry"
37 #define AtspiDbusPathRegistry "/org/a11y/atspi/registry"
38 #define AtspiDbusInterfaceRegistry "org.a11y.atspi.Registry"
39 #define AtspiDbusPathRoot "/org/a11y/atspi/accessible/root"
40 #define AtspiDbusInterfaceSocket "org.a11y.atspi.Socket"
41 #define AtspiPath "/org/a11y/atspi/accessible"
42 #define AtspiDbusInterfaceAccessible "org.a11y.atspi.Accessible"
43 #define AtspiDbusInterfaceAction "org.a11y.atspi.Action"
44 #define AtspiDbusInterfaceApplication "org.a11y.atspi.Application"
45 #define AtspiDbusInterfaceCollection "org.a11y.atspi.Collection"
46 #define AtspiDbusInterfaceComponent "org.a11y.atspi.Component"
47 #define AtspiDbusInterfaceDocument "org.a11y.atspi.Document"
48 #define AtspiDbusInterfaceEditableText "org.a11y.atspi.EditableText"
49 #define AtspiDbusInterfaceEventKeyboard "org.a11y.atspi.Event.Keyboard"
50 #define AtspiDbusInterfaceEventMouse "org.a11y.atspi.Event.Mouse"
51 #define AtspiDbusInterfaceEventObject "org.a11y.atspi.Event.Object"
52 #define AtspiDbusInterfaceHyperlink "org.a11y.atspi.Hyperlink"
53 #define AtspiDbusInterfaceHypertext "org.a11y.atspi.Hypertext"
54 #define AtspiDbusInterfaceImage "org.a11y.atspi.Image"
55 #define AtspiDbusInterfaceSelection "org.a11y.atspi.Selection"
56 #define AtspiDbusInterfaceTable "org.a11y.atspi.Table"
57 #define AtspiDbusInterfaceTableCell "org.a11y.atspi.TableCell"
58 #define AtspiDbusInterfaceText "org.a11y.atspi.Text"
59 #define AtspiDbusInterfaceValue "org.a11y.atspi.Value"
60 #define AtspiDbusInterfaceSocket "org.a11y.atspi.Socket"
61 #define AtspiDbusInterfaceEventWindow "org.a11y.atspi.Event.Window"
62
63 #define AtspiDbusPathDec "/org/a11y/atspi/registry/deviceeventcontroller"
64 #define AtspiDbusInterfaceDec "org.a11y.atspi.DeviceEventController"
65 #define AtspiDbusInterfaceDeviceEventListener "org.a11y.atspi.DeviceEventListener"
66
67 #define DirectReadingDBusName "org.tizen.ScreenReader"
68 #define DirectReadingDBusPath "/org/tizen/DirectReading"
69 #define DirectReadingDBusInterface "org.tizen.DirectReading"
70
71 struct ObjectPath;
72
73 /**
74  * @brief Enumeration used for quering Accessibility objects
75  */
76 enum class MatchType : int32_t
77 {
78   INVALID,
79   ALL,
80   ANY,
81   NONE,
82   EMPTY
83 };
84
85 /**
86  * @brief Enumeration used for quering Accessibility objects
87  * SortOrder::Canonical uses breadth-first search and sort objects in order of indexes in parent
88  * SortOrder::ReverseCanonical uses SortOrder::Canonical and reverse collection
89  * The rest of orders is not supported.
90  */
91 enum class SortOrder : uint32_t
92 {
93   INVALID,
94   CANONICAL,
95   FLOW,
96   TAB,
97   REVERSE_CANONICAL,
98   REVERSE_FLOW,
99   REVERSE_TAB,
100   LAST_DEFINED
101 };
102
103 namespace DBus
104 {
105 class CurrentBridgePtr
106 {
107   static Dali::Accessibility::Bridge*& get()
108   {
109     static thread_local Dali::Accessibility::Bridge* b = nullptr;
110     return b;
111   }
112   Dali::Accessibility::Bridge* prev;
113   CurrentBridgePtr(const CurrentBridgePtr&) = delete;
114   CurrentBridgePtr(CurrentBridgePtr&&)      = delete;
115   CurrentBridgePtr& operator=(const CurrentBridgePtr&) = delete;
116   CurrentBridgePtr& operator=(CurrentBridgePtr&&) = delete;
117
118 public:
119   CurrentBridgePtr(Dali::Accessibility::Bridge* b)
120   : prev(get())
121   {
122     get() = b;
123   }
124
125   ~CurrentBridgePtr()
126   {
127     get() = prev;
128   }
129
130   static Dali::Accessibility::Bridge* current()
131   {
132     return get();
133   }
134 };
135
136 namespace detail
137 {
138 template<typename T>
139 struct signature_accessible_impl : signature_helper<signature_accessible_impl<T>>
140 {
141   using subtype = std::pair<std::string, ObjectPath>;
142
143   static constexpr auto name_v = concat("AtspiAccessiblePtr");
144   static constexpr auto sig_v  = concat("(so)");
145
146   /**
147    * @brief Marshals value v as marshalled type into message
148    */
149   static void set(const DBusWrapper::MessageIterPtr& iter, T* t)
150   {
151     if(t)
152     {
153       auto v = t->GetAddress();
154       signature<subtype>::set(iter, {v.GetBus(), ObjectPath{std::string{ATSPI_PREFIX_PATH} + v.GetPath()}});
155     }
156     else
157     {
158       signature<subtype>::set(iter, {"", ObjectPath{ATSPI_NULL_PATH}});
159     }
160   }
161
162   /**
163    * @brief Marshals value from marshalled type into variable v
164    */
165   static bool get(const DBusWrapper::MessageIterPtr& iter, T*& v)
166   {
167     subtype tmp;
168     if(!signature<subtype>::get(iter, tmp))
169     {
170       return false;
171     }
172
173     if(tmp.second.value == ATSPI_NULL_PATH)
174     {
175       v = nullptr;
176       return true;
177     }
178
179     if(tmp.second.value.substr(0, strlen(ATSPI_PREFIX_PATH)) != ATSPI_PREFIX_PATH)
180     {
181       return false;
182     }
183
184     auto b = CurrentBridgePtr::current();
185     if(b->GetBusName() != tmp.first)
186     {
187       return false;
188     }
189
190     v = b->FindByPath(tmp.second.value.substr(strlen(ATSPI_PREFIX_PATH)));
191     return v != nullptr;
192   }
193 };
194
195 template<>
196 struct signature<Dali::Accessibility::Accessible*> : public signature_accessible_impl<Dali::Accessibility::Accessible>
197 {
198 };
199
200 template<>
201 struct signature<Dali::Accessibility::Address> : signature_helper<signature<Dali::Accessibility::Address>>
202 {
203   using subtype = std::pair<std::string, ObjectPath>;
204
205   static constexpr auto name_v = concat("AtspiAccessiblePtr");
206   static constexpr auto sig_v  = concat("(so)");
207
208   /**
209    * @brief Marshals value v as marshalled type into message
210    */
211   static void set(const DBusWrapper::MessageIterPtr& iter, const Dali::Accessibility::Address& v)
212   {
213     if(v)
214     {
215       signature<subtype>::set(iter, {v.GetBus(), ObjectPath{std::string{ATSPI_PREFIX_PATH} + v.GetPath()}});
216     }
217     else
218     {
219       signature<subtype>::set(iter, {v.GetBus(), ObjectPath{ATSPI_NULL_PATH}});
220     }
221   }
222
223   /**
224    * @brief Marshals value from marshalled type into variable v
225    */
226   static bool get(const DBusWrapper::MessageIterPtr& iter, Dali::Accessibility::Address& v)
227   {
228     subtype tmp;
229     if(!signature<subtype>::get(iter, tmp))
230     {
231       return false;
232     }
233
234     if(tmp.second.value == ATSPI_NULL_PATH)
235     {
236       v = {};
237       return true;
238     }
239     if(tmp.second.value.substr(0, strlen(ATSPI_PREFIX_PATH)) != ATSPI_PREFIX_PATH)
240     {
241       return false;
242     }
243
244     v = {std::move(tmp.first), tmp.second.value.substr(strlen(ATSPI_PREFIX_PATH))};
245     return true;
246   }
247 };
248
249 template<>
250 struct signature<Dali::Accessibility::States> : signature_helper<signature<Dali::Accessibility::States>>
251 {
252   using subtype = std::array<uint32_t, 2>;
253
254   static constexpr auto name_v = signature<subtype>::name_v;
255   static constexpr auto sig_v  = signature<subtype>::sig_v;
256
257   /**
258    * @brief Marshals value v as marshalled type into message
259    */
260   static void set(const DBusWrapper::MessageIterPtr& iter, const Dali::Accessibility::States& v)
261   {
262     signature<subtype>::set(iter, v.GetRawData());
263   }
264
265   /**
266    * @brief Marshals value from marshalled type into variable v
267    */
268   static bool get(const DBusWrapper::MessageIterPtr& iter, Dali::Accessibility::States& v)
269   {
270     subtype tmp;
271     if(!signature<subtype>::get(iter, tmp))
272     {
273       return false;
274     }
275     v = Dali::Accessibility::States{tmp};
276     return true;
277   }
278 };
279 } // namespace detail
280 } // namespace DBus
281
282 struct _Logger
283 {
284   const char*        file;
285   int                line;
286   std::ostringstream tmp;
287
288   _Logger(const char* f, int l)
289   : file(f),
290     line(l)
291   {
292   }
293
294   ~_Logger()
295   {
296     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, "%s:%d: %s", file, line, tmp.str().c_str());
297   }
298
299   template<typename T>
300   _Logger& operator<<(T&& t)
301   {
302     tmp << std::forward<T>(t);
303     return *this;
304   }
305 };
306
307 struct _LoggerEmpty
308 {
309   template<typename T>
310   _LoggerEmpty& operator<<(T&& t)
311   {
312     return *this;
313   }
314 };
315
316 struct _LoggerScope
317 {
318   const char* file;
319   int         line;
320
321   _LoggerScope(const char* f, int l)
322   : file(f),
323     line(l)
324   {
325     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, "%s:%d: +", file, line);
326   }
327
328   ~_LoggerScope()
329   {
330     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, "%s:%d: -", file, line);
331   }
332 };
333
334 #define LOG() _Logger(__FILE__, __LINE__)
335 #define SCOPE() _LoggerScope _l##__LINE__(__FILE__, __LINE__)
336
337 #endif // DALI_INTERNAL_ATSPI_ACCESSIBILITY_COMMON_H