[dali_2.3.24] Merge branch 'devel/master'
[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) 2022 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/dbus-locators.h>
30 #include <dali/internal/accessibility/bridge/dbus/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  * @brief The CurrentBridgePtr class is to save the current Accessibility Bridge.
87  */
88 class CurrentBridgePtr
89 {
90   static Dali::Accessibility::Bridge*& Get()
91   {
92     static thread_local Dali::Accessibility::Bridge* bridge = nullptr;
93     return bridge;
94   }
95   Dali::Accessibility::Bridge* mPrev;
96   CurrentBridgePtr(const CurrentBridgePtr&) = delete;
97   CurrentBridgePtr(CurrentBridgePtr&&)      = delete;
98   CurrentBridgePtr& operator=(const CurrentBridgePtr&) = delete;
99   CurrentBridgePtr& operator=(CurrentBridgePtr&&) = delete;
100
101 public:
102   CurrentBridgePtr(Dali::Accessibility::Bridge* bridge)
103   : mPrev(Get())
104   {
105     Get() = bridge;
106   }
107
108   ~CurrentBridgePtr()
109   {
110     Get() = mPrev;
111   }
112
113   static Dali::Accessibility::Bridge* GetCurrentBridge()
114   {
115     return Get();
116   }
117 }; // CurrentBridgePtr
118
119 // Templates for setting and getting Accessible values
120 namespace detail
121 {
122 template<>
123 struct signature<Dali::Accessibility::Address> : signature_helper<signature<Dali::Accessibility::Address>>
124 {
125   using subtype = std::pair<std::string, ObjectPath>;
126
127   static constexpr auto name_v = concat("AtspiAccessiblePtr");
128   static constexpr auto sig_v  = signature<subtype>::sig_v; // "(so)"
129
130   /**
131    * @brief Marshals value address as marshalled type into message
132    */
133   static void set(const DBusWrapper::MessageIterPtr& iter, const Dali::Accessibility::Address& address)
134   {
135     if(address)
136     {
137       signature<subtype>::set(iter, {address.GetBus(), ObjectPath{std::string{ATSPI_PREFIX_PATH} + address.GetPath()}});
138     }
139     else
140     {
141       signature<subtype>::set(iter, {address.GetBus(), ObjectPath{ATSPI_NULL_PATH}});
142     }
143   }
144
145   /**
146    * @brief Marshals value from marshalled type into variable address
147    */
148   static bool get(const DBusWrapper::MessageIterPtr& iter, Dali::Accessibility::Address& address)
149   {
150     subtype tmp;
151     if(!signature<subtype>::get(iter, tmp))
152     {
153       return false;
154     }
155
156     if(tmp.second.value == ATSPI_NULL_PATH)
157     {
158       address = {};
159       return true;
160     }
161     if(tmp.second.value.substr(0, strlen(ATSPI_PREFIX_PATH)) != ATSPI_PREFIX_PATH)
162     {
163       return false;
164     }
165
166     address = {std::move(tmp.first), tmp.second.value.substr(strlen(ATSPI_PREFIX_PATH))};
167     return true;
168   }
169 };
170
171 template<typename T>
172 struct SignatureAccessibleImpl : signature_helper<SignatureAccessibleImpl<T>>
173 {
174   using subtype = Dali::Accessibility::Address;
175
176   static constexpr auto name_v = signature<subtype>::name_v;
177   static constexpr auto sig_v  = signature<subtype>::sig_v;
178
179   /**
180    * @brief Marshals value address as marshalled type into message
181    */
182   static void set(const DBusWrapper::MessageIterPtr& iter, T* accessible)
183   {
184     signature<subtype>::set(iter, accessible ? accessible->GetAddress() : subtype{});
185   }
186
187   /**
188    * @brief Marshals value from marshalled type into variable path
189    */
190   static bool get(const DBusWrapper::MessageIterPtr& iter, T*& path)
191   {
192     subtype address;
193
194     signature<subtype>::get(iter, address);
195
196     auto currentBridge = CurrentBridgePtr::GetCurrentBridge();
197     if(currentBridge->GetBusName() != address.GetBus())
198     {
199       return false;
200     }
201
202     path = currentBridge->FindByPath(address.GetPath());
203     return path != nullptr;
204   }
205 };
206
207 template<>
208 struct signature<Dali::Accessibility::Accessible*> : public SignatureAccessibleImpl<Dali::Accessibility::Accessible>
209 {
210 };
211
212 template<>
213 struct signature<Dali::Accessibility::States> : signature_helper<signature<Dali::Accessibility::States>>
214 {
215   using subtype = std::array<uint32_t, 2>;
216
217   static constexpr auto name_v = signature<subtype>::name_v;
218   static constexpr auto sig_v  = signature<subtype>::sig_v;
219
220   /**
221    * @brief Marshals value state as marshalled type into message
222    */
223   static void set(const DBusWrapper::MessageIterPtr& iter, const Dali::Accessibility::States& states)
224   {
225     signature<subtype>::set(iter, states.GetRawData());
226   }
227
228   /**
229    * @brief Marshals value from marshalled type into variable state
230    */
231   static bool get(const DBusWrapper::MessageIterPtr& iter, Dali::Accessibility::States& state)
232   {
233     subtype tmp;
234     if(!signature<subtype>::get(iter, tmp))
235     {
236       return false;
237     }
238     state = Dali::Accessibility::States{tmp};
239     return true;
240   }
241 };
242 } // namespace detail
243 } // namespace DBus
244
245 struct _Logger
246 {
247   const char*        mFile;
248   int                mLine;
249   std::ostringstream mTmp;
250
251   _Logger(const char* file, int line)
252   : mFile(file),
253     mLine(line)
254   {
255   }
256
257   ~_Logger()
258   {
259     Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, "%s:%d: %s", mFile, mLine, mTmp.str().c_str());
260   }
261
262   template<typename T>
263   _Logger& operator<<(T&& t)
264   {
265     mTmp << std::forward<T>(t);
266     return *this;
267   }
268 };
269
270 struct _LoggerEmpty
271 {
272   template<typename T>
273   _LoggerEmpty& operator<<(T&& t)
274   {
275     return *this;
276   }
277 };
278
279 struct _LoggerScope
280 {
281   const char* mFile;
282   int         mLine;
283
284   _LoggerScope(const char* file, int line)
285   : mFile(file),
286     mLine(line)
287   {
288     Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, "%s:%d: +", mFile, mLine);
289   }
290
291   ~_LoggerScope()
292   {
293     Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, "%s:%d: -", mFile, mLine);
294   }
295 };
296
297 #define LOG() _Logger(__FILE__, __LINE__)
298 #define SCOPE() _LoggerScope _l##__LINE__(__FILE__, __LINE__)
299
300 #endif // DALI_INTERNAL_ATSPI_ACCESSIBILITY_COMMON_H