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