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