Merge "Support partial update in case of window rotation" into devel/master
[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...)>(funcName,
147                                                           [=](ARGS... args) -> DBus::ValueOrError<RET...> {
148                                                             try
149                                                             {
150                                                               return (self->*funcPtr)(std::move(args)...);
151                                                             }
152                                                             catch(std::domain_error& e)
153                                                             {
154                                                               return DBus::Error{e.what()};
155                                                             }
156                                                           });
157   }
158
159   template<typename T, typename SELF>
160   void AddGetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
161                                  const std::string&              funcName,
162                                  T (SELF::*funcPtr)())
163   {
164     if(auto self = dynamic_cast<SELF*>(this))
165       desc.addProperty<T>(funcName,
166                           [=]() -> DBus::ValueOrError<T> {
167                             try
168                             {
169                               return (self->*funcPtr)();
170                             }
171                             catch(std::domain_error& e)
172                             {
173                               return DBus::Error{e.what()};
174                             }
175                           },
176                           {});
177   }
178
179   template<typename T, typename SELF>
180   void AddSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
181                                  const std::string&              funcName,
182                                  void (SELF::*funcPtr)(T))
183   {
184     if(auto self = dynamic_cast<SELF*>(this))
185       desc.addProperty<T>(funcName, {}, [=](T t) -> DBus::ValueOrError<void> {
186         try
187         {
188           (self->*funcPtr)(std::move(t));
189           return {};
190         }
191         catch(std::domain_error& e)
192         {
193           return DBus::Error{e.what()};
194         }
195       });
196   }
197
198   template<typename T, typename T1, typename SELF>
199   void AddGetSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
200                                     const std::string&              funcName,
201                                     T1 (SELF::*funcPtrGet)(),
202                                     DBus::ValueOrError<void> (SELF::*funcPtrSet)(T))
203   {
204     if(auto self = dynamic_cast<SELF*>(this))
205       desc.addProperty<T>(
206         funcName,
207         [=]() -> DBus::ValueOrError<T> {
208           try
209           {
210             return (self->*funcPtrGet)();
211           }
212           catch(std::domain_error& e)
213           {
214             return DBus::Error{e.what()};
215           }
216         },
217         [=](T t) -> DBus::ValueOrError<void> {
218           try
219           {
220             (self->*funcPtrSet)(std::move(t));
221             return {};
222           }
223           catch(std::domain_error& e)
224           {
225             return DBus::Error{e.what()};
226           }
227         });
228   }
229   template<typename T, typename T1, typename SELF>
230   void AddGetSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
231                                     const std::string&              funcName,
232                                     T1 (SELF::*funcPtrGet)(),
233                                     void (SELF::*funcPtrSet)(T))
234   {
235     if(auto self = dynamic_cast<SELF*>(this))
236       desc.addProperty<T>(
237         funcName,
238         [=]() -> DBus::ValueOrError<T> {
239           try
240           {
241             return (self->*funcPtrGet)();
242           }
243           catch(std::domain_error& e)
244           {
245             return DBus::Error{e.what()};
246           }
247         },
248         [=](T t) -> DBus::ValueOrError<void> {
249           try
250           {
251             (self->*funcPtrSet)(std::move(t));
252             return {};
253           }
254           catch(std::domain_error& e)
255           {
256             return DBus::Error{e.what()};
257           }
258         });
259   }
260   static std::string StripPrefix(const std::string& path);
261
262   Dali::Accessibility::Accessible* Find(const std::string& path) const;
263   Dali::Accessibility::Accessible* Find(const Dali::Accessibility::Address& ptr) const;
264   Dali::Accessibility::Accessible* FindSelf() const;
265   Dali::Accessibility::Accessible* FindByPath(const std::string& name) const override;
266   void                             SetApplicationName(std::string name) override
267   {
268     application.name = std::move(name);
269   }
270
271 protected:
272   mutable AppAccessible                         application;
273   std::vector<Dali::Accessibility::Accessible*> popups;
274
275 private:
276   void IdSet(int id);
277   int  IdGet();
278   void RegisteredEventsUpdate();
279
280   using CacheElementType = std::tuple<
281     Dali::Accessibility::Address,
282     Dali::Accessibility::Address,
283     Dali::Accessibility::Address,
284     std::vector<Dali::Accessibility::Address>,
285     std::vector<std::string>,
286     std::string,
287     Dali::Accessibility::Role,
288     std::string,
289     std::array<uint32_t, 2>>;
290   DBus::ValueOrError<std::vector<CacheElementType>> GetItems();
291   CacheElementType                                  CreateCacheElement(Dali::Accessibility::Accessible* item);
292
293 protected:
294   BridgeBase();
295   virtual ~BridgeBase();
296
297   ForceUpResult ForceUp() override;
298   void          ForceDown() override;
299
300   DBus::DBusServer           dbusServer;
301   DBusWrapper::ConnectionPtr con;
302   int                        id = 0;
303   DBus::DBusClient           registry;
304   bool                       allowObjectBoundsChangedEvent{false};
305 };
306
307 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H