ea6c746b28aaea5f6233d7e3ebc906a027848b33
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / bridge-base.h
1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_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/public-api/signals/connection-tracker.h>
23 #include <memory>
24
25 // INTERNAL INCLUDES
26 #include <dali/internal/accessibility/bridge/accessibility-common.h>
27
28 class AppAccessible : public virtual Dali::Accessibility::Accessible, public virtual Dali::Accessibility::Collection
29 {
30 public:
31   Dali::Accessibility::EmptyAccessibleWithAddress parent;
32   std::vector<Dali::Accessibility::Accessible*>   children;
33   std::string                                     name;
34
35   std::string GetName() override
36   {
37     return name;
38   }
39
40   std::string GetDescription() override
41   {
42     return "";
43   }
44
45   Dali::Accessibility::Accessible* GetParent() override
46   {
47     return &parent;
48   }
49
50   size_t GetChildCount() override
51   {
52     return children.size();
53   }
54
55   Dali::Accessibility::Accessible* GetChildAtIndex(size_t index) override
56   {
57     auto s = children.size();
58     if(index >= s)
59       throw std::domain_error{"invalid index " + std::to_string(index) + " for object with " + std::to_string(s) + " children"};
60     return children[index];
61   }
62
63   size_t GetIndexInParent() override
64   {
65     throw std::domain_error{"can't call GetIndexInParent on application object"};
66   }
67
68   Dali::Accessibility::Role GetRole() override
69   {
70     return Dali::Accessibility::Role::APPLICATION;
71   }
72
73   Dali::Accessibility::States GetStates() override
74   {
75     return {};
76   }
77
78   Dali::Accessibility::Attributes GetAttributes() override
79   {
80     return {};
81   }
82
83   Dali::Accessibility::Accessible* getActiveWindow()
84   {
85     return children.empty() ? nullptr : children[0];
86   }
87
88   bool DoGesture(const Dali::Accessibility::GestureInfo& gestureInfo) override
89   {
90     return false;
91   }
92
93   std::vector<Dali::Accessibility::Relation> GetRelationSet() override
94   {
95     return {};
96   }
97
98   Dali::Accessibility::Address GetAddress() override
99   {
100     return {"", "root"};
101   }
102 };
103
104 enum class FilteredEvents
105 {
106   boundsChanged
107 };
108
109 namespace std
110 {
111 template<>
112 struct hash<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>>
113 {
114   size_t operator()(std::pair<FilteredEvents, Dali::Accessibility::Accessible*> v) const
115   {
116     return (static_cast<size_t>(v.first) * 131) ^ reinterpret_cast<size_t>(v.second);
117   }
118 };
119 } // namespace std
120
121 class BridgeBase : public Dali::Accessibility::Bridge, public Dali::ConnectionTracker
122 {
123   std::unordered_map<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>, std::pair<unsigned int, std::function<void()>>> filteredEvents;
124
125   bool tickFilteredEvents();
126
127 public:
128   void addFilteredEvent(FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function<void()> functor);
129
130   const std::string& GetBusName() const override;
131   void               AddTopLevelWindow(Dali::Accessibility::Accessible* window) override;
132   void               RemoveTopLevelWindow(Dali::Accessibility::Accessible* window) override;
133   void               AddPopup(Dali::Accessibility::Accessible*) override;
134   void               RemovePopup(Dali::Accessibility::Accessible*) override;
135
136   Dali::Accessibility::Accessible* GetApplication() const override
137   {
138     return &application;
139   }
140
141   template<typename SELF, typename... RET, typename... ARGS>
142   void AddFunctionToInterface(
143     DBus::DBusInterfaceDescription& desc, const std::string& funcName, DBus::ValueOrError<RET...> (SELF::*funcPtr)(ARGS...))
144   {
145     if(auto self = dynamic_cast<SELF*>(this))
146       desc.addMethod<DBus::ValueOrError<RET...>(ARGS...)>(
147         funcName,
148         [=](ARGS... args) -> DBus::ValueOrError<RET...> {
149           try
150           {
151             return (self->*funcPtr)(std::move(args)...);
152           }
153           catch(std::domain_error& e)
154           {
155             return DBus::Error{e.what()};
156           }
157         });
158   }
159
160   template<typename T, typename SELF>
161   void AddGetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
162                                  const std::string&              funcName,
163                                  T (SELF::*funcPtr)())
164   {
165     if(auto self = dynamic_cast<SELF*>(this))
166       desc.addProperty<T>(funcName,
167                           [=]() -> DBus::ValueOrError<T> {
168                             try
169                             {
170                               return (self->*funcPtr)();
171                             }
172                             catch(std::domain_error& e)
173                             {
174                               return DBus::Error{e.what()};
175                             }
176                           },
177                           {});
178   }
179
180   template<typename T, typename SELF>
181   void AddSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
182                                  const std::string&              funcName,
183                                  void (SELF::*funcPtr)(T))
184   {
185     if(auto self = dynamic_cast<SELF*>(this))
186       desc.addProperty<T>(funcName, {}, [=](T t) -> DBus::ValueOrError<void> {
187         try
188         {
189           (self->*funcPtr)(std::move(t));
190           return {};
191         }
192         catch(std::domain_error& e)
193         {
194           return DBus::Error{e.what()};
195         }
196       });
197   }
198
199   template<typename T, typename T1, typename SELF>
200   void AddGetSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
201                                     const std::string&              funcName,
202                                     T1 (SELF::*funcPtrGet)(),
203                                     DBus::ValueOrError<void> (SELF::*funcPtrSet)(T))
204   {
205     if(auto self = dynamic_cast<SELF*>(this))
206       desc.addProperty<T>(
207         funcName,
208         [=]() -> DBus::ValueOrError<T> {
209           try
210           {
211             return (self->*funcPtrGet)();
212           }
213           catch(std::domain_error& e)
214           {
215             return DBus::Error{e.what()};
216           }
217         },
218         [=](T t) -> DBus::ValueOrError<void> {
219           try
220           {
221             (self->*funcPtrSet)(std::move(t));
222             return {};
223           }
224           catch(std::domain_error& e)
225           {
226             return DBus::Error{e.what()};
227           }
228         });
229   }
230   template<typename T, typename T1, typename SELF>
231   void AddGetSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
232                                     const std::string&              funcName,
233                                     T1 (SELF::*funcPtrGet)(),
234                                     void (SELF::*funcPtrSet)(T))
235   {
236     if(auto self = dynamic_cast<SELF*>(this))
237       desc.addProperty<T>(
238         funcName,
239         [=]() -> DBus::ValueOrError<T> {
240           try
241           {
242             return (self->*funcPtrGet)();
243           }
244           catch(std::domain_error& e)
245           {
246             return DBus::Error{e.what()};
247           }
248         },
249         [=](T t) -> DBus::ValueOrError<void> {
250           try
251           {
252             (self->*funcPtrSet)(std::move(t));
253             return {};
254           }
255           catch(std::domain_error& e)
256           {
257             return DBus::Error{e.what()};
258           }
259         });
260   }
261   static std::string StripPrefix(const std::string& path);
262
263   Dali::Accessibility::Accessible* Find(const std::string& path) const;
264   Dali::Accessibility::Accessible* Find(const Dali::Accessibility::Address& ptr) const;
265   Dali::Accessibility::Accessible* FindSelf() const;
266   Dali::Accessibility::Accessible* FindByPath(const std::string& name) const override;
267   void                             SetApplicationName(std::string name) override
268   {
269     application.name = std::move(name);
270   }
271
272 protected:
273   mutable AppAccessible                         application;
274   std::vector<Dali::Accessibility::Accessible*> popups;
275
276 private:
277   void IdSet(int id);
278   int  IdGet();
279   void RegisteredEventsUpdate();
280
281   using CacheElementType = std::tuple<
282     Dali::Accessibility::Address,
283     Dali::Accessibility::Address,
284     Dali::Accessibility::Address,
285     std::vector<Dali::Accessibility::Address>,
286     std::vector<std::string>,
287     std::string,
288     Dali::Accessibility::Role,
289     std::string,
290     std::array<uint32_t, 2>>;
291   DBus::ValueOrError<std::vector<CacheElementType>> GetItems();
292   CacheElementType                                  CreateCacheElement(Dali::Accessibility::Accessible* item);
293
294 protected:
295   BridgeBase();
296   virtual ~BridgeBase();
297
298   ForceUpResult ForceUp() override;
299   void          ForceDown() override;
300
301   DBus::DBusServer           dbusServer;
302   DBusWrapper::ConnectionPtr con;
303   int                        id = 0;
304   DBus::DBusClient           registry;
305   bool                       allowObjectBoundsChangedEvent{false};
306 };
307
308 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H