[ATSPI] Add some descriptions to Bridge objects
[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 /* DBus Interfaces */
34
35 #define A11yDbusName "org.a11y.Bus"
36 #define A11yDbusPath "/org/a11y/bus"
37 #define A11yDbusStatusInterface "org.a11y.Status"
38 #define AtspiDbusNameRegistry "org.a11y.atspi.Registry"
39 #define AtspiDbusPathRegistry "/org/a11y/atspi/registry"
40 #define AtspiDbusInterfaceRegistry "org.a11y.atspi.Registry"
41 #define AtspiDbusPathRoot "/org/a11y/atspi/accessible/root"
42 #define AtspiDbusInterfaceSocket "org.a11y.atspi.Socket"
43 #define AtspiPath "/org/a11y/atspi/accessible"
44 #define AtspiDbusInterfaceAccessible "org.a11y.atspi.Accessible"
45 #define AtspiDbusInterfaceAction "org.a11y.atspi.Action"
46 #define AtspiDbusInterfaceApplication "org.a11y.atspi.Application"
47 #define AtspiDbusInterfaceCache "org.a11y.atspi.Cache"
48 #define AtspiDbusPathCache "/org/a11y/atspi/cache"
49 #define AtspiDbusInterfaceCollection "org.a11y.atspi.Collection"
50 #define AtspiDbusInterfaceComponent "org.a11y.atspi.Component"
51 #define AtspiDbusInterfaceDocument "org.a11y.atspi.Document"
52 #define AtspiDbusInterfaceEditableText "org.a11y.atspi.EditableText"
53 #define AtspiDbusInterfaceEventKeyboard "org.a11y.atspi.Event.Keyboard"
54 #define AtspiDbusInterfaceEventMouse "org.a11y.atspi.Event.Mouse"
55 #define AtspiDbusInterfaceEventObject "org.a11y.atspi.Event.Object"
56 #define AtspiDbusInterfaceHyperlink "org.a11y.atspi.Hyperlink"
57 #define AtspiDbusInterfaceHypertext "org.a11y.atspi.Hypertext"
58 #define AtspiDbusInterfaceImage "org.a11y.atspi.Image"
59 #define AtspiDbusInterfaceSelection "org.a11y.atspi.Selection"
60 #define AtspiDbusInterfaceTable "org.a11y.atspi.Table"
61 #define AtspiDbusInterfaceTableCell "org.a11y.atspi.TableCell"
62 #define AtspiDbusInterfaceText "org.a11y.atspi.Text"
63 #define AtspiDbusInterfaceValue "org.a11y.atspi.Value"
64 #define AtspiDbusInterfaceSocket "org.a11y.atspi.Socket"
65 #define AtspiDbusInterfaceEventWindow "org.a11y.atspi.Event.Window"
66
67 #define AtspiDbusPathDec "/org/a11y/atspi/registry/deviceeventcontroller"
68 #define AtspiDbusInterfaceDec "org.a11y.atspi.DeviceEventController"
69 #define AtspiDbusInterfaceDeviceEventListener "org.a11y.atspi.DeviceEventListener"
70
71 #define DirectReadingDBusName "org.tizen.ScreenReader"
72 #define DirectReadingDBusPath "/org/tizen/DirectReading"
73 #define DirectReadingDBusInterface "org.tizen.DirectReading"
74
75 struct ObjectPath;
76
77 /**
78  * @brief Enumeration used for quering Accessibility objects
79  */
80 enum class MatchType : int32_t
81 {
82   INVALID,
83   ALL,
84   ANY,
85   NONE,
86   EMPTY
87 };
88
89 /**
90  * @brief Enumeration used for quering Accessibility objects
91  * SortOrder::Canonical uses breadth-first search and sort objects in order of indexes in parent
92  * SortOrder::ReverseCanonical uses SortOrder::Canonical and reverse collection
93  * The rest of orders is not supported.
94  */
95 enum class SortOrder : uint32_t
96 {
97   INVALID,
98   CANONICAL,
99   FLOW,
100   TAB,
101   REVERSE_CANONICAL,
102   REVERSE_FLOW,
103   REVERSE_TAB,
104   LAST_DEFINED
105 };
106
107 namespace DBus
108 {
109
110 /**
111  * @brief The CurrentBridgePtr class is to save the current Accessibility Bridge.
112  */
113 class CurrentBridgePtr
114 {
115   static Dali::Accessibility::Bridge*& Get()
116   {
117     static thread_local Dali::Accessibility::Bridge* bridge = nullptr;
118     return bridge;
119   }
120   Dali::Accessibility::Bridge* mPrev;
121   CurrentBridgePtr(const CurrentBridgePtr&) = delete;
122   CurrentBridgePtr(CurrentBridgePtr&&)      = delete;
123   CurrentBridgePtr& operator=(const CurrentBridgePtr&) = delete;
124   CurrentBridgePtr& operator=(CurrentBridgePtr&&) = delete;
125
126 public:
127   CurrentBridgePtr(Dali::Accessibility::Bridge* bridge)
128   : mPrev(Get())
129   {
130     Get() = bridge;
131   }
132
133   ~CurrentBridgePtr()
134   {
135     Get() = mPrev;
136   }
137
138   static Dali::Accessibility::Bridge* GetCurrentBridge()
139   {
140     return Get();
141   }
142 }; // CurrentBridgePtr
143
144
145 // Templates for setting and getting Accessible values
146 namespace detail
147 {
148 template<typename T>
149 struct SignatureAccessibleImpl : signature_helper<SignatureAccessibleImpl<T>>
150 {
151   using subtype = std::pair<std::string, ObjectPath>;
152
153   static constexpr auto name_v = concat("AtspiAccessiblePtr");
154   static constexpr auto sig_v  = concat("(so)");
155
156   /**
157    * @brief Marshals value address as marshalled type into message
158    */
159   static void set(const DBusWrapper::MessageIterPtr& iter, T* accessible)
160   {
161     if(accessible)
162     {
163       auto address = accessible->GetAddress();
164       signature<subtype>::set(iter, {address.GetBus(), ObjectPath{std::string{ATSPI_PREFIX_PATH} + address.GetPath()}});
165     }
166     else
167     {
168       signature<subtype>::set(iter, {"", ObjectPath{ATSPI_NULL_PATH}});
169     }
170   }
171
172   /**
173    * @brief Marshals value from marshalled type into variable path
174    */
175   static bool get(const DBusWrapper::MessageIterPtr& iter, T*& path)
176   {
177     subtype tmp;
178     if(!signature<subtype>::get(iter, tmp))
179     {
180       return false;
181     }
182
183     if(tmp.second.value == ATSPI_NULL_PATH)
184     {
185       path = nullptr;
186       return true;
187     }
188
189     if(tmp.second.value.substr(0, strlen(ATSPI_PREFIX_PATH)) != ATSPI_PREFIX_PATH)
190     {
191       return false;
192     }
193
194     auto currentBridge = CurrentBridgePtr::GetCurrentBridge();
195     if(currentBridge->GetBusName() != tmp.first)
196     {
197       return false;
198     }
199
200     path = currentBridge->FindByPath(tmp.second.value.substr(strlen(ATSPI_PREFIX_PATH)));
201     return path != nullptr;
202   }
203 };
204
205 template<>
206 struct signature<Dali::Accessibility::Accessible*> : public SignatureAccessibleImpl<Dali::Accessibility::Accessible>
207 {
208 };
209
210 template<>
211 struct signature<Dali::Accessibility::Address> : signature_helper<signature<Dali::Accessibility::Address>>
212 {
213   using subtype = std::pair<std::string, ObjectPath>;
214
215   static constexpr auto name_v = concat("AtspiAccessiblePtr");
216   static constexpr auto sig_v  = concat("(so)");
217
218   /**
219    * @brief Marshals value address as marshalled type into message
220    */
221   static void set(const DBusWrapper::MessageIterPtr& iter, const Dali::Accessibility::Address& address)
222   {
223     if(address)
224     {
225       signature<subtype>::set(iter, {address.GetBus(), ObjectPath{std::string{ATSPI_PREFIX_PATH} + address.GetPath()}});
226     }
227     else
228     {
229       signature<subtype>::set(iter, {address.GetBus(), ObjectPath{ATSPI_NULL_PATH}});
230     }
231   }
232
233   /**
234    * @brief Marshals value from marshalled type into variable address
235    */
236   static bool get(const DBusWrapper::MessageIterPtr& iter, Dali::Accessibility::Address& address)
237   {
238     subtype tmp;
239     if(!signature<subtype>::get(iter, tmp))
240     {
241       return false;
242     }
243
244     if(tmp.second.value == ATSPI_NULL_PATH)
245     {
246       address = {};
247       return true;
248     }
249     if(tmp.second.value.substr(0, strlen(ATSPI_PREFIX_PATH)) != ATSPI_PREFIX_PATH)
250     {
251       return false;
252     }
253
254     address = {std::move(tmp.first), tmp.second.value.substr(strlen(ATSPI_PREFIX_PATH))};
255     return true;
256   }
257 };
258
259 template<>
260 struct signature<Dali::Accessibility::States> : signature_helper<signature<Dali::Accessibility::States>>
261 {
262   using subtype = std::array<uint32_t, 2>;
263
264   static constexpr auto name_v = signature<subtype>::name_v;
265   static constexpr auto sig_v  = signature<subtype>::sig_v;
266
267   /**
268    * @brief Marshals value state as marshalled type into message
269    */
270   static void set(const DBusWrapper::MessageIterPtr& iter, const Dali::Accessibility::States& states)
271   {
272     signature<subtype>::set(iter, states.GetRawData());
273   }
274
275   /**
276    * @brief Marshals value from marshalled type into variable state
277    */
278   static bool get(const DBusWrapper::MessageIterPtr& iter, Dali::Accessibility::States& state)
279   {
280     subtype tmp;
281     if(!signature<subtype>::get(iter, tmp))
282     {
283       return false;
284     }
285     state = Dali::Accessibility::States{tmp};
286     return true;
287   }
288 };
289 } // namespace detail
290 } // namespace DBus
291
292 struct _Logger
293 {
294   const char*        mFile;
295   int                mLine;
296   std::ostringstream mTmp;
297
298   _Logger(const char* file, int line)
299   : mFile(file),
300     mLine(line)
301   {
302   }
303
304   ~_Logger()
305   {
306     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, "%s:%d: %s", mFile, mLine, mTmp.str().c_str());
307   }
308
309   template<typename T>
310   _Logger& operator<<(T&& t)
311   {
312     mTmp << std::forward<T>(t);
313     return *this;
314   }
315 };
316
317 struct _LoggerEmpty
318 {
319   template<typename T>
320   _LoggerEmpty& operator<<(T&& t)
321   {
322     return *this;
323   }
324 };
325
326 struct _LoggerScope
327 {
328   const char* mFile;
329   int         mLine;
330
331   _LoggerScope(const char* file, int line)
332   : mFile(file),
333     mLine(line)
334   {
335     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, "%s:%d: +", mFile, mLine);
336   }
337
338   ~_LoggerScope()
339   {
340     Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, "%s:%d: -", mFile, mLine);
341   }
342 };
343
344 #define LOG() _Logger(__FILE__, __LINE__)
345 #define SCOPE() _LoggerScope _l##__LINE__(__FILE__, __LINE__)
346
347 #endif // DALI_INTERNAL_ATSPI_ACCESSIBILITY_COMMON_H