Use existing callback ID for recurring callbacks
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / tizen-wayland / atspi / bridge-base.h
1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H
3
4 /*
5  * Copyright (c) 2019 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/tizen-wayland/atspi/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     return { "", "root" };
100   }
101
102 };
103
104
105 enum class FilteredEvents {
106   boundsChanged
107 };
108
109
110 namespace std {
111   template <> struct hash<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>> {
112     size_t operator () (std::pair<FilteredEvents, Dali::Accessibility::Accessible*> v) const {
113       return (static_cast<size_t>(v.first) * 131) ^ reinterpret_cast<size_t>(v.second);
114     }
115   };
116 }
117
118
119 class BridgeBase : public Dali::Accessibility::Bridge, public Dali::ConnectionTracker
120 {
121   std::unordered_map<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>, std::pair<unsigned int, std::function<void()>>> filteredEvents;
122
123   bool tickFilteredEvents();
124
125 public:
126
127   void addFilteredEvent(FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function<void()> functor);
128
129   const std::string& GetBusName() const override;
130   void AddTopLevelWindow( Dali::Accessibility::Accessible* window ) override;
131   void RemoveTopLevelWindow( Dali::Accessibility::Accessible* window ) override;
132   void AddPopup( Dali::Accessibility::Accessible* ) override;
133   void RemovePopup( Dali::Accessibility::Accessible* ) override;
134
135   Dali::Accessibility::Accessible* GetApplication() const override
136   {
137     return &application;
138   }
139
140   template < typename SELF, typename... RET, typename... ARGS >
141   void AddFunctionToInterface(
142       DBus::DBusInterfaceDescription& desc, const std::string& funcName,
143       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, T ( SELF::*funcPtr )() )
162   {
163     if ( auto self = dynamic_cast< SELF* >( this ) )
164       desc.addProperty< T >( funcName,
165                            [=]() -> DBus::ValueOrError< T > {
166                              try
167                              {
168                                return ( self->*funcPtr )();
169                              }
170                              catch( std::domain_error& e )
171                              {
172                                return DBus::Error{e.what()};
173                              }
174                            },
175                            {} );
176   }
177
178   template < typename T, typename SELF >
179   void AddSetPropertyToInterface( DBus::DBusInterfaceDescription& desc,
180                                   const std::string& funcName, void ( SELF::*funcPtr )( T ) )
181   {
182     if ( auto self = dynamic_cast< SELF* >( this ) )
183       desc.addProperty< T >( funcName, {},
184                            [=]( T t ) -> DBus::ValueOrError< void > {
185                              try
186                              {
187                                ( self->*funcPtr )( std::move( t ) );
188                                return {};
189                              }
190                              catch( std::domain_error& e )
191                              {
192                                return DBus::Error{e.what()};
193                              }
194                            } );
195   }
196
197   template < typename T, typename T1, typename SELF >
198   void AddGetSetPropertyToInterface( DBus::DBusInterfaceDescription& desc,
199                                      const std::string& funcName, T1 ( SELF::*funcPtrGet )(), DBus::ValueOrError< void > ( SELF::*funcPtrSet )( T ) )
200   {
201     if ( auto self = dynamic_cast< SELF* >( this ) )
202       desc.addProperty< T >( funcName,
203                            [=]() -> DBus::ValueOrError< T > {
204                              try
205                              {
206                                return ( self->*funcPtrGet )();
207                              }
208                              catch( std::domain_error& e )
209                              {
210                                return DBus::Error{e.what()};
211                              }
212                            },
213                            [=]( T t ) -> DBus::ValueOrError< void > {
214                              try
215                              {
216                                ( self->*funcPtrSet )( std::move( t ) );
217                                return {};
218                              }
219                              catch( std::domain_error& e )
220                              {
221                                return DBus::Error{e.what()};
222                              }
223                            } );
224   }
225   template < typename T, typename T1, typename SELF >
226   void AddGetSetPropertyToInterface( DBus::DBusInterfaceDescription& desc,
227                                      const std::string& funcName, T1 ( SELF::*funcPtrGet )(), void ( SELF::*funcPtrSet )( T ) )
228   {
229     if ( auto self = dynamic_cast< SELF* >( this ) )
230       desc.addProperty< T >( funcName,
231                            [=]() -> DBus::ValueOrError< T > {
232                              try
233                              {
234                                return ( self->*funcPtrGet )();
235                              }
236                              catch( std::domain_error& e )
237                              {
238                                return DBus::Error{e.what()};
239                              }
240                            },
241                            [=]( T t ) -> DBus::ValueOrError< void > {
242                              try
243                              {
244                                ( self->*funcPtrSet )( std::move( t ) );
245                                return {};
246                              }
247                              catch( std::domain_error& e )
248                              {
249                                return DBus::Error{e.what()};
250                              }
251                            } );
252   }
253   static std::string StripPrefix( const std::string& path );
254
255   Dali::Accessibility::Accessible* Find( const std::string& path ) const;
256   Dali::Accessibility::Accessible* Find( const Dali::Accessibility::Address& ptr ) const;
257   Dali::Accessibility::Accessible* FindSelf() const;
258   Dali::Accessibility::Accessible* FindByPath( const std::string& name ) const override;
259   void SetApplicationName( std::string name ) override
260   {
261     application.name = std::move( name );
262   }
263
264 protected:
265   mutable AppAccessible application;
266   std::vector<Dali::Accessibility::Accessible*> popups;
267 private:
268   void IdSet( int id );
269   int IdGet();
270
271   using CacheElementType = std::tuple<
272       Dali::Accessibility::Address, Dali::Accessibility::Address, Dali::Accessibility::Address,
273       std::vector< Dali::Accessibility::Address >,
274       std::vector< std::string >,
275       std::string,
276       Dali::Accessibility::Role,
277       std::string,
278       std::array< uint32_t, 2 > >;
279   DBus::ValueOrError< std::vector< CacheElementType > > GetItems();
280   CacheElementType CreateCacheElement( Dali::Accessibility::Accessible* item );
281
282 protected:
283   BridgeBase();
284   virtual ~BridgeBase();
285
286   ForceUpResult ForceUp() override;
287   void ForceDown() override;
288
289   DBus::DBusServer dbusServer;
290   DBusWrapper::ConnectionPtr con;
291   int id = 0;
292 };
293
294 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H