1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H
5 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <dali/public-api/dali-adaptor-version.h>
23 #include <dali/public-api/signals/connection-tracker.h>
27 #include <dali/internal/accessibility/bridge/accessibility-common.h>
30 * @brief The AppAccessible class is to define Accessibility Application.
32 class AppAccessible : public virtual Dali::Accessibility::Accessible, public virtual Dali::Accessibility::Collection, public virtual Dali::Accessibility::Application
35 Dali::Accessibility::EmptyAccessibleWithAddress mParent;
36 std::vector<Dali::Accessibility::Accessible*> mChildren;
39 std::string GetName() override
44 std::string GetDescription() override
49 Dali::Accessibility::Accessible* GetParent() override
54 size_t GetChildCount() override
56 return mChildren.size();
59 Dali::Accessibility::Accessible* GetChildAtIndex(size_t index) override
61 auto size = mChildren.size();
64 throw std::domain_error{"invalid index " + std::to_string(index) + " for object with " + std::to_string(size) + " children"};
66 return mChildren[index];
69 size_t GetIndexInParent() override
71 throw std::domain_error{"can't call GetIndexInParent on application object"};
74 Dali::Accessibility::Role GetRole() override
76 return Dali::Accessibility::Role::APPLICATION;
79 Dali::Accessibility::States GetStates() override
84 Dali::Accessibility::Attributes GetAttributes() override
90 * @brief Gets the active window.
92 * @return Null if mChildren is empty, otherwise the active window
93 * @note Currently, the default window would be returned when mChildren is not empty.
95 Dali::Accessibility::Accessible* GetActiveWindow()
97 return mChildren.empty() ? nullptr : mChildren[0];
100 bool DoGesture(const Dali::Accessibility::GestureInfo& gestureInfo) override
105 std::vector<Dali::Accessibility::Relation> GetRelationSet() override
110 Dali::Accessibility::Address GetAddress() override
115 std::string GetToolkitName() override
120 std::string GetVersion() override
122 return std::to_string(Dali::ADAPTOR_MAJOR_VERSION) + "." + std::to_string(Dali::ADAPTOR_MINOR_VERSION);
127 * @brief Enumeration for FilteredEvents.
129 enum class FilteredEvents
131 BOUNDS_CHANGED ///< Bounds changed
134 // Custom specialization of std::hash
138 struct hash<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>>
140 size_t operator()(std::pair<FilteredEvents, Dali::Accessibility::Accessible*> value) const
142 return (static_cast<size_t>(value.first) * 131) ^ reinterpret_cast<size_t>(value.second);
148 * @brief The BridgeBase class is basic class for Bridge functions.
150 class BridgeBase : public Dali::Accessibility::Bridge, public Dali::ConnectionTracker
152 std::unordered_map<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>, std::pair<unsigned int, std::function<void()>>> mFilteredEvents;
155 * @brief Removes all FilteredEvents using Tick signal.
157 * @return False if mFilteredEvents is empty, otherwise true.
159 bool TickFilteredEvents();
163 * @brief Adds FilteredEvents, Accessible, and delay time to mFilteredEvents.
165 * @param[in] kind FilteredEvents enum value
166 * @param[in] obj Accessible object
167 * @param[in] delay The delay time
168 * @param[in] functor The function to be called // NEED TO UPDATE!
170 void AddFilteredEvent(FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function<void()> functor);
173 * @copydoc Dali::Accessibility::Bridge::GetBusName()
175 const std::string& GetBusName() const override;
178 * @copydoc Dali::Accessibility::Bridge::AddTopLevelWindow()
180 void AddTopLevelWindow(Dali::Accessibility::Accessible* window) override;
183 * @copydoc Dali::Accessibility::Bridge::RemoveTopLevelWindow()
185 void RemoveTopLevelWindow(Dali::Accessibility::Accessible* window) override;
188 * @copydoc Dali::Accessibility::Bridge::AddPopup()
190 void AddPopup(Dali::Accessibility::Accessible* object) override;
193 * @copydoc Dali::Accessibility::Bridge::RemovePopup()
195 void RemovePopup(Dali::Accessibility::Accessible* object) override;
198 * @copydoc Dali::Accessibility::Bridge::GetApplication()
200 Dali::Accessibility::Accessible* GetApplication() const override
202 return &mApplication;
206 * @brief Adds function to dbus interface.
208 template<typename SELF, typename... RET, typename... ARGS>
209 void AddFunctionToInterface(
210 DBus::DBusInterfaceDescription& desc, const std::string& funcName, DBus::ValueOrError<RET...> (SELF::*funcPtr)(ARGS...))
212 if(auto self = dynamic_cast<SELF*>(this))
213 desc.addMethod<DBus::ValueOrError<RET...>(ARGS...)>(
215 [=](ARGS... args) -> DBus::ValueOrError<RET...> {
218 return (self->*funcPtr)(std::move(args)...);
220 catch(std::domain_error& e)
222 return DBus::Error{e.what()};
228 * @brief Adds 'Get' property to dbus interface.
230 template<typename T, typename SELF>
231 void AddGetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
232 const std::string& funcName,
233 T (SELF::*funcPtr)())
235 if(auto self = dynamic_cast<SELF*>(this))
236 desc.addProperty<T>(funcName,
237 [=]() -> DBus::ValueOrError<T> {
240 return (self->*funcPtr)();
242 catch(std::domain_error& e)
244 return DBus::Error{e.what()};
251 * @brief Adds 'Set' property to dbus interface.
253 template<typename T, typename SELF>
254 void AddSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
255 const std::string& funcName,
256 void (SELF::*funcPtr)(T))
258 if(auto self = dynamic_cast<SELF*>(this))
259 desc.addProperty<T>(funcName, {}, [=](T t) -> DBus::ValueOrError<void> {
262 (self->*funcPtr)(std::move(t));
265 catch(std::domain_error& e)
267 return DBus::Error{e.what()};
273 * @brief Adds 'Set' and 'Get' properties to dbus interface.
275 template<typename T, typename T1, typename SELF>
276 void AddGetSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
277 const std::string& funcName,
278 T1 (SELF::*funcPtrGet)(),
279 DBus::ValueOrError<void> (SELF::*funcPtrSet)(T))
281 if(auto self = dynamic_cast<SELF*>(this))
284 [=]() -> DBus::ValueOrError<T> {
287 return (self->*funcPtrGet)();
289 catch(std::domain_error& e)
291 return DBus::Error{e.what()};
294 [=](T t) -> DBus::ValueOrError<void> {
297 (self->*funcPtrSet)(std::move(t));
300 catch(std::domain_error& e)
302 return DBus::Error{e.what()};
308 * @brief Adds 'Get' and 'Set' properties to dbus interface.
310 template<typename T, typename T1, typename SELF>
311 void AddGetSetPropertyToInterface(DBus::DBusInterfaceDescription& desc,
312 const std::string& funcName,
313 T1 (SELF::*funcPtrGet)(),
314 void (SELF::*funcPtrSet)(T))
316 if(auto self = dynamic_cast<SELF*>(this))
319 [=]() -> DBus::ValueOrError<T> {
322 return (self->*funcPtrGet)();
324 catch(std::domain_error& e)
326 return DBus::Error{e.what()};
329 [=](T t) -> DBus::ValueOrError<void> {
332 (self->*funcPtrSet)(std::move(t));
335 catch(std::domain_error& e)
337 return DBus::Error{e.what()};
343 * @brief Gets the string of the path excluding the specified prefix.
345 * @param path The path to get
346 * @return The string stripped of the specific prefix
348 static std::string StripPrefix(const std::string& path);
351 * @brief Finds the Accessible object according to the path.
353 * @param[in] path The path for Accessible object
354 * @return The Accessible object corresponding to the path
356 Dali::Accessibility::Accessible* Find(const std::string& path) const;
359 * @brief Finds the Accessible object with the given address.
361 * @param[in] ptr The unique Address of the object
362 * @return The Accessible object corresponding to the path
364 Dali::Accessibility::Accessible* Find(const Dali::Accessibility::Address& ptr) const;
367 * @brief Returns the target object of the currently executed DBus method call.
369 * And any subclasses redefine `FindSelf` with a different return type as a convenient wrapper around dynamic_cast.
370 * @return The Accessible object
371 * @note When a DBus method is called on some object, this target object (`currentObject`) is temporarily saved by the bridge,
372 * because DBus handles the invocation target separately from the method arguments.
373 * We then use the saved object inside the 'glue' method (e.g. BridgeValue::GetMinimum)
374 * to call the equivalent method on the respective C++ object (this could be ScrollBar::AccessibleImpl::GetMinimum in the example given).
376 Dali::Accessibility::Accessible* FindSelf() const;
379 * @copydoc Dali::Accessibility::Bridge::FindByPath()
381 Dali::Accessibility::Accessible* FindByPath(const std::string& name) const override;
384 * @copydoc Dali::Accessibility::Bridge::SetApplicationName()
386 void SetApplicationName(std::string name) override
388 mApplication.mName = std::move(name);
392 mutable AppAccessible mApplication;
393 std::vector<Dali::Accessibility::Accessible*> mPopups;
399 * @param[in] id An ID (integer value)
404 * @brief Gets the ID.
405 * @return The ID to be set
410 * @brief Update registered events.
412 void UpdateRegisteredEvents();
414 using CacheElementType = std::tuple<
415 Dali::Accessibility::Address,
416 Dali::Accessibility::Address,
417 Dali::Accessibility::Address,
418 std::vector<Dali::Accessibility::Address>,
419 std::vector<std::string>,
421 Dali::Accessibility::Role,
423 std::array<uint32_t, 2>>;
426 * @brief Gets Items // NEED TO UPDATE!
430 DBus::ValueOrError<std::vector<CacheElementType>> GetItems();
433 * @brief Creates CacheElement.
435 * CreateCacheElement method works for GetItems which is a part of ATSPI protocol.
436 * ATSPI client library (libatspi from at-spi2-core) depending on cacheing policy configuration uses GetItems
437 * to pre-load entire accessible tree from application to its own cache in single dbus call.
438 * Otherwise the particular nodes in a tree are cached lazily when client library tries to access them.
439 * @param item Accessible to get information
440 * @return The elements to be cached
442 CacheElementType CreateCacheElement(Dali::Accessibility::Accessible* item);
446 virtual ~BridgeBase();
449 * @copydoc Dali::Accessibility::Bridge::ForceUp()
451 ForceUpResult ForceUp() override;
454 * @copydoc Dali::Accessibility::Bridge::ForceDown()
456 void ForceDown() override;
458 DBus::DBusServer mDbusServer;
459 DBusWrapper::ConnectionPtr mConnectionPtr;
461 DBus::DBusClient mRegistry;
462 bool IsBoundsChangedEventAllowed{false};
465 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H