Merge "Fix RenderTarget and RenderPass doesn't destroy issue" 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/actors/layer.h>
23 #include <dali/public-api/dali-adaptor-version.h>
24 #include <dali/public-api/signals/connection-tracker.h>
25 #include <memory>
26
27 // INTERNAL INCLUDES
28 #include <dali/devel-api/adaptor-framework/window-devel.h>
29 #include <dali/internal/accessibility/bridge/accessibility-common.h>
30
31 /**
32  * @brief The AppAccessible class is to define Accessibility Application.
33  */
34 class AppAccessible : public virtual Dali::Accessibility::Accessible, public virtual Dali::Accessibility::Collection, public virtual Dali::Accessibility::Application
35 {
36 public:
37   Dali::Accessibility::EmptyAccessibleWithAddress mParent;
38   std::vector<Dali::Accessibility::Accessible*>   mChildren;
39   std::vector<Dali::Window>                       mWindows;
40   std::string                                     mName;
41
42   std::string GetName() override
43   {
44     return mName;
45   }
46
47   std::string GetDescription() override
48   {
49     return "";
50   }
51
52   Dali::Accessibility::Accessible* GetParent() override
53   {
54     return &mParent;
55   }
56
57   size_t GetChildCount() override
58   {
59     return mChildren.size();
60   }
61
62   Dali::Accessibility::Accessible* GetChildAtIndex(size_t index) override
63   {
64     auto size = mChildren.size();
65     if(index >= size)
66     {
67       throw std::domain_error{"invalid index " + std::to_string(index) + " for object with " + std::to_string(size) + " children"};
68     }
69     return mChildren[index];
70   }
71
72   size_t GetIndexInParent() override
73   {
74     throw std::domain_error{"can't call GetIndexInParent on application object"};
75   }
76
77   Dali::Accessibility::Role GetRole() override
78   {
79     return Dali::Accessibility::Role::APPLICATION;
80   }
81
82   Dali::Accessibility::States GetStates() override
83   {
84     return {};
85   }
86
87   Dali::Accessibility::Attributes GetAttributes() override
88   {
89     return {};
90   }
91
92   /**
93    * @brief Gets the Accessible object from the window.
94    *
95    * @param[in] window The window to find
96    * @return Null if mChildren is empty, otherwise the Accessible object
97    * @note Currently, the default window would be returned when mChildren is not empty.
98    */
99   Dali::Accessibility::Accessible* GetWindowAccessible(Dali::Window window)
100   {
101     if(mChildren.empty())
102     {
103       return nullptr;
104     }
105
106     Dali::Layer rootLayer = window.GetRootLayer();
107
108     // Find a child which is related to the window.
109     for(auto i = 0u; i < mChildren.size(); ++i)
110     {
111       if(rootLayer == mChildren[i]->GetInternalActor())
112       {
113         return mChildren[i];
114       }
115     }
116
117     // If can't find its children, return the default window.
118     return mChildren[0];
119   }
120
121   bool DoGesture(const Dali::Accessibility::GestureInfo& gestureInfo) override
122   {
123     return false;
124   }
125
126   std::vector<Dali::Accessibility::Relation> GetRelationSet() override
127   {
128     return {};
129   }
130
131   Dali::Actor GetInternalActor() override
132   {
133     return Dali::Actor{};
134   }
135
136   Dali::Accessibility::Address GetAddress() override
137   {
138     return {"", "root"};
139   }
140
141   std::string GetToolkitName() override
142   {
143     return {"dali"};
144   }
145
146   std::string GetVersion() override
147   {
148     return std::to_string(Dali::ADAPTOR_MAJOR_VERSION) + "." + std::to_string(Dali::ADAPTOR_MINOR_VERSION);
149   }
150 };
151
152 /**
153  * @brief Enumeration for FilteredEvents.
154  */
155 enum class FilteredEvents
156 {
157   BOUNDS_CHANGED ///< Bounds changed
158 };
159
160 // Custom specialization of std::hash
161 namespace std
162 {
163 template<>
164 struct hash<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>>
165 {
166   size_t operator()(std::pair<FilteredEvents, Dali::Accessibility::Accessible*> value) const
167   {
168     return (static_cast<size_t>(value.first) * 131) ^ reinterpret_cast<size_t>(value.second);
169   }
170 };
171 } // namespace std
172
173 /**
174  * @brief The BridgeBase class is basic class for Bridge functions.
175  */
176 class BridgeBase : public Dali::Accessibility::Bridge, public Dali::ConnectionTracker
177 {
178   std::unordered_map<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>, std::pair<unsigned int, std::function<void()>>> mFilteredEvents;
179
180   /**
181    * @brief Removes all FilteredEvents using Tick signal.
182    *
183    * @return False if mFilteredEvents is empty, otherwise true.
184    */
185   bool TickFilteredEvents();
186
187 public:
188   /**
189    * @brief Adds FilteredEvents, Accessible, and delay time to mFilteredEvents.
190    *
191    * @param[in] kind FilteredEvents enum value
192    * @param[in] obj Accessible object
193    * @param[in] delay The delay time
194    * @param[in] functor The function to be called // NEED TO UPDATE!
195    */
196   void AddFilteredEvent(FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function<void()> functor);
197
198   /**
199    * @brief Callback when the visibility of the window is changed.
200    *
201    * @param[in] window The window to be changed
202    * @param[in] visible The visibility of the window
203    */
204   void OnWindowVisibilityChanged(Dali::Window window, bool visible);
205
206   /**
207    * @brief Callback when the window focus is changed.
208    *
209    * @param[in] window The window whose focus is changed
210    * @param[in] focusIn Whether the focus is in/out
211    */
212   void OnWindowFocusChanged(Dali::Window window, bool focusIn);
213
214   /**
215    * @copydoc Dali::Accessibility::Bridge::GetBusName()
216    */
217   const std::string& GetBusName() const override;
218
219   /**
220    * @copydoc Dali::Accessibility::Bridge::AddTopLevelWindow()
221    */
222   void AddTopLevelWindow(Dali::Accessibility::Accessible* windowAccessible) override;
223
224   /**
225    * @copydoc Dali::Accessibility::Bridge::RemoveTopLevelWindow()
226    */
227   void RemoveTopLevelWindow(Dali::Accessibility::Accessible* windowAccessible) override;
228
229   /**
230    * @copydoc Dali::Accessibility::Bridge::RegisterDefaultLabel()
231    */
232   void RegisterDefaultLabel(Dali::Accessibility::Accessible* object) override;
233
234   /**
235    * @copydoc Dali::Accessibility::Bridge::UnregisterDefaultLabel()
236    */
237   void UnregisterDefaultLabel(Dali::Accessibility::Accessible* object) override;
238
239   /**
240    * @copydoc Dali::Accessibility::Bridge::GetDefaultLabel()
241    */
242   Dali::Accessibility::Accessible* GetDefaultLabel() const override
243   {
244     return mDefaultLabels.empty() ? nullptr : mDefaultLabels.back();
245   }
246
247   /**
248    * @copydoc Dali::Accessibility::Bridge::GetApplication()
249    */
250   Dali::Accessibility::Accessible* GetApplication() const override
251   {
252     return &mApplication;
253   }
254
255   /**
256    * @brief Adds function to dbus interface.
257    */
258   template<typename SELF, typename... RET, typename... ARGS>
259   void AddFunctionToInterface(
260     DBus::DBusInterfaceDescription& desc, const std::string& funcName, DBus::ValueOrError<RET...> (SELF::*funcPtr)(ARGS...))
261   {
262     if(auto self = dynamic_cast<SELF*>(this))
263       desc.addMethod<DBus::ValueOrError<RET...>(ARGS...)>(
264         funcName,
265         [=](ARGS... args) -> DBus::ValueOrError<RET...> {
266           try
267           {
268             return (self->*funcPtr)(std::move(args)...);
269           }
270           catch(std::domain_error& e)
271           {
272             return DBus::Error{e.what()};
273           }
274         });
275   }
276
277   /**
278    * @brief Adds 'Get' property to dbus interface.
279    */
280   template<typename T, typename SELF>
281   void AddGetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
282                                  const std::string&              funcName,
283                                  T (SELF::*funcPtr)())
284   {
285     if(auto self = dynamic_cast<SELF*>(this))
286       desc.addProperty<T>(funcName,
287                           [=]() -> DBus::ValueOrError<T> {
288                             try
289                             {
290                               return (self->*funcPtr)();
291                             }
292                             catch(std::domain_error& e)
293                             {
294                               return DBus::Error{e.what()};
295                             }
296                           },
297                           {});
298   }
299
300   /**
301    * @brief Adds 'Set' property to dbus interface.
302    */
303   template<typename T, typename SELF>
304   void AddSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
305                                  const std::string&              funcName,
306                                  void (SELF::*funcPtr)(T))
307   {
308     if(auto self = dynamic_cast<SELF*>(this))
309       desc.addProperty<T>(funcName, {}, [=](T t) -> DBus::ValueOrError<void> {
310         try
311         {
312           (self->*funcPtr)(std::move(t));
313           return {};
314         }
315         catch(std::domain_error& e)
316         {
317           return DBus::Error{e.what()};
318         }
319       });
320   }
321
322   /**
323    * @brief Adds 'Set' and 'Get' properties to dbus interface.
324    */
325   template<typename T, typename T1, typename SELF>
326   void AddGetSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
327                                     const std::string&              funcName,
328                                     T1 (SELF::*funcPtrGet)(),
329                                     DBus::ValueOrError<void> (SELF::*funcPtrSet)(T))
330   {
331     if(auto self = dynamic_cast<SELF*>(this))
332       desc.addProperty<T>(
333         funcName,
334         [=]() -> DBus::ValueOrError<T> {
335           try
336           {
337             return (self->*funcPtrGet)();
338           }
339           catch(std::domain_error& e)
340           {
341             return DBus::Error{e.what()};
342           }
343         },
344         [=](T t) -> DBus::ValueOrError<void> {
345           try
346           {
347             (self->*funcPtrSet)(std::move(t));
348             return {};
349           }
350           catch(std::domain_error& e)
351           {
352             return DBus::Error{e.what()};
353           }
354         });
355   }
356
357   /**
358    * @brief Adds 'Get' and 'Set' properties to dbus interface.
359    */
360   template<typename T, typename T1, typename SELF>
361   void AddGetSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
362                                     const std::string&              funcName,
363                                     T1 (SELF::*funcPtrGet)(),
364                                     void (SELF::*funcPtrSet)(T))
365   {
366     if(auto self = dynamic_cast<SELF*>(this))
367       desc.addProperty<T>(
368         funcName,
369         [=]() -> DBus::ValueOrError<T> {
370           try
371           {
372             return (self->*funcPtrGet)();
373           }
374           catch(std::domain_error& e)
375           {
376             return DBus::Error{e.what()};
377           }
378         },
379         [=](T t) -> DBus::ValueOrError<void> {
380           try
381           {
382             (self->*funcPtrSet)(std::move(t));
383             return {};
384           }
385           catch(std::domain_error& e)
386           {
387             return DBus::Error{e.what()};
388           }
389         });
390   }
391
392   /**
393    * @brief Gets the string of the path excluding the specified prefix.
394    *
395    * @param path The path to get
396    * @return The string stripped of the specific prefix
397    */
398   static std::string StripPrefix(const std::string& path);
399
400   /**
401    * @brief Finds the Accessible object according to the path.
402    *
403    * @param[in] path The path for Accessible object
404    * @return The Accessible object corresponding to the path
405    */
406   Dali::Accessibility::Accessible* Find(const std::string& path) const;
407
408   /**
409    * @brief Finds the Accessible object with the given address.
410    *
411    * @param[in] ptr The unique Address of the object
412    * @return The Accessible object corresponding to the path
413    */
414   Dali::Accessibility::Accessible* Find(const Dali::Accessibility::Address& ptr) const;
415
416   /**
417    * @brief Returns the target object of the currently executed DBus method call.
418    *
419    * And any subclasses redefine `FindSelf` with a different return type as a convenient wrapper around dynamic_cast.
420    * @return The Accessible object
421    * @note When a DBus method is called on some object, this target object (`currentObject`) is temporarily saved by the bridge,
422    * because DBus handles the invocation target separately from the method arguments.
423    * We then use the saved object inside the 'glue' method (e.g. BridgeValue::GetMinimum)
424    * to call the equivalent method on the respective C++ object (this could be ScrollBar::AccessibleImpl::GetMinimum in the example given).
425    */
426   Dali::Accessibility::Accessible* FindSelf() const;
427
428   /**
429    * @copydoc Dali::Accessibility::Bridge::FindByPath()
430    */
431   Dali::Accessibility::Accessible* FindByPath(const std::string& name) const override;
432
433   /**
434    * @copydoc Dali::Accessibility::Bridge::SetApplicationName()
435    */
436   void SetApplicationName(std::string name) override
437   {
438     mApplication.mName = std::move(name);
439   }
440
441 protected:
442   mutable AppAccessible                         mApplication;
443   std::vector<Dali::Accessibility::Accessible*> mDefaultLabels;
444
445 private:
446   /**
447    * @brief Sets an ID.
448    * @param[in] id An ID (integer value)
449    */
450   void SetId(int id);
451
452   /**
453    * @brief Gets the ID.
454    * @return The ID to be set
455    */
456   int GetId();
457
458   /**
459    * @brief Update registered events.
460    */
461   void UpdateRegisteredEvents();
462
463   using CacheElementType = std::tuple<
464     Dali::Accessibility::Address,
465     Dali::Accessibility::Address,
466     Dali::Accessibility::Address,
467     std::vector<Dali::Accessibility::Address>,
468     std::vector<std::string>,
469     std::string,
470     Dali::Accessibility::Role,
471     std::string,
472     std::array<uint32_t, 2>>;
473
474   /**
475    * @brief Gets Items  // NEED TO UPDATE!
476    *
477    * @return
478    */
479   DBus::ValueOrError<std::vector<CacheElementType>> GetItems();
480
481   /**
482    * @brief Creates CacheElement.
483    *
484    * CreateCacheElement method works for GetItems which is a part of ATSPI protocol.
485    * ATSPI client library (libatspi from at-spi2-core) depending on cacheing policy configuration uses GetItems
486    * to pre-load entire accessible tree from application to its own cache in single dbus call.
487    * Otherwise the particular nodes in a tree are cached lazily when client library tries to access them.
488    * @param item Accessible to get information
489    * @return The elements to be cached
490    */
491   CacheElementType CreateCacheElement(Dali::Accessibility::Accessible* item);
492
493 protected:
494   BridgeBase();
495   virtual ~BridgeBase();
496
497   /**
498    * @copydoc Dali::Accessibility::Bridge::ForceUp()
499    */
500   ForceUpResult ForceUp() override;
501
502   /**
503    * @copydoc Dali::Accessibility::Bridge::ForceDown()
504    */
505   void ForceDown() override;
506
507   DBus::DBusServer           mDbusServer;
508   DBusWrapper::ConnectionPtr mConnectionPtr;
509   int                        mId = 0;
510   DBus::DBusClient           mRegistry;
511   bool                       IsBoundsChangedEventAllowed{false};
512 };
513
514 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H