[Tizen](ATSPI) squashed implementation 48/214048/1 submit/tizen/20190917.102651 submit/tizen/20190917.223923
authordongsug.song <dongsug.song@samsung.com>
Tue, 17 Sep 2019 09:34:03 +0000 (18:34 +0900)
committerdongsug.song <dongsug.song@samsung.com>
Tue, 17 Sep 2019 09:34:10 +0000 (18:34 +0900)
Author: Radoslaw Cybulski <r.cybulski@partner.samsung.com>

Change-Id: I79d6adf9133da0912adda8383b3205ba9a5ba508

65 files changed:
.gitignore
automated-tests/src/dali-adaptor/dali-test-suite-utils/adaptor-test-application.h
build/tizen/adaptor/Makefile.am
build/tizen/adaptor/configure.ac
dali/devel-api/adaptor-framework/accessibility-adaptor.cpp [deleted file]
dali/devel-api/adaptor-framework/accessibility-adaptor.h [deleted file]
dali/devel-api/adaptor-framework/accessibility-gesture-handler.h [deleted file]
dali/devel-api/adaptor-framework/accessibility.h [new file with mode: 0644]
dali/devel-api/file.list
dali/internal/accessibility/accessibility-impl.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/accessibility-common.h [new file with mode: 0644]
dali/internal/accessibility/bridge/accessible.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-accessible.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-accessible.h [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-action.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-action.h [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-base.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-base.h [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-collection.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-collection.h [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-component.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-component.h [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-editable-text.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-editable-text.h [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-impl.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-object.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-object.h [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-text.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-text.h [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-value.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/bridge-value.h [new file with mode: 0644]
dali/internal/accessibility/bridge/component.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/dbus-locators.h [new file with mode: 0644]
dali/internal/accessibility/bridge/dbus.cpp [new file with mode: 0644]
dali/internal/accessibility/bridge/dbus.h [new file with mode: 0644]
dali/internal/accessibility/bridge/optional.h [new file with mode: 0644]
dali/internal/accessibility/common/accessibility-adaptor-impl.cpp [deleted file]
dali/internal/accessibility/common/accessibility-adaptor-impl.h [deleted file]
dali/internal/accessibility/common/accessibility-gesture-detector.cpp [deleted file]
dali/internal/accessibility/common/accessibility-gesture-detector.h [deleted file]
dali/internal/accessibility/file.list
dali/internal/accessibility/generic/accessibility-adaptor-impl-generic.cpp [deleted file]
dali/internal/accessibility/tizen-wayland/tizen-common/accessibility-adaptor-impl-tizen.cpp [deleted file]
dali/internal/accessibility/tizen-wayland/tizen-ivi/accessibility-adaptor-impl-ivi.cpp [deleted file]
dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.cpp [deleted file]
dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.h [deleted file]
dali/internal/accessibility/tizen-wayland/tizen-tv/accessibility-adaptor-impl-tv.cpp [deleted file]
dali/internal/accessibility/tizen-wayland/tizen-wearable/accessibility-adaptor-impl-wearable.cpp [deleted file]
dali/internal/adaptor/common/adaptor-impl.cpp
dali/internal/adaptor/common/adaptor-impl.h
dali/internal/adaptor/common/adaptor.cpp
dali/internal/adaptor/common/application-impl.cpp
dali/internal/adaptor/generic/adaptor-impl-generic.cpp
dali/internal/adaptor/tizen-wayland/adaptor-impl-tizen.cpp
dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp
dali/internal/imaging/common/image-operations.cpp
dali/internal/system/common/object-profiler.cpp
dali/internal/window-system/common/event-handler.cpp
dali/internal/window-system/common/event-handler.h
dali/internal/window-system/common/window-impl.cpp
dali/public-api/adaptor-framework/accessibility.cpp [new file with mode: 0644]
dali/public-api/adaptor-framework/accessibility.h [new file with mode: 0644]
dali/public-api/adaptor-framework/tts-player.h
dali/public-api/file.list
packaging/dali-adaptor.spec

index 3480ca9..7ac2864 100644 (file)
@@ -39,3 +39,4 @@ tags
 /debuglinks.list
 /debugsources.list
 /dali/internal/adaptor/common/system-cache-path.cpp
+/.vscode/*
index 99f24d7..86a9809 100644 (file)
@@ -21,6 +21,7 @@
 // INTERNAL INCLUDES
 #include "test-application.h"
 #include "adaptor-test-adaptor-impl.h"
+#include <dali/public-api/adaptor-framework/accessibility.h>
 
 namespace Dali
 {
@@ -38,6 +39,8 @@ public:
                           float  verticalDpi   = DEFAULT_VERTICAL_DPI )
   : TestApplication( surfaceWidth, surfaceHeight, horizontalDpi, verticalDpi )
   {
+    //Dali::Accessibility::DBusWrapper::Install(std::unique_ptr<Dali::Accessibility::DBusWrapper>(new Dali::Accessibility::TestDBusWrapper()));
+
     Internal::Adaptor::Adaptor::SetAvailable();
   }
 
index aec1ab8..b549138 100644 (file)
@@ -30,13 +30,13 @@ pkgconfig_DATA = dali-adaptor.pc dali-adaptor-integration.pc
 if UBUNTU_PROFILE
 LIBDALI_ADAPTOR_LA_SOURCES = \
                   $(adaptor_accessibility_common_src_files) \
-                  $(adaptor_accessibility_ubuntu_src_files) \
                   $(adaptor_adaptor_common_src_files) \
                   $(adaptor_adaptor_ubuntu_src_files) \
                   $(adaptor_clipboard_common_src_files) \
                   $(adaptor_clipboard_ubuntu_x11_src_files) \
                   $(adaptor_framework_generic_src_files) \
                   $(devel_api_src_files) \
+                  $(bridge_src_files) \
                   $(adaptor_devel_api_text_abstraction_src_files) \
                   $(adaptor_graphics_common_src_files) \
                   $(adaptor_graphics_gles_src_files) \
@@ -87,14 +87,13 @@ endif
 if MOBILE_PROFILE
 LIBDALI_ADAPTOR_LA_SOURCES = \
                   $(adaptor_accessibility_common_src_files) \
-                  $(adaptor_accessibility_tizen_wayland_src_files) \
-                  $(adaptor_accessibility_tizen_mobile_src_files) \
                   $(adaptor_adaptor_common_src_files) \
                   $(adaptor_adaptor_tizen_wayland_src_files) \
                   $(adaptor_clipboard_common_src_files) \
                   $(adaptor_clipboard_tizen_wayland_src_files) \
                   $(adaptor_framework_generic_src_files) \
                   $(devel_api_src_files) \
+                  $(bridge_src_files) \
                   $(adaptor_devel_api_text_abstraction_src_files) \
                   $(adaptor_graphics_common_src_files) \
                   $(adaptor_graphics_gles_src_files) \
@@ -153,14 +152,13 @@ endif
 if IVI_PROFILE
 LIBDALI_ADAPTOR_LA_SOURCES = \
                   $(adaptor_accessibility_common_src_files) \
-                  $(adaptor_accessibility_tizen_wayland_src_files) \
-                  $(adaptor_accessibility_tizen_ivi_src_files) \
                   $(adaptor_adaptor_common_src_files) \
                   $(adaptor_adaptor_tizen_wayland_src_files) \
                   $(adaptor_clipboard_common_src_files) \
                   $(adaptor_clipboard_tizen_wayland_src_files) \
                   $(adaptor_framework_generic_src_files) \
                   $(devel_api_src_files) \
+                  $(bridge_src_files) \
                   $(adaptor_devel_api_text_abstraction_src_files) \
                   $(adaptor_graphics_common_src_files) \
                   $(adaptor_graphics_gles_src_files) \
@@ -220,14 +218,13 @@ endif
 if TV_PROFILE
 LIBDALI_ADAPTOR_LA_SOURCES = \
                   $(adaptor_accessibility_common_src_files) \
-                  $(adaptor_accessibility_tizen_wayland_src_files) \
-                  $(adaptor_accessibility_tizen_tv_src_files) \
                   $(adaptor_adaptor_common_src_files) \
                   $(adaptor_adaptor_tizen_wayland_src_files) \
                   $(adaptor_clipboard_common_src_files) \
                   $(adaptor_clipboard_tizen_wayland_src_files) \
                   $(adaptor_framework_generic_src_files) \
                   $(devel_api_src_files) \
+                  $(bridge_src_files) \
                   $(adaptor_devel_api_text_abstraction_src_files) \
                   $(adaptor_graphics_common_src_files) \
                   $(adaptor_graphics_gles_src_files) \
@@ -285,14 +282,13 @@ endif
 if COMMON_PROFILE
 LIBDALI_ADAPTOR_LA_SOURCES = \
                   $(adaptor_accessibility_common_src_files) \
-                  $(adaptor_accessibility_tizen_wayland_src_files) \
-                  $(adaptor_accessibility_tizen_common_src_files) \
                   $(adaptor_adaptor_common_src_files) \
                   $(adaptor_adaptor_tizen_wayland_src_files) \
                   $(adaptor_clipboard_common_src_files) \
                   $(adaptor_clipboard_tizen_wayland_src_files) \
                   $(adaptor_framework_generic_src_files) \
                   $(devel_api_src_files) \
+                  $(bridge_src_files) \
                   $(adaptor_devel_api_text_abstraction_src_files) \
                   $(adaptor_graphics_common_src_files) \
                   $(adaptor_graphics_gles_src_files) \
@@ -352,8 +348,6 @@ endif
 if WEARABLE_PROFILE
 LIBDALI_ADAPTOR_LA_SOURCES = \
                   $(adaptor_accessibility_common_src_files) \
-                  $(adaptor_accessibility_tizen_wayland_src_files) \
-                  $(adaptor_accessibility_tizen_wearable_src_files) \
                   $(adaptor_adaptor_common_src_files) \
                   $(adaptor_adaptor_tizen_wayland_src_files) \
                   $(adaptor_adaptor_tizen_wearable_src_files) \
@@ -361,6 +355,7 @@ LIBDALI_ADAPTOR_LA_SOURCES = \
                   $(adaptor_clipboard_tizen_wayland_src_files) \
                   $(adaptor_framework_generic_src_files) \
                   $(devel_api_src_files) \
+                  $(bridge_src_files) \
                   $(adaptor_devel_api_text_abstraction_src_files) \
                   $(adaptor_graphics_common_src_files) \
                   $(adaptor_graphics_gles_src_files) \
index b182ba7..2dedcbe 100644 (file)
@@ -58,8 +58,8 @@ PKG_CHECK_MODULES(TTRACE,  ttrace, AC_DEFINE(ENABLE_TTRACE, 1, [ttrace available
 PKG_CHECK_MODULES(ECORE, ecore)
 PKG_CHECK_MODULES(ECORE_IPC, ecore-ipc)
 PKG_CHECK_MODULES(ECORE_IMF, [ecore-imf >= 1.13], [ecore_imf_1_13=yes], [ecore_imf_1_13=no])
-# Check for EldBus.h in ECore
-PKG_CHECK_MODULES(ELDBUS, eldbus, [ eldbus_available=yes ],  [ eldbus_available=no ] )
+# Check for EldBus.h in ECore, required for ATSPI
+PKG_CHECK_MODULES(ELDBUS, eldbus, [ eldbus_available=yes ])
 
 DALI_ELDBUS_AVAILABLE=
 if test "x$eldbus_available" = "xyes"; then
diff --git a/dali/devel-api/adaptor-framework/accessibility-adaptor.cpp b/dali/devel-api/adaptor-framework/accessibility-adaptor.cpp
deleted file mode 100644 (file)
index f635aba..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
-
-namespace Dali
-{
-
-AccessibilityAdaptor::AccessibilityAdaptor()
-{
-}
-
-AccessibilityAdaptor AccessibilityAdaptor::Get()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::Get();
-}
-
-AccessibilityAdaptor::~AccessibilityAdaptor()
-{
-}
-
-Vector2 AccessibilityAdaptor::GetReadPosition() const
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).GetReadPosition();
-}
-
-bool AccessibilityAdaptor::IsEnabled() const
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).IsEnabled();
-}
-
-void AccessibilityAdaptor::SetActionHandler(AccessibilityActionHandler& handler)
-{
-  Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).SetActionHandler(handler);
-}
-
-void AccessibilityAdaptor::SetGestureHandler(AccessibilityGestureHandler& handler)
-{
-  Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).SetGestureHandler(handler);
-}
-
-bool AccessibilityAdaptor::HandleActionNextEvent(bool allowEndFeedback)
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionNextEvent(allowEndFeedback);
-}
-
-bool AccessibilityAdaptor::HandleActionPreviousEvent(bool allowEndFeedback)
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionPreviousEvent(allowEndFeedback);
-}
-
-bool AccessibilityAdaptor::HandleActionActivateEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionActivateEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionReadEvent(unsigned int x, unsigned int y,  bool allowReadAgain)
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionReadEvent(x, y, allowReadAgain);
-}
-
-bool AccessibilityAdaptor::HandleActionReadNextEvent(bool allowEndFeedback)
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionReadNextEvent(allowEndFeedback);
-}
-
-bool AccessibilityAdaptor::HandleActionReadPreviousEvent(bool allowEndFeedback)
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionReadPreviousEvent(allowEndFeedback);
-}
-
-bool AccessibilityAdaptor::HandleActionUpEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionUpEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionDownEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionDownEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionClearFocusEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionClearFocusEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionScrollEvent(const TouchPoint& point, unsigned long timeStamp)
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionScrollEvent(point, timeStamp);
-}
-
-bool AccessibilityAdaptor::HandleActionTouchEvent(const TouchPoint& point, unsigned long timeStamp)
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionTouchEvent(point, timeStamp);
-}
-
-bool AccessibilityAdaptor::HandleActionBackEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionBackEvent();
-}
-
-void AccessibilityAdaptor::HandleActionEnableEvent()
-{
-  Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionEnableEvent();
-}
-
-void AccessibilityAdaptor::HandleActionDisableEvent()
-{
-  Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionDisableEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionScrollUpEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionScrollUpEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionScrollDownEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionScrollDownEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionPageLeftEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionPageLeftEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionPageRightEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionPageRightEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionPageUpEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionPageUpEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionPageDownEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionPageDownEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionMoveToFirstEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionMoveToFirstEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionMoveToLastEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionMoveToLastEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionReadFromTopEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionReadFromTopEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionReadFromNextEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionReadFromNextEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionZoomEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionZoomEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionReadPauseResumeEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionReadPauseResumeEvent();
-}
-
-bool AccessibilityAdaptor::HandleActionStartStopEvent()
-{
-  return Internal::Adaptor::AccessibilityAdaptor::GetImplementation(*this).HandleActionStartStopEvent();
-}
-
-AccessibilityAdaptor::AccessibilityAdaptor( Internal::Adaptor::AccessibilityAdaptor& manager )
-: BaseHandle( &manager )
-{
-}
-
-AccessibilityAdaptor::AccessibilityAdaptor( Internal::Adaptor::AccessibilityAdaptor* manager )
-: BaseHandle( manager )
-{
-}
-
-} // namespace Dali
diff --git a/dali/devel-api/adaptor-framework/accessibility-adaptor.h b/dali/devel-api/adaptor-framework/accessibility-adaptor.h
deleted file mode 100755 (executable)
index 251f591..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-#ifndef DALI_ACCESSIBILITY_ADAPTOR_H
-#define DALI_ACCESSIBILITY_ADAPTOR_H
-
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/events/touch-event.h>
-#include <dali/public-api/object/base-handle.h>
-#include <dali/public-api/dali-adaptor-common.h>
-
-namespace Dali
-{
-
-namespace Internal DALI_INTERNAL
-{
-namespace Adaptor
-{
-class AccessibilityAdaptor;
-}
-}
-
-class AccessibilityActionHandler;
-class AccessibilityGestureHandler;
-class TouchPoint;
-
-/**
- * @brief The AccessibilityAdaptor provides communication to the accessibility manager interface (implemented in toolkit).
- *
- */
-class DALI_ADAPTOR_API AccessibilityAdaptor : public BaseHandle
-{
-public:
-
-  /**
-   * @brief Create an uninitialized handle.
-   *
-   * This can be initialized by calling getting the adaptor from Dali::Adaptor.
-   */
-  AccessibilityAdaptor();
-
-  /**
-   * @brief Retrieve a handle to the AccessibilityAdaptor.
-   *
-   * @return A handle to the AccessibilityAdaptor.
-   */
-  static AccessibilityAdaptor Get();
-
-  /**
-   * @brief Destructor
-   *
-   * This is non-virtual since derived Handle types must not contain data or virtual methods.
-   */
-  ~AccessibilityAdaptor();
-
-  /**
-   * @brief Returns the current position of the read action.
-   * @return The current event position.
-   */
-  Vector2 GetReadPosition() const;
-
-  /**
-   * @brief Query whether the accessibility(screen-reader) is enabled.
-   *
-   * The accessibility will be enabled by system setting.
-   * @return True if the accessibility(screen-reader) is enabled.
-   */
-  bool IsEnabled() const;
-
-  /**
-   * @brief Set the handler to handle accessibility actions.
-   *
-   * @param[in] handler The Accessibility action handler.
-   * @note Handlers should remove themselves when they are destroyed.
-   */
-  void SetActionHandler(AccessibilityActionHandler& handler);
-
-  /**
-   * @brief Set the handler to handle accessibility gestures.
-   *
-   * @param[in] handler The Accessibility gesture handler.
-   * @note Handlers should remove themselves when they are destroyed.
-   */
-  void SetGestureHandler(AccessibilityGestureHandler& handler);
-
-  /**
-   * @brief Handle the accessibility action to move focus to the next focusable actor
-   * (by one finger flick down).
-   *
-   * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionNextEvent(bool allowEndFeedback = true);
-
-  /**
-   * @brief Handle the accessibility action to move focus to the previous focusable actor
-   * (by one finger flick up).
-   *
-   * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionPreviousEvent(bool allowEndFeedback = true);
-
-  /**
-   * @brief Handle the accessibility action to activate the current focused actor (by one
-   * finger )
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionActivateEvent();
-
-  /**
-   * @brief Handle the accessibility action to focus and read the actor (by one finger tap or move).
-   *
-   * @param x x position of event
-   * @param y y position of event
-   * @param allowReadAgain true if the action read again the same object (i.e. read action)
-   *                       false if the action just read when the focus object is changed (i.e. over action)
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain);
-
-  /**
-   * @brief Handle the accessibility action to move focus to the next focusable actor
-   * (by one finger flick right).
-   *
-   * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionReadNextEvent(bool allowEndFeedback = true);
-
-  /**
-   * @brief Handle the accessibility action to move focus to the previous focusable actor
-   * (by one finger flick up).
-   *
-   * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the front
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionReadPreviousEvent(bool allowEndFeedback = true);
-
-  /**
-   * @brief Handle the accessibility action to change the value when the current focused
-   * actor is a slider (by double finger down and move up and right).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionUpEvent();
-
-  /**
-   * @brief Handle the accessibility action to change the value when the current focused
-   * actor is a slider (by double finger down and move down and left).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionDownEvent();
-
-  /**
-   * @brief Handle the accessibility action to clear the focus from the current focused
-   * actor if any, so that no actor is focused in the focus chain.
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionClearFocusEvent();
-
-  /**
-   * @brief Handle the accessibility action to scroll when there is a scroller on the touched position
-   * (by 2 finger touch & move, 2 finger flick).
-   *
-   * @param[in]  point      The touch point information.
-   * @param[in]  timeStamp  The time the touch occurred.
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionScrollEvent(const TouchPoint& point, unsigned long timeStamp);
-
-  /**
-   * @brief Handle the accessibility action to move for the current focused actor
-   * (by 1 finger tap & hold and move).
-   *
-   * @param[in]  point      The touch point information.
-   * @param[in]  timeStamp  The time the touch occurred.
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionTouchEvent(const TouchPoint& point, unsigned long timeStamp);
-
-  /**
-   * @brief Handle the accessibility action to navigate back (by two fingers circle draw).
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionBackEvent();
-
-  /**
-   * @brief Handle the accessibility action to enable the feature.
-   */
-  void HandleActionEnableEvent();
-
-  /**
-   * @brief Handle the accessibility action to disable the feature.
-   */
-  void HandleActionDisableEvent();
-
-  /**
-   * @brief Handle the accessibility action to scroll up the list and focus on
-   * the first item on the list after the scrolling and read the item
-   * (by two finger swipe up).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionScrollUpEvent();
-
-  /**
-   * @brief Handle the accessibility action to scroll down the list and focus on
-   * the first item on the list after the scrolling and read the item
-   * (by two finger swipe down).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionScrollDownEvent();
-
-  /**
-   * @brief Handle the accessibility action to scroll left to the previous page
-   * (by two finger swipe left).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionPageLeftEvent();
-
-  /**
-   * @brief Handle the accessibility action to scroll right to the next page
-   * (by two finger swipe right).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionPageRightEvent();
-
-  /**
-   * @brief Handle the accessibility action to scroll up to the previous page
-   * (by one finger swipe left and right).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionPageUpEvent();
-
-  /**
-   * @brief Handle the accessibility action to scroll down to the next page
-   * (by one finger swipe right and left).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionPageDownEvent();
-
-  /**
-   * @brief Handle the accessibility action to move the focus to the first item on the screen
-   * (by one finger swipe up and down).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionMoveToFirstEvent();
-
-  /**
-   * @brief Handle the accessibility action to move the focus to the last item on the screen
-   * (by one finger swipe down and up).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionMoveToLastEvent();
-
-  /**
-   * @brief Handle the accessibility action to move the focus to the first item on the top
-   * and read from the top item continuously (by three fingers single tap).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionReadFromTopEvent();
-
-  /**
-   * @brief Handle the accessibility action to move focus to and read from the next focusable
-   * actor continuously (by three fingers double tap).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionReadFromNextEvent();
-
-  /**
-   * @brief Handle the accessibility action to do the zooming
-   * (by one finger triple tap).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionZoomEvent();
-
-  /**
-   * @brief Handle the accessibility action to pause/resume the current speech
-   * (by two fingers single tap).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionReadPauseResumeEvent();
-
-  /**
-   * @brief Handle the accessibility action to start/stop the current action
-   * (by two fingers double tap).
-   *
-   * @return Whether the action is performed successfully or not.
-   */
-  bool HandleActionStartStopEvent();
-
-public: // Not intended for application developers
-
-  /**
-   * @brief Creates a handle using the Adaptor::Internal implementation.
-   *
-   * @param[in] adaptor The AccessibilityAdaptor implementation.
-   */
-  DALI_INTERNAL AccessibilityAdaptor( Internal::Adaptor::AccessibilityAdaptor& adaptor );
-
-  /**
-   * @brief This constructor is used by AccessibilityAdaptor::Get().
-   *
-   * @param[in] adaptor A pointer to the accessibility adaptor.
-   */
-  explicit DALI_INTERNAL AccessibilityAdaptor( Internal::Adaptor::AccessibilityAdaptor* adaptor );
-};
-
-} // namespace Dali
-
-#endif // DALI_ACCESSIBILITY_ADAPTOR_H
diff --git a/dali/devel-api/adaptor-framework/accessibility-gesture-handler.h b/dali/devel-api/adaptor-framework/accessibility-gesture-handler.h
deleted file mode 100644 (file)
index 4b8c859..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef DALI_ACCESSIBILITY_GESTURE_HANDLER_H
-#define DALI_ACCESSIBILITY_GESTURE_HANDLER_H
-
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-event.h>
-
-namespace Dali
-{
-
-/**
- * AccessibilityGestureHandler is an interface used by Dali to handle accessibility gestures
- * passed by the accessibility manager.
- */
-class AccessibilityGestureHandler
-{
-public:
-
-  /**
-   * Handle the accessibility pan gesture.
-   * @param[in]  panEvent  The pan event to be handled.
-   * @return whether the gesture is handled successfully or not.
-   */
-  virtual bool HandlePanGesture( const AccessibilityGestureEvent& panEvent ) = 0;
-
-}; // class AccessibilityGestureHandler
-
-} // namespace Dali
-
-#endif // DALI_ACCESSIBILITY_GESTURE_HANDLER_H
diff --git a/dali/devel-api/adaptor-framework/accessibility.h b/dali/devel-api/adaptor-framework/accessibility.h
new file mode 100644 (file)
index 0000000..8ffe231
--- /dev/null
@@ -0,0 +1,965 @@
+#ifndef DALI_ACCESSIBILITY_DEVEL_H
+#define DALI_ACCESSIBILITY_DEVEL_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/math/rect.h>
+#include <atomic>
+#include <bitset>
+#include <exception>
+#include <functional>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+#include <stdexcept>
+
+//INTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/accessibility.h>
+
+namespace Dali
+{
+namespace Accessibility
+{
+class Accessible;
+class Text;
+class Value;
+class Component;
+class Collection;
+class Action;
+
+/**
+ * @brief Base class for different accessibility bridges
+ *
+ * Bridge is resposible for initializing and managing connection on accessibility bus.
+ * Accessibility clients will not get any information about UI without initialized and upraised bridge.
+ * Concrete implementation depends on the accessibility technology available on the platform.
+ *
+ * @note This class is singleton.
+ */
+struct DALI_ADAPTOR_API Bridge
+{
+  enum class ForceUpResult
+  {
+    JUST_STARTED,
+    ALREADY_UP
+  };
+
+  /**
+   * @brief Destructor
+   */
+  virtual ~Bridge() = default;
+
+  /**
+   * @brief Get bus name which bridge is initialized on
+   */
+  virtual const std::string& GetBusName() const = 0;
+
+  /**
+   * @brief Registers top level window
+   *
+   * Hierarchy of objects visible for accessibility clients is based on tree-like
+   * structure created from Actors objects. This method allows to connect chosen
+   * object as direct ancestor of application and therefore make it visible for
+   * accessibility clients.
+   */
+  virtual void AddTopLevelWindow( Accessible* ) = 0;
+
+  /**
+   * @brief Removes top level window
+   *
+   * Hierarchy of objects visible for accessibility clients is based on tree-like
+   * structure created from Actors objects. This method removes previously added
+   * window from visible accessibility objects.
+   */
+  virtual void RemoveTopLevelWindow( Accessible* ) = 0;
+
+  /**
+   * @brief Adds popup window
+   *
+   * Hierarchy of objects visible for accessibility clients is based on tree-like
+   * structure created from Actors objects. This method adds new popup to the tree.
+   */
+  virtual void AddPopup( Accessible* ) = 0;
+
+  /**
+   * @brief Removes popup window
+   *
+   * Hierarchy of objects visible for accessibility clients is based on tree-like
+   * structure created from Actors objects. This method removes previously added
+   * popup window.
+   */
+  virtual void RemovePopup( Accessible* ) = 0;
+
+  /**
+   * @brief Set name of current application which will be visible on accessibility bus
+   */
+  virtual void SetApplicationName( std::string ) = 0;
+
+  /**
+   * @brief Get object being root of accessibility tree
+   *
+   * @return handler to accessibility object
+   */
+  virtual Accessible* GetApplication() const = 0;
+
+  /**
+   * @brief Find an object in accessibility tree
+   *
+   * @param[in] s path to object
+   *
+   * @return handler to accessibility object
+   */
+  virtual Accessible* FindByPath( const std::string& s) const = 0;
+
+  /**
+   * @brief Show application on accessibility bus
+   */
+  virtual void ApplicationShown() = 0;
+
+  /**
+   * @brief Hide application on accessibility bus
+   */
+  virtual void ApplicationHidden() = 0;
+
+  /**
+   * @brief Initialize accessibility bus
+   */
+  virtual void Initialize() = 0;
+
+  /**
+   * @brief Terminate accessibility bus
+   */
+  virtual void Terminate() = 0;
+
+  /**
+   * @brief This method is called, when bridge is being activated.
+   */
+  virtual ForceUpResult ForceUp()
+  {
+    if( data )
+      return ForceUpResult::ALREADY_UP;
+    data = std::make_shared< Data >();
+    data->bridge = this;
+    return ForceUpResult::JUST_STARTED;
+  }
+  virtual void ForceDown();
+  bool IsUp() const { return bool(data); }
+
+  /**
+   * @brief Emits caret-moved event on at-spi bus.
+   **/
+  virtual void EmitCaretMoved( Accessible* obj, unsigned int cursorPosition ) = 0;
+
+  /**
+   * @brief Emits active-descendant-changed event on at-spi bus.
+   **/
+  virtual void EmitActiveDescendantChanged( Accessible* obj, Accessible *child ) = 0;
+
+  /**
+   * @brief Emits text-changed event on at-spi bus.
+   **/
+  virtual void EmitTextChanged( Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string &content ) = 0;
+
+  /**
+   * @brief Emits state-changed event on at-spi bus.
+   **/
+  virtual void EmitStateChanged( Accessible* obj, State state, int val1, int val2 = 0 ) = 0;
+
+  /**
+   * @brief Emits window event on at-spi bus.
+   **/
+  virtual void Emit( Accessible* obj, WindowEvent we, unsigned int detail1 = 0 ) = 0;
+
+  /**
+   * @brief Emits property-changed event on at-spi bus.
+   **/
+  virtual void Emit( Accessible* obj, ObjectPropertyChangeEvent ev ) = 0;
+
+  /**
+   * @brief Emits bounds-changed event on at-spi bus.
+   **/
+  virtual void EmitBoundsChanged( Accessible* obj, Rect<> rect ) = 0;
+
+  /**
+   * @brief Emits key event on at-spi bus.
+   *
+   * Screen-reader might receive this event and reply, that given keycode is consumed. In that case
+   * further processing of the keycode should be ignored.
+   **/
+  virtual Consumed Emit( KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText ) = 0;
+
+  /**
+   * @brief Force accessibility client to read provided text.
+   *
+   * @note Text can be read only if accessibility client uses Text To Speach module
+   *
+   * @param[in] text string that should be read
+   * @param[in] discardable flag pointing if text can be discarded by subsequent reading request
+   * @param[in] callback function called every time the status of reading has changed, callback type
+   * specifies one parameter (of type std::string), which can be one of the following signals:
+   *     “ReadingCancelled”
+   *     “ReadingStopped”
+   *     “ReadingSkipped”
+   */
+  virtual void Say( const std::string& text, bool discardable, std::function<void(std::string)> callback ) = 0;
+
+  /**
+   * @brief Force accessibility client to pause / resume.
+   *
+   * @param[in] pause true if you want to pause, false if you want to resume
+   */
+  virtual void PauseResume( bool pause ) = 0;
+
+  /**
+   * @brief Returns instance of bridge singleton object.
+   **/
+  static Bridge* GetCurrentBridge();
+
+protected:
+  struct Data
+  {
+    std::unordered_set< Accessible* > knownObjects;
+    std::string busName;
+    Bridge* bridge = nullptr;
+    Actor highlightActor, currentlyHighlightedActor;
+  };
+  std::shared_ptr< Data > data;
+  friend class Accessible;
+
+  /**
+   * @brief Registers accessible object to be known in bridge object
+   *
+   * Bridge must known about all currently alive accessible objects, as some requst
+   * might come and object will be identified by number id (it's memory address).
+   * To avoid memory corruption number id is checked against set of known objects.
+   **/
+  void RegisterOnBridge( Accessible* );
+
+  /**
+   * @brief Tells bridge, that given object is considered root (doesn't have any parents).
+   *
+   * All root objects will have the same parent - application object. Application object
+   * is controlled by bridge and private.
+   **/
+  void SetIsOnRootLevel( Accessible* );
+};
+
+inline bool IsUp()
+{
+  return Bridge::GetCurrentBridge()->IsUp();
+}
+
+/**
+ * @brief Basic interface implemented by all accessibility objects
+ */
+class DALI_IMPORT_API Accessible
+{
+protected:
+  Accessible();
+
+  Accessible( const Accessible& ) = delete;
+  Accessible( Accessible&& ) = delete;
+
+  Accessible& operator=( const Accessible& ) = delete;
+  Accessible& operator=( Accessible&& ) = delete;
+
+public:
+  virtual ~Accessible();
+
+  using utf8_t = unsigned char;
+
+  /**
+   * @brief Calculaties word boundaries in given utf8 text.
+   *
+   * s and length represents source text pointer and it's length respectively. langauge represents
+   * language to use. Word boundaries are returned as non-zero values in table breaks, which
+   * must be of size at least length.
+   **/
+  void FindWordSeparationsUtf8( const utf8_t *s, size_t length, const char *language, char *breaks );
+
+  /**
+   * @brief Calculaties line boundaries in given utf8 text.
+   *
+   * s and length represents source text pointer and it's length respectively. langauge represents
+   * language to use. Line boundaries are returned as non-zero values in table breaks, which
+   * must be of size at least length.
+   **/
+  void FindLineSeparationsUtf8( const utf8_t *s, size_t length, const char *language, char *breaks );
+
+  /**
+   * @brief Helper function for emiting active-descendant-changed event
+   **/
+  void EmitActiveDescendantChanged( Accessible* obj, Accessible *child );
+
+  /**
+   * @brief Helper function for emiting state-changed event
+   **/
+  void EmitStateChanged( State state, int newValue1, int newValue2 = 0 );
+
+  /**
+   * @brief Helper function for emiting bounds-changed event
+   **/
+  void EmitBoundsChanged( Rect<> rect );
+
+  /**
+   * @brief Emit "showing" event.
+   * The method inform accessibility clients about "showing" state
+   *
+   * @param[in] showing flag pointing if object is showing
+   */
+  void EmitShowing( bool showing );
+
+  /**
+   * @brief Emit "visible" event.
+   * The method inform accessibility clients about "visible" state
+   *
+   * @param[in] visible flag pointing if object is visible
+   */
+  void EmitVisible( bool visible );
+
+  /**
+   * @brief Emit "highlighted" event.
+   * The method inform accessibility clients about "highlighted" state
+   *
+   * @param[in] set flag pointing if object is highlighted
+   */
+  void EmitHighlighted( bool set );
+
+  /**
+   * @brief Emit "focused" event.
+   * The method inform accessibility clients about "focused" state
+   *
+   * @param[in] set flag pointing if object is focused
+   */
+  void EmitFocused( bool set );
+
+  /**
+   * @brief Emit "text inserted" event
+   *
+   * @param[in] position caret position
+   * @param[in] length text length
+   * @param[in] content inserted text
+   */
+  void EmitTextInserted( unsigned int position, unsigned int length, const std::string &content );
+
+  /**
+   * @brief Emit "text deleted" event
+   *
+   * @param[in] position caret position
+   * @param[in] length text length
+   * @param[in] content deleted text
+   */
+  void EmitTextDeleted( unsigned int position, unsigned int length, const std::string &content );
+
+  /**
+   * @brief Emit "caret moved" event
+   *
+   * @param[in] cursorPosition new caret position
+   */
+  void EmitTextCaretMoved( unsigned int cursorPosition );
+
+  /**
+   * @brief Emit "highlighted" event
+   *
+   * @param[in] we enumerated window event
+   * @param[in] detail1 additional parameter which interpretation depends on chosen event
+   */
+  void Emit( WindowEvent we, unsigned int detail1 = 0 );
+
+  void Emit( ObjectPropertyChangeEvent ev );
+  /**
+   * @brief Get accessibility name
+   *
+   * @return string with name
+   */
+  virtual std::string GetName() = 0;
+
+  /**
+   * @brief Get accessibility description
+   *
+   * @return string with description
+   */
+  virtual std::string GetDescription() = 0;
+
+  /**
+   * @brief Get parent
+   *
+   * @return handler to accessibility object
+   */
+  virtual Accessible* GetParent() = 0;
+
+  /**
+   * @brief Get count of children
+   *
+   * @return unsigned integer value
+   */
+  virtual size_t GetChildCount() = 0;
+
+  /**
+   * @brief Get collection with all children
+   *
+   * @return collection of accessibility objects
+   */
+  virtual std::vector< Accessible* > GetChildren();
+
+  /**
+   * @brief Get nth child
+   *
+   * @return accessibility object
+   */
+  virtual Accessible* GetChildAtIndex( size_t index ) = 0;
+
+  /**
+   * @brief Get index that current object has in its parent's children collection
+   *
+   * @return unsigned integer index
+   */
+  virtual size_t GetIndexInParent() = 0;
+
+  /**
+   * @brief Get accessibility role
+   *
+   * @return Role enumeration
+   *
+   * @see Dali::Accessibility::Role
+   */
+  virtual Role GetRole() = 0;
+
+  /**
+   * @brief Get name of accessibility role
+   *
+   * @return string with human readable role converted from enumeration
+   *
+   * @see Dali::Accessibility::Role
+   * @see Accessibility::Accessible::GetRole
+   */
+  virtual std::string GetRoleName();
+
+  /**
+   * @brief Get localized name of accessibility role
+   *
+   * @return string with human readable role translated according to current
+   * translation domain
+   *
+   * @see Dali::Accessibility::Role
+   * @see Accessibility::Accessible::GetRole
+   * @see Accessibility::Accessible::GetRoleName
+   *
+   * @note translation is not supported in this version
+   */
+  virtual std::string GetLocalizedRoleName();
+
+  /**
+   * @brief Get accessibility states
+   *
+   * @return collection of states
+   *
+   * @note States class is instatation of ArrayBitset template class
+   *
+   * @see Dali::Accessibility::State
+   * @see Dali::Accessibility::ArrayBitset
+   */
+  virtual States GetStates() = 0;
+
+  /**
+   * @brief Get accessibility attributes
+   *
+   * @return map of attributes and their values
+   */
+  virtual Attributes GetAttributes() = 0;
+
+  //TODO probably shouldn't be public
+  virtual bool IsProxy();
+
+  /**
+   * @brief Get unique address on accessibility bus
+   *
+   * @return class containing address
+   *
+   * @see Dali::Accessibility::Address
+   */
+  virtual Address GetAddress();
+
+  /**
+   * @brief Get accessibility object, which is "default label" for this object
+   */
+  virtual Accessible* GetDefaultLabel();
+
+  /**
+   * @brief Depute an object to perform provided gesture
+   *
+   * @param[in] gestureInfo structure describing the gesture
+   *
+   * @return true on success, false otherwise
+   *
+   * @see Dali::Accessibility::GestureInfo
+   */
+  virtual bool DoGesture(const GestureInfo &gestureInfo) = 0;
+
+  /**
+   * @brief Re-emits selected states of an Accessibility Object
+   *
+   * @param[in] states chosen states to re-emit
+   * @param[in] doRecursive if true all children of the Accessibility Object will also re-emit the states
+   */
+  void NotifyAccessibilityStateChange( Dali::Accessibility::States states, bool doRecursive );
+
+  /**
+   * @brief Get information about current object and all relations that connects
+   * it with other accessibility objects
+   *
+   * @return iterable collection of Relation objects
+   *
+   * @see Dali::Accessibility::Relation
+   */
+  virtual std::vector<Relation> GetRelationSet() = 0;
+
+  /**
+   * @brief Get all implemented interfaces
+   *
+   * @return collection of strings with implemented interfaces
+   */
+  std::vector< std::string > GetInterfaces();
+
+  /**
+   * @brief Check if object is on root level
+   */
+  bool GetIsOnRootLevel() const { return isOnRootLevel; }
+
+  /**
+   * @brief The method registers functor resposible for converting Actor into Accessible
+   * @param functor returning Accessible handle from Actor object
+   */
+  static void RegisterControlAccessibilityGetter( std::function< Accessible*( Dali::Actor ) > functor);
+
+  /**
+   * @brief Acquire Accessible object from Actor object
+   *
+   * @param[in] actor Actor object
+   * @param[in] root true, if it's top level object (window)
+   *
+   * @return handle to Accessible object
+   */
+  static Accessible* Get( Dali::Actor actor, bool root = false );
+
+protected:
+  std::shared_ptr< Bridge::Data > GetBridgeData();
+  static Dali::Actor GetHighlightActor();
+  static void SetHighlightActor(Dali::Actor actor);
+  static Dali::Actor GetCurrentlyHighlightedActor();
+  static void SetCurrentlyHighlightedActor(Dali::Actor);
+private:
+  friend class Bridge;
+
+  std::weak_ptr< Bridge::Data > bridgeData;
+  bool isOnRootLevel = false;
+};
+
+/**
+ * @brief Interface enabling to perform provided actions
+ */
+class DALI_IMPORT_API Action : public virtual Accessible
+{
+public:
+  /**
+   * @brief Get name of action with given index
+   *
+   * @param[in] index index of action
+   *
+   * @return string with name of action
+   */
+  virtual std::string GetActionName( size_t index ) = 0;
+
+  /**
+   * @brief Get translated name of action with given index
+   *
+   * @param[in] index index of action
+   *
+   * @return string with name of action translated according to current translation domain
+   *
+   * @note translation is not supported in this version
+   */
+  virtual std::string GetLocalizedActionName( size_t index ) = 0;
+
+  /**
+   * @brief Get description of action with given index
+   *
+   * @param[in] index index of action
+   *
+   * @return string with description of action
+   */
+  virtual std::string GetActionDescription( size_t index ) = 0;
+
+  /**
+   * @brief Get key code binded to action with given index
+   *
+   * @param[in] index index of action
+   *
+   * @return string with key name
+   */
+  virtual std::string GetActionKeyBinding( size_t index ) = 0;
+
+  /**
+   * @brief Get number of provided actions
+   *
+   * @return unsigned integer with number of actions
+   */
+  virtual size_t GetActionCount() = 0;
+
+  /**
+   * @brief Perform an action with given index
+   *
+   * @param index index of action
+   *
+   * @return true on success, false otherwise
+   */
+  virtual bool DoAction( size_t index ) = 0;
+
+  /**
+   * @brief Perform an action with given name
+   *
+   * @param name name of action
+   *
+   * @return true on success, false otherwise
+   */
+  virtual bool DoAction( const std::string& name ) = 0;
+
+  //TODO DoActionName
+};
+
+/**
+ * @brief Interface enabling advanced quering of accessibility objects
+ *
+ * @note since all mathods can be implemented inside bridge,
+ * none methods have to be overrided
+ */
+class DALI_IMPORT_API Collection : public virtual Accessible
+{
+public:
+};
+
+/**
+ * @brief Interface representing objects having screen coordinates
+ */
+class DALI_IMPORT_API Component : public virtual Accessible
+{
+public:
+  /**
+   * @brief Get rectangle describing size
+   *
+   * @param[in] ctype enumeration with type of coordinate systems
+   *
+   * @return Rect<> object
+   *
+   * @see Dali::Rect
+   */
+  virtual Rect<> GetExtents( CoordType ctype ) = 0;
+
+  /**
+   * @brief Get layer current object is localized on
+   *
+   * @return enumeration pointing layer
+   *
+   * @see Dali::Accessibility::ComponentLayer
+   */
+  virtual ComponentLayer GetLayer() = 0;
+
+  /**
+   * @brief Get value of z-order
+   *
+   * @return value of z-order
+   */
+  virtual int16_t GetMdiZOrder() = 0;
+
+  /**
+   * @brief Set current object as "focused"
+   *
+   * @return true on success, false otherwise
+   */
+  virtual bool GrabFocus() = 0;
+
+  /**
+   * @brief Get value of alpha channel
+   *
+   * @return alpha channel value in range [0.0, 1.0]
+   */
+  virtual double GetAlpha() = 0;
+
+  /**
+   * @brief Set current object as "highlighted"
+   *
+   * The method assings "highlighted" state, simultaneously removing it
+   * from currently highlighted object.
+   *
+   * @return true on success, false otherwise
+   */
+  virtual bool GrabHighlight() = 0;
+
+  /**
+   * @brief Set current object as "unhighlighted"
+   *
+   * The method removes "highlighted" state from object.
+   *
+   * @return true on success, false otherwise
+   *
+   * @see Dali:Accessibility::State
+   */
+  virtual bool ClearHighlight() = 0;
+
+  //TODO remove
+  virtual int GetHighlightIndex() = 0;
+
+  /**
+   * @brief Check whether object can be scrolled
+   *
+   * @return true if object is scrollable, false otherwise
+   *
+   * @see Dali:Accessibility::State
+   */
+  virtual bool IsScrollable();
+
+  /**
+   * @brief Get Accessible object containing given point
+   *
+   * @param[in] p two-dimensional point
+   * @param[in] ctype enumeration with type of coordinate system
+   *
+   * @return handle to last child of current object which contains given point
+   *
+   * @see Dali::Accessibility::Point
+   */
+  virtual Accessible* GetAccessibleAtPoint( Point p, CoordType ctype );
+
+  /**
+   * @brief Check if current object contains given point
+   *
+   * @param[in] p two-dimensional point
+   * @param[in] ctype enumeration with type of coordinate system
+   *
+   * @return handle to Accessible object
+   *
+   * @see Dali::Accessibility::Point
+   */
+  virtual bool Contains( Point p, CoordType ctype );
+};
+
+/**
+ * @brief Interface representing objects which can store numeric value
+ */
+class DALI_IMPORT_API Value : public virtual Accessible
+{
+public:
+  /**
+   * @brief Get the lowest possible value
+   *
+   * @return double value
+  */
+  virtual double GetMinimum() = 0;
+
+  /**
+   * @brief Get current value
+   *
+   * @return double value
+  */
+  virtual double GetCurrent() = 0;
+
+  /**
+   * @brief Get the highest possible value
+   *
+   * @return double value
+  */
+  virtual double GetMaximum() = 0;
+
+  /**
+   * @brief Set value
+   *
+   * @param[in] val double value
+   *
+   * @return true if value could have been assigned, false otherwise
+  */
+  virtual bool SetCurrent( double val) = 0;
+
+  /**
+   * @brief Get the lowest increment that can be distinguished
+   *
+   * @return double value
+  */
+  virtual double GetMinimumIncrement() = 0;
+};
+
+/**
+ * @brief Interface representing objects which can store immutable texts
+ *
+ * @see Dali::Accessibility::EditableText
+ */
+class DALI_IMPORT_API Text : public virtual Accessible
+{
+public:
+  /**
+   * @brief Get stored text in given range
+   *
+   * @param[in] startOffset index of first character
+   * @param[in] endOffset index of first character after the last one expected
+   *
+   * @return substring of stored text
+   */
+  virtual std::string GetText( size_t startOffset, size_t endOffset ) = 0;
+
+  /**
+   * @brief Get number of all stored characters
+   *
+   * @return number of characters
+   */
+  virtual size_t GetCharacterCount() = 0;
+
+  virtual size_t GetCaretOffset() = 0;
+  virtual bool SetCaretOffset(size_t offset) = 0;
+
+  /**
+   * @brief Get substring of stored text truncated in concrete gradation
+   *
+   * @param[in] offset position in stored text
+   * @param[in] boundary enumeration describing text gradation
+   *
+   * @return Range structure containing acquired text and offsets in original string
+   *
+   * @see Dali::Accessibility::Range
+   */
+  virtual Range GetTextAtOffset( size_t offset, TextBoundary boundary ) = 0;
+
+  /**
+   * @brief Get selected text
+   *
+   * @param[in] selectionNum selection index
+   * @note Currently only one selection (i.e. with index = 0) is supported
+   *
+   * @return Range structure containing acquired text and offsets in original string
+   *
+   * @see Dali::Accessibility::Range
+   */
+  virtual Range GetSelection( size_t selectionNum ) = 0;
+
+  /**
+   * @brief Remove selection
+   *
+   * @param[in] selectionNum selection index
+   * @note Currently only one selection (i.e. with index = 0) is supported
+   *
+   * @return bool on success, false otherwise
+   */
+  virtual bool RemoveSelection( size_t selectionNum ) = 0;
+
+  /**
+   * @brief Get selected text
+   *
+   * @param[in] selectionNum selection index
+   * @param[in] startOffset index of first character
+   * @param[in] endOffset index of first character after the last one expected
+   *
+   * @note Currently only one selection (i.e. with index = 0) is supported
+   *
+   * @return true on success, false otherwise
+   */
+  virtual bool SetSelection( size_t selectionNum, size_t startOffset, size_t endOffset ) = 0;
+};
+
+/**
+ * @brief Interface representing objects which can store editable texts
+ *
+ * @note Paste method is entirely implemented inside bridge
+ *
+ * @see Dali::Accessibility::EditableText
+ */
+class DALI_IMPORT_API EditableText : public virtual Accessible
+{
+public:
+  /**
+   * @brief Copy text in range to system clipboard
+   *
+   * @param[in] startPosition index of first character
+   * @param[in] endPosition index of first character after the last one expected
+   *
+   * @return true on success, false otherwise
+   */
+  virtual bool CopyText( size_t startPosition, size_t endPosition ) = 0;
+
+  /**
+   * @brief Cut text in range to system clipboard
+   *
+   * @param[in] startPosition index of first character
+   * @param[in] endPosition index of first character after the last one expected
+   *
+   * @return true on success, false otherwise
+   */
+  virtual bool CutText( size_t startPosition, size_t endPosition ) = 0;
+};
+
+/**
+ * @brief minimalistic, always empty Accessible object with settable address
+ *
+ * For those situations, where you want to return address in different bridge
+ * (embedding for example), but the object itself ain't planned to be used otherwise.
+ * This object has null parent, no children, empty name and so on
+ */
+class DALI_IMPORT_API EmptyAccessibleWithAddress : public virtual Accessible
+{
+public:
+  EmptyAccessibleWithAddress() = default;
+  EmptyAccessibleWithAddress( Address address ) : address( std::move( address ) ) {}
+
+  void SetAddress( Address address ) { this->address = std::move( address ); }
+
+  std::string GetName() override { return ""; }
+  std::string GetDescription() override { return ""; }
+  Accessible* GetParent() override { return nullptr; }
+  size_t GetChildCount() override { return 0; }
+  std::vector< Accessible* > GetChildren() override { return {}; }
+  Accessible* GetChildAtIndex( size_t index ) override
+  {
+    throw std::domain_error{"out of bounds index (" + std::to_string( index ) + ") - no children"};
+  }
+  size_t GetIndexInParent() override { return static_cast< size_t >( -1 ); }
+  Role GetRole() override { return {}; }
+  std::string GetRoleName() override;
+  States GetStates() override { return {}; }
+  Attributes GetAttributes() override { return {}; }
+  Address GetAddress() override
+  {
+    return address;
+  }
+  bool DoGesture(const GestureInfo &gestureInfo) override
+  {
+      return false;
+  }
+  std::vector<Relation> GetRelationSet() override
+  {
+      return {};
+  }
+
+private:
+  Address address;
+};
+
+}
+}
+
+#endif // DALI_ACCESSIBILITY_DEVEL_H
index 7f88752..e0851be 100755 (executable)
@@ -1,5 +1,4 @@
 devel_api_src_files = \
-  $(adaptor_devel_api_dir)/adaptor-framework/accessibility-adaptor.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/application-devel.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/autofill-group.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/autofill-item.cpp \
@@ -39,10 +38,6 @@ devel_api_src_files = \
 
 
 devel_api_adaptor_framework_header_files = \
-  $(adaptor_devel_api_dir)/adaptor-framework/accessibility-adaptor.h \
-  $(adaptor_devel_api_dir)/adaptor-framework/accessibility-action-handler.h \
-  $(adaptor_devel_api_dir)/adaptor-framework/accessibility-gesture-handler.h \
-  $(adaptor_devel_api_dir)/adaptor-framework/accessibility-gesture-event.h \
   $(adaptor_devel_api_dir)/adaptor-framework/application-devel.h \
   $(adaptor_devel_api_dir)/adaptor-framework/autofill-group.h \
   $(adaptor_devel_api_dir)/adaptor-framework/autofill-item.h \
@@ -86,7 +81,8 @@ devel_api_adaptor_framework_header_files = \
   $(adaptor_devel_api_dir)/adaptor-framework/physical-keyboard.h \
   $(adaptor_devel_api_dir)/adaptor-framework/key-devel.h \
   $(adaptor_devel_api_dir)/adaptor-framework/thread-settings.h \
-  $(adaptor_devel_api_dir)/adaptor-framework/window-devel.h
+  $(adaptor_devel_api_dir)/adaptor-framework/window-devel.h \
+  $(adaptor_devel_api_dir)/adaptor-framework/accessibility.h
 
 devel_api_text_abstraction_src_files = \
    $(adaptor_devel_api_dir)/text-abstraction/bidirectional-support.cpp \
@@ -115,4 +111,3 @@ text_abstraction_header_files = \
    $(adaptor_devel_api_dir)/text-abstraction/text-abstraction-definitions.h \
    $(adaptor_devel_api_dir)/text-abstraction/text-renderer.h \
    $(adaptor_devel_api_dir)/text-abstraction/text-renderer-layout-helper.h
-
diff --git a/dali/internal/accessibility/accessibility-impl.cpp b/dali/internal/accessibility/accessibility-impl.cpp
new file mode 100644 (file)
index 0000000..2a7da00
--- /dev/null
@@ -0,0 +1,765 @@
+/*
+ * Copyright 2019  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// CLASS HEADER
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/actors/layer.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/object/object-registry.h>
+#include <dali/public-api/object/type-info.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/devel-api/actors/actor-devel.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/dali-adaptor-common.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+
+using namespace Dali::Accessibility;
+using namespace Dali;
+
+const std::string& Dali::Accessibility::Address::GetBus() const
+{
+  return bus.empty() && Bridge::GetCurrentBridge() ? Bridge::GetCurrentBridge()->GetBusName() : bus;
+}
+
+std::string EmptyAccessibleWithAddress::GetRoleName()
+{
+  return "";
+}
+
+std::string Accessible::GetLocalizedRoleName()
+{
+  return GetRoleName();
+}
+
+std::string Accessible::GetRoleName()
+{
+  switch( GetRole() )
+  {
+    case Role::INVALID:
+    {
+      return "invalid";
+    }
+    case Role::ACCELERATOR_LABEL:
+    {
+      return "accelerator label";
+    }
+    case Role::ALERT:
+    {
+      return "alert";
+    }
+    case Role::ANIMATION:
+    {
+      return "animation";
+    }
+    case Role::ARROW:
+    {
+      return "arrow";
+    }
+    case Role::CALENDAR:
+    {
+      return "calendar";
+    }
+    case Role::CANVAS:
+    {
+      return "canvas";
+    }
+    case Role::CHECK_BOX:
+    {
+      return "check box";
+    }
+    case Role::CHECK_MENU_ITEM:
+    {
+      return "check menu item";
+    }
+    case Role::COLOR_CHOOSER:
+    {
+      return "color chooser";
+    }
+    case Role::COLUMN_HEADER:
+    {
+      return "column header";
+    }
+    case Role::COMBO_BOX:
+    {
+      return "combo box";
+    }
+    case Role::DATE_EDITOR:
+    {
+      return "date editor";
+    }
+    case Role::DESKTOP_ICON:
+    {
+      return "desktop icon";
+    }
+    case Role::DESKTOP_FRAME:
+    {
+      return "desktop frame";
+    }
+    case Role::DIAL:
+    {
+      return "dial";
+    }
+    case Role::DIALOG:
+    {
+      return "dialog";
+    }
+    case Role::DIRECTORY_PANE:
+    {
+      return "directory pane";
+    }
+    case Role::DRAWING_AREA:
+    {
+      return "drawing area";
+    }
+    case Role::FILE_CHOOSER:
+    {
+      return "file chooser";
+    }
+    case Role::FILLER:
+    {
+      return "filler";
+    }
+    case Role::FOCUS_TRAVERSABLE:
+    {
+      return "focus traversable";
+    }
+    case Role::FONT_CHOOSER:
+    {
+      return "font chooser";
+    }
+    case Role::FRAME:
+    {
+      return "frame";
+    }
+    case Role::GLASS_PANE:
+    {
+      return "glass pane";
+    }
+    case Role::HTML_CONTAINER:
+    {
+      return "html container";
+    }
+    case Role::ICON:
+    {
+      return "icon";
+    }
+    case Role::IMAGE:
+    {
+      return "image";
+    }
+    case Role::INTERNAL_FRAME:
+    {
+      return "internal frame";
+    }
+    case Role::LABEL:
+    {
+      return "label";
+    }
+    case Role::LAYERED_PANE:
+    {
+      return "layered pane";
+    }
+    case Role::LIST:
+    {
+      return "list";
+    }
+    case Role::LIST_ITEM:
+    {
+      return "list item";
+    }
+    case Role::MENU:
+    {
+      return "menu";
+    }
+    case Role::MENU_BAR:
+    {
+      return "menu bar";
+    }
+    case Role::MENU_ITEM:
+    {
+      return "menu item";
+    }
+    case Role::OPTION_PANE:
+    {
+      return "option pane";
+    }
+    case Role::PAGE_TAB:
+    {
+      return "page tab";
+    }
+    case Role::PAGE_TAB_LIST:
+    {
+      return "page tab list";
+    }
+    case Role::PANEL:
+    {
+      return "panel";
+    }
+    case Role::PASSWORD_TEXT:
+    {
+      return "password text";
+    }
+    case Role::POPUP_MENU:
+    {
+      return "popup menu";
+    }
+    case Role::PROGRESS_BAR:
+    {
+      return "progress bar";
+    }
+    case Role::PUSH_BUTTON:
+    {
+      return "push button";
+    }
+    case Role::RADIO_BUTTON:
+    {
+      return "radio button";
+    }
+    case Role::RADIO_MENU_ITEM:
+    {
+      return "radio menu item";
+    }
+    case Role::ROOT_PANE:
+    {
+      return "root pane";
+    }
+    case Role::ROW_HEADER:
+    {
+      return "row header";
+    }
+    case Role::SCROLL_BAR:
+    {
+      return "scroll bar";
+    }
+    case Role::SCROLL_PANE:
+    {
+      return "scroll pane";
+    }
+    case Role::SEPARATOR:
+    {
+      return "separator";
+    }
+    case Role::SLIDER:
+    {
+      return "slider";
+    }
+    case Role::SPIN_BUTTON:
+    {
+      return "spin button";
+    }
+    case Role::SPLIT_PANE:
+    {
+      return "split pane";
+    }
+    case Role::STATUS_BAR:
+    {
+      return "status bar";
+    }
+    case Role::TABLE:
+    {
+      return "table";
+    }
+    case Role::TABLE_CELL:
+    {
+      return "table cell";
+    }
+    case Role::TABLE_COLUMN_HEADER:
+    {
+      return "table column header";
+    }
+    case Role::TABLE_ROW_HEADER:
+    {
+      return "table row header";
+    }
+    case Role::TEAROFF_MENU_ITEM:
+    {
+      return "tearoff menu item";
+    }
+    case Role::TERMINAL:
+    {
+      return "terminal";
+    }
+    case Role::TEXT:
+    {
+      return "text";
+    }
+    case Role::TOGGLE_BUTTON:
+    {
+      return "toggle button";
+    }
+    case Role::TOOL_BAR:
+    {
+      return "tool bar";
+    }
+    case Role::TOOL_TIP:
+    {
+      return "tool tip";
+    }
+    case Role::TREE:
+    {
+      return "tree";
+    }
+    case Role::TREE_TABLE:
+    {
+      return "tree table";
+    }
+    case Role::UNKNOWN:
+    {
+      return "unknown";
+    }
+    case Role::VIEWPORT:
+    {
+      return "viewport";
+    }
+    case Role::WINDOW:
+    {
+      return "window";
+    }
+    case Role::EXTENDED:
+    {
+      return "extended";
+    }
+    case Role::HEADER:
+    {
+      return "header";
+    }
+    case Role::FOOTER:
+    {
+      return "footer";
+    }
+    case Role::PARAGRAPH:
+    {
+      return "paragraph";
+    }
+    case Role::RULER:
+    {
+      return "ruler";
+    }
+    case Role::APPLICATION:
+    {
+      return "application";
+    }
+    case Role::AUTOCOMPLETE:
+    {
+      return "autocomplete";
+    }
+    case Role::EDITBAR:
+    {
+      return "edit bar";
+    }
+    case Role::EMBEDDED:
+    {
+      return "embedded";
+    }
+    case Role::ENTRY:
+    {
+      return "entry";
+    }
+    case Role::CHART:
+    {
+      return "chart";
+    }
+    case Role::CAPTION:
+    {
+      return "caution";
+    }
+    case Role::DOCUMENT_FRAME:
+    {
+      return "document frame";
+    }
+    case Role::HEADING:
+    {
+      return "heading";
+    }
+    case Role::PAGE:
+    {
+      return "page";
+    }
+    case Role::SECTION:
+    {
+      return "section";
+    }
+    case Role::REDUNDANT_OBJECT:
+    {
+      return "redundant object";
+    }
+    case Role::FORM:
+    {
+      return "form";
+    }
+    case Role::LINK:
+    {
+      return "link";
+    }
+    case Role::INPUT_METHOD_WINDOW:
+    {
+      return "input method window";
+    }
+    case Role::TABLE_ROW:
+    {
+      return "table row";
+    }
+    case Role::TREE_ITEM:
+    {
+      return "tree item";
+    }
+    case Role::DOCUMENT_SPREADSHEET:
+    {
+      return "document spreadsheet";
+    }
+    case Role::DOCUMENT_PRESENTATION:
+    {
+      return "document presentation";
+    }
+    case Role::DOCUMENT_TEXT:
+    {
+      return "document text";
+    }
+    case Role::DOCUMENT_WEB:
+    {
+      return "document web";
+    }
+    case Role::DOCUMENT_EMAIL:
+    {
+      return "document email";
+    }
+    case Role::COMMENT:
+    {
+      return "comment";
+    }
+    case Role::LIST_BOX:
+    {
+      return "list box";
+    }
+    case Role::GROUPING:
+    {
+      return "grouping";
+    }
+    case Role::IMAGE_MAP:
+    {
+      return "image map";
+    }
+    case Role::NOTIFICATION:
+    {
+      return "notification";
+    }
+    case Role::INFO_BAR:
+    {
+      return "info bar";
+    }
+    case Role::LEVEL_BAR:
+    {
+      return "level bar";
+    }
+    case Role::TITLE_BAR:
+    {
+      return "title bar";
+    }
+    case Role::BLOCK_QUOTE:
+    {
+      return "block quote";
+    }
+    case Role::AUDIO:
+    {
+      return "audio";
+    }
+    case Role::VIDEO:
+    {
+      return "video";
+    }
+    case Role::DEFINITION:
+    {
+      return "definition";
+    }
+    case Role::ARTICLE:
+    {
+      return "article";
+    }
+    case Role::LANDMARK:
+    {
+      return "landmark";
+    }
+    case Role::LOG:
+    {
+      return "log";
+    }
+    case Role::MARQUEE:
+    {
+      return "marquee";
+    }
+    case Role::MATH:
+    {
+      return "math";
+    }
+    case Role::RATING:
+    {
+      return "rating";
+    }
+    case Role::TIMER:
+    {
+      return "timer";
+    }
+    case Role::STATIC:
+    {
+      return "static";
+    }
+    case Role::MATH_FRACTION:
+    {
+      return "math fraction";
+    }
+    case Role::MATH_ROOT:
+    {
+      return "math root";
+    }
+    case Role::SUBSCRIPT:
+    {
+      return "subscript";
+    }
+    case Role::SUPERSCRIPT:
+    {
+      return "superscript";
+    }
+    case Role::_COUNT:
+    {
+      break;
+    }
+  }
+  return "";
+}
+
+Dali::Actor Accessible::GetCurrentlyHighlightedActor()
+{
+  return IsUp() ? Bridge::GetCurrentBridge()->data->currentlyHighlightedActor : Dali::Actor{};
+}
+
+void Accessible::SetCurrentlyHighlightedActor(Dali::Actor actor)
+{
+  if (IsUp()) {
+    Bridge::GetCurrentBridge()->data->currentlyHighlightedActor = actor;
+  }
+}
+
+Dali::Actor Accessible::GetHighlightActor()
+{
+  return IsUp() ? Bridge::GetCurrentBridge()->data->highlightActor : Dali::Actor{};
+}
+
+void Accessible::SetHighlightActor(Dali::Actor actor)
+{
+  if (IsUp()) {
+    Bridge::GetCurrentBridge()->data->highlightActor = actor;
+  }
+}
+
+void Bridge::ForceDown()
+{
+  auto highlighted = Accessible::GetCurrentlyHighlightedActor();
+  if( highlighted )
+  {
+    auto p = dynamic_cast< Component* >( Accessible::Get( highlighted ) );
+    if( p )
+      p->ClearHighlight();
+  }
+  data = {};
+}
+
+void Bridge::SetIsOnRootLevel( Accessible* o )
+{
+  o->isOnRootLevel = true;
+}
+
+class NonControlAccessible : public virtual Accessible, public virtual Collection, public virtual Component
+{
+public:
+  Dali::Actor actor;
+  bool root = false;
+
+  NonControlAccessible( Dali::Actor actor, bool root ) : actor( actor ), root( root )
+  {
+  }
+
+  Dali::Rect<> GetExtents( Dali::Accessibility::CoordType ctype ) override
+  {
+    Vector2 screenPosition = actor.GetProperty( Dali::DevelActor::Property::SCREEN_POSITION ).Get< Vector2 >();
+    Vector3 size = actor.GetCurrentSize() * actor.GetCurrentWorldScale();
+    bool positionUsesAnchorPoint =
+        actor.GetProperty( Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
+            .Get< bool >();
+    Vector3 anchorPointOffSet =
+        size * ( positionUsesAnchorPoint ? actor.GetCurrentAnchorPoint()
+                                        : AnchorPoint::TOP_LEFT );
+    Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x,
+                                screenPosition.y - anchorPointOffSet.y );
+
+    return { position.x, position.y, size.x, size.y };
+  }
+  Dali::Accessibility::ComponentLayer GetLayer() override
+  {
+    return Dali::Accessibility::ComponentLayer::WINDOW;
+  }
+  int16_t GetMdiZOrder()
+  {
+    return 0;
+  }
+  double GetAlpha()
+  {
+    return 0;
+  }
+  bool GrabFocus() override
+  {
+    return false;
+  }
+  bool GrabHighlight() override
+  {
+    return false;
+  }
+  bool ClearHighlight() override
+  {
+    return false;
+  }
+  int GetHighlightIndex() override
+  {
+    return 0;
+  }
+  bool IsScrollable() override
+  {
+    return false;
+  }
+  std::string GetName() override
+  {
+    return actor.GetName();
+  }
+  std::string GetDescription() override
+  {
+    return "";
+  }
+  Accessible* GetParent() override
+  {
+    if( GetIsOnRootLevel() )
+    {
+      auto b = GetBridgeData();
+      return b->bridge->GetApplication();
+    }
+    return Get( actor.GetParent() );
+  }
+  size_t GetChildCount() override
+  {
+    return static_cast< size_t >( actor.GetChildCount() );
+  }
+  Accessible* GetChildAtIndex( size_t index ) override
+  {
+    auto s = static_cast< size_t >( actor.GetChildCount() );
+    if( index >= s )
+      throw std::domain_error{"invalid index " + std::to_string( index ) + " for object with " + std::to_string( s ) + " children"};
+    return Get( actor.GetChildAt( static_cast< unsigned int >( index ) ) );
+  }
+  size_t GetIndexInParent() override
+  {
+    auto p = actor.GetParent();
+    if( !p )
+      return 0;
+    auto s = static_cast< size_t >( p.GetChildCount() );
+    for( auto i = 0u; i < s; ++i )
+    {
+      if( p.GetChildAt( i ) == actor )
+        return i;
+    }
+    throw std::domain_error{"actor is not a child of it's parent"};
+  }
+  Role GetRole() override
+  {
+    return root ? Role::WINDOW : Role::REDUNDANT_OBJECT;
+  }
+  States GetStates() override
+  {
+    States s;
+    if( root )
+    {
+      s[State::HIGHLIGHTABLE] = true;
+      s[State::ENABLED] = true;
+      s[State::SENSITIVE] = true;
+      s[State::SHOWING] = true;
+      s[State::VISIBLE] = true;
+      s[State::ACTIVE] = true;
+    }
+    else
+    {
+      auto t = GetParent()->GetStates();
+      s[State::SHOWING] = t[State::SHOWING];
+      s[State::VISIBLE] = t[State::VISIBLE];
+    }
+    return s;
+  }
+  Attributes GetAttributes() override
+  {
+    Dali::TypeInfo type;
+    actor.GetTypeInfo( type );
+    return {
+        {"t", type.GetName()},
+    };
+  }
+  bool DoGesture(const GestureInfo &gestureInfo) override
+  {
+      return false;
+  }
+  std::vector<Relation> GetRelationSet() override
+  {
+      return {};
+  }
+};
+
+using NonControlAccessiblesType = std::unordered_map< const Dali::RefObject*, std::unique_ptr< NonControlAccessible > >;
+static NonControlAccessiblesType nonControlAccessibles;
+
+static std::function< Accessible*( Dali::Actor ) > convertingFunctor = []( Dali::Actor ) -> Accessible* {
+  return nullptr;
+};
+
+void Accessible::RegisterControlAccessibilityGetter( std::function< Accessible*( Dali::Actor ) > functor )
+{
+  convertingFunctor = functor;
+}
+
+Accessible* Accessible::Get( Dali::Actor actor, bool root )
+{
+  if( !actor )
+  {
+    return nullptr;
+  }
+  auto p = convertingFunctor( actor );
+  if( !p )
+  {
+    if( nonControlAccessibles.empty() )
+    {
+      auto registry = Dali::Stage::GetCurrent().GetObjectRegistry();
+      registry.ObjectDestroyedSignal().Connect( []( const Dali::RefObject* obj ) {
+        nonControlAccessibles.erase( obj );
+      } );
+    }
+    auto it = nonControlAccessibles.emplace( &actor.GetBaseObject(), nullptr );
+    if( it.second )
+    {
+      it.first->second.reset( new NonControlAccessible( actor, root ) );
+    }
+    p = it.first->second.get();
+  }
+  return p;
+}
diff --git a/dali/internal/accessibility/bridge/accessibility-common.h b/dali/internal/accessibility/bridge/accessibility-common.h
new file mode 100644 (file)
index 0000000..03f3146
--- /dev/null
@@ -0,0 +1,339 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_COMMON_H
+#define DALI_INTERNAL_ACCESSIBILITY_COMMON_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/dali-adaptor-common.h>
+#include <dali/internal/accessibility/bridge/dbus.h>
+#include <dali/internal/accessibility/bridge/dbus-locators.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+
+#define A11yDbusName "org.a11y.Bus"
+#define A11yDbusPath "/org/a11y/bus"
+#define A11yDbusStatusInterface "org.a11y.Status"
+#define AtspiDbusNameRegistry "org.a11y.atspi.Registry"
+#define AtspiDbusPathRoot "/org/a11y/atspi/accessible/root"
+#define AtspiDbusInterfaceSocket "org.a11y.atspi.Socket"
+#define AtspiPath "/org/a11y/atspi/accessible"
+#define AtspiDbusInterfaceAccessible "org.a11y.atspi.Accessible"
+#define AtspiDbusInterfaceAction "org.a11y.atspi.Action"
+#define AtspiDbusInterfaceApplication "org.a11y.atspi.Application"
+#define AtspiDbusInterfaceCollection "org.a11y.atspi.Collection"
+#define AtspiDbusInterfaceComponent "org.a11y.atspi.Component"
+#define AtspiDbusInterfaceDocument "org.a11y.atspi.Document"
+#define AtspiDbusInterfaceEditableText "org.a11y.atspi.EditableText"
+#define AtspiDbusInterfaceEventKeyboard "org.a11y.atspi.Event.Keyboard"
+#define AtspiDbusInterfaceEventMouse "org.a11y.atspi.Event.Mouse"
+#define AtspiDbusInterfaceEventObject "org.a11y.atspi.Event.Object"
+#define AtspiDbusInterfaceHyperlink "org.a11y.atspi.Hyperlink"
+#define AtspiDbusInterfaceHypertext "org.a11y.atspi.Hypertext"
+#define AtspiDbusInterfaceImage "org.a11y.atspi.Image"
+#define AtspiDbusInterfaceSelection "org.a11y.atspi.Selection"
+#define AtspiDbusInterfaceTable "org.a11y.atspi.Table"
+#define AtspiDbusInterfaceTableCell "org.a11y.atspi.TableCell"
+#define AtspiDbusInterfaceText "org.a11y.atspi.Text"
+#define AtspiDbusInterfaceValue "org.a11y.atspi.Value"
+#define AtspiDbusInterfaceSocket "org.a11y.atspi.Socket"
+#define AtspiDbusInterfaceEventWindow "org.a11y.atspi.Event.Window"
+
+#define AtspiDbusPathDec "/org/a11y/atspi/registry/deviceeventcontroller"
+#define AtspiDbusInterfaceDec "org.a11y.atspi.DeviceEventController"
+#define AtspiDbusInterfaceDeviceEventListener "org.a11y.atspi.DeviceEventListener"
+
+#define DirectReadingDBusName "org.tizen.ScreenReader"
+#define DirectReadingDBusPath "/org/tizen/DirectReading"
+#define DirectReadingDBusInterface "org.tizen.DirectReading"
+
+struct ObjectPath;
+
+/**
+ * @brief Enumeration used for quering Accessibility objects
+ */
+enum class MatchType : int32_t
+{
+  INVALID,
+  ALL,
+  ANY,
+  NONE, //FIXME Underscore was added because "None" has been defined in another library
+  EMPTY
+};
+
+/**
+ * @brief Enumeration used for quering Accessibility objects
+ *
+ * SortOrder::Canonical uses breadth-first search and sort objects in order of indexes in parent
+ * SortOrder::ReverseCanonical uses SortOrder::Canonical and reverse collection
+ * The rest of orders is not supported.
+ */
+enum class SortOrder : uint32_t
+{
+  INVALID,
+  CANONICAL,
+  FLOW,
+  TAB,
+  REVERSE_CANONICAL,
+  REVERSE_FLOW,
+  REVERSE_TAB,
+  LAST_DEFINED
+};
+
+namespace DBus
+{
+class CurrentBridgePtr
+{
+  static Dali::Accessibility::Bridge*& get()
+  {
+    static thread_local Dali::Accessibility::Bridge* b = nullptr;
+    return b;
+  }
+  Dali::Accessibility::Bridge* prev;
+  CurrentBridgePtr( const CurrentBridgePtr& ) = delete;
+  CurrentBridgePtr( CurrentBridgePtr&& ) = delete;
+  CurrentBridgePtr& operator=( const CurrentBridgePtr& ) = delete;
+  CurrentBridgePtr& operator=( CurrentBridgePtr&& ) = delete;
+
+public:
+  CurrentBridgePtr( Dali::Accessibility::Bridge* b ) : prev( get() ) { get() = b; }
+  ~CurrentBridgePtr() { get() = prev; }
+
+  static Dali::Accessibility::Bridge* current() { return get(); }
+};
+
+namespace detail
+{
+template < typename T >
+struct signature_accessible_impl
+{
+  using subtype = std::pair< std::string, ObjectPath >;
+
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "AtspiAccessiblePtr";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "(so)";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, T* t )
+  {
+    if( t )
+    {
+      auto v = t->GetAddress();
+      signature< subtype >::set( iter, {v.GetBus(), ObjectPath{std::string{ATSPI_PREFIX_PATH} + v.GetPath()}} );
+    }
+    else
+    {
+      signature< subtype >::set( iter, {"", ObjectPath{ATSPI_NULL_PATH}} );
+    }
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, T*& v )
+  {
+    subtype tmp;
+    if( !signature< subtype >::get( iter, tmp ) )
+      return false;
+    if( tmp.second.value == ATSPI_NULL_PATH )
+    {
+      v = nullptr;
+      return true;
+    }
+    if( tmp.second.value.substr( 0, strlen( ATSPI_PREFIX_PATH ) ) != ATSPI_PREFIX_PATH )
+      return false;
+    auto b = CurrentBridgePtr::current();
+    if( b->GetBusName() != tmp.first )
+      return false;
+    v = b->FindByPath( tmp.second.value.substr( strlen( ATSPI_PREFIX_PATH ) ) );
+    return v != nullptr;
+  }
+};
+
+template <>
+struct signature< Dali::Accessibility::Accessible* > : public signature_accessible_impl< Dali::Accessibility::Accessible >
+{
+};
+
+template <>
+struct signature< Dali::Accessibility::Address >
+{
+  using subtype = std::pair< std::string, ObjectPath >;
+
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "AtspiAccessiblePtr";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "(so)";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const Dali::Accessibility::Address& v )
+  {
+    if( v )
+    {
+      signature< subtype >::set( iter, {v.GetBus(), ObjectPath{std::string{ATSPI_PREFIX_PATH} + v.GetPath()}} );
+    }
+    else
+    {
+      signature< subtype >::set( iter, {v.GetBus(), ObjectPath{ATSPI_NULL_PATH}} );
+    }
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, Dali::Accessibility::Address& v )
+  {
+    subtype tmp;
+    if( !signature< subtype >::get( iter, tmp ) )
+      return false;
+    if( tmp.second.value == ATSPI_NULL_PATH )
+    {
+      v = {};
+      return true;
+    }
+    if( tmp.second.value.substr( 0, strlen( ATSPI_PREFIX_PATH ) ) != ATSPI_PREFIX_PATH )
+      return false;
+    v = {std::move( tmp.first ), tmp.second.value.substr( strlen( ATSPI_PREFIX_PATH ) )};
+    return true;
+  }
+};
+
+template <>
+struct signature< Dali::Accessibility::States >
+{
+  using subtype = std::array< uint32_t, 2 >;
+
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return signature< subtype >::name();
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return signature< subtype >::sig();
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const Dali::Accessibility::States& v )
+  {
+    signature< subtype >::set( iter, v.GetRawData() );
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, Dali::Accessibility::States& v )
+  {
+    subtype tmp;
+    if( !signature< subtype >::get( iter, tmp ) )
+      return false;
+    v = Dali::Accessibility::States{tmp};
+    return true;
+  }
+};
+}
+}
+
+struct _Logger
+{
+  const char* file;
+  int line;
+  std::ostringstream tmp;
+
+  _Logger( const char* f, int l ) : file( f ), line( l ) {}
+
+  ~_Logger()
+  {
+    Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s:%d: %s", file, line, tmp.str().c_str() );
+  }
+
+  template < typename T >
+  _Logger& operator<<( T&& t )
+  {
+    tmp << std::forward< T >( t );
+    return *this;
+  }
+};
+
+struct _LoggerEmpty
+{
+  template < typename T >
+  _LoggerEmpty& operator<<( T&& t )
+  {
+    return *this;
+  }
+};
+
+struct _LoggerScope
+{
+  const char* file;
+  int line;
+
+  _LoggerScope( const char* f, int l ) : file( f ), line( l )
+  {
+    Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s:%d: +", file, line );
+  }
+  ~_LoggerScope()
+  {
+    Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s:%d: -", file, line );
+  }
+};
+
+#define LOG() _Logger( __FILE__, __LINE__ )
+#define SCOPE() _LoggerScope _l##__LINE__( __FILE__, __LINE__ )
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_COMMON_H
diff --git a/dali/internal/accessibility/bridge/accessible.cpp b/dali/internal/accessibility/bridge/accessible.cpp
new file mode 100644 (file)
index 0000000..c30116d
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+
+//INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/accessibility-common.h>
+#include <third-party/libunibreak/wordbreak.h>
+#include <third-party/libunibreak/linebreak.h>
+
+using namespace Dali::Accessibility;
+
+std::vector< std::string > Accessible::GetInterfaces()
+{
+  std::vector< std::string > tmp;
+  tmp.push_back( AtspiDbusInterfaceAccessible );
+  if( dynamic_cast< Collection* >( this ) )
+    tmp.push_back( AtspiDbusInterfaceCollection );
+  if( dynamic_cast< Text* >( this ) )
+    tmp.push_back( AtspiDbusInterfaceText );
+  if( dynamic_cast< Value* >( this ) )
+    tmp.push_back( AtspiDbusInterfaceValue );
+  if( dynamic_cast< Component* >( this ) )
+    tmp.push_back( AtspiDbusInterfaceComponent );
+  if( auto d = dynamic_cast< Action* >( this ) )
+  {
+    if( d->GetActionCount() > 0 )
+      tmp.push_back( AtspiDbusInterfaceAction );
+  }
+  return tmp;
+}
+
+Accessible::Accessible()
+{
+}
+
+Accessible::~Accessible()
+{
+  auto b = bridgeData.lock();
+  if( b )
+    b->knownObjects.erase( this );
+}
+
+void Accessible::EmitActiveDescendantChanged( Accessible* obj, Accessible *child )
+{
+  if( auto b = GetBridgeData() )
+  {
+    b->bridge->EmitActiveDescendantChanged( obj, child );
+  }
+}
+
+void Accessible::EmitStateChanged( State state, int newValue1, int newValue2 )
+{
+  if( auto b = GetBridgeData() )
+  {
+    b->bridge->EmitStateChanged( this, state, newValue1, newValue2 );
+  }
+}
+
+void Accessible::EmitShowing( bool showing )
+{
+  if( auto b = GetBridgeData() )
+  {
+    b->bridge->EmitStateChanged( this, State::SHOWING, showing ? 1 : 0, 0 );
+  }
+}
+
+void Accessible::EmitVisible( bool visible )
+{
+  if( auto b = GetBridgeData() )
+  {
+    b->bridge->EmitStateChanged( this, State::VISIBLE, visible ? 1 : 0, 0 );
+  }
+}
+
+void Accessible::EmitHighlighted( bool set )
+{
+  if( auto b = GetBridgeData() )
+  {
+    b->bridge->EmitStateChanged( this, State::HIGHLIGHTED, set ? 1 : 0, 0 );
+  }
+}
+
+void Accessible::EmitFocused( bool set )
+{
+  if ( auto b = GetBridgeData() ) {
+    b->bridge->EmitStateChanged( this, State::FOCUSED, set ? 1 : 0, 0 );
+  }
+}
+void Accessible::EmitTextInserted( unsigned int position, unsigned int length, const std::string &content )
+{
+  if ( auto b = GetBridgeData() ) {
+    b->bridge->EmitTextChanged( this, TextChangedState::INSERT, position, length, content );
+  }
+}
+void Accessible::EmitTextDeleted( unsigned int position, unsigned int length, const std::string &content )
+{
+  if ( auto b = GetBridgeData() ) {
+    b->bridge->EmitTextChanged( this, TextChangedState::DELETE, position, length, content );
+  }
+}
+void Accessible::EmitTextCaretMoved( unsigned int cursorPosition )
+{
+  if ( auto b = GetBridgeData() ) {
+    b->bridge->EmitCaretMoved( this, cursorPosition );
+  }
+}
+void Accessible::Emit( WindowEvent we, unsigned int detail1 )
+{
+  if( auto b = GetBridgeData() )
+  {
+    b->bridge->Emit( this, we, detail1 );
+  }
+}
+void Accessible::Emit( ObjectPropertyChangeEvent ev )
+{
+  if( auto b = GetBridgeData() )
+  {
+    b->bridge->Emit( this, ev );
+  }
+}
+
+void Accessible::EmitBoundsChanged( Rect<> rect )
+{
+  if( auto b = GetBridgeData() )
+  {
+    b->bridge->EmitBoundsChanged( this, rect );
+  }
+}
+
+std::vector< Accessible* > Accessible::GetChildren()
+{
+  std::vector< Accessible* > tmp( GetChildCount() );
+  for( auto i = 0u; i < tmp.size(); ++i )
+  {
+    tmp[i] = GetChildAtIndex( i );
+  }
+  return tmp;
+}
+
+std::shared_ptr< Bridge::Data > Accessible::GetBridgeData()
+{
+  auto b = bridgeData.lock();
+  if( !b )
+  {
+    auto p = Bridge::GetCurrentBridge();
+    b = p->data;
+  }
+  return b;
+}
+
+Address Accessible::GetAddress()
+{
+  auto b = bridgeData.lock();
+  if( !b )
+  {
+    b = GetBridgeData();
+    if ( b )
+      b->bridge->RegisterOnBridge( this );
+  }
+  std::ostringstream tmp;
+  tmp << this;
+  return {b ? b->busName : "", tmp.str() };
+}
+
+void Bridge::RegisterOnBridge( Accessible* obj )
+{
+  assert( !obj->bridgeData.lock() || obj->bridgeData.lock() == data );
+  if( !obj->bridgeData.lock() )
+  {
+    assert( data );
+    data->knownObjects.insert( obj );
+    obj->bridgeData = data;
+  }
+}
+
+bool Accessible::IsProxy()
+{
+  return false;
+}
+
+Accessible* Accessible::GetDefaultLabel()
+{
+       return this;
+}
+
+void Accessible::NotifyAccessibilityStateChange( Dali::Accessibility::States states, bool doRecursive )
+{
+  if( auto b = GetBridgeData() )
+  {
+    auto s = GetStates() & states;
+    for( auto i = 0u; i < s.size(); i++ )
+    {
+      auto index = static_cast< Dali::Accessibility::State >( i );
+      if( s[index] )
+        b->bridge->EmitStateChanged( this, index, 1, 0 );
+    }
+    if( doRecursive )
+    {
+      auto children = GetChildren();
+      for( auto c : children )
+        c->NotifyAccessibilityStateChange( states, doRecursive );
+    }
+  }
+}
+
+void Accessible::FindWordSeparationsUtf8( const utf8_t *s, size_t length, const char *language, char *breaks )
+{
+  set_wordbreaks_utf8( s, length, language, breaks );
+}
+
+void Accessible::FindLineSeparationsUtf8( const utf8_t *s, size_t length, const char *language, char *breaks )
+{
+  set_linebreaks_utf8( s, length, language, breaks );
+}
diff --git a/dali/internal/accessibility/bridge/bridge-accessible.cpp b/dali/internal/accessibility/bridge/bridge-accessible.cpp
new file mode 100644 (file)
index 0000000..c7cbcb3
--- /dev/null
@@ -0,0 +1,803 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/bridge-accessible.h>
+
+// EXTERNAL INCLUDES
+#include <iostream>
+
+//comment out 2 lines below to get more logs
+#undef LOG
+#define LOG() _LoggerEmpty()
+
+using namespace Dali::Accessibility;
+
+#define GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH 10000
+
+BridgeAccessible::BridgeAccessible()
+{
+}
+
+void BridgeAccessible::RegisterInterfaces()
+{
+  DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceAccessible};
+  AddGetPropertyToInterface( desc, "ChildCount", &BridgeAccessible::GetChildCount );
+  AddGetPropertyToInterface( desc, "Name", &BridgeAccessible::GetName );
+  AddGetPropertyToInterface( desc, "Description", &BridgeAccessible::GetDescription );
+  AddGetPropertyToInterface( desc, "Parent", &BridgeAccessible::GetParent );
+  AddFunctionToInterface( desc, "GetRole", &BridgeAccessible::GetRole );
+  AddFunctionToInterface( desc, "GetRoleName", &BridgeAccessible::GetRoleName );
+  AddFunctionToInterface( desc, "GetLocalizedRoleName", &BridgeAccessible::GetLocalizedRoleName );
+  AddFunctionToInterface( desc, "GetState", &BridgeAccessible::GetStates );
+  AddFunctionToInterface( desc, "GetAttributes", &BridgeAccessible::GetAttributes );
+  AddFunctionToInterface( desc, "GetInterfaces", &BridgeAccessible::GetInterfaces );
+  AddFunctionToInterface( desc, "GetChildAtIndex", &BridgeAccessible::GetChildAtIndex );
+  AddFunctionToInterface( desc, "GetChildren", &BridgeAccessible::GetChildren );
+  AddFunctionToInterface( desc, "GetIndexInParent", &BridgeAccessible::GetIndexInParent );
+  AddFunctionToInterface( desc, "GetNavigableAtPoint", &BridgeAccessible::GetNavigableAtPoint );
+  AddFunctionToInterface( desc, "GetNeighbor", &BridgeAccessible::GetNeighbor );
+  AddFunctionToInterface( desc, "GetDefaultLabelInfo", &BridgeAccessible::GetDefaultLabelInfo );
+  AddFunctionToInterface( desc, "DoGesture", &BridgeAccessible::DoGesture );
+  AddFunctionToInterface( desc, "GetReadingMaterial", &BridgeAccessible::GetReadingMaterial );
+  AddFunctionToInterface( desc, "GetRelationSet", &BridgeAccessible::GetRelationSet );
+  dbusServer.addInterface( "/", desc, true );
+}
+
+static bool AcceptObjectCheckRole( Component* obj )
+{
+  if( !obj )
+    return false;
+  switch( obj->GetRole() )
+  {
+    case Role::APPLICATION:
+    case Role::FILLER:
+    case Role::SCROLL_PANE:
+    case Role::SPLIT_PANE:
+    case Role::WINDOW:
+    case Role::IMAGE:
+    case Role::IMAGE_MAP:
+    case Role::LIST:
+    case Role::ICON:
+    case Role::TOOL_BAR:
+    case Role::REDUNDANT_OBJECT:
+    case Role::COLOR_CHOOSER:
+    case Role::TREE_TABLE:
+    case Role::PAGE_TAB_LIST:
+    case Role::PAGE_TAB:
+    case Role::SPIN_BUTTON:
+    case Role::INPUT_METHOD_WINDOW:
+    case Role::EMBEDDED:
+    case Role::INVALID:
+    case Role::NOTIFICATION:
+    case Role::DATE_EDITOR:
+    case Role::TABLE:
+    {
+      return false;
+    }
+    default:
+    {
+      break;
+    }
+  }
+
+  return true;
+}
+
+static bool AcceptObjectCheckRelations( Component* obj)
+{
+  auto r = obj->GetRelationSet();
+
+  for (const auto& it : r)
+    if (it.relationType == RelationType::CONTROLLED_BY)
+      return false;
+
+  return true;
+}
+
+static Component* GetScrollableParent( Accessible* obj )
+{
+  while( obj )
+  {
+    obj = obj->GetParent();
+    auto comp = dynamic_cast< Component* >( obj );
+    if( comp && comp->IsScrollable() )
+      return comp;
+  }
+  return nullptr;
+}
+
+static bool ObjectIsItem( Component* obj )
+{
+  if( !obj )
+    return false;
+  auto role = obj->GetRole();
+  return role == Role::LIST_ITEM || role == Role::MENU_ITEM;
+}
+
+static bool ObjectIsCollapsed( Component* obj )
+{
+  if( !obj )
+    return false;
+  const auto states = obj->GetStates();
+  return states[State::EXPANDABLE] && !states[State::EXPANDED];
+}
+
+static bool OobjectIsZeroSize( Component* obj )
+{
+  if( !obj )
+    return false;
+  auto extents = obj->GetExtents( CoordType::WINDOW );
+  return extents.height == 0 || extents.width == 0;
+}
+
+static bool AcceptObject( Component* obj )
+{
+  if( !obj )
+    return false;
+  const auto states = obj->GetStates();
+  if( !states[State::VISIBLE] )
+    return false;
+  if( !AcceptObjectCheckRole( obj ) )
+    return false;
+  if ( !AcceptObjectCheckRelations( obj ) )
+    return false;
+  //   if (CALL(get_object_in_relation_by_type, obj, ATSPI_RELATION_CONTROLLED_BY) != NULL) return 0;
+  if ( !AcceptObjectCheckRelations( obj ) )
+    return false;
+  if( !states[State::HIGHLIGHTABLE] )
+    return false;
+
+  if( GetScrollableParent( obj ) != nullptr )
+  {
+    auto parent = dynamic_cast< Component* >( obj->GetParent() );
+
+    if( parent )
+    {
+      return !ObjectIsItem( obj ) || !ObjectIsCollapsed( parent );
+    }
+  }
+  else
+  {
+    if( OobjectIsZeroSize( obj ) )
+    {
+      return false;
+    }
+    if( !states[State::SHOWING] )
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+static bool AcceptObject( Accessible* obj )
+{
+  auto c = dynamic_cast< Component* >( obj );
+  return AcceptObject( c );
+}
+
+static std::string objDump( Component* obj )
+{
+  if ( !obj )
+    return "nullptr";
+  std::ostringstream o;
+  auto e = obj->GetExtents( CoordType::SCREEN );
+  o << "name: " << obj->GetName() << " extent: (" << e.x << ", "
+      << e.y << "), [" << e.width << ", " << e.height << "]";
+  return o.str();
+}
+
+Component * BridgeAccessible::GetObjectInRelation( Accessible * obj, RelationType ralationType )
+{
+  if ( !obj )
+    return nullptr;
+  for ( auto &relation : obj->GetRelationSet() )
+  {
+    if ( relation.relationType == ralationType )
+    {
+      for ( auto &address : relation.targets )
+      {
+        auto component = dynamic_cast<Component*>( Find( address ) );
+        if ( component )
+          return component;
+      }
+    }
+  }
+  return nullptr;
+}
+
+static std::string makeIndent( unsigned int maxRecursionDepth )
+{
+  return std::string( GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH - maxRecursionDepth, ' ' );
+}
+
+Component* BridgeAccessible::CalculateNavigableAccessibleAtPoint( Accessible* root, Point p, CoordType cType, unsigned int maxRecursionDepth )
+{
+  if( !root || maxRecursionDepth == 0 )
+    return nullptr;
+  auto root_component = dynamic_cast< Component* >( root );
+  LOG() << "CalculateNavigableAccessibleAtPoint: checking: " << makeIndent(maxRecursionDepth) << objDump(root_component);
+
+  if( root_component && !root_component->Contains( p, cType ) )
+    return nullptr;
+
+  auto children = root->GetChildren();
+  for( auto childIt = children.rbegin(); childIt != children.rend(); childIt++ )
+  {
+    //check recursively all children first
+    auto result = CalculateNavigableAccessibleAtPoint( *childIt, p, cType, maxRecursionDepth - 1 );
+    if( result )
+      return result;
+  }
+  if( root_component )
+  {
+    //Found a candidate, all its children are already checked
+    auto controledBy = GetObjectInRelation( root_component, RelationType::CONTROLLED_BY );
+    if ( !controledBy )
+      controledBy = root_component;
+
+    if ( controledBy->IsProxy() || AcceptObject( controledBy ) )
+    {
+      LOG() << "CalculateNavigableAccessibleAtPoint: found:    " << makeIndent(maxRecursionDepth) << objDump( root_component );
+      return controledBy;
+    }
+  }
+  return nullptr;
+}
+
+BridgeAccessible::ReadingMaterialType BridgeAccessible::GetReadingMaterial()
+{
+  auto self = FindSelf();
+  auto attributes = self->GetAttributes();
+  auto name = self->GetName();
+  std::string labeledByName = "";
+  std::string textIfceName = "";
+  auto role = static_cast< uint32_t >( self->GetRole() );
+  auto states = self->GetStates();
+  auto localizedName = self->GetLocalizedRoleName();
+  auto childCount = static_cast< int32_t >( self->GetChildCount() );
+
+  double currentValue = 0.0;
+  double minimumIncrement = 0.0;
+  double maximumValue = 0.0;
+  double minimumValue = 0.0;
+
+  auto description = self->GetDescription();
+  auto indexInParent = static_cast< int32_t >( self->GetIndexInParent() );
+  bool isSelectedInParent = false;
+  bool hasCheckBoxChild = false;
+  int32_t firstSelectedChildIndex = 0;
+  int32_t selectedChildCount = 0;
+
+  for( auto i = 0u; i < static_cast< size_t >( childCount ); ++i )
+  {
+    auto q = self->GetChildAtIndex( i );
+    auto s = q->GetStates();
+    if( s[State::SELECTABLE] )
+    {
+      ++selectedChildCount;
+      if( s[State::SELECTED] )
+      {
+        if( firstSelectedChildIndex < 0 )
+          firstSelectedChildIndex = static_cast< int32_t >( i );
+      }
+    }
+    if( q->GetRole() == Role::CHECK_BOX )
+      hasCheckBoxChild = true;
+  }
+
+  int32_t listChildrenCount = 0;
+  Accessible* parent = self->GetParent();
+  auto parentStateSet = parent ? parent->GetStates() : States{};
+  auto parentChildCount = parent ? static_cast< int32_t >( parent->GetChildCount() ) : 0;
+  auto parentRole = static_cast< uint32_t >( parent ? parent->GetRole() : Role{} );
+  Accessible* describedByObject = nullptr;
+
+  return {
+      attributes,
+      name,
+      labeledByName,
+      textIfceName,
+      role,
+      states,
+      localizedName,
+      childCount,
+      currentValue,
+      minimumIncrement,
+      maximumValue,
+      minimumValue,
+      description,
+      indexInParent,
+      isSelectedInParent,
+      hasCheckBoxChild,
+      listChildrenCount,
+      firstSelectedChildIndex,
+      parent,
+      parentStateSet,
+      parentChildCount,
+      parentRole,
+      selectedChildCount,
+      describedByObject};
+}
+
+DBus::ValueOrError< bool > BridgeAccessible::DoGesture( Dali::Accessibility::Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, Dali::Accessibility::GestureState state, uint32_t eventTime )
+{
+ return FindSelf()->DoGesture( Dali::Accessibility::GestureInfo {type, xBeg, xEnd, yBeg, yEnd, state, eventTime});
+}
+
+DBus::ValueOrError< Accessible*, uint8_t, Accessible* > BridgeAccessible::GetNavigableAtPoint( int32_t x, int32_t y, uint32_t coordType )
+{
+  Accessible* deputy = nullptr;
+  auto accessible = FindSelf();
+  auto cType = static_cast< CoordType >( coordType );
+  LOG() << "GetNavigableAtPoint: " << x << ", " << y << " type: " << coordType;
+  auto component = CalculateNavigableAccessibleAtPoint( accessible, {x, y}, cType, GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH );
+  bool recurse = false;
+  if( component )
+  {
+    const auto states = component->GetStates();
+    if( states[State::MODAL] )
+    {
+      component = nullptr;
+    }
+  }
+  if( component )
+  {
+    recurse = component->IsProxy();
+  }
+  //TODO: add deputy
+  return {component, recurse, deputy};
+}
+
+static bool CheckChainEndWithAttribute( Accessible* obj, unsigned char forward )
+{
+  if( !obj )
+    return false;
+  auto attrs = obj->GetAttributes();
+  for( auto& attr : attrs )
+  {
+    if( attr.first == "relation_chain_end" )
+    {
+      if( ( attr.second == "prev,end" && forward == 0 ) || ( attr.second == "next,end" && forward == 1 ) || attr.second == "prev,next,end" )
+      {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+static Accessible* DeputyOfProxyInParentGet( Accessible* obj )
+{
+  return nullptr;
+  // if (!obj)
+  //   return nullptr;
+  // Accessible *deputy = nullptr;
+  // auto children = obj->GetChildren();
+  // unsigned int index = 0;
+  // for (auto child : children) {
+  //   if (child->IsProxy()) {
+  //           if (index == 0) {
+  //                   //WRN("Proxy does not have deputy object");
+  //                   break;
+  //           }
+  //           deputy = children[index - 1];
+  //           break;
+  //   }
+  //   index++;
+  // }
+  // return deputy;
+}
+
+Accessible* BridgeAccessible::GetCurrentlyHighlighted()
+{
+  //TODO: add currently highlighted object
+  return nullptr;
+}
+
+std::vector< Accessible* > BridgeAccessible::ValidChildrenGet( const std::vector< Accessible* >& children, Accessible* start, Accessible* root )
+{
+  /* condition to find first(last) object regardless of scrollable parent.
+      looping navigation does not care scrollable parent.
+      1. currently highlighted object exists
+      2. both start and root are same */
+
+  /* TODO: add code, we need a scrollable implementation first
+       Accessible *current = GetCurrentlyHighlighted();
+   if (current && start == root) return children;
+   if(children.size() == 0) return {};
+
+   Eo *child = children[0];
+
+   if (child)
+     {
+        Evas_Coord x = 0, y = 0, w = 0, h = 0;
+        Evas_Coord sx = 0, sy = 0, sw = 0, sh = 0;
+
+        if (_new_scrollable_parent_viewport_geometry_get(child, start,
+                                                   &sx, &sy, &sw, &sh))
+          {
+             Eina_List *l, *l_next;
+             EINA_LIST_FOREACH_SAFE(children, l, l_next, child)
+               {
+                  eo_do(child,
+                        elm_interface_atspi_component_extents_get(EINA_FALSE,
+                                                             &x, &y, &w, &h));
+                  if (w == 0 || h == 0 ||
+                      !ELM_RECTS_INTERSECT(x, y, w, h, sx, sy, sw, sh))
+                     children = eina_list_remove_list(children, l);
+               }
+          }
+     }
+     */
+  return children;
+}
+
+static bool DeputyIs( Accessible* obj )
+{
+  //TODO: add deputy
+  return false;
+}
+
+static Accessible* ProxyInParentGet( Accessible* obj )
+{
+  if( !obj )
+    return nullptr;
+  auto children = obj->GetChildren();
+  for( auto& child : children )
+  {
+    if( child->IsProxy() )
+      return child;
+  }
+  return nullptr;
+}
+
+static bool ObjectRoleIsAcceptableWhenNavigatingNextPrev( Accessible* obj )
+{
+  if( !obj )
+    return false;
+  auto role = obj->GetRole();
+  return role != Role::POPUP_MENU && role != Role::DIALOG;
+}
+
+template < class T >
+struct CycleDetection
+{
+  CycleDetection( const T value ) : key( value ), currentSearchSize( 1 ), counter( 1 ) {}
+  bool check( const T value )
+  {
+    if( key == value )
+      return true;
+    if( --counter == 0 )
+    {
+      currentSearchSize <<= 1;
+      if( currentSearchSize == 0 )
+        return true; // UNDEFINED BEHAVIOR
+      counter = currentSearchSize;
+      key = value;
+    }
+    return false;
+  }
+  T key;
+  unsigned int currentSearchSize;
+  unsigned int counter;
+};
+
+static Accessible* FindNonDefunctChild( const std::vector< Accessible* >& children, unsigned int currentIndex, unsigned char forward )
+{
+  unsigned int childrenCount = children.size();
+  for( ; currentIndex < childrenCount; forward ? ++currentIndex : --currentIndex )
+  {
+    Accessible* n = children[currentIndex];
+    if( n && !n->GetStates()[State::DEFUNCT] )
+      return n;
+  }
+  return nullptr;
+}
+
+static Accessible* DirectionalDepthFirstSearchTryNonDefunctChild( Accessible* node, const std::vector< Accessible* >& children, unsigned char forward )
+{
+  if( !node )
+    return nullptr;
+  auto childrenCount = children.size();
+  if( childrenCount > 0 )
+  {
+    const bool isShowing = GetScrollableParent( node ) == nullptr ? node->GetStates()[State::SHOWING] : true;
+    if( isShowing )
+    {
+      return FindNonDefunctChild( children, forward ? 0 : childrenCount - 1, forward );
+    }
+  }
+  return nullptr;
+}
+
+Accessible* BridgeAccessible::GetNextNonDefunctSibling( Accessible* obj, Accessible* start, Accessible* root, unsigned char forward )
+{
+  if( !obj )
+    return nullptr;
+  auto parent = obj->GetParent();
+  if( !parent )
+    return nullptr;
+
+  auto children = ValidChildrenGet( parent->GetChildren(), start, root );
+
+  unsigned int children_count = children.size();
+  if( children_count == 0 )
+  {
+    return nullptr;
+  }
+  unsigned int current = 0;
+  for( ; current < children_count && children[current] != obj; ++current )
+    ;
+  if( current >= children_count )
+  {
+    return nullptr;
+  }
+  forward ? ++current : --current;
+  auto ret = FindNonDefunctChild( children, current, forward );
+  return ret;
+}
+
+Accessible* BridgeAccessible::DirectionalDepthFirstSearchTryNonDefunctSibling( bool& all_children_visited, Accessible* node, Accessible* start, Accessible* root, unsigned char forward )
+{
+  while( true )
+  {
+    Accessible* sibling = GetNextNonDefunctSibling( node, start, root, forward );
+    if( sibling )
+    {
+      node = sibling;
+      all_children_visited = false;
+      break;
+    }
+    // walk up...
+    node = node->GetParent();
+    if( node == nullptr || node == root )
+      return nullptr;
+
+    // in backward traversing stop the walk up on parent
+    if( !forward )
+      break;
+  }
+  return node;
+}
+
+Accessible* BridgeAccessible::CalculateNeighbor( Accessible* root, Accessible* start, unsigned char forward, BridgeAccessible::GetNeighborSearchMode search_mode )
+{
+  if( start && CheckChainEndWithAttribute( start, forward ) )
+    return start;
+  if( root && root->GetStates()[State::DEFUNCT] )
+    return NULL;
+  if( start && start->GetStates()[State::DEFUNCT] )
+  {
+    start = NULL;
+    forward = 1;
+  }
+
+  if( search_mode == BridgeAccessible::GetNeighborSearchMode::recurseToOutside )
+  {
+    /* This only works if we navigate backward, and it is not possible to
+                find in embedded process. In this case the deputy should be used */
+    return DeputyOfProxyInParentGet( start );
+  }
+
+  Accessible* node = start ? start : root;
+  if( !node )
+    return nullptr;
+
+  // initialization of all-children-visited flag for start node - we assume
+  // that when we begin at start node and we navigate backward, then all children
+  // are visited, so navigation will ignore start's children and go to
+  // previous sibling available.
+  /* Regarding condtion (start != root):
+        The last object can be found only if all_children_visited is false.
+        The start is same with root, when looking for the last object. */
+  bool all_children_visited = ( start != root ) && ( search_mode != BridgeAccessible::GetNeighborSearchMode::recurseFromRoot && !forward );
+  // true, if starting element should be ignored. this is only used in rare case of
+  // recursive search failing to find an object.
+  // consider tree, where element A on bus BUS_A has child B on bus BUS_B. when going "next" from
+  // element A algorithm has to descend into BUS_B and search element B and its children. this is done
+  // by returning to our caller object B with special flag set (meaning - continue the search from B on bus BUS_B).
+  // if next object will be found there (on BUS_B), then search ends. but if not, then our caller will find it out
+  // and will call us again with object A and flag search_mode set to NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING.
+  // this flag means, that object A was already checked previously and we should skip it and its children.
+  bool force_next = ( search_mode == BridgeAccessible::GetNeighborSearchMode::continueAfterFailedRecursion );
+
+  CycleDetection< Accessible* > cycleDetection( node );
+  while( node )
+  {
+    if( node->GetStates()[State::DEFUNCT] )
+      return nullptr;
+
+    // always accept proxy object from different world
+    if( !force_next && node->IsProxy() )
+      return node;
+
+    auto children = node->GetChildren();
+    children = ValidChildrenGet( children, start, root );
+
+    // do accept:
+    // 1. not start node
+    // 2. parent after all children in backward traversing
+    // 3. Nodes with roles: ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_POPUP_MENU and ATSPI_ROLE_DIALOG, only when looking for first or last element.
+    //    Objects with those roles shouldnt be reachable, when navigating next / prev.
+    bool all_children_visited_or_moving_forward = ( children.size() == 0 || forward || all_children_visited );
+    if( !force_next && node != start && all_children_visited_or_moving_forward && AcceptObject( node ) )
+    {
+      if( start == NULL || ObjectRoleIsAcceptableWhenNavigatingNextPrev( node ) )
+        return node;
+    }
+
+    Accessible* next_related_in_direction = !force_next ? GetObjectInRelation( node, forward ? RelationType::FLOWS_TO : RelationType::FLOWS_FROM ) : nullptr;
+    /* force_next means that the search_mode is NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING
+                       in this case the node is elm_layout which is parent of proxy object.
+                       There is an access object working for the proxy object, and the access
+                       object could have relation information. This relation information should
+                       be checked first before using the elm_layout as a node. */
+    if( force_next && forward )
+    {
+      auto deputy = DeputyOfProxyInParentGet( node );
+      next_related_in_direction =
+          GetObjectInRelation( deputy, forward ? RelationType::FLOWS_TO : RelationType::FLOWS_FROM );
+    }
+
+    if( next_related_in_direction && start->GetStates()[State::DEFUNCT] )
+      next_related_in_direction = NULL;
+    unsigned char want_cycle_detection = 0;
+    if( next_related_in_direction )
+    {
+      /* Check next_related_in_direction is deputy object */
+      Accessible* parent;
+      if( !forward )
+      {
+        /* If the prev object is deputy, then go to inside of its proxy first */
+        if( DeputyIs( next_related_in_direction ) )
+        {
+          parent = next_related_in_direction->GetParent();
+          next_related_in_direction = ProxyInParentGet( parent );
+        }
+      }
+      else
+      {
+        /* If current object is deputy, and it has relation next object,
+                   then do not use the relation next object, and use proxy first */
+        if( DeputyIs( node ) )
+        {
+          parent = node->GetParent();
+          next_related_in_direction = ProxyInParentGet( parent );
+        }
+      }
+      node = next_related_in_direction;
+      want_cycle_detection = 1;
+    }
+    else
+    {
+      auto child = !force_next && !all_children_visited ? DirectionalDepthFirstSearchTryNonDefunctChild( node, children, forward ) : nullptr;
+      if( child )
+      {
+        want_cycle_detection = 1;
+      }
+      else
+      {
+        if( !force_next && node == root )
+          return NULL;
+        all_children_visited = true;
+        child = DirectionalDepthFirstSearchTryNonDefunctSibling( all_children_visited, node, start, root, forward );
+      }
+      node = child;
+    }
+    force_next = 0;
+    if( want_cycle_detection && cycleDetection.check( node ) )
+    {
+      return NULL;
+    }
+  }
+  return NULL;
+}
+
+DBus::ValueOrError< Accessible*, uint8_t > BridgeAccessible::GetNeighbor( std::string rootPath, int32_t direction, int32_t search_mode )
+{
+  auto start = FindSelf();
+  rootPath = StripPrefix( rootPath );
+  auto root = !rootPath.empty() ? Find( rootPath ) : nullptr;
+  auto accessible = CalculateNeighbor( root, start, direction == 1, static_cast< GetNeighborSearchMode >( search_mode ) );
+  unsigned char recurse = 0;
+  if( accessible )
+  {
+    recurse = accessible->IsProxy();
+  }
+  return {accessible, recurse};
+}
+
+Accessible* BridgeAccessible::GetParent()
+{
+  // NOTE: currently bridge supports single application root element.
+  // only element set as application root might return nullptr from GetParent
+  // if you want more, then you need to change setApplicationRoot to
+  // add/remove ApplicationRoot and make roots a vector.
+  auto p = FindSelf()->GetParent();
+  assert( p );
+  return p;
+}
+DBus::ValueOrError< std::vector< Accessible* > > BridgeAccessible::GetChildren()
+{
+  return FindSelf()->GetChildren();
+}
+std::string BridgeAccessible::GetDescription()
+{
+  return FindSelf()->GetDescription();
+}
+DBus::ValueOrError< uint32_t > BridgeAccessible::GetRole()
+{
+  return static_cast< unsigned int >( FindSelf()->GetRole() );
+}
+DBus::ValueOrError< std::string > BridgeAccessible::GetRoleName()
+{
+  return FindSelf()->GetRoleName();
+}
+DBus::ValueOrError< std::string > BridgeAccessible::GetLocalizedRoleName()
+{
+  return FindSelf()->GetLocalizedRoleName();
+}
+DBus::ValueOrError< int32_t > BridgeAccessible::GetIndexInParent()
+{
+  return FindSelf()->GetIndexInParent();
+}
+DBus::ValueOrError< std::array< uint32_t, 2 > > BridgeAccessible::GetStates()
+{
+  return FindSelf()->GetStates().GetRawData();
+}
+DBus::ValueOrError< std::unordered_map< std::string, std::string > > BridgeAccessible::GetAttributes()
+{
+  return FindSelf()->GetAttributes();
+}
+DBus::ValueOrError< std::vector< std::string > > BridgeAccessible::GetInterfaces()
+{
+  return FindSelf()->GetInterfaces();
+}
+int BridgeAccessible::GetChildCount()
+{
+  return FindSelf()->GetChildCount();
+}
+DBus::ValueOrError< Accessible* > BridgeAccessible::GetChildAtIndex( int index )
+{
+  if( index < 0 )
+    throw std::domain_error{"negative index (" + std::to_string( index ) + ")"};
+  return FindSelf()->GetChildAtIndex( static_cast< size_t >( index ) );
+}
+
+std::string BridgeAccessible::GetName()
+{
+  return FindSelf()->GetName();
+}
+
+DBus::ValueOrError< Accessible*, uint32_t , std::unordered_map< std::string, std::string > > BridgeAccessible::GetDefaultLabelInfo()
+{
+  auto defaultLabel = FindSelf()->GetDefaultLabel();
+  return {defaultLabel, static_cast< uint32_t >( defaultLabel->GetRole() ) , defaultLabel->GetAttributes()};
+}
+
+DBus::ValueOrError<std::vector< BridgeAccessible::Relation >> BridgeAccessible::GetRelationSet()
+{
+  auto relations = FindSelf()->GetRelationSet();
+  std::vector< BridgeAccessible::Relation > ret;
+
+  for (auto &it : relations)
+    ret.emplace_back(Relation{static_cast<uint32_t>(it.relationType), it.targets});
+
+  return ret;
+}
diff --git a/dali/internal/accessibility/bridge/bridge-accessible.h b/dali/internal/accessibility/bridge/bridge-accessible.h
new file mode 100644 (file)
index 0000000..9abdd36
--- /dev/null
@@ -0,0 +1,105 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_ACCESSIBLE_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_ACCESSIBLE_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <array>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+// INTERNAL INCLUDES
+#include "bridge-base.h"
+
+class BridgeAccessible : public virtual BridgeBase
+{
+protected:
+  BridgeAccessible();
+
+  void RegisterInterfaces();
+
+public:
+  enum class GetNeighborSearchMode
+  {
+    normal = 0,
+    recurseFromRoot = 1,
+    continueAfterFailedRecursion = 2,
+    recurseToOutside = 3,
+  };
+  int GetChildCount();
+  DBus::ValueOrError< Dali::Accessibility::Accessible* > GetChildAtIndex( int index );
+  Dali::Accessibility::Accessible* GetParent();
+  DBus::ValueOrError< std::vector< Dali::Accessibility::Accessible* > > GetChildren();
+  std::string GetName();
+  std::string GetDescription();
+  DBus::ValueOrError< uint32_t > GetRole();
+  DBus::ValueOrError< std::string > GetRoleName();
+  DBus::ValueOrError< std::string > GetLocalizedRoleName();
+  DBus::ValueOrError< int32_t > GetIndexInParent();
+  DBus::ValueOrError< std::array< uint32_t, 2 > > GetStates();
+  DBus::ValueOrError< std::unordered_map< std::string, std::string > > GetAttributes();
+  DBus::ValueOrError< std::vector< std::string > > GetInterfaces();
+  DBus::ValueOrError< Dali::Accessibility::Accessible*, uint8_t, Dali::Accessibility::Accessible* > GetNavigableAtPoint( int32_t x, int32_t y, uint32_t coordType );
+  DBus::ValueOrError< Dali::Accessibility::Accessible*, uint8_t > GetNeighbor( std::string root_path, int32_t direction, int32_t search_mode );
+  DBus::ValueOrError< Dali::Accessibility::Accessible*, uint32_t , std::unordered_map< std::string, std::string > > GetDefaultLabelInfo();
+  using ReadingMaterialType = DBus::ValueOrError<
+      std::unordered_map< std::string, std::string >, // attributes
+      std::string,                                    // name
+      std::string,                                    // labeledByName
+      std::string,                                    // textIfceName
+      uint32_t,
+      Dali::Accessibility::States,
+      std::string,                      // localized name
+      int32_t,                          // child count
+      double,                           // current value
+      double,                           // minimum increment
+      double,                           // maximum value
+      double,                           // minimum value
+      std::string,                      // description
+      int32_t,                          // index in parent
+      bool,                             // isSelectedInParent
+      bool,                             // hasCheckBoxChild
+      int32_t,                          // listChildrenCount
+      int32_t,                          // firstSelectedChildIndex
+      Dali::Accessibility::Accessible*, // parent
+      Dali::Accessibility::States,      // parentStateSet
+      int32_t,                          // parentChildCount
+      uint32_t,                         // parentRole
+      int32_t,                          // selectedChildCount,
+      Dali::Accessibility::Accessible*  // describedByObject
+      >;
+
+  ReadingMaterialType GetReadingMaterial();
+
+  DBus::ValueOrError< bool > DoGesture( Dali::Accessibility::Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, Dali::Accessibility::GestureState state, uint32_t eventTime );
+
+  using Relation = std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > >;
+  DBus::ValueOrError<std::vector< Relation >> GetRelationSet();
+
+private:
+  Dali::Accessibility::Accessible* CalculateNeighbor( Dali::Accessibility::Accessible* root, Dali::Accessibility::Accessible* start, unsigned char forward, GetNeighborSearchMode search_mode );
+  std::vector< Dali::Accessibility::Accessible* > ValidChildrenGet( const std::vector< Dali::Accessibility::Accessible* >& children, Dali::Accessibility::Accessible* start, Dali::Accessibility::Accessible* root );
+  Dali::Accessibility::Accessible* GetCurrentlyHighlighted();
+  Dali::Accessibility::Accessible* DirectionalDepthFirstSearchTryNonDefunctSibling( bool& all_children_visited, Dali::Accessibility::Accessible* node, Dali::Accessibility::Accessible* start, Dali::Accessibility::Accessible* root, unsigned char forward );
+  Dali::Accessibility::Accessible* GetNextNonDefunctSibling( Dali::Accessibility::Accessible* obj, Dali::Accessibility::Accessible* start, Dali::Accessibility::Accessible* root, unsigned char forward );
+  Dali::Accessibility::Component* CalculateNavigableAccessibleAtPoint( Dali::Accessibility::Accessible* root, Dali::Accessibility::Point p, Dali::Accessibility::CoordType cType, unsigned int maxRecursionDepth );
+  Dali::Accessibility::Component * GetObjectInRelation(Dali::Accessibility::Accessible * obj, Dali::Accessibility::RelationType ralationType);
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_ACCESSIBLE_H
diff --git a/dali/internal/accessibility/bridge/bridge-action.cpp b/dali/internal/accessibility/bridge/bridge-action.cpp
new file mode 100644 (file)
index 0000000..47c5eae
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/bridge-action.h>
+
+// EXTERNAL INCLUDES
+#include <iostream>
+
+using namespace Dali::Accessibility;
+
+void BridgeAction::RegisterInterfaces()
+{
+  DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceAction};
+
+  AddGetPropertyToInterface( desc, "NActions", &BridgeAction::GetActionCount );
+
+  AddFunctionToInterface( desc, "GetName", &BridgeAction::GetActionName );
+  AddFunctionToInterface( desc, "GetLocalizedName", &BridgeAction::GetLocalizedActionName );
+  AddFunctionToInterface( desc, "GetDescription", &BridgeAction::GetActionDescription );
+  AddFunctionToInterface( desc, "GetKeyBinding", &BridgeAction::GetActionKeyBinding );
+  AddFunctionToInterface( desc, "DoAction", &BridgeAction::DoAction );
+  AddFunctionToInterface( desc, "DoActionName", &BridgeAction::DoActionName );
+  dbusServer.addInterface( "/", desc, true );
+}
+
+Action* BridgeAction::FindSelf() const
+{
+  auto s = BridgeBase::FindSelf();
+  assert( s );
+  auto s2 = dynamic_cast< Action* >( s );
+  if( !s2 )
+    throw std::domain_error{"object " + s->GetAddress().ToString() + " doesn't have Action interface"};
+  return s2;
+}
+
+DBus::ValueOrError< std::string > BridgeAction::GetActionName( int32_t index )
+{
+  return FindSelf()->GetActionName( index );
+}
+
+DBus::ValueOrError< std::string > BridgeAction::GetLocalizedActionName( int32_t index )
+{
+  return FindSelf()->GetLocalizedActionName( index );
+}
+
+DBus::ValueOrError< std::string > BridgeAction::GetActionDescription( int32_t index )
+{
+  return FindSelf()->GetActionDescription( index );
+}
+
+DBus::ValueOrError< std::string > BridgeAction::GetActionKeyBinding( int32_t index )
+{
+  return FindSelf()->GetActionKeyBinding( index );
+}
+
+DBus::ValueOrError< int32_t > BridgeAction::GetActionCount()
+{
+  return FindSelf()->GetActionCount();
+  ;
+}
+
+DBus::ValueOrError< bool > BridgeAction::DoAction( int32_t index )
+{
+  return FindSelf()->DoAction( index );
+}
+
+DBus::ValueOrError< bool > BridgeAction::DoActionName( std::string name )
+{
+  auto self = FindSelf();
+  auto cnt = self->GetActionCount();
+  for( auto i = 0u; i < cnt; ++i )
+  {
+    if( self->GetActionName( i ) == name )
+    {
+      return self->DoAction( i );
+    }
+  }
+  throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have action '" + name + "'"};
+}
diff --git a/dali/internal/accessibility/bridge/bridge-action.h b/dali/internal/accessibility/bridge/bridge-action.h
new file mode 100644 (file)
index 0000000..a47eb82
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_ACTION_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_ACTION_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <tuple>
+#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/bridge-base.h>
+
+class BridgeAction : public virtual BridgeBase
+{
+protected:
+  BridgeAction() = default;
+
+  void RegisterInterfaces();
+
+  Dali::Accessibility::Action* FindSelf() const;
+
+public:
+  DBus::ValueOrError< std::string > GetActionName( int32_t index );
+  DBus::ValueOrError< std::string > GetLocalizedActionName( int32_t index );
+  DBus::ValueOrError< std::string > GetActionDescription( int32_t index );
+  DBus::ValueOrError< std::string > GetActionKeyBinding( int32_t index );
+  DBus::ValueOrError< int32_t > GetActionCount();
+  DBus::ValueOrError< bool > DoAction( int32_t index );
+  DBus::ValueOrError< bool > DoActionName( std::string name );
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_ACTION_H
diff --git a/dali/internal/accessibility/bridge/bridge-base.cpp b/dali/internal/accessibility/bridge/bridge-base.cpp
new file mode 100644 (file)
index 0000000..1662b98
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/bridge-base.h>
+
+// EXTERNAL INCLUDES
+#include <atomic>
+#include <cstdlib>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/timer.h>
+
+using namespace Dali::Accessibility;
+
+static Dali::Timer tickTimer;
+
+BridgeBase::~BridgeBase()
+{
+}
+
+BridgeBase::BridgeBase()
+{
+}
+
+void BridgeBase::addFilteredEvent(FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function<void()> functor)
+{
+  if (delay < 0)
+    delay = 0;
+  auto it = filteredEvents.insert({ { kind, obj }, { static_cast<unsigned int>(delay * 10), {} } });
+  if (it.second)
+    functor();
+  else
+    it.first->second.second = std::move(functor);
+  if (!tickTimer) {
+    tickTimer = Dali::Timer::New(100);
+    tickTimer.TickSignal().Connect(this, &BridgeBase::tickFilteredEvents);
+  }
+}
+
+bool BridgeBase::tickFilteredEvents()
+{
+  for(auto it = filteredEvents.begin(); it != filteredEvents.end(); ) {
+    if (it->second.first) {
+      --it->second.first;
+    }
+    else {
+      if (it->second.second) {
+        it->second.second();
+        it->second.second = {};
+      }
+      else {
+        it = filteredEvents.erase(it);
+        continue;
+      }
+    }
+    ++it;
+  }
+  return !filteredEvents.empty();
+}
+
+BridgeBase::ForceUpResult BridgeBase::ForceUp()
+{
+  if( Bridge::ForceUp() == ForceUpResult::ALREADY_UP )
+    return ForceUpResult::ALREADY_UP;
+  auto proxy = DBus::DBusClient{dbusLocators::atspi::BUS, dbusLocators::atspi::OBJ_PATH,
+                                dbusLocators::atspi::BUS_INTERFACE, DBus::ConnectionType::SESSION};
+  auto addr = proxy.method< std::string() >( dbusLocators::atspi::GET_ADDRESS ).call();
+
+  if( !addr )
+    throw std::domain_error{std::string( "failed at call '" ) + dbusLocators::atspi::GET_ADDRESS +
+                          "': " + addr.getError().message};
+
+  con = DBusWrapper::Installed()->eldbus_address_connection_get_impl( std::get< 0 >( addr ) );
+  data->busName = DBus::getConnectionName( con );
+  dbusServer = {con};
+
+  {
+    DBus::DBusInterfaceDescription desc{"org.a11y.atspi.Cache"};
+    AddFunctionToInterface( desc, "GetItems", &BridgeBase::GetItems );
+    dbusServer.addInterface( "/org/a11y/atspi/cache", desc );
+  }
+  {
+    DBus::DBusInterfaceDescription desc{"org.a11y.atspi.Application"};
+    AddGetSetPropertyToInterface( desc, "Id", &BridgeBase::IdGet, &BridgeBase::IdSet );
+    dbusServer.addInterface( AtspiPath, desc );
+  }
+  return ForceUpResult::JUST_STARTED;
+}
+
+void BridgeBase::ForceDown()
+{
+  Bridge::ForceDown();
+  dbusServer = {};
+  con = {};
+}
+
+const std::string& BridgeBase::GetBusName() const
+{
+  static std::string empty;
+  return data ? data->busName : empty;
+}
+
+Accessible* BridgeBase::FindByPath( const std::string& name ) const
+{
+  try
+  {
+    return Find( name );
+  }
+  catch( std::domain_error )
+  {
+    return nullptr;
+  }
+}
+
+void BridgeBase::AddPopup( Accessible* obj )
+{
+  if( std::find( popups.begin(), popups.end(), obj ) != popups.end() ) return;
+  popups.push_back( obj );
+  if (IsUp())
+  {
+    obj->Emit( WindowEvent::ACTIVATE, 0 );
+  }
+}
+
+void BridgeBase::RemovePopup( Accessible* obj )
+{
+  auto it = std::find( popups.begin(), popups.end(), obj );
+  if( it == popups.end() ) return;
+  popups.erase( it );
+  if (IsUp())
+  {
+    obj->Emit( WindowEvent::DEACTIVATE, 0 );
+    if( popups.empty() )
+    {
+      application.children.back()->Emit( WindowEvent::ACTIVATE, 0 );
+    }
+    else
+    {
+      popups.back()->Emit( WindowEvent::ACTIVATE, 0 );
+    }
+  }
+
+}
+
+void BridgeBase::AddTopLevelWindow( Accessible* root )
+{
+  application.children.push_back( root );
+  SetIsOnRootLevel( root );
+}
+
+void BridgeBase::RemoveTopLevelWindow( Accessible* root )
+{
+       for(auto i = 0u; i < application.children.size(); ++i) {
+               if( application.children[i] == root )
+               {
+                       application.children.erase(application.children.begin() + i);
+                       break;
+               }
+       }
+}
+
+// Accessible *BridgeBase::getApplicationRoot() const
+// {
+//     return rootElement;
+// }
+
+std::string BridgeBase::StripPrefix( const std::string& path )
+{
+  auto size = strlen( AtspiPath );
+  return path.substr( size + 1 );
+}
+
+Accessible* BridgeBase::Find( const std::string& path ) const
+{
+  if( path == "root" )
+    return &application;
+  void* p;
+  std::istringstream tmp{ path };
+  if (! ( tmp >> p) )
+    throw std::domain_error{"invalid path '" + path + "'"};
+  auto it = data->knownObjects.find( static_cast<Accessible*>( p ) );
+  if( it == data->knownObjects.end() )
+    throw std::domain_error{"unknown object '" + path + "'"};
+  return static_cast<Accessible*>( p );
+}
+
+Accessible* BridgeBase::Find( const Address& ptr ) const
+{
+  assert( ptr.GetBus() == data->busName );
+  return Find( ptr.GetPath() );
+}
+
+Accessible* BridgeBase::FindSelf() const
+{
+  auto pth = DBus::DBusServer::getCurrentObjectPath();
+  auto size = strlen( AtspiPath );
+  if( pth.size() <= size )
+    throw std::domain_error{"invalid path '" + pth + "'"};
+  if( pth.substr( 0, size ) != AtspiPath )
+    throw std::domain_error{"invalid path '" + pth + "'"};
+  if( pth[size] != '/' )
+    throw std::domain_error{"invalid path '" + pth + "'"};
+  return Find( StripPrefix( pth ) );
+}
+
+void BridgeBase::IdSet( int id )
+{
+  this->id = id;
+}
+int BridgeBase::IdGet()
+{
+  return this->id;
+}
+
+auto BridgeBase::GetItems() -> DBus::ValueOrError< std::vector< CacheElementType > >
+{
+  auto root = &application;
+
+  std::vector< CacheElementType > res;
+
+       std::function< void(Accessible*) > proc = [&]( Accessible* item ) {
+       res.emplace_back( std::move( CreateCacheElement( root ) ) );
+
+               for( auto i = 0u; i < item->GetChildCount(); ++i )
+               {
+                       proc( item->GetChildAtIndex( i ) );
+               }
+       };
+
+  return res;
+}
+
+auto BridgeBase::CreateCacheElement( Accessible* item ) -> CacheElementType
+{
+  if( !item )
+    return {};
+
+  auto root = &application;
+  auto parent = item->GetParent();
+
+  std::vector< Address > children;
+  for( auto i = 0u; i < item->GetChildCount(); ++i )
+  {
+    children.emplace_back( item->GetChildAtIndex( i )->GetAddress() );
+  }
+
+  return std::make_tuple(
+      item->GetAddress(),
+      root->GetAddress(),
+      parent ? parent->GetAddress() : Address{},
+      children,
+      item->GetInterfaces(),
+      item->GetName(),
+      item->GetRole(),
+      item->GetDescription(),
+      item->GetStates().GetRawData() );
+}
diff --git a/dali/internal/accessibility/bridge/bridge-base.h b/dali/internal/accessibility/bridge/bridge-base.h
new file mode 100644 (file)
index 0000000..7c413db
--- /dev/null
@@ -0,0 +1,274 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/signals/connection-tracker.h>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/accessibility-common.h>
+
+class AppAccessible : public virtual Dali::Accessibility::Accessible, public virtual Dali::Accessibility::Collection
+{
+public:
+  Dali::Accessibility::EmptyAccessibleWithAddress parent;
+  std::vector< Dali::Accessibility::Accessible* > children;
+  std::string name;
+
+  std::string GetName() override
+  {
+    return name;
+  }
+  std::string GetDescription() override
+  {
+    return "";
+  }
+  Dali::Accessibility::Accessible* GetParent() override
+  {
+    return &parent;
+  }
+  size_t GetChildCount() override
+  {
+    return children.size();
+  }
+  Dali::Accessibility::Accessible* GetChildAtIndex( size_t index ) override
+  {
+    auto s = children.size();
+    if( index >= s )
+      throw std::domain_error{"invalid index " + std::to_string( index ) + " for object with " + std::to_string( s ) + " children"};
+    return children[index];
+  }
+  size_t GetIndexInParent() override
+  {
+    throw std::domain_error{"can't call GetIndexInParent on application object"};
+  }
+  Dali::Accessibility::Role GetRole() override
+  {
+    return Dali::Accessibility::Role::APPLICATION;
+  }
+  Dali::Accessibility::States GetStates() override
+  {
+    return {};
+  }
+  Dali::Accessibility::Attributes GetAttributes() override
+  {
+    return {};
+  }
+  Dali::Accessibility::Accessible* getActiveWindow()
+  {
+    return children.empty() ? nullptr : children[0];
+  }
+  bool DoGesture(const Dali::Accessibility::GestureInfo &gestureInfo) override
+  {
+      return false;
+  }
+  std::vector<Dali::Accessibility::Relation> GetRelationSet() override
+  {
+      return {};
+  }
+  Dali::Accessibility::Address GetAddress() override {
+    return { "", "root" };
+  }
+};
+
+enum class FilteredEvents {
+  boundsChanged
+};
+
+namespace std {
+  template <> struct hash<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>> {
+    size_t operator () (std::pair<FilteredEvents, Dali::Accessibility::Accessible*> v) const {
+      return (static_cast<size_t>(v.first) * 131) ^ reinterpret_cast<size_t>(v.second);
+    }
+  };
+}
+
+class BridgeBase : public Dali::Accessibility::Bridge, public Dali::ConnectionTracker
+{
+  std::unordered_map<std::pair<FilteredEvents, Dali::Accessibility::Accessible*>, std::pair<unsigned int, std::function<void()>>> filteredEvents;
+
+  bool tickFilteredEvents();
+public:
+
+  void addFilteredEvent(FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function<void()> functor);
+
+  const std::string& GetBusName() const override;
+  void AddTopLevelWindow( Dali::Accessibility::Accessible* window ) override;
+  void RemoveTopLevelWindow( Dali::Accessibility::Accessible* window ) override;
+  void AddPopup( Dali::Accessibility::Accessible* ) override;
+  void RemovePopup( Dali::Accessibility::Accessible* ) override;
+
+  Dali::Accessibility::Accessible* GetApplication() const override
+  {
+    return &application;
+  }
+
+  template < typename SELF, typename... RET, typename... ARGS >
+  void AddFunctionToInterface(
+      DBus::DBusInterfaceDescription& desc, const std::string& funcName,
+      DBus::ValueOrError< RET... > ( SELF::*funcPtr )( ARGS... ) )
+  {
+    if ( auto self = dynamic_cast< SELF* >( this ) )
+      desc.addMethod< DBus::ValueOrError< RET... >( ARGS... ) >( funcName,
+                                                               [=]( ARGS... args ) -> DBus::ValueOrError< RET... > {
+                                                                 try
+                                                                 {
+                                                                   return ( self->*funcPtr )( std::move( args )... );
+                                                                 }
+                                                                 catch( std::domain_error& e )
+                                                                 {
+                                                                   return DBus::Error{e.what()};
+                                                                 }
+                                                               } );
+  }
+  template < typename T, typename SELF >
+  void AddGetPropertyToInterface( DBus::DBusInterfaceDescription& desc,
+                                  const std::string& funcName, T ( SELF::*funcPtr )() )
+  {
+    if ( auto self = dynamic_cast< SELF* >( this ) )
+      desc.addProperty< T >( funcName,
+                           [=]() -> DBus::ValueOrError< T > {
+                             try
+                             {
+                               return ( self->*funcPtr )();
+                             }
+                             catch( std::domain_error& e )
+                             {
+                               return DBus::Error{e.what()};
+                             }
+                           },
+                           {} );
+  }
+  template < typename T, typename SELF >
+  void AddSetPropertyToInterface( DBus::DBusInterfaceDescription& desc,
+                                  const std::string& funcName, void ( SELF::*funcPtr )( T ) )
+  {
+    if ( auto self = dynamic_cast< SELF* >( this ) )
+      desc.addProperty< T >( funcName, {},
+                           [=]( T t ) -> DBus::ValueOrError< void > {
+                             try
+                             {
+                               ( self->*funcPtr )( std::move( t ) );
+                               return {};
+                             }
+                             catch( std::domain_error& e )
+                             {
+                               return DBus::Error{e.what()};
+                             }
+                           } );
+  }
+  template < typename T, typename T1, typename SELF >
+  void AddGetSetPropertyToInterface( DBus::DBusInterfaceDescription& desc,
+                                     const std::string& funcName, T1 ( SELF::*funcPtrGet )(), DBus::ValueOrError< void > ( SELF::*funcPtrSet )( T ) )
+  {
+    if ( auto self = dynamic_cast< SELF* >( this ) )
+      desc.addProperty< T >( funcName,
+                           [=]() -> DBus::ValueOrError< T > {
+                             try
+                             {
+                               return ( self->*funcPtrGet )();
+                             }
+                             catch( std::domain_error& e )
+                             {
+                               return DBus::Error{e.what()};
+                             }
+                           },
+                           [=]( T t ) -> DBus::ValueOrError< void > {
+                             try
+                             {
+                               ( self->*funcPtrSet )( std::move( t ) );
+                               return {};
+                             }
+                             catch( std::domain_error& e )
+                             {
+                               return DBus::Error{e.what()};
+                             }
+                           } );
+  }
+  template < typename T, typename T1, typename SELF >
+  void AddGetSetPropertyToInterface( DBus::DBusInterfaceDescription& desc,
+                                     const std::string& funcName, T1 ( SELF::*funcPtrGet )(), void ( SELF::*funcPtrSet )( T ) )
+  {
+    if ( auto self = dynamic_cast< SELF* >( this ) )
+      desc.addProperty< T >( funcName,
+                           [=]() -> DBus::ValueOrError< T > {
+                             try
+                             {
+                               return ( self->*funcPtrGet )();
+                             }
+                             catch( std::domain_error& e )
+                             {
+                               return DBus::Error{e.what()};
+                             }
+                           },
+                           [=]( T t ) -> DBus::ValueOrError< void > {
+                             try
+                             {
+                               ( self->*funcPtrSet )( std::move( t ) );
+                               return {};
+                             }
+                             catch( std::domain_error& e )
+                             {
+                               return DBus::Error{e.what()};
+                             }
+                           } );
+  }
+  static std::string StripPrefix( const std::string& path );
+
+  Dali::Accessibility::Accessible* Find( const std::string& path ) const;
+  Dali::Accessibility::Accessible* Find( const Dali::Accessibility::Address& ptr ) const;
+  Dali::Accessibility::Accessible* FindSelf() const;
+  Dali::Accessibility::Accessible* FindByPath( const std::string& name ) const override;
+  void SetApplicationName( std::string name ) override
+  {
+    application.name = std::move( name );
+  }
+
+protected:
+  mutable AppAccessible application;
+  std::vector<Dali::Accessibility::Accessible*> popups;
+private:
+  void IdSet( int id );
+  int IdGet();
+
+  using CacheElementType = std::tuple<
+      Dali::Accessibility::Address, Dali::Accessibility::Address, Dali::Accessibility::Address,
+      std::vector< Dali::Accessibility::Address >,
+      std::vector< std::string >,
+      std::string,
+      Dali::Accessibility::Role,
+      std::string,
+      std::array< uint32_t, 2 > >;
+  DBus::ValueOrError< std::vector< CacheElementType > > GetItems();
+  CacheElementType CreateCacheElement( Dali::Accessibility::Accessible* item );
+
+protected:
+  BridgeBase();
+  virtual ~BridgeBase();
+
+  ForceUpResult ForceUp() override;
+  void ForceDown() override;
+
+  DBus::DBusServer dbusServer;
+  DBusWrapper::ConnectionPtr con;
+  int id = 0;
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H
diff --git a/dali/internal/accessibility/bridge/bridge-collection.cpp b/dali/internal/accessibility/bridge/bridge-collection.cpp
new file mode 100644 (file)
index 0000000..8c590ef
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/bridge-collection.h>
+
+// EXTERNAL INCLUDES
+#include <algorithm>
+#include <iostream>
+#include <unordered_set>
+#include <vector>
+
+using namespace Dali::Accessibility;
+
+void BridgeCollection::RegisterInterfaces()
+{
+  DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceCollection};
+  AddFunctionToInterface( desc, "GetMatches", &BridgeCollection::GetMatches );
+  dbusServer.addInterface( "/", desc, true );
+}
+
+Collection* BridgeCollection::FindSelf() const
+{
+  auto s = BridgeBase::FindSelf();
+  assert( s );
+  auto s2 = dynamic_cast< Collection* >( s );
+  if( !s2 )
+    throw std::domain_error{"object " + s->GetAddress().ToString() + " doesn't have Collection interface"};
+  return s2;
+}
+
+enum
+{
+  ATSPI_Collection_MATCH_INVALID,
+  ATSPI_Collection_MATCH_ALL,
+  ATSPI_Collection_MATCH_ANY,
+  ATSPI_Collection_MATCH_NONE,
+  ATSPI_Collection_MATCH_EMPTY,
+  ATSPI_Collection_MATCH_LAST_DEFINED,
+};
+
+struct BridgeCollection::Comparer
+{
+  using Mode = MatchType;
+
+  enum class CompareFuncExit
+  {
+    FIRST_FOUND,
+    FIRST_NOT_FOUND
+  };
+
+  static Mode ConvertToMatchType( int32_t mode )
+  {
+    switch( mode )
+    {
+      case ATSPI_Collection_MATCH_INVALID:
+      {
+        return Mode::INVALID;
+      }
+      case ATSPI_Collection_MATCH_ALL:
+      {
+        return Mode::ALL;
+      }
+      case ATSPI_Collection_MATCH_ANY:
+      {
+        return Mode::ANY;
+      }
+      case ATSPI_Collection_MATCH_NONE:
+      {
+        return Mode::NONE;
+      }
+      case ATSPI_Collection_MATCH_EMPTY:
+      {
+        return Mode::EMPTY;
+      }
+    }
+    return Mode::INVALID;
+  }
+
+  struct ComparerInterfaces
+  {
+    std::unordered_set< std::string > object;
+    std::vector< std::string > requested;
+    Mode mode = Mode::INVALID;
+
+    ComparerInterfaces( MatchRule* rule ) : mode( ConvertToMatchType( std::get< Index::InterfacesMatchType >( *rule ) ) )
+    {
+      requested = {std::get< Index::Interfaces >( *rule ).begin(), std::get< Index::Interfaces >( *rule ).end()};
+    }
+    void Update( Accessible* obj )
+    {
+      object.clear();
+      for( auto& q : obj->GetInterfaces() )
+        object.insert( std::move( q ) );
+    }
+    bool RequestEmpty() const { return requested.empty(); }
+    bool ObjectEmpty() const { return object.empty(); }
+    bool Compare( CompareFuncExit exit )
+    {
+      bool foundAny = false;
+      for( auto& iname : requested )
+      {
+        bool found = ( object.find( iname ) != object.end() );
+        if( found )
+          foundAny = true;
+        if( found == ( exit == CompareFuncExit::FIRST_FOUND ) )
+          return found;
+      }
+      return foundAny;
+    }
+  };
+  struct ComparerAttributes
+  {
+    std::unordered_map< std::string, std::string > requested, object;
+    Mode mode = Mode::INVALID;
+
+    ComparerAttributes( MatchRule* rule ) : mode( ConvertToMatchType( std::get< Index::AttributesMatchType >( *rule ) ) )
+    {
+      requested = std::get< Index::Attributes >( *rule );
+    }
+    void Update( Accessible* obj )
+    {
+      object = obj->GetAttributes();
+    }
+    bool RequestEmpty() const { return requested.empty(); }
+    bool ObjectEmpty() const { return object.empty(); }
+    bool Compare( CompareFuncExit exit )
+    {
+      bool foundAny = false;
+      for( auto& iname : requested )
+      {
+        auto it = object.find( iname.first );
+        bool found = it != object.end() && iname.second == it->second;
+        if( found )
+          foundAny = true;
+        if( found == ( exit == CompareFuncExit::FIRST_FOUND ) )
+        {
+          return found;
+        }
+      }
+      return foundAny;
+    }
+  };
+  struct ComparerRoles
+  {
+    using Roles = BitSets< 4, Role >;
+    Roles requested, object;
+    Mode mode = Mode::INVALID;
+
+    ComparerRoles( MatchRule* rule ) : mode( ConvertToMatchType( std::get< Index::RolesMatchType >( *rule ) ) )
+    {
+      requested = Roles{std::get< Index::Roles >( *rule )};
+    }
+    void Update( Accessible* obj )
+    {
+      object = {};
+      object[obj->GetRole()] = true;
+      assert( object );
+    }
+    bool RequestEmpty() const { return !requested; }
+    bool ObjectEmpty() const { return !object; }
+    bool Compare( CompareFuncExit exit )
+    {
+      switch( mode )
+      {
+        case Mode::INVALID:
+        {
+          return true;
+        }
+        case Mode::EMPTY:
+        case Mode::ALL:
+        {
+          return requested == ( object & requested );
+        }
+        case Mode::ANY:
+        {
+          return bool( object & requested );
+        }
+        case Mode::NONE:
+        {
+          return bool( object & requested );
+        }
+      }
+      return false;
+    }
+  };
+  struct ComparerStates
+  {
+    States requested, object;
+    Mode mode = Mode::INVALID;
+
+    ComparerStates( MatchRule* rule ) : mode( ConvertToMatchType( std::get< Index::StatesMatchType >( *rule ) ) )
+    {
+      requested = States{std::get< Index::States >( *rule )};
+    }
+    void Update( Accessible* obj )
+    {
+      object = obj->GetStates();
+    }
+    bool RequestEmpty() const { return !requested; }
+    bool ObjectEmpty() const { return !object; }
+    bool Compare( CompareFuncExit exit )
+    {
+      switch( mode )
+      {
+        case Mode::INVALID:
+        {
+          return true;
+        }
+        case Mode::EMPTY:
+        case Mode::ALL:
+        {
+          return requested == ( object & requested );
+        }
+        case Mode::ANY:
+        {
+          return bool( object & requested );
+        }
+        case Mode::NONE:
+        {
+          return bool( object & requested );
+        }
+      }
+      return false;
+    }
+  };
+
+  template < typename T >
+  bool compareFunc( T& cmp, Accessible* obj )
+  {
+    if( cmp.mode == Mode::INVALID )
+      return true;
+    cmp.Update( obj );
+    switch( cmp.mode )
+    {
+      case Mode::ANY:
+      {
+        if( cmp.RequestEmpty() || cmp.ObjectEmpty() )
+          return false;
+        break;
+      }
+      case Mode::ALL:
+      {
+        if( cmp.RequestEmpty() )
+          return true;
+        if( cmp.ObjectEmpty() )
+          return false;
+        break;
+      }
+      case Mode::NONE:
+      {
+        if( cmp.RequestEmpty() || cmp.ObjectEmpty() )
+          return true;
+        break;
+      }
+      case Mode::EMPTY:
+      {
+        if( cmp.RequestEmpty() && cmp.ObjectEmpty() )
+          return true;
+        if( cmp.RequestEmpty() || cmp.ObjectEmpty() )
+          return false;
+        break;
+      }
+      case Mode::INVALID:
+      {
+        return true;
+      }
+    }
+
+    switch( cmp.mode )
+    {
+      case Mode::EMPTY:
+      case Mode::ALL:
+      {
+        if( !cmp.Compare( CompareFuncExit::FIRST_NOT_FOUND ) )
+          return false;
+        break;
+      }
+      case Mode::ANY:
+      {
+        if( cmp.Compare( CompareFuncExit::FIRST_FOUND ) )
+          return true;
+        break;
+      }
+      case Mode::NONE:
+      {
+        if( cmp.Compare( CompareFuncExit::FIRST_FOUND ) )
+          return false;
+        break;
+      }
+      case Mode::INVALID:
+      {
+        return true;
+      }
+    }
+    switch( cmp.mode )
+    {
+      case Mode::EMPTY:
+      case Mode::ALL:
+      case Mode::NONE:
+      {
+        return true;
+      }
+      case Mode::ANY:
+      {
+        return false;
+      }
+      case Mode::INVALID:
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  ComparerInterfaces ci;
+  ComparerAttributes ca;
+  ComparerRoles cr;
+  ComparerStates cs;
+
+  Comparer( MatchRule* mr ) : ci( mr ), ca( mr ), cr( mr ), cs( mr ) {}
+
+  bool operator()( Accessible* obj )
+  {
+    return compareFunc( ci, obj ) &&
+           compareFunc( ca, obj ) &&
+           compareFunc( cr, obj ) &&
+           compareFunc( cs, obj );
+  }
+};
+
+void BridgeCollection::VisitNodes( Accessible* obj, std::vector< Accessible* >& result, Comparer& cmp, size_t maxCount )
+{
+  if( result.size() >= maxCount )
+    return;
+
+  if( cmp( obj ) )
+    result.emplace_back( obj );
+
+  for( auto i = 0u; i < obj->GetChildCount(); ++i )
+    VisitNodes( obj->GetChildAtIndex( i ), result, cmp, maxCount );
+}
+
+DBus::ValueOrError< std::vector< Accessible* > > BridgeCollection::GetMatches( MatchRule rule, uint32_t sortBy, int32_t count, bool traverse )
+{
+  std::vector< Accessible* > res;
+  auto self = BridgeBase::FindSelf();
+  auto matcher = Comparer{&rule};
+  VisitNodes( self, res, matcher, count );
+
+  switch( static_cast< SortOrder >( sortBy ) )
+  {
+    case SortOrder::CANONICAL:
+    {
+      break;
+    }
+
+    case SortOrder::REVERSE_CANONICAL:
+    {
+      std::reverse( res.begin(), res.end() );
+      break;
+    }
+
+    default:
+    {
+      throw std::domain_error{"unsupported sorting order"};
+    }
+      //TODO: other cases
+  }
+
+  return res;
+}
diff --git a/dali/internal/accessibility/bridge/bridge-collection.h b/dali/internal/accessibility/bridge/bridge-collection.h
new file mode 100644 (file)
index 0000000..c4a279d
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_COLLECTION_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_COLLECTION_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <array>
+#include <tuple>
+#include <unordered_map>
+#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/bridge-base.h>
+
+class BridgeCollection : public virtual BridgeBase
+{
+private:
+  struct Comparer;
+  static void VisitNodes( Dali::Accessibility::Accessible* obj, std::vector< Dali::Accessibility::Accessible* >& result, Comparer& cmp, size_t maxCount );
+
+protected:
+  BridgeCollection() = default;
+
+  void RegisterInterfaces();
+
+  Dali::Accessibility::Collection* FindSelf() const;
+
+public:
+  using MatchRule = std::tuple<
+      std::array< int32_t, 2 >, int32_t,
+      std::unordered_map< std::string, std::string >, int32_t,
+      std::array< int32_t, 4 >, int32_t,
+      std::vector< std::string >, int32_t,
+      bool >;
+  struct Index
+  {
+    enum
+    {
+      States,
+      StatesMatchType,
+      Attributes,
+      AttributesMatchType,
+      Roles,
+      RolesMatchType,
+      Interfaces,
+      InterfacesMatchType,
+    };
+  };
+
+  DBus::ValueOrError< std::vector< Dali::Accessibility::Accessible* > > GetMatches( MatchRule rule, uint32_t sortBy, int32_t count, bool traverse );
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_COLLECTION_H
diff --git a/dali/internal/accessibility/bridge/bridge-component.cpp b/dali/internal/accessibility/bridge/bridge-component.cpp
new file mode 100644 (file)
index 0000000..1e65ddc
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/bridge-component.h>
+
+// EXTERNAL INCLUDES
+#include <iostream>
+
+#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
+
+using namespace Dali::Accessibility;
+
+BridgeComponent::BridgeComponent()
+{
+}
+
+void BridgeComponent::RegisterInterfaces()
+{
+  DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceComponent};
+  AddFunctionToInterface( desc, "Contains", &BridgeComponent::Contains );
+  AddFunctionToInterface( desc, "GetAccessibleAtPoint", &BridgeComponent::GetAccessibleAtPoint );
+  AddFunctionToInterface( desc, "GetExtents", &BridgeComponent::GetExtents );
+  AddFunctionToInterface( desc, "GetPosition", &BridgeComponent::GetPosition );
+  AddFunctionToInterface( desc, "GetSize", &BridgeComponent::GetSize );
+  AddFunctionToInterface( desc, "GetLayer", &BridgeComponent::GetLayer );
+  AddFunctionToInterface( desc, "GetAlpha", &BridgeComponent::GetAlpha );
+  AddFunctionToInterface( desc, "GetMDIZOrder", &BridgeComponent::GetMdiZOrder );
+  AddFunctionToInterface( desc, "GrabHighlight", &BridgeComponent::GrabHighlight );
+  AddFunctionToInterface( desc, "GrabFocus", &BridgeComponent::GrabFocus );
+  AddFunctionToInterface( desc, "ClearHighlight", &BridgeComponent::ClearHighlight );
+  dbusServer.addInterface( "/", desc, true );
+}
+
+Component* BridgeComponent::FindSelf() const
+{
+  auto s = BridgeBase::FindSelf();
+  assert( s );
+  auto s2 = dynamic_cast< Component* >( s );
+  if( !s2 )
+    throw std::domain_error{"object " + s->GetAddress().ToString() + " doesn't have Component interface"};
+  return s2;
+}
+
+DBus::ValueOrError< bool > BridgeComponent::Contains( int32_t x, int32_t y, uint32_t coordType )
+{
+  return FindSelf()->Contains( {x, y}, static_cast< CoordType >( coordType ) );
+}
+DBus::ValueOrError< Accessible* > BridgeComponent::GetAccessibleAtPoint( int32_t x, int32_t y, uint32_t coordType )
+{
+  return FindSelf()->GetAccessibleAtPoint( {x, y}, static_cast< CoordType >( coordType ) );
+}
+DBus::ValueOrError< std::tuple< int32_t, int32_t, int32_t, int32_t > > BridgeComponent::GetExtents( uint32_t coordType )
+{
+  auto p = FindSelf()->GetExtents( static_cast< CoordType >( coordType ) );
+  return std::tuple< int32_t, int32_t, int32_t, int32_t >{p.x, p.y, p.width, p.height};
+}
+DBus::ValueOrError< int32_t, int32_t > BridgeComponent::GetPosition( uint32_t coordType )
+{
+  auto p = FindSelf()->GetExtents( static_cast< CoordType >( coordType ) );
+  return { static_cast<int32_t>(p.x), static_cast<int32_t>(p.y) };
+}
+DBus::ValueOrError< int32_t, int32_t > BridgeComponent::GetSize( uint32_t coordType )
+{
+  auto p = FindSelf()->GetExtents( static_cast< CoordType >( coordType ) );
+  return { static_cast<int32_t>(p.width), static_cast<int32_t>(p.height) };
+}
+DBus::ValueOrError< ComponentLayer > BridgeComponent::GetLayer()
+{
+  return FindSelf()->GetLayer();
+}
+DBus::ValueOrError< double > BridgeComponent::GetAlpha()
+{
+  return FindSelf()->GetAlpha();
+}
+DBus::ValueOrError< bool > BridgeComponent::GrabFocus()
+{
+  return FindSelf()->GrabFocus();
+}
+DBus::ValueOrError< bool > BridgeComponent::GrabHighlight()
+{
+  return FindSelf()->GrabHighlight();
+}
+DBus::ValueOrError< bool > BridgeComponent::ClearHighlight()
+{
+  return FindSelf()->ClearHighlight();
+}
+DBus::ValueOrError< int16_t > BridgeComponent::GetMdiZOrder()
+{
+  return FindSelf()->GetMdiZOrder();
+}
diff --git a/dali/internal/accessibility/bridge/bridge-component.h b/dali/internal/accessibility/bridge/bridge-component.h
new file mode 100644 (file)
index 0000000..dcc8f49
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_COMPONENT_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_COMPONENT_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <array>
+#include <string>
+#include <tuple>
+#include <unordered_map>
+#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/bridge-base.h>
+
+class BridgeComponent : public virtual BridgeBase
+{
+protected:
+  BridgeComponent();
+
+  void RegisterInterfaces();
+
+  Dali::Accessibility::Component* FindSelf() const;
+
+public:
+  DBus::ValueOrError< bool > Contains( int32_t x, int32_t y, uint32_t coordType );
+  DBus::ValueOrError< Dali::Accessibility::Accessible* > GetAccessibleAtPoint( int32_t x, int32_t y, uint32_t coordType );
+  DBus::ValueOrError< std::tuple< int32_t, int32_t, int32_t, int32_t > > GetExtents( uint32_t coordType );
+  DBus::ValueOrError< int32_t, int32_t > GetPosition( uint32_t coordType );
+  DBus::ValueOrError< int32_t, int32_t > GetSize( uint32_t coordType );
+  DBus::ValueOrError< Dali::Accessibility::ComponentLayer > GetLayer();
+  DBus::ValueOrError< double > GetAlpha();
+  DBus::ValueOrError< bool > GrabFocus();
+  DBus::ValueOrError< bool > GrabHighlight();
+  DBus::ValueOrError< bool > ClearHighlight();
+  DBus::ValueOrError< int16_t > GetMdiZOrder();
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_COMPONENT_H
diff --git a/dali/internal/accessibility/bridge/bridge-editable-text.cpp b/dali/internal/accessibility/bridge/bridge-editable-text.cpp
new file mode 100644 (file)
index 0000000..5f18775
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/bridge-editable-text.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/clipboard/common/clipboard-impl.h>
+//#include <dali/internal/input/common/imf-manager-impl.h>
+
+using namespace Dali::Accessibility;
+
+void BridgeEditableText::RegisterInterfaces()
+{
+  DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceEditableText};
+  AddFunctionToInterface( desc, "CopyText", &BridgeEditableText::CopyText );
+  AddFunctionToInterface( desc, "CutText", &BridgeEditableText::CutText );
+  AddFunctionToInterface( desc, "PasteText", &BridgeEditableText::PasteText );
+  dbusServer.addInterface( "/", desc, true );
+}
+
+EditableText* BridgeEditableText::FindSelf() const
+{
+  auto s = BridgeBase::FindSelf();
+  assert( s );
+  auto s2 = dynamic_cast< EditableText* >( s );
+  if( !s2 )
+    throw std::domain_error{"object " + s->GetAddress().ToString() + " doesn't have Text interface"};
+  return s2;
+}
+
+DBus::ValueOrError< bool > BridgeEditableText::CopyText( int32_t startPos, int32_t endPos )
+{
+  return FindSelf()->CopyText( startPos, endPos );
+}
+
+DBus::ValueOrError< bool > BridgeEditableText::CutText( int32_t startPos, int32_t endPos )
+{
+  return FindSelf()->CutText( startPos, endPos );
+}
+
+DBus::ValueOrError< bool > BridgeEditableText::PasteText( int32_t pos )
+{
+  // auto imfManager = Dali::Internal::Adaptor::ImfManager::Get();
+  // imfManager.SetCursorPosition( pos );
+  // auto clipboard = Dali::Internal::Adaptor::Clipboard::Get();
+  // clipboard.RequestItem();
+  // return true;
+  return false;
+}
diff --git a/dali/internal/accessibility/bridge/bridge-editable-text.h b/dali/internal/accessibility/bridge/bridge-editable-text.h
new file mode 100644 (file)
index 0000000..e7d707b
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_EDITABLE_TEXT_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_EDITABLE_TEXT_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/bridge-base.h>
+
+class BridgeEditableText : public virtual BridgeBase
+{
+protected:
+  BridgeEditableText() = default;
+
+  void RegisterInterfaces();
+
+  Dali::Accessibility::EditableText* FindSelf() const;
+
+public:
+  DBus::ValueOrError< bool > CopyText( int32_t startPos, int32_t endPos );
+  DBus::ValueOrError< bool > CutText( int32_t startPos, int32_t endPos );
+  DBus::ValueOrError< bool > PasteText( int32_t pos );
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_EDITABLE_TEXT_H
diff --git a/dali/internal/accessibility/bridge/bridge-impl.cpp b/dali/internal/accessibility/bridge/bridge-impl.cpp
new file mode 100644 (file)
index 0000000..3f621c1
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <iostream>
+#include <unordered_map>
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/bridge-accessible.h>
+#include <dali/internal/accessibility/bridge/bridge-action.h>
+#include <dali/internal/accessibility/bridge/bridge-collection.h>
+#include <dali/internal/accessibility/bridge/bridge-component.h>
+#include <dali/internal/accessibility/bridge/bridge-object.h>
+#include <dali/internal/accessibility/bridge/bridge-value.h>
+#include <dali/internal/accessibility/bridge/bridge-text.h>
+#include <dali/internal/accessibility/bridge/bridge-editable-text.h>
+
+using namespace Dali::Accessibility;
+
+class BridgeImpl : public virtual BridgeBase,
+                   public BridgeAccessible,
+                   public BridgeObject,
+                   public BridgeComponent,
+                   public BridgeCollection,
+                   public BridgeAction,
+                   public BridgeValue,
+                   public BridgeText,
+                   public BridgeEditableText
+{
+  DBus::DBusClient listenOnAtspiEnabledSignalClient;
+  DBus::DBusClient registryClient, directReadingClient;
+  bool screenReaderEnabled = false, isEnabled = false, isShown = false;
+  std::unordered_map <int32_t, std::function<void(std::string)>> directReadingCallbacks;
+  Dali::Actor highlightedActor;
+  std::function<void(Dali::Actor)> highlightClearAction;
+public:
+  BridgeImpl()
+  {
+    listenOnAtspiEnabledSignalClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface,
+                                                             DBus::ConnectionType::SESSION};
+    listenOnAtspiEnabledSignalClient.addPropertyChangedEvent< bool >( "ScreenReaderEnabled", [this]( bool res ) {
+      screenReaderEnabled = res;
+      if( screenReaderEnabled || isEnabled )
+        ForceUp();
+      else
+        ForceDown();
+    } );
+    listenOnAtspiEnabledSignalClient.addPropertyChangedEvent< bool >( "IsEnabled", [this]( bool res ) {
+      isEnabled = res;
+      if( screenReaderEnabled || isEnabled )
+        ForceUp();
+      else
+        ForceDown();
+    } );
+  }
+
+  Consumed Emit( KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText ) override
+  {
+    if (!IsUp()) return Consumed::NO;
+    unsigned int evType = 0;
+
+    switch( type )
+    {
+      case KeyEventType::KEY_PRESSED:
+        evType = 0;
+        {
+          break;
+        }
+      case KeyEventType::KEY_RELEASED:
+        evType = 1;
+        {
+          break;
+        }
+      default:
+      {
+        return Consumed::NO;
+      }
+    }
+    auto m = registryClient.method< bool( std::tuple< uint32_t, int32_t, int32_t, int32_t, int32_t, std::string, bool > ) >( "NotifyListenersSync" );
+    auto result = m.call( std::tuple< uint32_t, int32_t, int32_t, int32_t, int32_t, std::string, bool >{evType, 0, static_cast< int32_t >( keyCode ), 0, static_cast< int32_t >( timeStamp ), keyName, isText ? 1 : 0} );
+    if( !result )
+    {
+      LOG() << result.getError().message;
+      return Consumed::NO;
+    }
+    return std::get< 0 >( result ) ? Consumed::YES : Consumed::NO;
+  }
+
+  void PauseResume( bool pause ) override
+  {
+    auto r = directReadingClient.method< DBus::ValueOrError< void >( bool ) > ( "PauseResume" ).call( pause );
+    if (!r) {
+      LOG() << "Direct reading command failed (" << r.getError().message << ")";
+    }
+  }
+
+  void Say( const std::string& text, bool discardable, std::function< void(std::string) > callback ) override
+  {
+         auto commandId = directReadingClient.method< DBus::ValueOrError< std::string, bool, int32_t >( std::string, bool ) > ( "ReadCommand" ).call( text, discardable );
+         if ( !commandId ) {
+                 LOG() << "Direct reading command failed (" << commandId.getError().message << ")";
+         } else if( callback ) {
+           directReadingCallbacks.emplace( std::get< 2 >( commandId ), callback);
+         }
+  }
+
+  void ForceDown() override
+  {
+    if (data) {
+      if (data->currentlyHighlightedActor && data->highlightActor) {
+        data->currentlyHighlightedActor.Remove(data->highlightActor);
+      }
+      data->currentlyHighlightedActor = {};
+      data->highlightActor = {};
+    }
+    highlightedActor = {};
+    highlightClearAction = {};
+    BridgeAccessible::ForceDown();
+    registryClient = {};
+    directReadingClient = {};
+    directReadingCallbacks.clear();
+  }
+  void Terminate() override
+  {
+    if (data) {
+      data->currentlyHighlightedActor = {};
+      data->highlightActor = {};
+    }
+    ForceDown();
+    listenOnAtspiEnabledSignalClient = {};
+    dbusServer = {};
+    con = {};
+  }
+
+  ForceUpResult ForceUp() override
+  {
+    if( BridgeAccessible::ForceUp() == ForceUpResult::ALREADY_UP )
+      return ForceUpResult::ALREADY_UP;
+
+    BridgeObject::RegisterInterfaces();
+    BridgeAccessible::RegisterInterfaces();
+    BridgeComponent::RegisterInterfaces();
+    BridgeCollection::RegisterInterfaces();
+    BridgeAction::RegisterInterfaces();
+    BridgeValue::RegisterInterfaces();
+    BridgeText::RegisterInterfaces();
+    BridgeEditableText::RegisterInterfaces();
+
+    RegisterOnBridge( &application );
+
+    registryClient = { AtspiDbusNameRegistry, AtspiDbusPathDec, AtspiDbusInterfaceDec, con };
+    directReadingClient = DBus::DBusClient{ DirectReadingDBusName, DirectReadingDBusPath, DirectReadingDBusInterface, con };
+    directReadingClient.addSignal< void(int32_t, std::string) >( "ReadingStateChanged", [=]( int32_t id, std::string readingState ) {
+      auto it = directReadingCallbacks.find( id );
+      if (it != directReadingCallbacks.end())
+      {
+        it->second( readingState );
+        directReadingCallbacks.erase( it );
+      }
+    });
+    auto proxy = DBus::DBusClient{AtspiDbusNameRegistry, AtspiDbusPathRoot, AtspiDbusInterfaceSocket, con};
+    Address root{"", "root"};
+    auto res = proxy.method< Address( Address ) >( "Embed" ).call( root );
+    if (!res)
+      LOG() << "Call to Embed failed: " << res.getError().message;
+    assert( res );
+    application.parent.SetAddress( std::move( std::get< 0 >( res ) ) );
+    if (isShown) {
+      EmitActivate();
+    }
+    return ForceUpResult::JUST_STARTED;
+  }
+
+  void EmitActivate()
+  {
+    auto win = application.getActiveWindow();
+    if (win) {
+      win->Emit( WindowEvent::ACTIVATE, 0 );
+    }
+  }
+  void EmitDeactivate()
+  {
+    auto win = application.getActiveWindow();
+    if (win) {
+      win->Emit( WindowEvent::DEACTIVATE, 0 );
+    }
+  }
+  void ApplicationHidden() override
+  {
+    if ( isShown && IsUp() )
+      EmitDeactivate();
+    isShown = false;
+  }
+  void ApplicationShown() override
+  {
+    if ( !isShown && IsUp() )
+      EmitActivate();
+    isShown = true;
+  }
+  void Initialize() override
+  {
+    auto req = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION};
+    auto p = req.property< bool >( "ScreenReaderEnabled" ).get();
+    if( p )
+      screenReaderEnabled = std::get< 0 >( p );
+    p = req.property< bool >( "IsEnabled" ).get();
+    if( p )
+      isEnabled = std::get< 0 >( p );
+    if( screenReaderEnabled || isEnabled )
+      ForceUp();
+  }
+};
+
+Bridge* Bridge::GetCurrentBridge()
+{
+  static BridgeImpl *bridge = new BridgeImpl;
+  return bridge;
+}
diff --git a/dali/internal/accessibility/bridge/bridge-object.cpp b/dali/internal/accessibility/bridge/bridge-object.cpp
new file mode 100644 (file)
index 0000000..762329e
--- /dev/null
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/bridge-object.h>
+
+// EXTERNAL INCLUDES
+#include <iostream>
+#include <string>
+
+using namespace Dali::Accessibility;
+
+BridgeObject::BridgeObject()
+{
+}
+
+void BridgeObject::RegisterInterfaces()
+{
+  // DBus::DBusInterfaceDescription desc{ AtspiDbusInterfaceEventObject };
+  // stateChanged = addSignal<std::string, int, int, DBus::EldbusVariant<int>, Accessible*>(desc, "StateChanged");
+  // dbusServer.addInterface("/", desc, true);
+}
+
+void BridgeObject::EmitActiveDescendantChanged( Accessible* obj, Accessible *child )
+{
+  if (!IsUp()) return;
+  auto index = child->GetIndexInParent();
+
+  auto addr = obj->GetAddress();
+  const auto prefixPath = "/org/a11y/atspi/accessible/";
+  const auto nullPath = "/org/a11y/atspi/null";
+  std::string p;
+  if( addr )
+    p = prefixPath + addr.GetPath();
+  else
+    p = nullPath;
+  dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< Address >, Address >(
+      p,
+      AtspiDbusInterfaceEventObject,
+      "ActiveDescendantChanged",
+      "",
+      index,
+      0,
+      { child->GetAddress() },
+      {"", "root"} );
+}
+
+void BridgeObject::Emit( Accessible* obj, Dali::Accessibility::ObjectPropertyChangeEvent ev )
+{
+  if (!IsUp()) return;
+  const char* name = nullptr;
+  switch( ev )
+  {
+    case ObjectPropertyChangeEvent::NAME:
+    {
+      name = "accessible-name";
+      break;
+    }
+    case ObjectPropertyChangeEvent::DESCRIPTION:
+    {
+      name = "accessible-description";
+      break;
+    }
+    case ObjectPropertyChangeEvent::VALUE:
+    {
+      name = "accessible-value";
+      break;
+    }
+    case ObjectPropertyChangeEvent::PARENT:
+    {
+      name = "accessible-parent";
+      break;
+    }
+    case ObjectPropertyChangeEvent::ROLE:
+    {
+      name = "accessible-role";
+      break;
+    }
+  }
+  if( name )
+  {
+    auto addr = obj->GetAddress();
+    std::string p;
+    if( addr )
+      p = ATSPI_PREFIX_PATH + addr.GetPath();
+    else
+      p = ATSPI_NULL_PATH;
+    dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< int >, Address >(
+        p,
+        AtspiDbusInterfaceEventObject,
+        "PropertyChange",
+        name,
+        0,
+        0,
+        {0},
+        {"", "root"} );
+  }
+}
+
+void BridgeObject::Emit( Accessible* obj, WindowEvent we, unsigned int detail1 )
+{
+  if (!IsUp()) return;
+  const char* name = nullptr;
+  switch( we )
+  {
+    case WindowEvent::PROPERTY_CHANGE:
+    {
+      name = "PropertyChange";
+      break;
+    }
+    case WindowEvent::MINIMIZE:
+    {
+      name = "Minimize";
+      break;
+    }
+    case WindowEvent::MAXIMIZE:
+    {
+      name = "Maximize";
+      break;
+    }
+    case WindowEvent::RESTORE:
+    {
+      name = "Restore";
+      break;
+    }
+    case WindowEvent::CLOSE:
+    {
+      name = "Close";
+      break;
+    }
+    case WindowEvent::CREATE:
+    {
+      name = "Create";
+      break;
+    }
+    case WindowEvent::REPARENT:
+    {
+      name = "Reparent";
+      break;
+    }
+    case WindowEvent::DESKTOP_CREATE:
+    {
+      name = "DesktopCreate";
+      break;
+    }
+    case WindowEvent::DESKTOP_DESTROY:
+    {
+      name = "DesktopDestroy";
+      break;
+    }
+    case WindowEvent::DESTROY:
+    {
+      name = "Destroy";
+      break;
+    }
+    case WindowEvent::ACTIVATE:
+    {
+      name = "Activate";
+      break;
+    }
+    case WindowEvent::DEACTIVATE:
+    {
+      name = "Deactivate";
+      break;
+    }
+    case WindowEvent::RAISE:
+    {
+      name = "Raise";
+      break;
+    }
+    case WindowEvent::LOWER:
+    {
+      name = "Lower";
+      break;
+    }
+    case WindowEvent::MOVE:
+    {
+      name = "Move";
+      break;
+    }
+    case WindowEvent::RESIZE:
+    {
+      name = "Resize";
+      break;
+    }
+    case WindowEvent::SHADE:
+    {
+      name = "Shade";
+      break;
+    }
+    case WindowEvent::UU_SHADE:
+    {
+      name = "uUshade";
+      break;
+    }
+    case WindowEvent::RESTYLE:
+    {
+      name = "Restyle";
+      break;
+    }
+  }
+  if( name )
+  {
+    auto addr = obj->GetAddress();
+    std::string p;
+    if( addr )
+      p = ATSPI_PREFIX_PATH + addr.GetPath();
+    else
+      p = ATSPI_NULL_PATH;
+    dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< int >, Address >(
+        p,
+        AtspiDbusInterfaceEventWindow,
+        name,
+        "",
+        detail1,
+        0,
+        {0},
+        {"", "root"} );
+  }
+}
+
+void BridgeObject::EmitStateChanged( Accessible* obj, State state, int newValue1, int newValue2 )
+{
+  if (!IsUp()) return;
+  const char* stateName = nullptr;
+  switch( state )
+  {
+    case State::INVALID:
+    {
+      stateName = "invalid";
+      break;
+    }
+    case State::ACTIVE:
+    {
+      stateName = "active";
+      break;
+    }
+    case State::ARMED:
+    {
+      stateName = "armed";
+      break;
+    }
+    case State::BUSY:
+    {
+      stateName = "busy";
+      break;
+    }
+    case State::CHECKED:
+    {
+      stateName = "checked";
+      break;
+    }
+    case State::COLLAPSED:
+    {
+      stateName = "collapsed";
+      break;
+    }
+    case State::DEFUNCT:
+    {
+      stateName = "defunct";
+      break;
+    }
+    case State::EDITABLE:
+    {
+      stateName = "editable";
+      break;
+    }
+    case State::ENABLED:
+    {
+      stateName = "enabled";
+      break;
+    }
+    case State::EXPANDABLE:
+    {
+      stateName = "expandable";
+      break;
+    }
+    case State::EXPANDED:
+    {
+      stateName = "expanded";
+      break;
+    }
+    case State::FOCUSABLE:
+    {
+      stateName = "focusable";
+      break;
+    }
+    case State::FOCUSED:
+    {
+      stateName = "focused";
+      break;
+    }
+    case State::HAS_TOOLTIP:
+    {
+      stateName = "has-tooltip";
+      break;
+    }
+    case State::HORIZONTAL:
+    {
+      stateName = "horizontal";
+      break;
+    }
+    case State::ICONIFIED:
+    {
+      stateName = "iconified";
+      break;
+    }
+    case State::MODAL:
+    {
+      stateName = "modal";
+      break;
+    }
+    case State::MULTI_LINE:
+    {
+      stateName = "multi-line";
+      break;
+    }
+    case State::MULTI_SELECTABLE:
+    {
+      stateName = "multiselectable";
+      break;
+    }
+    case State::OPAQUE:
+    {
+      stateName = "opaque";
+      break;
+    }
+    case State::PRESSED:
+    {
+      stateName = "pressed";
+      break;
+    }
+    case State::RESIZEABLE:
+    {
+      stateName = "resizable";
+      break;
+    }
+    case State::SELECTABLE:
+    {
+      stateName = "selectable";
+      break;
+    }
+    case State::SELECTED:
+    {
+      stateName = "selected";
+      break;
+    }
+    case State::SENSITIVE:
+    {
+      stateName = "sensitive";
+      break;
+    }
+    case State::SHOWING:
+    {
+      stateName = "showing";
+      break;
+    }
+    case State::SINGLE_LINE:
+    {
+      stateName = "single-line";
+      break;
+    }
+    case State::STALE:
+    {
+      stateName = "stale";
+      break;
+    }
+    case State::TRANSIENT:
+    {
+      stateName = "transient";
+      break;
+    }
+    case State::VERTICAL:
+    {
+      stateName = "vertical";
+      break;
+    }
+    case State::VISIBLE:
+    {
+      stateName = "visible";
+      break;
+    }
+    case State::MANAGES_DESCENDANTS:
+    {
+      stateName = "manages-descendants";
+      break;
+    }
+    case State::INDETERMINATE:
+    {
+      stateName = "indeterminate";
+      break;
+    }
+    case State::REQUIRED:
+    {
+      stateName = "required";
+      break;
+    }
+    case State::TRUNCATED:
+    {
+      stateName = "truncated";
+      break;
+    }
+    case State::ANIMATED:
+    {
+      stateName = "animated";
+      break;
+    }
+    case State::INVALID_ENTRY:
+    {
+      stateName = "invalid-entry";
+      break;
+    }
+    case State::SUPPORTS_AUTOCOMPLETION:
+    {
+      stateName = "supports-autocompletion";
+      break;
+    }
+    case State::SELECTABLE_TEXT:
+    {
+      stateName = "selectable-text";
+      break;
+    }
+    case State::IS_DEFAULT:
+    {
+      stateName = "is-default";
+      break;
+    }
+    case State::VISITED:
+    {
+      stateName = "visited";
+      break;
+    }
+    case State::CHECKABLE:
+    {
+      stateName = "checkable";
+      break;
+    }
+    case State::HAS_POPUP:
+    {
+      stateName = "has-popup";
+      break;
+    }
+    case State::READ_ONLY:
+    {
+      stateName = "read-only";
+      break;
+    }
+    case State::HIGHLIGHTED:
+    {
+      stateName = "highlighted";
+      break;
+    }
+    case State::HIGHLIGHTABLE:
+    {
+      stateName = "highlightable";
+      break;
+    }
+    case State::_COUNT:
+    {
+      break;
+    }
+  }
+  if( stateName )
+  {
+    auto addr = obj->GetAddress();
+    std::string p;
+    if( addr )
+      p = ATSPI_PREFIX_PATH + addr.GetPath();
+    else
+      p = ATSPI_NULL_PATH;
+    dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< int >, Address >(
+        p,
+        AtspiDbusInterfaceEventObject,
+        "StateChanged",
+        stateName,
+        newValue1,
+        newValue2,
+        {0},
+        {"", "root"} );
+  }
+}
+
+void BridgeObject::EmitBoundsChanged( Accessible* obj, Dali::Rect<> rect )
+{
+  auto addr = obj->GetAddress();
+  const auto prefixPath = "/org/a11y/atspi/accessible/";
+  const auto nullPath = "/org/a11y/atspi/null";
+  std::string p;
+  if( addr )
+    p = prefixPath + addr.GetPath();
+  else
+    p = nullPath;
+  DBus::EldbusVariant< std::tuple<int32_t, int32_t, int32_t, int32_t> > tmp {
+    std::tuple<int32_t, int32_t, int32_t, int32_t>{ rect.x, rect.y, rect.width, rect.height } };
+  addFilteredEvent(FilteredEvents::boundsChanged, obj, 1.0f, [=]() {
+    dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address >(
+      p,
+      AtspiDbusInterfaceEventObject,
+      "BoundsChanged",
+      "",
+      0,
+      0,
+      tmp,
+      {"", "root"} );
+  });
+}
+
+void BridgeObject::EmitCaretMoved( Accessible* obj, unsigned int cursorPosition )
+{
+  auto addr = obj->GetAddress();
+  std::string p = addr ? ATSPI_PREFIX_PATH + addr.GetPath() : ATSPI_NULL_PATH;
+  dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< int >, Address >(
+    p,
+    AtspiDbusInterfaceEventObject,
+    "TextCaretMoved",
+    "",
+    cursorPosition,
+    0,
+    {0},
+    {"", "root"} );
+}
+
+void BridgeObject::EmitTextChanged( Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string &content )
+{
+  const char* stateName = nullptr;
+  switch( state )
+  {
+    case TextChangedState::INSERT:
+    {
+      stateName = "insert";
+      break;
+    }
+    case TextChangedState::DELETE:
+    {
+      stateName = "delete";
+      break;
+    }
+    case TextChangedState::_COUNT:
+    {
+      break;
+    }
+  }
+  if( stateName )
+  {
+    auto addr = obj->GetAddress();
+    std::string p = addr ? ATSPI_PREFIX_PATH + addr.GetPath() : ATSPI_NULL_PATH;
+    dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< std::string >, Address >(
+        p,
+        AtspiDbusInterfaceEventObject,
+        "TextChanged",
+        stateName,
+        position,
+        length,
+        {content},
+        {"", "root"} );
+  }
+}
diff --git a/dali/internal/accessibility/bridge/bridge-object.h b/dali/internal/accessibility/bridge/bridge-object.h
new file mode 100644 (file)
index 0000000..18fa86b
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OBJECT_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OBJECT_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <array>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/bridge-base.h>
+#include <dali/public-api/math/rect.h>
+
+class BridgeObject : public virtual BridgeBase
+{
+protected:
+  BridgeObject();
+
+  void RegisterInterfaces();
+
+  DBus::DBusInterfaceDescription::SignalId stateChanged;
+
+  void EmitActiveDescendantChanged( Dali::Accessibility::Accessible* obj, Dali::Accessibility::Accessible *child ) override;
+  void EmitCaretMoved( Dali::Accessibility::Accessible* obj, unsigned int cursorPosition ) override;
+  void EmitTextChanged( Dali::Accessibility::Accessible* obj, Dali::Accessibility::TextChangedState state, unsigned int position, unsigned int length, const std::string &content ) override;
+  void EmitStateChanged( Dali::Accessibility::Accessible* obj, Dali::Accessibility::State state, int val1, int val2 ) override;
+  void Emit( Dali::Accessibility::Accessible* obj, Dali::Accessibility::WindowEvent we, unsigned int detail1 ) override;
+  void Emit( Dali::Accessibility::Accessible* obj, Dali::Accessibility::ObjectPropertyChangeEvent we ) override;
+  void EmitBoundsChanged( Dali::Accessibility::Accessible* obj, Dali::Rect<> rect ) override;
+
+public:
+  int GetChildCount();
+  DBus::ValueOrError< Dali::Accessibility::Accessible* > GetChildAtIndex( int index );
+  Dali::Accessibility::Accessible* GetParent();
+  DBus::ValueOrError< std::vector< Dali::Accessibility::Accessible* > > GetChildren();
+  std::string GetName();
+  std::string GetDescription();
+  DBus::ValueOrError< uint32_t > GetRole();
+  DBus::ValueOrError< std::string > GetRoleName();
+  DBus::ValueOrError< std::string > GetLocalizedRoleName();
+  DBus::ValueOrError< int32_t > GetIndexInParent();
+  DBus::ValueOrError< std::array< uint32_t, 2 > > GetStates();
+  DBus::ValueOrError< std::unordered_map< std::string, std::string > > GetAttributes();
+  DBus::ValueOrError< std::vector< std::string > > GetInterfaces();
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OBJECT_H
diff --git a/dali/internal/accessibility/bridge/bridge-text.cpp b/dali/internal/accessibility/bridge/bridge-text.cpp
new file mode 100644 (file)
index 0000000..0c3ed82
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/bridge-text.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/input/common/input-method-context-factory.h>
+
+using namespace Dali::Accessibility;
+
+void BridgeText::RegisterInterfaces()
+{
+  DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceText};
+  AddFunctionToInterface( desc, "GetText", &BridgeText::GetText );
+  AddGetPropertyToInterface( desc, "CharacterCount", &BridgeText::GetCharacterCount );
+  AddGetPropertyToInterface( desc, "CaretOffset", &BridgeText::GetCaretOffset );
+  AddFunctionToInterface( desc, "SetCaretOffset", &BridgeText::SetCaretOffset );
+  AddFunctionToInterface( desc, "GetTextAtOffset", &BridgeText::GetTextAtOffset );
+  AddFunctionToInterface( desc, "GetSelection", &BridgeText::GetSelection );
+  AddFunctionToInterface( desc, "SetSelection", &BridgeText::SetSelection );
+  AddFunctionToInterface( desc, "RemoveSelection", &BridgeText::RemoveSelection );
+  dbusServer.addInterface( "/", desc, true );
+}
+
+Text* BridgeText::FindSelf() const
+{
+  auto s = BridgeBase::FindSelf();
+  assert( s );
+  auto s2 = dynamic_cast< Text* >( s );
+  if( !s2 )
+    throw std::domain_error{"object " + s->GetAddress().ToString() + " doesn't have Text interface"};
+  return s2;
+}
+
+DBus::ValueOrError< std::string > BridgeText::GetText( int startOffset, int endOffset )
+{
+  return FindSelf()->GetText( startOffset, endOffset );
+}
+
+DBus::ValueOrError< int32_t > BridgeText::GetCharacterCount()
+{
+  return FindSelf()->GetCharacterCount();
+}
+
+DBus::ValueOrError< int32_t > BridgeText::GetCaretOffset()
+{
+  return FindSelf()->GetCaretOffset();
+}
+
+DBus::ValueOrError< bool > BridgeText::SetCaretOffset( int32_t offset )
+{
+  return FindSelf()->SetCaretOffset(offset);
+}
+
+DBus::ValueOrError< std::string, int, int > BridgeText::GetTextAtOffset( int32_t offset, uint32_t boundary )
+{
+  auto r = FindSelf()->GetTextAtOffset( offset, static_cast< TextBoundary >( boundary ) );
+  return {r.content, static_cast< int >( r.startOffset ), static_cast< int >( r.endOffset )};
+}
+
+DBus::ValueOrError< int, int > BridgeText::GetSelection( int32_t selectionNum )
+{
+  auto r = FindSelf()->GetSelection( selectionNum );
+  return {static_cast< int >( r.startOffset ), static_cast< int >( r.endOffset )};
+}
+
+DBus::ValueOrError< bool > BridgeText::RemoveSelection( int32_t selectionNum )
+{
+  return FindSelf()->RemoveSelection( selectionNum );
+}
+
+DBus::ValueOrError< bool > BridgeText::SetSelection( int32_t selectionNum, int32_t startOffset, int32_t endOffset )
+{
+  return FindSelf()->SetSelection( selectionNum, startOffset, endOffset );
+}
diff --git a/dali/internal/accessibility/bridge/bridge-text.h b/dali/internal/accessibility/bridge/bridge-text.h
new file mode 100644 (file)
index 0000000..f8661a7
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_TEXT_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_TEXT_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/bridge-base.h>
+
+class BridgeText : public virtual BridgeBase
+{
+protected:
+  BridgeText() = default;
+
+  void RegisterInterfaces();
+
+  Dali::Accessibility::Text* FindSelf() const;
+
+public:
+  DBus::ValueOrError< std::string > GetText( int startOffset, int endOffset );
+  DBus::ValueOrError< int32_t > GetCharacterCount();
+  DBus::ValueOrError< int32_t > GetCaretOffset();
+  DBus::ValueOrError< bool > SetCaretOffset( int32_t offset );
+  DBus::ValueOrError< std::string, int, int > GetTextAtOffset( int32_t offset, uint32_t boundary );
+  DBus::ValueOrError< int, int > GetSelection( int32_t selectionNum );
+  DBus::ValueOrError< bool > RemoveSelection( int32_t selectionNum );
+  DBus::ValueOrError< bool > SetSelection( int32_t selectionNum, int32_t startOffset, int32_t endOffset );
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_TEXT_H
diff --git a/dali/internal/accessibility/bridge/bridge-value.cpp b/dali/internal/accessibility/bridge/bridge-value.cpp
new file mode 100644 (file)
index 0000000..aa1a34c
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/bridge-value.h>
+
+// EXTERNAL INCLUDES
+#include <iostream>
+
+using namespace Dali::Accessibility;
+
+BridgeValue::BridgeValue()
+{
+}
+
+void BridgeValue::RegisterInterfaces()
+{
+  DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceValue};
+  AddGetSetPropertyToInterface( desc, "CurrentValue", &BridgeValue::GetCurrentValue, &BridgeValue::SetCurrentValue );
+  AddGetPropertyToInterface( desc, "MaximumValue", &BridgeValue::GetMaximumValue );
+  AddGetPropertyToInterface( desc, "MinimumIncrement", &BridgeValue::GetMinimumIncrement );
+  AddGetPropertyToInterface( desc, "MinimumValue", &BridgeValue::GetMinimumValue );
+  dbusServer.addInterface( "/", desc, true );
+}
+
+Value* BridgeValue::FindSelf() const
+{
+  auto s = BridgeBase::FindSelf();
+  assert( s );
+  auto s2 = dynamic_cast< Value* >( s );
+  if( !s2 )
+    throw std::domain_error{"object " + s->GetAddress().ToString() + " doesn't have Value interface"};
+  return s2;
+}
+double BridgeValue::GetCurrentValue()
+{
+  return FindSelf()->GetCurrent();
+}
+void BridgeValue::SetCurrentValue( double new_value )
+{
+  FindSelf()->SetCurrent( new_value );
+}
+double BridgeValue::GetMaximumValue()
+{
+  return FindSelf()->GetMaximum();
+}
+double BridgeValue::GetMinimumIncrement()
+{
+  return FindSelf()->GetMinimumIncrement();
+}
+double BridgeValue::GetMinimumValue()
+{
+  return FindSelf()->GetMinimum();
+}
diff --git a/dali/internal/accessibility/bridge/bridge-value.h b/dali/internal/accessibility/bridge/bridge-value.h
new file mode 100644 (file)
index 0000000..0fb921f
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_VALUE_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_VALUE_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <array>
+#include <string>
+#include <tuple>
+#include <unordered_map>
+#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/bridge-base.h>
+
+class BridgeValue : public virtual BridgeBase
+{
+protected:
+  BridgeValue();
+
+  void RegisterInterfaces();
+
+  Dali::Accessibility::Value* FindSelf() const;
+
+public:
+  double GetCurrentValue();
+  void SetCurrentValue( double new_value );
+  double GetMaximumValue();
+  double GetMinimumIncrement();
+  double GetMinimumValue();
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_VALUE_H
diff --git a/dali/internal/accessibility/bridge/component.cpp b/dali/internal/accessibility/bridge/component.cpp
new file mode 100644 (file)
index 0000000..73334a1
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+
+// EXTERNAL INCLUDES
+#include <iostream>
+
+// INTERNAL INCLUDES
+#include <dali/internal/accessibility/bridge/accessibility-common.h>
+
+using namespace Dali::Accessibility;
+
+bool Component::Contains( Point p, CoordType ctype )
+{
+  auto extents = GetExtents( ctype );
+  return p.x >= extents.x && p.y >= extents.y && p.x <= extents.x + extents.width && p.y <= extents.y + extents.height;
+}
+
+Accessible* Component::GetAccessibleAtPoint( Point p, CoordType ctype )
+{
+  auto children = GetChildren();
+  for( auto childIt = children.rbegin(); childIt != children.rend(); childIt++ )
+  {
+    auto component = dynamic_cast< Component* >( *childIt );
+    if( component && component->Contains( p, ctype ) )
+    {
+      return component;
+    }
+  }
+  return nullptr;
+}
+
+bool Component::IsScrollable()
+{
+  return false;
+}
diff --git a/dali/internal/accessibility/bridge/dbus-locators.h b/dali/internal/accessibility/bridge/dbus-locators.h
new file mode 100644 (file)
index 0000000..1bfb8ec
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_LOCATORS_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_LOCATORS_H
+
+/*
+ * Copyright 2019  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace dbusLocators
+{
+namespace callmgr
+{
+static constexpr const char* BUS = "org.tizen.callmgr";
+static constexpr const char* OBJ_PATH = "/org/tizen/callmgr";
+static constexpr const char* INTERFACE = "org.tizen.callmgr";
+}
+
+namespace accessibilityEMod
+{
+static constexpr const char* BUS = "org.enlightenment.wm-screen-reader";
+static constexpr const char* OBJ_PATH = "/org/tizen/GestureNavigation";
+static constexpr const char* INTERFACE = "org.tizen.GestureNavigation";
+
+static constexpr const char* ACCESSORIES_SP_ENABLED = "AccessoriesSwitchProviderEnabled";
+static constexpr const char* KEY_DOWN_SIGNAL = "KeyDown";
+static constexpr const char* KEY_UP_SIGNAL = "KeyUp";
+
+static constexpr const char* SCREEN_SP_ENABLED = "ScreenSwitchProviderEnabled";
+static constexpr const char* MOUSE_DOWN_SIGNAL = "MouseDown";
+static constexpr const char* MOUSE_UP_SIGNAL = "MouseUp";
+
+static constexpr const char* BACK_BUTTON_INTERCEPTION_ENABLED = "BackButtonInterceptionEnabled";
+static constexpr const char* BACK_BUTTON_DOWN_SIGNAL = "BackButtonDown";
+static constexpr const char* BACK_BUTTON_UP_SIGNAL = "BackButtonUp";
+}
+
+namespace freeDesktop
+{
+static constexpr const char* BUS = "org.freedesktop.DBus";
+static constexpr const char* OBJ_PATH = "/org/freedesktop/DBus";
+static constexpr const char* INTERFACE = "org.freedesktop.DBus";
+static constexpr const char* PROPERTIES_INTERFACE = "org.freedesktop.DBus.Properties";
+static constexpr const char* GET_CONNECTION_UNIX_PROCESS_ID = "GetConnectionUnixProcessID";
+static constexpr const char* SET = "Set";
+static constexpr const char* GET = "Get";
+}
+
+namespace windowManager
+{
+static constexpr const char* BUS = "org.enlightenment.wm";
+static constexpr const char* OBJ_PATH = "/org/enlightenment/wm";
+static constexpr const char* INTERFACE = "org.enlightenment.wm.proc";
+static constexpr const char* GET_VISIBLE_WIN_INFO = "GetVisibleWinInfo";
+static constexpr const char* GET_FOCUS_PROC = "GetFocusProc";
+}
+
+namespace atspi
+{
+static constexpr const char* BUS = "org.a11y.Bus";
+static constexpr const char* OBJ_PATH = "/org/a11y/bus";
+static constexpr const char* BUS_INTERFACE = "org.a11y.Bus";
+static constexpr const char* STATUS_INTERFACE = "org.a11y.Status";
+
+static constexpr const char* GET_ADDRESS = "GetAddress";
+static constexpr const char* IS_ENABLED = "IsEnabled";
+static constexpr const char* GET_ATTRIBUTES = "GetAttributes";
+static constexpr const char* DO_ACTION_NAME = "DoActionName";
+static constexpr const char* PARENT = "Parent";
+static constexpr const char* GET_MATCHES = "GetMatches";
+static constexpr const char* GET_INDEX_IN_PARENT = "GetIndexInParent";
+static constexpr const char* SELECT_CHILD = "SelectChild";
+static constexpr const char* NAME = "Name";
+static constexpr const char* GET_ROLE = "GetRole";
+static constexpr const char* CHILD_COUNT = "ChildCount";
+static constexpr const char* GET_CHILD_AT_INDEX = "GetChildAtIndex";
+static constexpr const char* GET_STATE = "GetState";
+static constexpr const char* GET_RELATION_SET = "GetRelationSet";
+static constexpr const char* GET_EXTENTS = "GetExtents";
+static constexpr const char* CURRENT_VALUE = "CurrentValue";
+static constexpr const char* MAXIMUM_VALUE = "MaximumValue";
+static constexpr const char* MINIMUM_VALUE = "MinimumValue";
+static constexpr const char* GET_INTERFACES = "GetInterfaces";
+static constexpr const char* GET_NAVIGABLE_AT_POINT = "GetNavigableAtPoint";
+}
+}
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_LOCATORS_H
diff --git a/dali/internal/accessibility/bridge/dbus.cpp b/dali/internal/accessibility/bridge/dbus.cpp
new file mode 100644 (file)
index 0000000..6353296
--- /dev/null
@@ -0,0 +1,1075 @@
+/*
+ * Copyright 2019  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// CLASS HEADER
+#include <dali/internal/accessibility/bridge/dbus.h>
+
+#include <dali/internal/accessibility/bridge/accessibility-common.h>
+
+// EXTERNAL INCLUDES
+#include <sstream>
+#include <iostream>
+#include <mutex>
+
+#include <Eldbus.h>
+#include <Ecore_Input.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/dali-adaptor-common.h>
+
+#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
+
+#undef EINA_FALSE
+#undef EINA_TRUE
+#define EINA_TRUE static_cast< Eina_Bool >( 1 )
+#define EINA_FALSE static_cast< Eina_Bool >( 0 )
+
+//#define DBUS_DEBUG(...) do { DBus::debugPrint(__FILE__, __LINE__, __VA_ARGS__); } while (0)
+
+std::atomic< unsigned int > DBus::detail::CallId::LastId{0};
+static std::function< void( const char*, size_t ) > debugPrinter;
+static std::mutex debugLock;
+
+thread_local std::string DBus::DBusServer::currentObjectPath;
+thread_local DBusWrapper::ConnectionPtr DBus::DBusServer::currentConnection;
+
+void DBus::setDebugPrinter( std::function< void( const char*, size_t ) > printer )
+{
+  std::lock_guard< std::mutex > lock( debugLock );
+  debugPrinter = std::move( printer );
+}
+
+void DBus::debugPrint( const char* file, size_t line, const char* format, ... )
+{
+  std::function< void( const char*, size_t ) > debugPrintFunc;
+  {
+    std::lock_guard< std::mutex > lock( debugLock );
+    if( !debugPrinter )
+      return;
+    debugPrintFunc = debugPrinter;
+  }
+  std::vector< char > buf( 4096 );
+  int offset;
+  while( true )
+  {
+    offset = snprintf( buf.data(), buf.size(), "%s:%u: ", file, static_cast< unsigned int >( line ) );
+    if( offset < 0 )
+      return;
+    if( static_cast< size_t >( offset ) < buf.size() )
+      break;
+    buf.resize( offset + 1 );
+  }
+
+  while( true )
+  {
+    va_list args;
+    va_start( args, format );
+    int z = vsnprintf( buf.data() + offset, buf.size() - offset, format, args );
+    va_end( args );
+    if( z < 0 )
+      return;
+    bool done = static_cast< size_t >( z ) + static_cast< size_t >( offset ) < buf.size();
+    buf.resize( static_cast< size_t >( z ) + static_cast< size_t >( offset ) );
+    if( done )
+      break;
+  }
+  debugPrintFunc( buf.data(), buf.size() );
+}
+
+DBusWrapper::ConnectionPtr DBus::getDBusConnectionByName( const std::string& name )
+{
+  return DBUS_W->eldbus_address_connection_get_impl( name );
+}
+
+DBusWrapper::ConnectionPtr DBus::getDBusConnectionByType( ConnectionType connectionType )
+{
+  return DBUS_W->eldbus_connection_get_impl(connectionType);
+}
+
+DBus::DBusClient::DBusClient( std::string busName, std::string pathName, std::string interfaceName, ConnectionType tp ) : DBusClient( std::move( busName ), std::move( pathName ), std::move( interfaceName ), getDBusConnectionByType( tp ) )
+{
+}
+
+DBus::DBusClient::DBusClient( std::string busName, std::string pathName, std::string interfaceName, const DBusWrapper::ConnectionPtr &conn )
+{
+  if( !conn )
+    connectionState->connection = getDBusConnectionByType( ConnectionType::SESSION );
+  else
+    connectionState->connection = conn;
+
+  std::ostringstream o;
+  o << "bus = " << busName << " path = " << pathName << " connection = " << DBUS_W->eldbus_connection_unique_name_get_impl( connectionState->connection );
+  info = o.str();
+
+  connectionState->object = DBUS_W->eldbus_object_get_impl( connectionState->connection, busName.c_str(), pathName.c_str() );
+  if( connectionState->object )
+  {
+    connectionState->proxy = DBUS_W->eldbus_proxy_get_impl( connectionState->object, interfaceName );
+    if( interfaceName != DBUS_INTERFACE_PROPERTIES )
+    {
+      connectionState->propertiesProxy = DBUS_W->eldbus_proxy_get_impl( connectionState->object, DBUS_INTERFACE_PROPERTIES );
+    }
+    else
+    {
+      connectionState->propertiesProxy = DBUS_W->eldbus_proxy_copy_impl( connectionState->proxy );
+    }
+  }
+  connectionInfo = std::make_shared< ConnectionInfo >();
+  connectionInfo->busName = std::move( busName );
+  connectionInfo->pathName = std::move( pathName );
+  connectionInfo->interfaceName = std::move( interfaceName );
+}
+
+DBus::DBusServer::DBusServer( ConnectionType tp ) : DBus::DBusServer( DBus::getDBusConnectionByType( tp ) )
+{
+}
+
+DBus::DBusServer::DBusServer( const DBusWrapper::ConnectionPtr &conn )
+{
+  if( !conn )
+    connection = getDBusConnectionByType( ConnectionType::SESSION );
+  else
+    connection = conn;
+}
+
+DBus::DBusInterfaceDescription::DBusInterfaceDescription( std::string interfaceName ) : interfaceName( std::move( interfaceName ) )
+{
+}
+
+void DBus::DBusServer::addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback )
+{
+  DBUS_W->add_interface_impl( fallback, pathName, connection, destructorObject->destructors, dscr.interfaceName, dscr.methods, dscr.properties, dscr.signals );
+}
+
+std::string DBus::DBusServer::getBusName() const
+{
+  return getConnectionName( connection );
+}
+
+std::string DBus::getConnectionName( const DBusWrapper::ConnectionPtr &c )
+{
+  return DBUS_W->eldbus_connection_unique_name_get_impl( c );
+}
+
+bool DBus::DBusClient::getFromEinaValue(const _Eina_Value *v, void *dst)
+{
+  return eina_value_get(const_cast<Eina_Value*>(v), dst);
+}
+
+/// \cond
+static std::unique_ptr<DBusWrapper> InstalledWrapper;
+
+struct DefaultDBusWrapper : public DBusWrapper {
+  constexpr static int ELDBUS_CALL_TIMEOUT = 1000;
+
+  DefaultDBusWrapper() {
+  }
+  ~DefaultDBusWrapper() {
+  }
+  #define DEFINE_GS(name, eldbus_name, unref_call) \
+    static eldbus_name *get(const std::shared_ptr<name> &a) { \
+      return static_cast<name ## Impl*>(a.get())->Value; \
+    } \
+    static eldbus_name *release(const std::shared_ptr<name> &a) { \
+      auto z = static_cast<name ## Impl*>(a.get())->Value; \
+      static_cast<name ## Impl*>(a.get())->Value = nullptr; \
+      return z; \
+    } \
+    template <typename ... ARGS> static std::shared_ptr<name> create(const eldbus_name *v, ARGS && ... args) { \
+      return std::make_shared<name ## Impl>(const_cast<eldbus_name*>(v), std::forward<ARGS>(args)...); \
+    }
+
+  #define DEFINE_TYPE(name, eldbus_name, unref_call) \
+  struct name ## Impl : public name { \
+    eldbus_name *Value = nullptr; \
+    bool EraseOnExit = false; \
+    name ## Impl(eldbus_name *Value, bool EraseOnExit = false) : Value(Value), EraseOnExit(EraseOnExit) { } \
+    ~name ## Impl() { \
+      if (EraseOnExit && Value) { unref_call; } \
+    } \
+  }; \
+  DEFINE_GS(name, eldbus_name, unref_call)
+
+  struct ConnectionImpl : public Connection {
+    Eldbus_Connection *Value = nullptr;
+    bool EraseOnExit = false;
+    ConnectionImpl(Eldbus_Connection *Value, bool EraseOnExit = false) : Value(Value), EraseOnExit(EraseOnExit) {
+      ecore_event_init();
+      eldbus_init();
+    }
+    ~ConnectionImpl() {
+      if (EraseOnExit && Value) {
+        eldbus_connection_unref( Value );
+      }
+      eldbus_shutdown();
+      ecore_event_shutdown();
+    }
+  };
+  struct MessageIterImpl : public MessageIter {
+    Eldbus_Message_Iter *Value = nullptr, *Parent = nullptr;
+    bool EraseOnExit = false;
+    MessageIterImpl(Eldbus_Message_Iter *Value, Eldbus_Message_Iter *Parent, bool EraseOnExit = false) : Value(Value), Parent(Parent), EraseOnExit(EraseOnExit) { }
+    ~MessageIterImpl() {
+      if (EraseOnExit && Value && Parent)
+        eldbus_message_iter_container_close(Parent, Value);
+    }
+  };
+
+  DEFINE_GS(Connection, Eldbus_Connection, )
+  DEFINE_GS(MessageIter, Eldbus_Message_Iter, )
+  DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref( Value ))
+  DEFINE_TYPE(Proxy, Eldbus_Proxy, )
+  DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref( Value ))
+  DEFINE_TYPE(Pending, Eldbus_Pending, )
+  DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
+  #undef DEFINE_TYPE
+
+  std::shared_ptr<Connection> eldbus_address_connection_get_impl(const std::string &addr) override {
+    eldbus_init();
+    auto p = eldbus_address_connection_get(addr.c_str());
+    auto w = create(p, true);
+    eldbus_shutdown();
+    return w;
+  }
+
+#define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
+  void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type src) override { \
+    eldbus_message_iter_arguments_append( get(it), #sig, src ); \
+  } \
+  bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type &dst) override { \
+    return eldbus_message_iter_get_and_next( get(it), (#sig)[0], &dst ); \
+  }
+
+  eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
+  eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
+  eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
+  eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
+  eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
+  eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
+  eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
+  eldbus_message_iter_arguments_append_impl_basic(double, d)
+
+#undef eldbus_message_iter_arguments_append_impl_basic
+
+  void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, bool src) override {
+    eldbus_message_iter_arguments_append( get(it), "b", src ? 1 : 0 );
+  }
+  bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, bool &dst) override {
+    unsigned char q;
+    auto z = eldbus_message_iter_get_and_next( get(it), 'b', &q );
+    dst = q != 0;
+    return z;
+  }
+  void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, const std::string &src) override {
+    eldbus_message_iter_arguments_append( get(it), "s", src.c_str() );
+  }
+  bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, std::string &dst) override {
+    auto iter = get(it);
+    const char* q;
+    if( !eldbus_message_iter_get_and_next( iter, 's', &q ) )
+    {
+      if( !eldbus_message_iter_get_and_next( iter, 'o', &q ) )
+        return false;
+    }
+    dst = q;
+    return true;
+  }
+  void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, const ObjectPath &src) override {
+    eldbus_message_iter_arguments_append( get(it), "o", src.value.c_str() );
+  }
+  bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, ObjectPath &dst) override {
+    const char* q;
+    if( !eldbus_message_iter_get_and_next( get(it), 'o', &q ) )
+      return false;
+    dst.value = q;
+    return true;
+  }
+
+  MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) override {
+    auto z = eldbus_message_iter_container_new( get(it), type, !sig.empty() ? sig.c_str() : NULL );
+    return create(z, get(it), true);
+  }
+  MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override {
+    Eldbus_Message_Iter* entry;
+    if (!eldbus_message_iter_get_and_next( get(it), type, &entry ) ) return {};
+    return create(entry, get(it), false);
+  }
+  MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &msg, bool) override {
+    return create(eldbus_message_iter_get(get(msg)), nullptr, false);
+  }
+  MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) {
+    return create(eldbus_proxy_method_call_new( get(proxy), funcName.c_str() ) );
+  }
+  MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override {
+    return create(eldbus_proxy_send_and_block(get(proxy), release(msg), ELDBUS_CALL_TIMEOUT) );
+  }
+  bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override {
+    const char *errname, *errmsg;
+    if( eldbus_message_error_get( get(msg), &errname, &errmsg ) ) {
+      name = errname;
+      text = errmsg;
+      return true;
+    }
+    return false;
+  }
+  std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override {
+    return eldbus_message_signature_get(get(msg));
+  }
+
+  static void callAsyncCb( void* data, const Eldbus_Message *msg,  Eldbus_Pending *pending )
+  {
+    auto d = static_cast< SendCallback* >( data );
+    (*d)( create(msg, false) );
+  }
+  static void pendingFreeCb( void* data, const void* )
+  {
+    auto d = static_cast< SendCallback* >( data );
+    delete d;
+  }
+  static void listenerCallbackFree( void* data, const void* )
+  {
+    auto d = static_cast< std::function< void( const Eldbus_Message* msg ) >* >( data );
+    delete d;
+  }
+
+  PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override {
+    auto cb = new SendCallback{ callback };
+    auto pending = eldbus_proxy_send( get(proxy), release(msg), callAsyncCb, cb, ELDBUS_CALL_TIMEOUT );
+    if( pending )
+    {
+      eldbus_pending_free_cb_add( pending, pendingFreeCb, cb );
+    }
+    else
+    {
+      delete cb;
+    }
+    return create(pending, false);
+  }
+  std::string eldbus_proxy_interface_get_impl(const ProxyPtr &proxy) override {
+    return eldbus_proxy_interface_get( get(proxy) );
+  }
+  static void listenerCallback( void* data, const Eldbus_Message* msg )
+  {
+    auto p = static_cast< std::function< void( const Eldbus_Message* msg ) >* >( data );
+    ( *p )( msg );
+  }
+  void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) override {
+    auto tmp = new std::function< void( const Eldbus_Message* msg ) >{
+      [cb](const Eldbus_Message* msg) {
+        cb(create(msg, false));
+      }
+    };
+    auto handler = eldbus_proxy_signal_handler_add( get(proxy), member.c_str(), listenerCallback, tmp );
+    if( handler )
+      eldbus_proxy_free_cb_add( get(proxy), listenerCallbackFree, tmp );
+    else
+      delete tmp;
+  }
+  std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override {
+    return eldbus_message_iter_signature_get( get(iter) );
+  }
+  MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) override {
+    return create(eldbus_message_method_return_new( get(msg) ) );
+  }
+  MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) override {
+    return create(eldbus_message_error_new( get(msg), err.c_str(), txt.c_str() ) );
+  }
+  PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) override {
+    return create(eldbus_connection_send( get(conn), get(msg), NULL, NULL, -1 ) );
+  }
+  MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) override {
+    return create(eldbus_message_signal_new( path.c_str(), iface.c_str(), name.c_str() ) );
+  }
+  MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) override {
+    return create(eldbus_message_ref( get(msg) ), true );
+  }
+  ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override {
+    Eldbus_Connection_Type eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
+
+    switch( type )
+    {
+      case ConnectionType::SYSTEM:
+      {
+        eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
+        break;
+      }
+      case ConnectionType::SESSION:
+      {
+        eldbusType = ELDBUS_CONNECTION_TYPE_SESSION;
+        break;
+      }
+    }
+
+    eldbus_init();
+    auto p = eldbus_connection_get( eldbusType );
+    auto w = create(p, true);
+    eldbus_shutdown();
+    return w;
+  }
+  std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) override {
+    return eldbus_connection_unique_name_get( get(conn) );
+  }
+  ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) override {
+      return create(eldbus_object_get(get(conn), bus.c_str(), path.c_str() ), true );
+  }
+  ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) override {
+    return create(eldbus_proxy_get(get(obj), interface.c_str() ), false );
+  }
+  ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) override {
+    return create(get(ptr), false );
+  }
+
+
+
+
+
+
+  struct Implementation
+  {
+    Eldbus_Service_Interface_Desc dsc;
+    std::vector< std::vector< Eldbus_Arg_Info > > argsInfos;
+    std::vector< Eldbus_Method > methods;
+    std::vector< Eldbus_Signal > signals;
+    std::vector< Eldbus_Property > properties;
+
+    std::unordered_map< std::string, DBusWrapper::MethodInfo > methodsMap;
+    std::unordered_map< std::string, DBusWrapper::PropertyInfo > propertiesMap;
+    std::unordered_map< unsigned int, DBusWrapper::SignalInfo > signalsMap;
+
+    DBusWrapper::ConnectionWeakPtr connection;
+  };
+
+  static std::unordered_map< const Eldbus_Service_Interface*, std::unique_ptr< Implementation > > globalEntries;
+  static std::mutex globalEntriesMutex;
+
+#undef EINA_FALSE
+#undef EINA_TRUE
+#define EINA_FALSE static_cast<Eina_Bool>(0)
+#define EINA_TRUE static_cast<Eina_Bool>(1)
+
+  static Eina_Bool property_get_callback( const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter,
+                                          const Eldbus_Message* message, Eldbus_Message** error )
+  {
+    Implementation* impl = nullptr;
+    {
+      std::lock_guard< std::mutex > lock( globalEntriesMutex );
+      auto it = globalEntries.find( iface );
+      if( it != globalEntries.end() )
+        impl = it->second.get();
+    }
+    if( !impl )
+      return EINA_FALSE;
+
+    auto it = impl->propertiesMap.find( propertyName );
+    if( it == impl->propertiesMap.end() || !it->second.getCallback )
+      return EINA_FALSE;
+
+    auto connection = impl->connection.lock();
+    if( !connection )
+      return EINA_FALSE;
+
+    DBus::DBusServer::CurrentObjectSetter currentObjectSetter( connection, eldbus_message_path_get( message ) );
+    auto reply = it->second.getCallback( create(message, false), create(iter, nullptr, false) );
+    if( !reply.empty() )
+    {
+      if( error )
+        *error = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", reply.c_str() );
+      return EINA_FALSE;
+    }
+
+    return EINA_TRUE;
+  }
+
+  static Eldbus_Message* property_set_callback( const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter,
+                                                const Eldbus_Message* message )
+  {
+    Implementation* impl = nullptr;
+    {
+      std::lock_guard< std::mutex > lock( globalEntriesMutex );
+      auto it = globalEntries.find( iface );
+      if( it != globalEntries.end() )
+        impl = it->second.get();
+    }
+    if( !impl )
+    {
+      auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown interface" );
+      return ret;
+    }
+    auto it = impl->propertiesMap.find( propertyName );
+    if( it == impl->propertiesMap.end() || !it->second.setCallback )
+    {
+      auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown setter" );
+      return ret;
+    }
+    auto connection = impl->connection.lock();
+    if( !connection )
+    {
+      auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Connection lost" );
+      return ret;
+    }
+
+    DBus::DBusServer::CurrentObjectSetter currentObjectSetter( connection, eldbus_message_path_get( message ) );
+    auto reply = it->second.setCallback( create(message, false), create(iter, nullptr, false) );
+
+    Eldbus_Message* ret = nullptr;
+    if( !reply.empty() )
+    {
+      ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", reply.c_str() );
+    }
+    else
+    {
+      ret = eldbus_message_method_return_new( message );
+    }
+    return ret;
+  }
+
+  static Eldbus_Message* method_callback( const Eldbus_Service_Interface* iface, const Eldbus_Message* message )
+  {
+    Implementation* impl = nullptr;
+    {
+      std::lock_guard< std::mutex > lock( globalEntriesMutex );
+      auto it = globalEntries.find( iface );
+      if( it != globalEntries.end() )
+        impl = it->second.get();
+    }
+    if( !impl )
+    {
+      auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown interface" );
+      return ret;
+    }
+    std::string memberName = eldbus_message_member_get( message );
+    auto it = impl->methodsMap.find( memberName );
+    if( it == impl->methodsMap.end() )
+    {
+      auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown method" );
+      return ret;
+    }
+    auto connection = impl->connection.lock();
+    if( !connection )
+    {
+      auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Connection lost" );
+      return ret;
+    }
+    DBus::DBusServer::CurrentObjectSetter currentObjectSetter( connection, eldbus_message_path_get( message ) );
+    auto reply = it->second.callback( create(message) );
+    return release(reply);
+  }
+
+  void add_interface_impl( bool fallback, const std::string& pathName,
+                              const ConnectionPtr &connection,
+                              std::vector<std::function<void()>> &destructors,
+                              const std::string& interfaceName,
+                              std::vector< MethodInfo >& dscrMethods,
+                              std::vector< PropertyInfo >& dscrProperties,
+                              std::vector< SignalInfo >& dscrSignals ) override
+  {
+    std::vector< Eldbus_Method > methods;
+    std::vector< Eldbus_Signal > signals;
+    std::vector< Eldbus_Property > properties;
+    std::vector< std::vector< Eldbus_Arg_Info > > argsInfos;
+    std::unordered_map< std::string, DBus::DBusInterfaceDescription::MethodInfo > methodsMap;
+    std::unordered_map< std::string, DBus::DBusInterfaceDescription::PropertyInfo > propertiesMap;
+    std::unordered_map< unsigned int, DBus::DBusInterfaceDescription::SignalInfo > signalsMap;
+
+    DBUS_DEBUG( "interface %s path %s on bus %s", interfaceName.c_str(), pathName.c_str(), DBus::getConnectionName( connection ).c_str() );
+    auto makeArgInfo = [&](const std::vector<std::pair<std::string, std::string>> &input) {
+      argsInfos.push_back({});
+      auto &dst = argsInfos.back();
+      for(auto &s : input) {
+        auto a = Strings.add(s.first);
+        auto b = Strings.add(s.second);
+        dst.push_back({ a, b });
+      }
+      dst.push_back({ nullptr, nullptr });
+      return dst.data();
+    };
+    for( auto& ee : dscrMethods )
+    {
+      auto key = ee.memberName;
+      DBUS_DEBUG( "adding method %s", ee.memberName.c_str() );
+      for( auto& r : ee.in )
+      {
+        DBUS_DEBUG( "in %s '%s'", r.first.c_str(), r.second.c_str() );
+      }
+      for( auto& r : ee.out )
+      {
+        DBUS_DEBUG( "out %s '%s'", r.first.c_str(), r.second.c_str() );
+      }
+      auto& e = ( methodsMap[key] = std::move( ee ) );
+      methods.push_back( {} );
+      auto& m = methods.back();
+      m.member = e.memberName.c_str();
+      m.in = makeArgInfo(e.in);
+      m.out = makeArgInfo(e.out);
+      m.cb = method_callback;
+      m.flags = 0;
+    }
+    for( auto& ee : dscrProperties )
+    {
+      auto key = ee.memberName;
+      DBUS_DEBUG( "adding property %s", ee.memberName.c_str() );
+      auto& e = ( propertiesMap[key] = std::move( ee ) );
+      properties.push_back( {} );
+      auto& m = properties.back();
+      m.name = e.memberName.c_str();
+      m.type = e.typeSignature.c_str();
+      m.get_func = e.getCallback ? property_get_callback : nullptr;
+      m.set_func = e.setCallback ? property_set_callback : nullptr;
+      m.flags = 0;
+    }
+    dscrMethods.clear();
+    dscrProperties.clear();
+    dscrSignals.clear();
+
+    methods.push_back( {nullptr, nullptr, nullptr, nullptr, 0} );
+    signals.push_back( {nullptr, nullptr, 0} );
+    properties.push_back( {nullptr, nullptr, nullptr, nullptr, 0} );
+
+    auto impl = std::unique_ptr< Implementation >( new Implementation{
+        {interfaceName.c_str(),
+        methods.data(),
+        signals.data(),
+        properties.data(),
+        nullptr,
+        nullptr},
+        std::move( argsInfos ),
+        std::move( methods ),
+        std::move( signals ),
+        std::move( properties ),
+        std::move( methodsMap ),
+        std::move( propertiesMap ),
+        std::move( signalsMap ),
+        connection} );
+
+    {
+      std::lock_guard< std::mutex > lock( globalEntriesMutex );
+      auto v = fallback ? eldbus_service_interface_fallback_register( get(connection), pathName.c_str(), &impl->dsc ) : eldbus_service_interface_register( get(connection), pathName.c_str(), &impl->dsc );
+      assert( v );
+      globalEntries[v] = std::move( impl );
+      DBUS_DEBUG( "registering interface %p (%d)", v, fallback ? 1 : 0 );
+      destructors.push_back([=]() {
+        DBUS_DEBUG( "unregistering interface %p", v );
+        eldbus_service_interface_unregister( v );
+        std::lock_guard< std::mutex > lock( globalEntriesMutex );
+        globalEntries.erase( v );
+      });
+    }
+  }
+  static void listenerEventChangedCallback( void* data, Eldbus_Proxy* proxy EINA_UNUSED, void* event )
+  {
+    auto p = static_cast< std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >* >( data );
+    ( *p )( static_cast< Eldbus_Proxy_Event_Property_Changed* >( event ) );
+  }
+  static void ProxyEventCallbackDelCb( void* data, const void *obj )
+  {
+    auto d = static_cast< std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >* >( data );
+    delete d;
+  }
+  void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const Eina_Value * ) > cb) override {
+    auto callbackLambdaPtr = new std::function< void( Eldbus_Proxy_Event_Property_Changed *epc ) >{
+      [cb, name, interface]( Eldbus_Proxy_Event_Property_Changed *ev ) {
+      const char* ifc = eldbus_proxy_interface_get( ev->proxy );
+      if( ev->name && ev->name == name && ifc && interface == ifc )
+      {
+        cb(ev->value);
+      }
+    } };
+    auto p = get(proxy);
+    eldbus_proxy_event_callback_add( p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
+                                     listenerEventChangedCallback, callbackLambdaPtr );
+    eldbus_proxy_free_cb_add( p, ProxyEventCallbackDelCb, callbackLambdaPtr );
+  }
+};
+
+std::unordered_map< const Eldbus_Service_Interface*, std::unique_ptr< DefaultDBusWrapper::Implementation > > DefaultDBusWrapper::globalEntries;
+std::mutex DefaultDBusWrapper::globalEntriesMutex;
+
+DBusWrapper *DBusWrapper::Installed()
+{
+  if (!InstalledWrapper)
+    InstalledWrapper.reset(new DefaultDBusWrapper);
+  return InstalledWrapper.get();
+}
+
+void DBusWrapper::Install(std::unique_ptr<DBusWrapper> w)
+{
+  InstalledWrapper = std::move(w);
+}
+
+/*
+// struct TestDBusWrapper::ConnectionImpl : public TestDBusWrapper::Connection {
+// };
+
+// TestDBusWrapper::TestDBusWrapper()
+// {
+//   eina_init();
+//   connection = std::make_shared<ConnectionImpl>();
+//   testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "ScreenReaderEnabled", MethodType::Getter}] =
+//   testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "IsEnabled", MethodType::Getter}] =
+//   [this](const DBusWrapper::MessagePtr &m) -> MessagePtr {
+//     auto reply = newReplyMessage(m);
+//     Encode(reply, std::tuple<TestDBusWrapper::Variant<bool>>{ TestDBusWrapper::Variant<bool>{ false} });
+//     return reply;
+//   };
+// }
+// TestDBusWrapper::~TestDBusWrapper()
+// {
+//   eina_shutdown();
+// }
+
+// TestDBusWrapper::ConnectionPtr TestDBusWrapper::eldbus_address_connection_get_impl(const std::string &addr)
+// {
+//   return connection;
+// }
+
+// struct TestDBusWrapper::MessageIterImpl : public TestDBusWrapper::MessageIter {
+//   MessagePtr msg;
+//   Element *elem;
+//   bool write;
+//   std::list<Element>::iterator it;
+//   MessageIterImpl(MessagePtr msg, Element *elem, bool write) : msg(std::move(msg)), elem(elem), write(write) {
+//     if (!write) it = elem->get<ElementList>().begin();
+//   }
+//   MessageIterImpl(MessagePtr msg, Element *elem, bool write, std::list<Element>::iterator it) : msg(std::move(msg)), elem(elem), write(write), it(it) { }
+// };
+// struct TestDBusWrapper::MessageImpl : public TestDBusWrapper::Message {
+//   std::string bus, path, interface, name;
+//   Element data;
+//   bool reply, error = false;
+//   std::string error_a, error_b;
+
+//   MessageImpl(std::string bus, std::string path, std::string interface, std::string name, bool reply) :
+//     bus(std::move(bus)), path(std::move(path)), interface(std::move(interface)), name(std::move(name)), data{ ElementList{} }, reply(reply) { }
+//   MessageImpl(std::string bus, std::string path, std::string interface, std::string name, std::string error_a, std::string error_b) :
+//     bus(std::move(bus)), path(std::move(path)), interface(std::move(interface)), name(std::move(name)), data{ ElementList{} },
+//     reply(true), error(true), error_a(std::move(error_a)), error_b(std::move(error_b)) { }
+// };
+// struct TestDBusWrapper::ProxyImpl : public TestDBusWrapper::Proxy {
+//   std::string bus, path, interface;
+//   ProxyImpl(std::string bus, std::string path, std::string interface) : bus(std::move(bus)), path(std::move(path)), interface(std::move(interface)) { }
+// };
+// struct TestDBusWrapper::ObjectImpl : public TestDBusWrapper::Object {
+//   std::string bus, path;
+//   ObjectImpl(std::string bus, std::string path) : bus(std::move(bus)), path(std::move(path)) { }
+// };
+// #define DEFINE_TYPE(name) TestDBusWrapper::name ## Impl *TestDBusWrapper::get(const name ## Ptr &v) { return static_cast<name ## Impl*>(v.get()); }
+//   DEFINE_TYPE(Connection)
+//   DEFINE_TYPE(Proxy)
+//   DEFINE_TYPE(Object)
+//   DEFINE_TYPE(Message)
+//   DEFINE_TYPE(MessageIter)
+// #undef DEFINE_TYPE
+
+// template <typename T> void TestDBusWrapperAppendBasic(const TestDBusWrapper::MessageIterPtr &it, T src) {
+//   auto m = TestDBusWrapper::get(it);
+//   if (!m->write) throw TestDBusWrapper::error{};
+//   if (!m->elem->isContainer()) throw TestDBusWrapper::error{};
+//   m->elem->get<TestDBusWrapper::ElementList>().push_back(TestDBusWrapper::Element{ src });
+// }
+// template <typename T> bool TestDBusWrapperGetBasicAndNext(const TestDBusWrapper::MessageIterPtr &it, T &src) {
+//   auto m = TestDBusWrapper::get(it);
+//   if (m->write) throw TestDBusWrapper::error{};
+//   if (!m->elem->isContainer()) return false;
+//   auto &lst = m->elem->get<TestDBusWrapper::ElementList>();
+//   if (m->it == lst.end()) return false;
+//   if (!m->it->is<T>()) return false;
+//   src = m->it->get<T>();
+//   ++m->it;
+//   return true;
+// }
+
+// #define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
+// void TestDBusWrapper::eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) { \
+//   TestDBusWrapperAppendBasic(it, src); \
+// } \
+// bool TestDBusWrapper::eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) { \
+//   return TestDBusWrapperGetBasicAndNext(it, dst); \
+// }
+// #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
+// eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
+
+// eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
+// eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
+// eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
+// eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
+// eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
+// eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
+// eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
+// eldbus_message_iter_arguments_append_impl_basic(double, d)
+// eldbus_message_iter_arguments_append_impl_basic(bool, b)
+// eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
+// eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
+
+// #undef eldbus_message_iter_arguments_append_impl_basic
+// #undef eldbus_message_iter_arguments_append_impl_basic_impl
+
+// TestDBusWrapper::MessageIterPtr TestDBusWrapper::eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) {
+//   auto m = get(it);
+//   if (!m->write) throw error{};
+//   if (!m->elem->isContainer()) throw error{};
+//   auto &lst = m->elem->get<ElementList>();
+//   if (type == 'r' || type == 'e' || type == 'a' || type == 'v') {
+//     lst.push_back({ ElementList{}, type });
+//     return std::make_shared<MessageIterImpl>(MessageIterImpl{ m->msg, &lst.back(), true });
+//   }
+//   throw error{};
+// }
+
+// TestDBusWrapper::MessageIterPtr TestDBusWrapper::eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) {
+//   auto m = get(it);
+//   if (m->write) throw error{};
+//   if (!m->elem->isContainer()) throw error{} << "not a container";
+//   auto &lst = m->elem->get<ElementList>();
+//   if (m->it == lst.end()) return {};
+//   if (m->it->signature() != type) return {};
+//   auto v = std::make_shared<MessageIterImpl>(MessageIterImpl{ m->msg, &*m->it, false });
+//   ++m->it;
+//   return v;
+// }
+
+// TestDBusWrapper::MessageIterPtr TestDBusWrapper::eldbus_message_iter_get_impl(const MessagePtr &it, bool write) {
+//   auto m = get(it);
+//   return std::make_shared<MessageIterImpl>(MessageIterImpl{ it, &m->data, write, m->data.get<ElementList>().begin() });
+// }
+
+// bool TestDBusWrapper::completed(const MessageIterPtr &iter)
+// {
+//   auto m = get(iter);
+//   assert(!m->write);
+//   return m->it == m->elem->get<ElementList>().end();
+// }
+
+// TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) {
+//   auto p = get(proxy);
+//   return std::make_shared<MessageImpl>(MessageImpl{
+//     p->bus, p->path, p->interface, funcName, false
+//   });
+// }
+// TestDBusWrapper::MessagePtr TestDBusWrapper::call(
+//     std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> &mp,
+//     const std::string &mpName, const MessagePtr &msg, MethodType type) {
+//   auto m = get(msg);
+//   auto findMethod = [&](std::string path, const std::string &iname, const std::string &name, MethodType type) {
+//     if (path.empty()) throw error{};
+//     if (path[0] != '/') {
+//       path = "/org/a11y/atspi/accessible/" + path;
+//       m->path = path;
+//     }
+//     while(!path.empty()) {
+//       auto it = mp.find(std::tuple<std::string, std::string, std::string, MethodType> { path, iname, name, type });
+//       if (it != mp.end()) return it;
+//       auto index = path.rfind('/');
+//       if (index == std::string::npos) break;
+//       path.resize(index);
+//     }
+//     return mp.end();
+//   };
+//   std::string iname, name;
+//   if (type == MethodType::Method && m->interface == "org.freedesktop.DBus.Properties") {
+//     type = m->name == "Get" ? MethodType::Getter : MethodType::Setter;
+//     auto &lst = m->data.get<ElementList>();
+//     assert(lst.size() >= 2);
+//     iname = lst.front().get<std::string>();
+//     lst.pop_front();
+//     name = lst.front().get<std::string>();
+//     lst.pop_front();
+//   }
+//   else {
+//     iname = m->interface;
+//     name = m->name;
+//   }
+//   auto it = findMethod(m->path, iname, name, type);
+//   if (it == mp.end()) {
+//     const char *mt;
+//     if (type == MethodType::Method) mt = "MethodType::Method";
+//     else if (type == MethodType::Getter) mt = "MethodType::Getter";
+//     else if (type == MethodType::Setter) mt = "MethodType::Setter";
+//     else assert(0);
+//     throw error{} << "missing {\"" << m->path << "\", \"" << iname << "\", \"" << name << "\", " << mt << "} in " << mpName;
+//   }
+//   DBus::DBusServer::CurrentObjectSetter setter{ connection, m->path };
+//   return it->second(msg);
+// }
+// TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) {
+//   auto p = get(proxy);
+//   auto m = get(msg);
+//   assert(p->bus == m->bus);
+//   assert(p->path == m->path);
+//   assert(p->interface == m->interface);
+//   return call(testMethods, "testMethods", msg, MethodType::Method);
+// }
+
+// bool TestDBusWrapper::eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) {
+//   auto m = get(msg);
+//   name = m->error_a;
+//   text = m->error_b;
+//   return m->error;
+// }
+// static void calculate_signature(std::ostringstream &ostr, TestDBusWrapper::Element &e)
+// {
+//   ostr << static_cast<char>(e.signature());
+//   if (e.isContainer()) {
+//     ostr << "(";
+//     auto &lst = e.get<TestDBusWrapper::ElementList>();
+//     for(auto &q : lst) calculate_signature(ostr, q);
+//     ostr << ")";
+//   }
+// }
+// std::string TestDBusWrapper::eldbus_message_signature_get_impl(const MessagePtr &msg) {
+//   auto m = get(msg);
+//   std::ostringstream ostr;
+//   for(auto &q : m->data.get<ElementList>())
+//     calculate_signature(ostr, q);
+//   return ostr.str();
+// }
+// TestDBusWrapper::PendingPtr TestDBusWrapper::eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) {
+//   auto p = get(proxy);
+//   auto m = get(msg);
+//   assert(p->bus == m->bus);
+//   assert(p->path == m->path);
+//   assert(p->interface == m->interface);
+//   asyncCalls.push_back([this, msg, callback]() {
+//     auto r = call(testMethods, "testMethods", msg, MethodType::Method);
+//     callback(r);
+//   });
+//   return {};
+// }
+// std::string TestDBusWrapper::eldbus_proxy_interface_get_impl(const ProxyPtr &proxy) {
+//   auto p = get(proxy);
+//   return p->interface;
+// }
+// void TestDBusWrapper::eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) {
+//   auto p = get(proxy);
+//   daliSignals[std::tuple<std::string, std::string, std::string> { p->path, p->interface, member }] = cb;
+// }
+// std::string TestDBusWrapper::eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) {
+//   auto m = get(iter);
+//   if (m->write) throw error{};
+//   if (!m->elem->isContainer()) throw error{};
+//   std::ostringstream ostr;
+//   auto &lst = m->elem->get<ElementList>();
+//   for(auto it = m->it; it != lst.end(); ++it)
+//     calculate_signature(ostr, *it);
+//   return ostr.str();
+// }
+// TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_message_method_return_new_impl( const MessagePtr &msg) {
+//   auto m = get(msg);
+//   return std::make_shared<MessageImpl>(MessageImpl{
+//     m->bus, m->path, m->interface, m->name, true
+//   });
+// }
+// TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) {
+//   auto m = get(msg);
+//   return std::make_shared<MessageImpl>(MessageImpl{
+//     m->bus, m->path, m->interface, m->name, err, txt
+//   });
+// }
+// TestDBusWrapper::PendingPtr TestDBusWrapper::eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) {
+//   call(testMethods, "testMethods", msg, MethodType::Method);
+//   return {};
+// }
+// std::shared_ptr<Eina_Value> TestDBusWrapper::createEinaValue(bool b) {
+//   Eina_Value *value = eina_value_new(EINA_VALUE_TYPE_UCHAR);
+//   eina_value_set(value, b);
+//   return std::shared_ptr<Eina_Value>(value, [](Eina_Value *v) {
+//     eina_value_free(v);
+//   });
+// }
+// TestDBusWrapper::MessagePtr TestDBusWrapper::newMessage(const std::string &path, const std::string &interface, const std::string &name, bool reply) {
+//   return std::make_shared<MessageImpl>(MessageImpl{
+//     "bus", path, interface, name, reply
+//   });
+// }
+// TestDBusWrapper::MessagePtr TestDBusWrapper::newReplyMessage(const MessagePtr &msg) {
+//   auto m = get(msg);
+//   return newMessage(m->path, m->interface, m->name, true);
+// }
+// TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) {
+//   return std::make_shared<MessageImpl>(MessageImpl{
+//     "bus", path, iface, name, true
+//   });
+// }
+// TestDBusWrapper::MessagePtr TestDBusWrapper::eldbus_message_ref_impl(const MessagePtr &msg) {
+//   return msg;
+// }
+// TestDBusWrapper::ConnectionPtr TestDBusWrapper::eldbus_connection_get_impl(ConnectionType type) {
+//   return connection;
+// }
+// std::string TestDBusWrapper::eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) {
+//   return "bus";
+// }
+// TestDBusWrapper::ObjectPtr TestDBusWrapper::eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) {
+//   return std::make_shared<ObjectImpl>(ObjectImpl{
+//     bus, path
+//   });
+// }
+// TestDBusWrapper::ProxyPtr TestDBusWrapper::eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) {
+//   auto o = get(obj);
+//   return std::make_shared<ProxyImpl>(ProxyImpl{ o->bus, o->path, interface });
+// }
+// TestDBusWrapper::ProxyPtr TestDBusWrapper::eldbus_proxy_copy_impl( const ProxyPtr &ptr) {
+//   return ptr;
+// }
+// void TestDBusWrapper::add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const Eina_Value * ) > cb) {
+//   auto p = get(proxy);
+//   propertyChangeListeners[std::tuple<std::string, std::string, std::string>{ p->path, interface, name }] = cb;
+// }
+// void TestDBusWrapper::add_interface_impl( bool fallback, const std::string& path_,
+//                             const ConnectionPtr &connection,
+//                             std::vector<std::function<void()>> &destructors,
+//                             const std::string& interface,
+//                             std::vector< MethodInfo >& dscrMethods,
+//                             std::vector< PropertyInfo >& dscrProperties,
+//                             std::vector< SignalInfo >& dscrSignals ) {
+//   std::string bus = "bus";
+//   std::string path = path_;
+//   while(!path.empty() && path.back() == '/') path.pop_back();
+//   for(auto &m : dscrMethods) {
+//     auto key = std::make_tuple( "/org/a11y/atspi/accessible" + path, interface, m.memberName, MethodType::Method );
+//     daliMethods[key] = m.callback;
+//   }
+//   for(auto &m : dscrProperties) {
+//     auto key = std::make_tuple( "/org/a11y/atspi/accessible" + path, interface, m.memberName, MethodType::Getter );
+//     daliMethods[key] = [=](const MessagePtr &msg) -> MessagePtr {
+//       auto ret = std::make_shared<MessageImpl>(MessageImpl{
+//         "bus", path, interface, m.memberName, true
+//       });
+//       auto v = m.getCallback(msg, std::make_shared<MessageIterImpl>(MessageIterImpl{ ret, &ret->data, true }));
+//       ret->error = !v.empty();
+//       if (ret->error) {
+//         ret->error_a = "call failed";
+//         ret->error_b = std::move(v);
+//       }
+//       return ret;
+//     };
+//     std::get<3>(key) = MethodType::Setter;
+//     daliMethods[key] = [=](const MessagePtr &msg) -> MessagePtr {
+//       auto v = m.setCallback(msg, std::make_shared<MessageIterImpl>(MessageIterImpl{ msg, &get(msg)->data, false }));
+//       return v.empty() ? std::make_shared<MessageImpl>(MessageImpl{
+//         "bus", path, interface, m.memberName, true,
+//       }) : std::make_shared<MessageImpl>(MessageImpl{
+//         "bus", path, interface, m.memberName, "call failed", v
+//       });
+//        // interface is probably wrong, due to retarded way properties are handlded by dbus
+//     };
+//   }
+//   for(auto &m : dscrSignals) {
+//     daliSignalsMap[std::tuple<std::string, std::string, unsigned int>{ "/org/a11y/atspi/accessible" + path, interface, m.uniqueId }] = m.memberName;
+//   }
+// }
+*/
+
+/// \endcond
\ No newline at end of file
diff --git a/dali/internal/accessibility/bridge/dbus.h b/dali/internal/accessibility/bridge/dbus.h
new file mode 100644 (file)
index 0000000..4aa28fb
--- /dev/null
@@ -0,0 +1,3322 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
+
+/*
+ * Copyright 2019  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <memory>
+#include <array>
+#include <atomic>
+#include <cstdint>
+#include <map>
+#include <sstream>
+#include <string>
+#include <thread>
+#include <tuple>
+#include <type_traits>
+#include <unordered_map>
+#include <vector>
+#include <functional>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/accessibility.h>
+#include <dali/internal/accessibility/bridge/optional.h>
+
+#define ATSPI_PREFIX_PATH "/org/a11y/atspi/accessible/"
+#define ATSPI_NULL_PATH "/org/a11y/atspi/null"
+
+struct _Eina_Value;
+
+/// \cond
+struct ObjectPath
+{
+  std::string value;
+};
+
+struct DALI_ADAPTOR_API DBusWrapper
+{
+  virtual ~DBusWrapper() = default;
+
+  enum class ConnectionType
+  {
+    SYSTEM,
+    SESSION
+  };
+
+#define DEFINE_TYPE(name, eldbus_name, unref_call) \
+    struct name { virtual ~name() = default; }; \
+    using name ## Ptr = std::shared_ptr<name>; \
+    using name ## WeakPtr = std::weak_ptr<name>; \
+
+  DEFINE_TYPE(Connection, Eldbus_Connection, )
+  DEFINE_TYPE(MessageIter, Eldbus_Message_Iter, eldbus_message_iter_container_close( Value ))
+  DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref( Value ))
+  DEFINE_TYPE(Proxy, Eldbus_Proxy, eldbus_proxy_unref( Value ))
+  DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref( Value ))
+  DEFINE_TYPE(Pending, Eldbus_Pending, )
+  DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
+
+#undef DEFINE_TYPE
+  virtual ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) = 0;
+
+#define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
+  virtual void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) = 0; \
+  virtual bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) = 0;
+#define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
+  eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
+
+  eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
+  eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
+  eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
+  eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
+  eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
+  eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
+  eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
+  eldbus_message_iter_arguments_append_impl_basic(double, d)
+  eldbus_message_iter_arguments_append_impl_basic(bool, b)
+  eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
+  eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
+
+#undef eldbus_message_iter_arguments_append_impl_basic
+#undef eldbus_message_iter_arguments_append_impl_basic_impl
+
+  virtual MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) = 0;
+  virtual MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) = 0;
+  virtual MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) = 0;
+  virtual MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) = 0;
+  virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) = 0;
+  virtual bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) = 0;
+  virtual std::string eldbus_message_signature_get_impl(const MessagePtr &msg) = 0;
+
+  using SendCallback = std::function<void(const MessagePtr &msg)>;
+  virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) = 0;
+  virtual std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) = 0;
+  virtual void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) = 0;
+  virtual std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) = 0;
+  virtual MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) = 0;
+  virtual MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) = 0;
+  virtual PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) = 0;
+  virtual MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) = 0;
+  virtual MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) = 0;
+  virtual ConnectionPtr eldbus_connection_get_impl(ConnectionType type) = 0;
+  virtual std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) = 0;
+  virtual ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) = 0;
+  virtual ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) = 0;
+  virtual ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) = 0;
+
+  class StringStorage
+  {
+  public:
+    struct char_ptr_deleter
+    {
+      void operator()( char* p )
+      {
+        free( p );
+      }
+    };
+    std::vector< std::unique_ptr< char, char_ptr_deleter > > storage;
+
+    const char* add( const char* txt )
+    {
+      auto ptr = strdup( txt );
+      storage.push_back( std::unique_ptr< char, char_ptr_deleter >( ptr ) );
+      return storage.back().get();
+    }
+    const char* add( const std::string& txt )
+    {
+      return add( txt.c_str() );
+    }
+  };
+
+  struct CallId
+  {
+    static std::atomic< unsigned int > LastId;
+    unsigned int id = ++LastId;
+  };
+  struct MethodInfo
+  {
+    CallId id;
+    std::string memberName;
+    std::vector< std::pair<std::string, std::string> > in, out; // _Eldbus_Arg_Info
+    std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > callback;
+  };
+  struct SignalInfo
+  {
+    CallId id;
+    std::string memberName;
+    std::vector< std::pair<std::string, std::string> > args;
+    unsigned int uniqueId;
+  };
+  struct PropertyInfo
+  {
+    CallId setterId, getterId;
+    std::string memberName, typeSignature;
+    std::function< std::string( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) > getCallback, setCallback;
+  };
+  struct SignalId
+  {
+    CallId id;
+
+    SignalId() = default;
+    SignalId( CallId id ) : id( id ) {}
+  };
+  virtual void add_interface_impl( bool fallback, const std::string& pathName,
+                              const ConnectionPtr &connection,
+                              std::vector<std::function<void()>> &destructors,
+                              const std::string& interfaceName,
+                              std::vector< MethodInfo >& dscrMethods,
+                              std::vector< PropertyInfo >& dscrProperties,
+                              std::vector< SignalInfo >& dscrSignals ) = 0;
+  virtual void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const _Eina_Value * ) > cb) = 0;
+  static DBusWrapper *Installed();
+  static void Install(std::unique_ptr<DBusWrapper>);
+
+  StringStorage Strings;
+};
+
+namespace detail {
+  enum class MethodType {
+    Method, Getter, Setter
+  };
+}
+
+namespace std {
+  template <> struct hash<std::tuple<std::string, std::string, std::string>> {
+    size_t operator () (const std::tuple<std::string, std::string, std::string> &a) const {
+      auto a1 = std::hash<std::string>()(std::get<0>(a));
+      auto a2 = std::hash<std::string>()(std::get<1>(a));
+      auto a3 = std::hash<std::string>()(std::get<2>(a));
+      size_t v = a1;
+      v = (v * 11400714819323198485llu) + a2;
+      v = (v * 11400714819323198485llu) + a3;
+      return v;
+    }
+  };
+  template <> struct hash<std::tuple<std::string, std::string, std::string, detail::MethodType>> {
+    size_t operator () (const std::tuple<std::string, std::string, std::string, detail::MethodType> &a) const {
+      auto a1 = std::hash<std::string>()(std::get<0>(a));
+      auto a2 = std::hash<std::string>()(std::get<1>(a));
+      auto a3 = std::hash<std::string>()(std::get<2>(a));
+      auto a4 = static_cast<size_t>(std::get<3>(a));
+      size_t v = a1;
+      v = (v * 11400714819323198485llu) + a2;
+      v = (v * 11400714819323198485llu) + a3;
+      v = (v * 11400714819323198485llu) + a4;
+      return v;
+    }
+  };
+  template <> struct hash<std::tuple<std::string, std::string, unsigned int>> {
+    size_t operator () (const std::tuple<std::string, std::string, unsigned int> &a) const {
+      auto a1 = std::hash<std::string>()(std::get<0>(a));
+      auto a2 = std::hash<std::string>()(std::get<1>(a));
+      auto a3 = std::get<2>(a);
+      size_t v = a1;
+      v = (v * 11400714819323198485llu) + a2;
+      v = (v * 11400714819323198485llu) + a3;
+      return v;
+    }
+  };
+}
+namespace detail {
+  template <typename T> struct DBusSigImpl { enum { value = 0, end = 0 }; };
+  template <typename T> struct DBusSig { enum { value = DBusSigImpl<typename std::decay<T>::type>::value, end = DBusSigImpl<typename std::decay<T>::type>::end }; };
+  template <typename T, typename Q, size_t I, size_t S> struct IndexFromTypeTupleImpl {
+    enum { value = std::is_same<typename std::decay<typename std::tuple_element<I, T>::type>::type, Q>::value ? I : IndexFromTypeTupleImpl<T, Q, I + 1, S>::value };
+  };
+  template <typename T, typename Q, size_t S> struct IndexFromTypeTupleImpl<T, Q, S, S> { enum { value = S }; };
+  template <typename T, typename Q> struct IndexFromTypeTuple {
+    enum { value = IndexFromTypeTupleImpl<T, typename std::decay<Q>::type, 0, std::tuple_size<T>::value>::value };
+  };
+  template <typename T, typename = void> struct Encoder;
+  template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple;
+}
+struct DALI_ADAPTOR_API TestDBusWrapper : public DBusWrapper
+{
+  using MethodType = detail::MethodType;
+  ConnectionPtr connection;
+  std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> testMethods;
+  std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> daliMethods;
+  std::unordered_map<std::tuple<std::string, std::string, unsigned int>, std::string> daliSignalsMap;
+  std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const MessagePtr&)>> daliSignals;
+  std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const _Eina_Value *)>> propertyChangeListeners;
+
+  std::vector<std::function<void()>> asyncCalls;
+
+  template <typename T> struct Variant {
+    T value;
+    Variant() = default;
+    Variant(T t) : value(std::move(t)) { }
+  };
+  template <typename ... ARGS> void Encode(const MessagePtr &m, const std::tuple<ARGS...> &args) {
+    auto iter = eldbus_message_iter_get_impl(m, true);
+    detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(*this, iter, args);
+  }
+  template <typename ... ARGS> void Decode(const MessagePtr &m, std::tuple<ARGS...> &args) {
+    auto iter = eldbus_message_iter_get_impl(m, false);
+    detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(*this, args, iter);
+  }
+  MessagePtr newMessage(const std::string &path, const std::string &interface, const std::string &name, bool reply);
+  MessagePtr newReplyMessage(const MessagePtr &m);
+
+  template <typename ... ARGS> void fromTestEmitSignal(std::string path, const std::string &interface, const std::string &name, const std::tuple<ARGS...> &args) {
+    if (path.empty()) throw error{};
+    if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
+    auto msg = newMessage(path, interface, name, false);
+    Encode(msg, args);
+    auto it = daliSignals.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
+    if (it == daliSignals.end()) throw error{};
+    it->second(msg);
+  }
+  static std::shared_ptr<_Eina_Value> createEinaValue(bool);
+  template <typename T> void fromTestChangeProperty(std::string path, const std::string &interface, const std::string &name, T new_value) {
+    auto v = createEinaValue(new_value);
+    if (path.empty()) throw error{};
+    if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
+    auto it = propertyChangeListeners.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
+    if (it == propertyChangeListeners.end()) throw error{};
+    it->second(v.get());
+  }
+  template <typename ... ARGS1, typename ... ARGS2> std::tuple<ARGS1...> fromTestCall(const std::string &path, const std::string &interface, const std::string &name, const std::tuple<ARGS2...> &args) {
+    auto msg = newMessage(path, interface, name, false);
+    Encode(msg, args);
+    auto res = call(daliMethods, "daliMethods", msg, MethodType::Method);
+    std::string a, b;
+    if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
+    std::tuple<ARGS1...> tmp;
+    Decode(res, tmp);
+    return tmp;
+  }
+  template <typename T> T fromTestGet(const std::string &path, const std::string &interface, const std::string &name) {
+    auto msg = newMessage(path, interface, name, false);
+    auto res = call(daliMethods, "daliMethods", msg, MethodType::Getter);
+    std::string a, b;
+    if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
+    std::tuple<T> tmp;
+    Decode(res, tmp);
+    return std::move(std::get<0>(tmp));
+  }
+  template <typename ... ARGS1, typename T> std::tuple<ARGS1...> fromTestSet(const std::string &path, const std::string &interface, const std::string &name, const T &arg) {
+    auto msg = newMessage(path, interface, name, false);
+    Encode(msg, TestDBusWrapper::Variant<T>{ arg });
+    auto res = call(daliMethods, "daliMethods", msg, MethodType::Setter);
+    std::string a, b;
+    if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
+    std::tuple<ARGS1...> tmp;
+    Decode(res, tmp);
+    return tmp;
+  }
+
+  TestDBusWrapper();
+  ~TestDBusWrapper();
+
+  class error : public std::exception {
+    std::shared_ptr<std::ostringstream> temp = std::make_shared<std::ostringstream>();
+    mutable std::string text;
+  public:
+    error() = default;
+
+    template <typename T> error &operator << (T &&t) {
+      *temp << std::forward<T>(t);
+      return *this;
+    }
+    const char *what() const noexcept override {
+      text = temp->str();
+      return text.c_str();
+    }
+  };
+  #define DEFINE_TYPE(name) struct name ## Impl; static name ## Impl *get(const name ## Ptr &);
+  DEFINE_TYPE(Connection)
+  DEFINE_TYPE(Proxy)
+  DEFINE_TYPE(Object)
+  DEFINE_TYPE(Message)
+  DEFINE_TYPE(MessageIter)
+  #undef DEFINE_TYPE
+
+  class Element;
+  using ElementList = std::list<Element>;
+  using ElementMap = std::map<std::string, std::string>;
+  using ElementTuple = std::tuple<
+    uint8_t, uint16_t, uint32_t, uint64_t, int16_t, int32_t, int64_t, double, bool, std::string, ObjectPath,
+    ElementList
+  >;
+
+  class Element {
+    ElementTuple data;
+    char signature_ = 0, end_ = 0, index_ = 0;
+    template <typename T> void set(T &&t, char signature = detail::DBusSig<T>::value) {
+      signature_ = signature;
+      end_ = detail::DBusSig<T>::end;
+      index_ = static_cast<char>(detail::IndexFromTypeTuple<ElementTuple, T>::value);
+      get<T>() = std::forward<T>(t);
+    }
+  public:
+    template <typename T> Element(T &&t, typename std::enable_if<detail::DBusSig<T>::value != 0>::type* = nullptr) { set(std::forward<T>(t)); }
+    Element(ElementList t, int signature) { set(std::move(t), static_cast<char>(signature)); }
+
+    char signature() const { return signature_; }
+    char end() const { return end_; }
+    char index() const { return index_; }
+    bool isContainer() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, ElementList>::value; }
+    template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
+    bool is() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, T>::value; }
+    template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
+    const T &get() const { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
+    template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
+    T &get() { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
+  };
+
+  ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) override;
+
+#define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
+  void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) override; \
+  bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) override;
+#define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
+  eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
+
+  eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
+  eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
+  eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
+  eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
+  eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
+  eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
+  eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
+  eldbus_message_iter_arguments_append_impl_basic(double, d)
+  eldbus_message_iter_arguments_append_impl_basic(bool, b)
+  eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
+  eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
+
+#undef eldbus_message_iter_arguments_append_impl_basic
+#undef eldbus_message_iter_arguments_append_impl_basic_impl
+
+  MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) override;
+  MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override;
+  MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) override;
+  MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) override;
+  MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override;
+  bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override;
+  std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override;
+  PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override;
+  std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) override;
+  void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) override;
+  std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override;
+  MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) override;
+  MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) override;
+  PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) override;
+  MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) override;
+  MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) override;
+  ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override;
+  std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) override;
+  ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) override;
+  ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) override;
+  ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) override;
+  void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const _Eina_Value * ) > cb) override;
+  void add_interface_impl( bool fallback, const std::string& pathName,
+                              const ConnectionPtr &connection,
+                              std::vector<std::function<void()>> &destructors,
+                              const std::string& interfaceName,
+                              std::vector< MethodInfo >& dscrMethods,
+                              std::vector< PropertyInfo >& dscrProperties,
+                              std::vector< SignalInfo >& dscrSignals ) override;
+  static bool completed(const MessageIterPtr &iter);
+private:
+  MessagePtr call(std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> &mp, const std::string &name, const MessagePtr &msg, MethodType type);
+};
+
+namespace detail {
+  template <> struct DBusSigImpl<uint8_t> { enum { value = 'y', end = 0 }; };
+  template <> struct DBusSigImpl<uint16_t> { enum { value = 'q', end = 0 }; };
+  template <> struct DBusSigImpl<uint32_t> { enum { value = 'u', end = 0 }; };
+  template <> struct DBusSigImpl<uint64_t> { enum { value = 't', end = 0 }; };
+  template <> struct DBusSigImpl<int16_t> { enum { value = 'n', end = 0 }; };
+  template <> struct DBusSigImpl<int32_t> { enum { value = 'i', end = 0 }; };
+  template <> struct DBusSigImpl<int64_t> { enum { value = 'x', end = 0 }; };
+  template <> struct DBusSigImpl<double> { enum { value = 'd', end = 0 }; };
+  template <> struct DBusSigImpl<bool> { enum { value = 'b', end = 0 }; };
+  template <> struct DBusSigImpl<std::string> { enum { value = 's', end = 0 }; };
+  template <> struct DBusSigImpl<ObjectPath> { enum { value = 'o', end = 0 }; };
+  template <> struct DBusSigImpl<TestDBusWrapper::ElementList> { enum { value = '(', end = ')' }; };
+  template <> struct DBusSigImpl<TestDBusWrapper::ElementMap> { enum { value = '{', end = '}' }; };
+
+  template <typename T> struct Encoder<T, decltype(TestDBusWrapper().eldbus_message_iter_arguments_append_impl(TestDBusWrapper::MessageIterPtr(), T()))> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+      w.eldbus_message_iter_arguments_append_impl(tgt, src);
+    }
+    static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      if (!w.eldbus_message_iter_get_and_next_impl(src, tgt)) throw TestDBusWrapper::error{};
+    }
+  };
+  template <typename T> struct Encoder<T, typename std::enable_if<std::is_enum<T>::value>::type> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+      Encoder<typename std::underlying_type<T>::type>::encode(w, tgt, static_cast<typename std::underlying_type<T>::type>(src));
+    }
+    static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      typename std::underlying_type<T>::type v = 0;
+      Encoder<typename std::underlying_type<T>::type>::decode(w, v, src);
+      tgt = static_cast<T>(v);
+    }
+  };
+  template <typename T> struct Encoder<const T> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+      Encoder<T>::encode(w, tgt, src);
+    }
+    static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      Encoder<T>::decode(w, tgt, src);
+    }
+  };
+  template <typename T> struct Encoder<const T &> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+      Encoder<T>::encode(w, tgt, src);
+    }
+    static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      Encoder<T>::decode(w, tgt, src);
+    }
+  };
+  template <typename T> struct Encoder<T &> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
+      Encoder<T>::encode(w, tgt, src);
+    }
+    static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      Encoder<T>::decode(w, tgt, src);
+    }
+  };
+  template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
+      Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::encode(w, tgt, std::get<I>(src));
+      EncoderTuple<I + 1, S, ARGS...>::encode(w, tgt, src);
+    }
+    static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::decode(w, std::get<I>(tgt), src);
+      EncoderTuple<I + 1, S, ARGS...>::decode(w, tgt, src);
+    }
+  };
+  template <size_t S, typename ... ARGS> struct EncoderTuple<S, S, ARGS...> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) { }
+    static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) { }
+  };
+  template <typename ...ARGS> struct Encoder<std::tuple<ARGS...>> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
+      auto var = w.eldbus_message_iter_container_new_impl( tgt, 'r', "");
+      EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(w, var, src);
+    }
+    static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'r' );
+      if( !s ) throw TestDBusWrapper::error{};
+      EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(w, tgt, s);
+    }
+  };
+  template <typename A, typename B> struct Encoder<std::pair<A, B>> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::pair<A, B> &src, char type = 'r') {
+      auto var = w.eldbus_message_iter_container_new_impl( tgt, type, "");
+      Encoder<A>::encode(w, var, src.first);
+      Encoder<B>::encode(w, var, src.second);
+    }
+    static void decode(TestDBusWrapper &w, std::pair<A, B> &tgt, const TestDBusWrapper::MessageIterPtr &src, char type = 'r') {
+      auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, type );
+      if( !s ) throw TestDBusWrapper::error{};
+      Encoder<A>::decode(w, tgt.first, s);
+      Encoder<B>::decode(w, tgt.second, s);
+    }
+  };
+  template <typename T> struct Encoder<TestDBusWrapper::Variant<T>> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const TestDBusWrapper::Variant<T> &src) {
+      //w.eldbus_message_iter_arguments_append_impl(tgt, src);
+      auto var = w.eldbus_message_iter_container_new_impl( tgt, 'v', "");
+      Encoder<T>::encode(w, var, src.value);
+    }
+    static void decode(TestDBusWrapper &w, TestDBusWrapper::Variant<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'v' );
+      if( !s ) throw TestDBusWrapper::error{};
+      Encoder<T>::decode(w, tgt.value, s);
+    }
+  };
+  template <typename T> struct Encoder<std::vector<T>> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::vector<T> &src) {
+      auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
+      for(auto &q : src)
+        Encoder<T>::encode(w, var, q);
+    }
+    static void decode(TestDBusWrapper &w, std::vector<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
+      if( !s ) throw TestDBusWrapper::error{};
+      while(!TestDBusWrapper::completed(s)) {
+        tgt.push_back({});
+        Encoder<T>::decode(w, tgt.back(), s);
+      }
+    }
+  };
+  template <typename K, typename V> struct Encoder<std::unordered_map<K,V>> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::unordered_map<K,V> &src) {
+      auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
+      for(auto &q : src){
+        Encoder<typename std::unordered_map<K,V>::value_type>::encode(w, var, q, 'e');
+      }
+    }
+    static void decode(TestDBusWrapper &w, std::unordered_map<K,V> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
+      if( !s ) throw TestDBusWrapper::error{};
+      while(!TestDBusWrapper::completed(s)) {
+        std::pair<K, V> tmp;
+        Encoder<std::pair<K,V>>::decode(w, tmp, s, 'e');
+        tgt.insert(std::move(tmp));
+      }
+    }
+  };
+  template <typename T, size_t I> struct Encoder<std::array<T, I>> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::array<T, I> &src) {
+      auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
+      for(auto &q : src)
+        Encoder<T>::encode(w, var, q);
+    }
+    static void decode(TestDBusWrapper &w, std::array<T, I> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
+      if( !s ) throw TestDBusWrapper::error{};
+      size_t i = 0;
+      while(!TestDBusWrapper::completed(s)) {
+        if(i >= tgt.size()) throw TestDBusWrapper::error{};
+        Encoder<T>::decode(w, tgt[i], s);
+        ++i;
+      }
+      if( i!=tgt.size()) throw TestDBusWrapper::error{};
+    }
+  };
+  template <> struct Encoder<Dali::Accessibility::Address> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const Dali::Accessibility::Address &src) {
+      Encoder<std::tuple<std::string, ObjectPath>>::encode(w, tgt,std::tuple<std::string, ObjectPath> {
+        src.GetBus(), ObjectPath{ "/org/a11y/atspi/accessible/" + src.GetPath() } }
+      );
+    }
+    static void decode(TestDBusWrapper &w, Dali::Accessibility::Address &tgt, const TestDBusWrapper::MessageIterPtr &src) {
+      std::tuple<std::string, ObjectPath> tmp;
+      Encoder<std::tuple<std::string, ObjectPath>>::decode(w, tmp, src);
+      static const size_t prefixSize = std::string{ "/org/a11y/atspi/accessible/" }.size();
+      tgt = { std::move(std::get<0>(tmp)), std::get<1>(tmp).value.substr(prefixSize) };
+    }
+  };
+  template <> struct Encoder<const char*> {
+    static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const char *src) {
+      Encoder<std::string>::encode(w, tgt, src);
+    }
+  };
+}
+/// \endcond
+
+#define DBUS_DEBUG( ... )                                \
+  do                                                     \
+  {                                                      \
+    DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \
+  } while( 0 )
+
+#define DBUS_W DBusWrapper::Installed()
+
+/**
+ * @brief Template based, single file, wrapper library around eldbus for DBUS based communication.
+ *
+ * Main motivation was missing asynchronous calls in AT-SPI library and difficulties,
+ * when using eldbus from C++.
+ *
+ * The library:
+ * - takes care of marshalling arguments to and from DBUS calls.
+ * - allows synchronous and asynchronous calls.
+ * - allows synchronous and asynchronous listeners on signals.
+ * - manages all involved objects' lifetimes.
+ * - errors are passed as optional-alike objects, no exceptions are used.
+ * - allows setting additional debug-print function for more details about
+ *   what's going on
+ *
+ * DBUS's method signatures (and expected return values) are specified as template argument,
+ * using functor syntax. For example:
+ * \code{.cpp}
+ * auto dbus = DBusClient{ ... };
+ * auto v = dbus.method<std::tuple<int, float>(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe");
+ * \endcode
+ * means (synchronous) call on dbus object, which takes three arguments (thus making call signature \b dds)
+ * of types float, float and string (float will be automatically converted to double).
+ * Expected return value is std::tuple<int, float>, which gives signature <B>(id)</B> - std::tuple acts
+ * as struct container. Returned value v will be of type ValueOrError<std::tuple<int, float>>.\n
+ * Slightly different (asynchronous) example:
+ * \code{.cpp}
+ * auto dbus = DBusClient{ ... };
+ * std::function<void(ValueOrError<int, float>)> callback;
+ * dbus.method<ValueOrError<int, float>(float, float, std::string)>("foo").asyncCall(callback, 1.0f, 2.0f, "qwe");
+ * \endcode
+ * Now the call takes the same arguments and has the same signature. But expected values are different -
+ * now the signature is simply \b id. ValueOrError acts in this case as placeholder for list of values,
+ * which DBUS allows as return data. The call itself is asynchronous - instead of expecting reply
+ * you need to pass a callback, which will be called either with received data and error message.
+ *
+ * Library is not thread-safe, the same object shouldn't be called from different threads without
+ * synchronization. There's no guarantee, that callbacks will be executed on the same thread.
+ */
+namespace DBus
+{
+/// \cond
+class DBusServer;
+class DBusClient;
+class DBusInterfaceDescription;
+
+/**
+ * @brief Formats debug message and calls debug printer (if any) with it
+ */
+void debugPrint( const char* file, size_t line, const char* format, ... );
+
+/**
+ * @brief Sets debug printer callback, which will be called with debug messages
+ *
+ * Callback will be called in various moments of DBus activity. First value passed to callback
+ * is pointer to text, second it's length. Text is ended with 0 (not counted towards it's size),
+ * user can safely printf it.
+ */
+void setDebugPrinter( std::function< void( const char*, size_t ) > );
+
+struct Error
+{
+  std::string message;
+
+  Error() = default;
+  Error( std::string msg ) : message( std::move( msg ) )
+  {
+    assert( !message.empty() );
+  }
+};
+
+struct Success
+{
+};
+/// \endcond
+
+/**
+ * @brief Value representing data, that came from DBUS or error message
+ *
+ * Object of this class either helds series of values (of types ARGS...)
+ * or error message. This object will be true in boolean context, if has data
+ * and false, if an error occured.
+ * It's valid to create ValueOrError object with empty argument list or void:
+ * \code{.cpp}
+ * ValueOrError<> v1;
+ * ValueOrError<void> v2;
+ * \endcode
+ * Both mean the same - ValueOrError containing no real data and being a marker,
+ * wherever operation successed or failed and containing possible error message.
+ */
+template < typename... ARGS >
+class ValueOrError
+{
+public:
+  /**
+   * @brief Empty constructor. Valid only, if all ARGS types are default constructible.
+   */
+  ValueOrError() = default;
+
+  /**
+   * @brief Value constructor.
+   *
+   * This will be initialized as success with passed in values.
+   */
+  ValueOrError( ARGS... t ) : value( std::move( t )... ) {}
+
+  /**
+   * @brief Alternative Value constructor.
+   *
+   * This will be initialized as success with passed in values.
+   */
+  ValueOrError( std::tuple< ARGS... > t ) : value( std::move( t ) ) {}
+
+  /**
+   * @brief Error constructor. This will be initialized as failure with given error message.
+   */
+  ValueOrError( Error e ) : error( std::move( e ) )
+  {
+    assert( !error.message.empty() );
+  }
+
+  /**
+   * @brief bool operator.
+   *
+   * Returns true, if operation was successful (getValues member is callable), or false
+   * when operation failed (getError is callable).
+   */
+  explicit operator bool() const
+  {
+    return error.message.empty();
+  }
+
+  /**
+   * @brief Returns error message object.
+   *
+   * Returns object containing error message associated with the failed operation.
+   * Only callable, if operation actually failed, otherwise will assert.
+   */
+  const Error& getError() const
+  {
+    return error;
+  }
+
+  /**
+   * @brief Returns modifiable tuple of held data.
+   *
+   * Returns reference to the internal tuple containing held data.
+   * User can modify (or move) data safely.
+   * Only callable, if operation actually successed, otherwise will assert.
+   */
+  std::tuple< ARGS... >& getValues()
+  {
+    assert( *this );
+    return value;
+  }
+
+  /**
+   * @brief Returns const tuple of held data.
+   *
+   * Returns const reference to the internal tuple containing held data.
+   * Only callable, if operation actually successed, otherwise will assert.
+   */
+  const std::tuple< ARGS... >& getValues() const
+  {
+    assert( *this );
+    return value;
+  }
+
+protected:
+  /// \cond
+  std::tuple< ARGS... > value;
+  Error error;
+  /// \endcond
+};
+
+/// \cond
+template <>
+class ValueOrError<>
+{
+public:
+  ValueOrError() = default;
+  ValueOrError( std::tuple<> t ) {}
+  ValueOrError( Error e ) : error( std::move( e ) )
+  {
+    assert( !error.message.empty() );
+  }
+
+  explicit operator bool() const
+  {
+    return error.message.empty();
+  }
+  const Error& getError() const
+  {
+    return error;
+  }
+  std::tuple<>& getValues()
+  {
+    assert( *this );
+    static std::tuple<> t;
+    return t;
+  }
+  std::tuple<> getValues() const
+  {
+    assert( *this );
+    return {};
+  }
+
+protected:
+  Error error;
+};
+
+template <>
+class ValueOrError< void >
+{
+public:
+  ValueOrError() = default;
+  ValueOrError( Success ) {}
+  ValueOrError( Error e ) : error( std::move( e ) )
+  {
+    assert( !error.message.empty() );
+  }
+
+  explicit operator bool() const
+  {
+    return error.message.empty();
+  }
+  const Error& getError() const
+  {
+    return error;
+  }
+  std::tuple<>& getValues()
+  {
+    assert( *this );
+    static std::tuple<> t;
+    return t;
+  }
+  std::tuple<> getValues() const
+  {
+    assert( *this );
+    return {};
+  }
+
+protected:
+  Error error;
+};
+
+using ObjectPath = ObjectPath;
+
+/// \endcond
+
+/**
+ * @brief Class used to marshall DBUS's variant type
+ *
+ * Minimalistic class, that allows user to specify DBUS variant type
+ * as argument or return value. You need to pass real type hidden under variant as
+ * template type \b A. At this point library doesn't allow to expected one of few classes
+ * as return data in variant. So for example user can't specify method call, which on return
+ * expects DBUS variant holding either string or int.
+ */
+template < typename A >
+struct EldbusVariant
+{
+  A value;
+};
+
+/**
+ * @brief Namespace for private, internal functions and classes
+ */
+namespace detail
+{
+/// \cond
+template < typename T, typename = void >
+struct signature;
+template < typename... ARGS >
+struct signature< std::tuple< ARGS... > >;
+template < typename A, typename B >
+struct signature< std::pair< A, B > >;
+template < typename A >
+struct signature< std::vector< A > >;
+template < typename A, size_t N >
+struct signature< std::array< A, N > >;
+template < typename A, typename B >
+struct signature< std::unordered_map< A, B > >;
+template < typename A, typename B >
+struct signature< std::map< A, B > >;
+/// \endcond
+
+/**
+ * @brief Signature class for marshalling uint8 type.
+ */
+template <>
+struct signature< uint8_t >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "uint8_t";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "y";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, uint8_t v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, uint8_t& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+};
+
+/**
+ * @brief Signature class for marshalling uint16 type.
+ */
+template <>
+struct signature< uint16_t >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "uint16_t";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "q";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, uint16_t v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, uint16_t& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+};
+
+/**
+ * @brief Signature class for marshalling uint32 type.
+ */
+template <>
+struct signature< uint32_t >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "uint32_t";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "u";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, uint32_t v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, uint32_t& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+};
+
+/**
+ * @brief Signature class for marshalling uint64 type.
+ */
+template <>
+struct signature< uint64_t >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "uint64_t";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "t";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, uint64_t v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, uint64_t& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+};
+
+/**
+ * @brief Signature class for marshalling int16 type.
+ */
+template <>
+struct signature< int16_t >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "int16_t";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "n";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, int16_t v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, int16_t& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+};
+
+/**
+ * @brief Signature class for marshalling int32 type.
+ */
+template <>
+struct signature< int32_t >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "int32_t";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "i";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, int32_t v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, int32_t& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+};
+
+/**
+ * @brief Signature class for marshalling int64 type.
+ */
+template <>
+struct signature< int64_t >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "int64_t";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "x";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, int64_t v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, int64_t& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+};
+
+/**
+ * @brief Signature class for marshalling double type.
+ */
+template <>
+struct signature< double >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "double";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "d";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, double v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
+  {
+    double v = 0;
+    auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+    v2 = static_cast< float >( v );
+    return r;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling float type.
+ */
+template <>
+struct signature< float >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "float";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "d";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, float v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
+  {
+    double v = 0;
+    auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+    v2 = static_cast< float >( v );
+    return r;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling boolean type.
+ */
+template <>
+struct signature< bool >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "bool";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "b";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, bool v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, bool& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+};
+
+template < typename T >
+struct signature< T, typename std::enable_if< std::is_enum< T >::value, void >::type >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "enum";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return signature<typename std::underlying_type<T>::type>::sig();
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, T v )
+  {
+    signature<typename std::underlying_type<T>::type>::set(iter, static_cast< int64_t >( v ));
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, T& v )
+  {
+    typename std::underlying_type<T>::type q = 0;
+    if (!signature<typename std::underlying_type<T>::type>::get(iter, q))
+      return false;
+
+    v = static_cast< T >( q );
+    return true;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling string type.
+ *
+ * Both (const) char * and std::string types are accepted as value to send.
+ * Only std::string is accepted as value to receive.
+ */
+template <>
+struct signature< std::string >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "string";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "s";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+// /**
+//  * @brief Marshals value v as marshalled type into message
+//  */
+//  static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
+//  {
+//    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+//  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+};
+
+template <>
+struct signature< ObjectPath >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "path";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "o";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const ObjectPath& v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, ObjectPath& v )
+  {
+    return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
+  {
+    ObjectPath q;
+    if (!DBUS_W->eldbus_message_iter_get_and_next_impl(iter, q)) return false;
+    v = std::move(q.value);
+    return true;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling (const) char * type.
+ *
+ * Both (const) char * and std::string types are accepted as value to send.
+ * You can't use (const) char * variable type to receive value.
+ */
+template <>
+struct signature< char* >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "string";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "s";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
+  {
+    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, std::string{ v });
+  }
+};
+/// \cond
+
+template < size_t INDEX, typename A, typename... ARGS >
+struct signature_tuple_element_type_helper
+{
+  using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type;
+};
+
+template < typename A, typename... ARGS >
+struct signature_tuple_element_type_helper< 0, A, ARGS... >
+{
+  using type = A;
+};
+/// \endcond
+
+/**
+ * @brief Helper class to marshall tuples
+ *
+ * This class marshals all elements of the tuple value starting at the index INDEX
+ * and incrementing. This class recursively calls itself with increasing INDEX value
+ * until INDEX is equal to SIZE, where recursive calling ends.
+ */
+template < size_t INDEX, size_t SIZE, typename... ARGS >
+struct signature_tuple_helper
+{
+  using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type;
+
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    if( INDEX + 1 >= SIZE )
+      return signature< current_type >::name();
+    return signature< current_type >::name() + ", " + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::name();
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return signature< current_type >::sig() + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::sig();
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
+  {
+    signature< current_type >::set( iter, std::get< INDEX >( args ) );
+    signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set( iter, args );
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
+  {
+    return signature< current_type >::get( iter, std::get< INDEX >( args ) ) &&
+           signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get( iter, args );
+  }
+};
+
+/**
+ * @brief Helper class to marshall tuples
+ *
+ * This class marks end of the tuple marshalling. Members of this class are called
+ * when INDEX value is equal to SIZE.
+ */
+template < size_t SIZE, typename... ARGS >
+struct signature_tuple_helper< SIZE, SIZE, ARGS... >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
+  {
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
+  {
+    return true;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling tuple of values
+ *
+ * This class marshalls tuple of values. This represents
+ * DBUS struct typle, encoded with character 'r'
+ */
+template < typename... ARGS >
+struct signature< std::tuple< ARGS... > >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "tuple<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "(" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig() + ")";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
+  {
+    auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'r', "");
+    signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( entry, args );
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
+  {
+    auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
+    if (!entry) return false;
+    return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( entry, args );
+  }
+};
+
+/**
+ * @brief Signature class for marshalling ValueOrError template type
+ *
+ * ValueOrError template type is used to marshall list of values passed to
+ * DBUS (or received from) at the "top" level. For example ss(s) is represented as
+ * \code{.cpp} ValueOrError<std::string, std::string, std::tuple<std::string>> \endcode
+ * While (ss(s)) is represented as
+ * \code{.cpp} std::tuple<std::string, std::string, std::tuple<std::string>> \endcode
+ * or
+ * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \endcode
+ */
+template < typename... ARGS >
+struct signature< ValueOrError< ARGS... > >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "ValueOrError<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig();
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< ARGS... >& args )
+  {
+    signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( iter, args.getValues() );
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< ARGS... >& args )
+  {
+    return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( iter, args.getValues() );
+  }
+};
+
+/**
+ * @brief Signature class for marshalling ValueOrError<void> type
+ */
+template <>
+struct signature< ValueOrError< void > >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "ValueOrError<void>";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< void >& args )
+  {
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< void >& args )
+  {
+    return true;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling ValueOrError<> type
+ */
+template <>
+struct signature< ValueOrError<> >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "ValueOrError<>";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError<>& args )
+  {
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError<>& args )
+  {
+    return true;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling pair of types
+ */
+template < typename A, typename B >
+struct signature< std::pair< A, B > >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "pair<" + signature_tuple_helper< 0, 2, A, B >::name() + ">";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "(" + signature_tuple_helper< 0, 2, A, B >::sig() + ")";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::pair< A, B >& ab, bool dictionary = false )
+  {
+    auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, dictionary ? 'e' : 'r', "");
+    signature_tuple_helper< 0, 2, A, B >::set( entry, ab );
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::pair< A, B >& ab )
+  {
+    auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
+    if (!entry) {
+      entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, '{' );
+      if (!entry) return false;
+    }
+
+    std::tuple< A, B > ab_tmp;
+    auto z = signature_tuple_helper< 0, 2, A, B >::get( entry, ab_tmp );
+    if( z )
+    {
+      ab.first = std::move( std::get< 0 >( ab_tmp ) );
+      ab.second = std::move( std::get< 1 >( ab_tmp ) );
+    }
+    return z;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling std::vector template type
+ *
+ * This marshals container's content as DBUS a ascii character type code.
+ */
+template < typename A >
+struct signature< std::vector< A > >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "vector<" + signature< A >::name() + ">";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "a" + signature< A >::sig();
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::vector< A >& v )
+  {
+    auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
+    assert( lst );
+    for( auto& a : v )
+    {
+      signature< A >::set( lst, a );
+    }
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::vector< A >& v )
+  {
+    auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
+    if (!s) return false;
+    v.clear();
+    A a;
+    while( signature< A >::get( s, a ) )
+      v.push_back( std::move( a ) );
+
+    return true;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling std::array template type
+ *
+ * This marshals container's content as DBUS a ascii character type code.
+ */
+template < typename A, size_t N >
+struct signature< std::array< A, N > >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "array<" + signature< A >::name() + ", " + std::to_string( N ) + ">";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "a" + signature< A >::sig();
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::array< A, N >& v )
+  {
+    auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
+    assert( lst );
+    for( auto& a : v )
+    {
+      signature< A >::set( lst, a );
+    }
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::array< A, N >& v )
+  {
+    auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
+    if ( !s )
+      return false;
+    for( auto& a : v )
+    {
+      if( !signature< A >::get( s, a ) )
+        return false;
+    }
+    return true;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling EldbusVariant type
+ *
+ * This marshals variant's content as DBUS v ascii character type code.
+ */
+template < typename A >
+struct signature< EldbusVariant< A > >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "variant<" + signature< A >::name() + ">";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "v";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const EldbusVariant< A >& v )
+  {
+    set( iter, v.value );
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
+  {
+    auto var = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'v', signature< A >::sig());
+    signature< A >::set( var, v );
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, EldbusVariant< A >& v )
+  {
+    auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'v' );
+    if( !s )
+      return false;
+    return signature< A >::get( s, v.value );
+  }
+};
+
+/**
+ * @brief Signature class for marshalling std::unordered_map template type
+ *
+ * This marshals container's content as DBUS {} ascii character type code.
+ * Note, that library doesnt check, if the key is basic type, as DBUS
+ * specification mandates.
+ * User can always exchange std::unordered_map for std::map and the reverse.
+ * User can receive such values as std::vector of std::pair<key, value> values.
+ * Order of such values is unspecified.
+ */
+template < typename A, typename B >
+struct signature< std::unordered_map< A, B > >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "unordered_map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::unordered_map< A, B >& v )
+  {
+    auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
+    auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
+    assert( lst );
+    for( auto& a : v )
+    {
+      signature< std::pair< A, B > >::set( lst, a, true );
+    }
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::unordered_map< A, B >& v )
+  {
+    auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
+    v.clear();
+    if( !s )
+      return false;
+    std::pair< A, B > a;
+    while( signature< std::pair< A, B > >::get( s, a ) )
+      v.insert( std::move( a ) );
+    return true;
+  }
+};
+
+/**
+ * @brief Signature class for marshalling std::unordered_map template type
+ *
+ * This marshals container's content as DBUS {} ascii character type code.
+ * Note, that library doesnt check, if the key is basic type, as DBUS
+ * specification mandates.
+ * User can always exchange std::unordered_map for std::map and the reverse.
+ * User can receive such values as std::vector of std::pair<key, value> values.
+ * Order of such values is unspecified.
+ */
+template < typename A, typename B >
+struct signature< std::map< A, B > >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const std::map< A, B >& v )
+  {
+    auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
+    auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
+    assert( lst );
+    for( auto& a : v )
+    {
+      signature< std::pair< A, B > >::set( lst, a, true );
+    }
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static bool get( const DBusWrapper::MessageIterPtr &iter, std::map< A, B >& v )
+  {
+    auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
+    if( !s )
+      return false;
+    std::pair< A, B > a;
+    while( signature< std::pair< A, B > >::get( s, a ) )
+      v.insert( std::move( a ) );
+    return true;
+  }
+};
+
+/**
+ * @brief Signature helper class for marshalling const reference types
+ */
+template < typename A >
+struct signature< const A& >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "const " + signature< A >::name() + "&";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return signature< A >::sig();
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
+  {
+    signature< A >::set( iter, v );
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
+  {
+    signature< A >::get( iter, v );
+  }
+};
+
+/**
+ * @brief Signature helper class for marshalling reference types
+ */
+template < typename A >
+struct signature< A& >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return signature< A >::name() + "&";
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return signature< A >::sig();
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
+  {
+    signature< A >::set( iter, v );
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
+  {
+    signature< A >::get( iter, v );
+  }
+};
+
+/**
+ * @brief Signature helper class for marshalling const types
+ */
+template < typename A >
+struct signature< const A >
+{
+  /**
+   * @brief Returns name of type marshalled, for informative purposes
+   */
+  static std::string name()
+  {
+    return "const " + signature< A >::name();
+  }
+
+  /**
+   * @brief Returns DBUS' signature of type marshalled
+   */
+  static std::string sig()
+  {
+    return signature< A >::sig();
+  }
+
+  /**
+   * @brief Marshals value v as marshalled type into message
+   */
+  static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
+  {
+    signature< A >::set( iter, v );
+  }
+
+  /**
+   * @brief Marshals value from marshalled type into variable v
+   */
+  static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
+  {
+    signature< A >::get( iter, v );
+  }
+};
+
+/// \cond
+using CallId = DBusWrapper::CallId;
+
+template < typename ValueType >
+ValueType unpackValues( CallId callId, const DBusWrapper::MessagePtr &msg )
+{
+  auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, false );
+  ValueType r;
+
+  if( iter )
+  {
+    if( !signature< ValueType >::get( iter, r ) )
+    {
+      DBUS_DEBUG( "ValueType is %s", signature< ValueType >::name().c_str() );
+      r = Error{"call " + std::to_string( callId.id ) + ": failed to unpack values, got signature '" +
+                DBUS_W->eldbus_message_signature_get_impl( msg ) + "', expected '" + signature< ValueType >::sig() + "'"};
+    }
+  }
+  else
+  {
+    r = Error{"call " + std::to_string( callId.id ) + ": failed to get iterator"};
+  }
+  return r;
+}
+
+inline void packValues_helper( const DBusWrapper::MessageIterPtr& ) {}
+
+template < typename A, typename... ARGS >
+void packValues_helper( const DBusWrapper::MessageIterPtr &iter, A&& a, ARGS&&... r )
+{
+  signature< A >::set( iter, std::forward< A >( a ) );
+  packValues_helper( iter, std::forward< ARGS >( r )... );
+}
+
+template < typename... ARGS >
+void packValues( CallId callId, const DBusWrapper::MessagePtr &msg, ARGS&&... r )
+{
+  auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, true );
+  packValues_helper( iter, std::forward< ARGS >( r )... );
+}
+
+template < typename >
+struct ReturnType;
+template < typename R, typename... ARGS >
+struct ReturnType< R( ARGS... ) >
+{
+  using type = R;
+};
+
+template < typename R, typename... ARGS >
+struct ReturnType< std::function< R( ARGS... ) > >
+{
+  using type = R;
+};
+
+template < int... >
+struct sequence
+{
+};
+
+template < int N, int... S >
+struct sequence_gen : sequence_gen< N - 1, N - 1, S... >
+{
+};
+
+template < int... S >
+struct sequence_gen< 0, S... >
+{
+  typedef sequence< S... > type;
+};
+
+template < typename C, typename... ARGS >
+struct apply_helper
+{
+  const std::function< C >& c;
+  const std::tuple< ARGS... >& args;
+
+  template < int... S >
+  auto apply_2( sequence< S... > ) const -> decltype( c( std::get< S >( args )... ) )
+  {
+    return c( std::get< S >( args )... );
+  }
+  auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
+  {
+    return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
+  }
+};
+
+template < typename C, typename A, typename... ARGS >
+struct apply_helper_2
+{
+  const std::function< C >& c;
+  const A& a;
+  const std::tuple< ARGS... >& args;
+
+  template < int... S >
+  auto apply_2( sequence< S... > ) const -> decltype( c( a, std::get< S >( args )... ) )
+  {
+    return c( a, std::get< S >( args )... );
+  }
+  auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
+  {
+    return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
+  }
+};
+
+template < typename C, typename... ARGS >
+auto apply( const std::function< C >& c, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
+{
+  apply_helper< C, ARGS... > ah{c, args};
+  return ah.apply_1();
+}
+
+template < typename C, typename D, typename... ARGS >
+auto apply( const std::function< C >& c, const D& d, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
+{
+  apply_helper_2< C, D, ARGS... > ah{c, d, args};
+  return ah.apply_1();
+}
+
+struct ConnectionState
+{
+  DBusWrapper::ConnectionPtr connection;
+  DBusWrapper::ObjectPtr object;
+  DBusWrapper::ProxyPtr proxy, propertiesProxy;
+};
+
+template < typename RETTYPE, typename... ARGS >
+RETTYPE call( CallId callId, const ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args )
+{
+  const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
+  if( !proxy )
+  {
+    DBUS_DEBUG( "call %d: not initialized", callId.id );
+    return Error{"not initialized"};
+  }
+
+  DBUS_DEBUG( "call %d: calling '%s'", callId.id, funcName.c_str() );
+  auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
+  if( !msg )
+  {
+    DBUS_DEBUG( "call %d: failed", callId.id );
+    return Error{"failed to create message"};
+  }
+
+  detail::packValues( callId, msg, args... );
+  auto reply = DBUS_W->eldbus_proxy_send_and_block_impl( proxy, msg );
+  DBUS_DEBUG( "call %d: calling '%s' done", callId.id, funcName.c_str() );
+  if( !reply )
+  {
+    DBUS_DEBUG( "call %d: failed", callId.id );
+    return Error{"eldbus returned null as reply"};
+  }
+  std::string errname, errmsg;
+  if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
+  {
+    DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
+    return Error{errname + ": " + errmsg};
+  }
+  DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
+    DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
+  return detail::unpackValues< RETTYPE >( callId, reply );
+}
+
+template < typename RETTYPE, typename... ARGS >
+void asyncCall( CallId callId, const ConnectionState &connectionState,
+                bool property, const std::string& funcName,
+                std::function< void( RETTYPE ) > callback, const ARGS&... args )
+{
+  const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
+  if( !proxy )
+  {
+    DBUS_DEBUG( "call %d: not initialized", callId.id );
+    callback( Error{"not initialized"} );
+    return;
+  }
+
+  auto msg = DBUS_W->eldbus_proxy_method_call_new_impl( proxy, funcName );
+  if( !msg )
+  {
+    DBUS_DEBUG( "call %d: failed", callId.id );
+    callback( Error{"failed to create message"} );
+    return;
+  }
+
+  detail::packValues( callId, msg, args... );
+  auto pending = DBUS_W->eldbus_proxy_send_impl( proxy, msg, [callback, callId, proxy]( const DBusWrapper::MessagePtr &reply ) {
+        DBUS_DEBUG( "call %d: calling done", callId.id );
+        if( !reply )
+        {
+          DBUS_DEBUG( "call %d: failed", callId.id );
+          callback( Error{"eldbus returned null as reply"} );
+        }
+        else
+        {
+          std::string errname, errmsg;
+          if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
+          {
+            DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
+            callback( Error{errname + ": " + errmsg} );
+          }
+          else
+          {
+            DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
+                DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
+            callback( detail::unpackValues< RETTYPE >( callId, reply ) );
+          }
+        }
+      }
+    );
+  if( pending )
+  {
+    DBUS_DEBUG( "call %d: call sent", callId.id );
+  }
+  else
+  {
+    DBUS_DEBUG( "call %d: failed to send call", callId.id );
+    callback( Error{"failed to send call"} );
+  }
+}
+
+inline void displayDebugCallInfo( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
+{
+  DBUS_DEBUG( "call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
+}
+
+inline void displayDebugCallInfoSignal( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
+{
+  DBUS_DEBUG( "call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
+}
+
+inline void displayDebugCallInfoProperty( CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName,
+                                          const std::string& propertyName )
+{
+  DBUS_DEBUG( "call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str() );
+}
+
+using StringStorage = DBusWrapper::StringStorage;
+
+template < typename A, typename... ARGS >
+struct EldbusArgGenerator_Helper
+{
+  static void add( std::vector< std::pair<std::string, std::string> >& r )
+  {
+    auto s = r.size();
+    auto sig = signature< A >::sig();
+    assert( !sig.empty() );
+    auto name = "p" + std::to_string( s + 1 );
+    r.push_back({ std::move(sig), std::move(name) });
+    EldbusArgGenerator_Helper<ARGS...>::add( r );
+  }
+};
+
+template <>
+struct EldbusArgGenerator_Helper< void >
+{
+  static void add( std::vector< std::pair<std::string, std::string> >& )
+  {
+  }
+};
+
+template <>
+struct EldbusArgGenerator_Helper< ValueOrError< void >, void >
+{
+  static void add( std::vector< std::pair<std::string, std::string> >& )
+  {
+  }
+};
+template <>
+struct EldbusArgGenerator_Helper< ValueOrError<>, void >
+{
+  static void add( std::vector< std::pair<std::string, std::string> >& )
+  {
+  }
+};
+
+template < typename... ARGS >
+struct EldbusArgGenerator_Helper< std::tuple< ARGS... > >
+{
+  static void add( std::vector< std::pair<std::string, std::string> >& r )
+  {
+    EldbusArgGenerator_Helper< ARGS..., void >::add( r );
+  }
+};
+
+template < typename RetType >
+struct dbus_interface_return_type_traits
+{
+  using type = ValueOrError< RetType >;
+};
+
+template < typename... ARGS >
+struct dbus_interface_return_type_traits< ValueOrError< ARGS... > >
+{
+  using type = ValueOrError< ARGS... >;
+};
+
+template < typename T >
+struct dbus_interface_traits;
+template < typename RetType, typename... ARGS >
+struct dbus_interface_traits< RetType( ARGS... ) >
+{
+  using Ret = typename dbus_interface_return_type_traits< RetType >::type;
+  using SyncCB = std::function< Ret( ARGS... ) >;
+  using AsyncCB = std::function< void( std::function< void( Ret ) >, ARGS... ) >;
+  using VEArgs = ValueOrError< ARGS... >;
+};
+
+template < typename T >
+struct EldbusArgGenerator_Args;
+template < typename RetType, typename... ARGS >
+struct EldbusArgGenerator_Args< RetType( ARGS... ) >
+{
+  static std::string name()
+  {
+    return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name();
+  }
+  static std::vector< std::pair<std::string, std::string> > get()
+  {
+    std::vector< std::pair<std::string, std::string> > tmp;
+    EldbusArgGenerator_Helper< ARGS..., void >::add( tmp );
+    return tmp;
+  }
+};
+
+template < typename T >
+struct EldbusArgGenerator_ReturnType;
+template < typename RetType, typename... ARGS >
+struct EldbusArgGenerator_ReturnType< RetType( ARGS... ) >
+{
+  static std::string name()
+  {
+    return signature< RetType >::name();
+  }
+  static std::vector< std::pair<std::string, std::string> > get( )
+  {
+    std::vector< std::pair<std::string, std::string> > tmp;
+    EldbusArgGenerator_Helper< RetType, void >::add( tmp );
+    return tmp;
+  }
+};
+
+template < typename T >
+struct EldbusArgGenerator_ReturnType;
+template < typename... ARGS >
+struct EldbusArgGenerator_ReturnType< void( ARGS... ) >
+{
+  static std::string name()
+  {
+    return "";
+  }
+  static std::vector< std::pair<std::string, std::string> > get( )
+  {
+    return {};
+  }
+};
+/// \endcond
+}
+
+using ConnectionType = DBusWrapper::ConnectionType;
+
+/**
+ * @brief Class representing client's end of DBUS connection
+ *
+ * Allows calling (synchronous and asynchronos) methods on selected interface
+ * Allows (synchronous and asynchronos) setting / getting properties.
+ * Allows registering signals.
+ */
+class DBusClient
+{
+  /// \cond
+  struct ConnectionInfo
+  {
+    std::string interfaceName, busName, pathName;
+  };
+  /// \endcond
+public:
+  /**
+   * @brief Default constructor, creates non-connected object.
+   */
+  DBusClient() = default;
+
+  /**
+   * @brief Connects to dbus choosen by tp, using given arguments
+   *
+   * @param bus_name name of the bus to connect to
+   * @param path_name object's path
+   * @param interface_name interface name
+   */
+  DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
+              ConnectionType tp );
+
+  /**
+   * @brief Connects to dbus using connection conn
+   *
+   * @param bus_name name of the bus to connect to
+   * @param path_name object's path
+   * @param interface_name interface name
+   * @param conn connection object from getDBusConnectionByType call
+   */
+  DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
+              const DBusWrapper::ConnectionPtr &conn = {} );
+
+  /**
+   * @brief Destructor object.
+   *
+   * All signals added will be disconnected.
+   * All asynchronous calls will be cancelled, their callback's will be called
+   * with failure message.
+   */
+  ~DBusClient() = default;
+  DBusClient( const DBusClient& ) = delete;
+  DBusClient( DBusClient&& ) = default;
+
+  DBusClient& operator=( DBusClient&& ) = default;
+  DBusClient& operator=( const DBusClient& ) = delete;
+
+  /**
+   * @brief bool operator
+   *
+   * Returns true, if object is connected to DBUS
+   */
+  explicit operator bool() const
+  {
+    return bool( connectionState->proxy );
+  }
+
+  /**
+   * @brief Helper class for calling a method
+   *
+   * Template type T defines both arguments sent to the method
+   * and expected values. Receiving different values will be reported as
+   * error. For example:
+   * \code{.cpp} Method<int(float, float)> \endcode
+   * defines method, which takes two arguments (two floats) and return
+   * single value of type int.
+   */
+  template < typename T >
+  struct Method
+  {
+    /// \cond
+    using RetType = typename detail::dbus_interface_traits< T >::Ret;
+    const detail::ConnectionState &connectionState;
+    std::string funcName;
+    std::string info;
+    std::shared_ptr< ConnectionInfo > connectionInfo;
+    /// \endcond
+
+    /**
+     * @brief Executes synchronous call on DBUS's method
+     *
+     * The function returns ValueOrError<...> object, which
+     * contains either received values or error message.
+     *
+     * @param args arguments to pass to the method
+     */
+    template < typename... ARGS >
+    RetType call( const ARGS&... args )
+    {
+      detail::CallId callId;
+      detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
+      return detail::call< RetType >( callId, connectionState, false, funcName, args... );
+    }
+
+    /**
+     * @brief Executes asynchronous call on DBUS's method
+     *
+     * The function calls callback with either received values or error message.
+     *
+     * @param callback callback functor, which will be called with return value(s) or error message
+     * @param args arguments to pass to the method
+     */
+    template < typename... ARGS >
+    void asyncCall( std::function< void( RetType ) > callback, const ARGS&... args )
+    {
+      detail::CallId callId;
+      detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
+      detail::asyncCall< RetType >( callId, connectionState, false, funcName, std::move( callback ), args... );
+    }
+  };
+
+  /**
+   * @brief Helper class for calling a property
+   *
+   * Template type T defines type of the value hidden under property.
+   * Note, that library automatically wraps both sent and received value into
+   * DBUS's wrapper type.
+   */
+  template < typename T >
+  struct Property
+  {
+    /// \cond
+    using RetType = typename detail::dbus_interface_return_type_traits< T >::type;
+    using VariantRetType = typename detail::dbus_interface_return_type_traits< EldbusVariant< T > >::type;
+    const detail::ConnectionState &connectionState;
+    std::string propName;
+    std::string info;
+    std::shared_ptr< ConnectionInfo > connectionInfo;
+    /// \endcond
+
+    /**
+     * @brief executes synchronous get on property
+     *
+     * The function returns ValueOrError<...> object, which
+     * contains either received values or error message.
+     */
+    RetType get()
+    {
+      detail::CallId callId;
+      detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
+      auto z = detail::call< VariantRetType >( callId, connectionState, true, "Get", connectionInfo->interfaceName, propName );
+      if( !z )
+        return z.getError();
+      return {std::get< 0 >( z.getValues() ).value};
+    }
+
+    /**
+     * @brief executes asynchronous get on property
+     *
+     * The function calls callback with either received values or error message.
+     *
+     * @param callback callback functor, which will be called with return value(s) or error message
+     */
+    void asyncGet( std::function< void( RetType ) > callback )
+    {
+      detail::CallId callId;
+      detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
+      auto cc = [callback]( VariantRetType reply ) {
+        if( reply )
+          callback( std::move( std::get< 0 >( reply.getValues() ).value ) );
+        else
+          callback( reply.getError() );
+      };
+      detail::asyncCall< VariantRetType >( callId, connectionState, true, "Get", std::move( cc ), connectionInfo->interfaceName, propName );
+    }
+
+    /**
+     * @brief executes synchronous set on property
+     *
+     * The function returns ValueOrError<void> object, with
+     * possible error message.
+     */
+    ValueOrError< void > set( const T& r )
+    {
+      detail::CallId callId;
+      detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
+      EldbusVariant< T > variantValue{std::move( r )};
+      return detail::call< ValueOrError< void > >( callId, connectionState, true, "Set", connectionInfo->interfaceName, propName, variantValue );
+    }
+
+    /**
+     * @brief executes asynchronous get on property
+     *
+     * The function calls callback with either received values or error message.
+     *
+     * @param callback callback functor, which will be called with return value(s) or error message
+     */
+    void asyncSet( std::function< void( ValueOrError< void > ) > callback, const T& r )
+    {
+      detail::CallId callId;
+      detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
+      EldbusVariant< T > variantValue{std::move( r )};
+      detail::asyncCall< ValueOrError< void > >( callId, connectionState, true, "Set", std::move( callback ), connectionInfo->interfaceName, propName, variantValue );
+    }
+  };
+
+  /**
+   * @brief Constructs Property<...> object for calling properties
+   *
+   * The function constructs and returns proxy object for calling property.
+   *
+   * @param propName property name to set and / or query
+   */
+  template < typename PropertyType >
+  Property< PropertyType > property( std::string propName )
+  {
+    return Property< PropertyType >{*connectionState, std::move( propName ), info, connectionInfo};
+  }
+
+  /**
+   * @brief Constructs Method<...> object for calling methods
+   *
+   * The function constructs and returns proxy object for calling method.
+   *
+   * @param funcName function name to call
+   */
+  template < typename MethodType >
+  Method< MethodType > method( std::string funcName )
+  {
+    return Method< MethodType >{*connectionState, std::move( funcName ), info, connectionInfo};
+  }
+
+  /**
+   * @brief Registers notification callback, when property has changed
+   *
+   * The callback will be called with new value, when property's value has changed.
+   * Note, that template type V must match expected type, otherwise undefined behavior will occur,
+   * there's no check for this.
+   */
+  template < typename V >
+  void addPropertyChangedEvent( std::string propertyName, std::function< void( V ) > callback )
+  {
+    detail::CallId callId;
+    detail::displayDebugCallInfoSignal( callId, propertyName, info, connectionInfo->interfaceName );
+    DBUS_DEBUG( "call %d: adding property", callId.id );
+    auto &cI = this->connectionInfo;
+    DBUS_W->add_property_changed_event_listener_impl(connectionState->proxy, cI->interfaceName, propertyName,
+      [callback]( const _Eina_Value *newValue ) {
+      V val = 0;
+      if( !getFromEinaValue( newValue, &val ) )
+      {
+        DBUS_DEBUG( "unable to get property's value" );
+        return;
+      }
+      callback( val );
+    });
+  }
+
+  /**
+   * @brief Registers callback on the DBUS' signal
+   *
+   * The function registers callback signalName. When signal comes, callback will be called.
+   * Callback object will exists as long as signal is registered. You can unregister signal
+   * by destroying DBusClient object.
+   *
+   * @param signalName name of the signal to register
+   * @param callback callback to call
+   */
+  template < typename SignalType >
+  void addSignal( std::string signalName, std::function< SignalType > callback )
+  {
+    detail::CallId callId;
+    detail::displayDebugCallInfoSignal( callId, signalName, info, connectionInfo->interfaceName );
+    DBUS_W->eldbus_proxy_signal_handler_add_impl( connectionState->proxy, signalName,
+      [callId, callback, signalName]( const DBusWrapper::MessagePtr &msg ) -> void {
+        std::string errname, aux;
+        if( DBUS_W->eldbus_message_error_get_impl( msg, errname, aux ) )
+        {
+          DBUS_DEBUG( "call %d: Eldbus error: %s %s", callId.id, errname.c_str(), aux.c_str() );
+          return;
+        }
+        DBUS_DEBUG( "call %d: received signal with signature '%s'", callId.id, DBUS_W->eldbus_message_signature_get_impl( msg ).c_str() );
+        using ParamsType = typename detail::dbus_interface_traits< SignalType >::VEArgs;
+        auto params = detail::unpackValues< ParamsType >( callId, msg );
+        if( !params )
+        {
+          DBUS_DEBUG( "call %d: failed: %s", callId.id, params.getError().message.c_str() );
+          return;
+        }
+        try
+        {
+          detail::apply( callback, params.getValues() );
+        }
+        catch( ... )
+        {
+          DBUS_DEBUG( "unhandled exception" );
+          assert( 0 );
+        }
+      });
+  }
+
+private:
+  /// \cond
+  std::unique_ptr<detail::ConnectionState> connectionState{ new detail::ConnectionState };
+  std::string info;
+  std::shared_ptr< ConnectionInfo > connectionInfo;
+
+  static bool getFromEinaValue(const _Eina_Value *v, void *dst);
+  /// \endcond
+};
+
+/**
+ * @brief Helper class describing DBUS's server interface
+ *
+ */
+class DBusInterfaceDescription
+{
+  friend class DBusServer;
+
+public:
+  /// \cond
+  using MethodInfo = DBusWrapper::MethodInfo;
+  using SignalInfo = DBusWrapper::SignalInfo;
+  using PropertyInfo = DBusWrapper::PropertyInfo;
+  using SignalId = DBusWrapper::SignalId;
+  /// \endcond
+
+  /**
+   * @brief Creates empty interface description with given name
+   *
+   * @param interfaceName name of the interface
+   */
+  DBusInterfaceDescription( std::string interfaceName );
+
+  /**
+   * @brief adds new, synchronous method to the interface
+   *
+   * When method memberName is called on DBUS, callback functor will be called
+   * with values received from DBUS. callback won't be called, if method was
+   * called with invalid signature. Value returned from functor (or error message)
+   * will be marshalled back to the caller.
+   *
+   * Template type T defines both arguments sent to the method
+   * and expected values. Receiving different values will be reported as
+   * error. For example:
+   * \code{.cpp} Method<int(float, float)> \endcode
+   * defines method, which takes two arguments (two floats) and return
+   * single value of type int.
+   *
+   * @param memberName name of the method
+   * @param callback functor, which will be called
+   */
+  template < typename T >
+  void addMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback )
+  {
+    detail::CallId callId;
+    MethodInfo mi;
+    methods.push_back( std::move( mi ) );
+    auto& z = methods.back();
+    z.in = detail::EldbusArgGenerator_Args< T >::get( );
+    z.out = detail::EldbusArgGenerator_ReturnType< T >::get( );
+    z.memberName = memberName;
+    DBUS_DEBUG( "call %d: method %s, in %s, out %s", callId.id, memberName.c_str(),
+                detail::EldbusArgGenerator_Args< T >::name().c_str(),
+                detail::EldbusArgGenerator_ReturnType< T >::name().c_str() );
+    z.callback = construct< T >( callId, callback );
+    z.id = callId;
+  }
+
+  /**
+   * @brief adds new, synchronous property to the interface
+   *
+   * When property memberName is called on DBUS, respective callback functor will be called
+   * with values received from DBUS. callback won't be called, if method was
+   * called with invalid signature. Value returned from functor (or error message)
+   * will be marshalled back to the caller.
+   *
+   * Template type T defines type of the value hidden under property.
+   * Note, that library automatically wraps both sent and received value into
+   * DBUS's wrapper type.
+   *
+   * @param memberName name of the method
+   * @param getter functor, which will be called when property is being read
+   * @param setter functor, which will be called when property is being set
+   */
+  template < typename T >
+  void addProperty( const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >( T ) > setter )
+  {
+    properties.push_back( {} );
+    auto& z = properties.back();
+    z.memberName = memberName;
+    z.typeSignature = detail::signature< T >::sig();
+    if( getter )
+    {
+      detail::CallId getterId;
+      z.getterId = getterId;
+      DBUS_DEBUG( "call %d: property %s (get) type %s", getterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
+      z.getCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) -> std::string {
+        try
+        {
+          auto v = detail::apply( getter, std::tuple<>{} );
+          if( v )
+          {
+            detail::signature< T >::set( dst, std::get< 0 >( v.getValues() ) );
+            DBUS_DEBUG( "call %d: success", getterId.id );
+            return "";
+          }
+          DBUS_DEBUG( "call %d: failed: %s", getterId.id, v.getError().message.c_str() );
+          return v.getError().message;
+        }
+        catch( std::exception& e )
+        {
+          return std::string( "unhandled exception (" ) + e.what() + ")";
+        }
+        catch( ... )
+        {
+          return "unhandled exception";
+        }
+      };
+    }
+    if( setter )
+    {
+      detail::CallId setterId;
+      z.setterId = setterId;
+      DBUS_DEBUG( "call %d: property %s (set) type %s", setterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
+      z.setCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &src_iter ) -> std::string {
+        std::tuple< T > value;
+        auto src_signature = DBUS_W->eldbus_message_iter_signature_get_impl( src_iter );
+        if( detail::signature< T >::get( src_iter, std::get< 0 >( value ) ) )
+        {
+          try
+          {
+            auto v = detail::apply( setter, std::move( value ) );
+            if( v )
+            {
+              DBUS_DEBUG( "call %d: success", setterId.id );
+              return "";
+            }
+            DBUS_DEBUG( "call %d: failed: %s", setterId.id, v.getError().message.c_str() );
+            return v.getError().message;
+          }
+          catch( std::exception& e )
+          {
+            return std::string( "unhandled exception (" ) + e.what() + ")";
+          }
+          catch( ... )
+          {
+            return "unhandled exception";
+          }
+        }
+        DBUS_DEBUG( "call %d: failed to unpack values, got signature '%s', expected '%s'", setterId.id,
+                    src_signature.c_str(), detail::signature< T >::sig().c_str() );
+        return "call " + std::to_string( setterId.id ) + ": failed to unpack values, got signature '" +
+                     src_signature + "', expected '" + detail::signature< T >::sig() + "'";
+      };
+    }
+  }
+
+  /**
+   * @brief adds new signal to the interface
+   *
+   * Template types ARGS defines values, which will be emited with the signal
+   *
+   * @param memberName name of the method
+   */
+  template < typename... ARGS >
+  SignalId addSignal( const std::string& memberName )
+  {
+    detail::CallId callId;
+    signals.push_back( {} );
+    auto& z = signals.back();
+    z.memberName = memberName;
+    z.args = detail::EldbusArgGenerator_Args< void( ARGS... ) >::get( DBUS_W->Strings );
+    z.id = callId;
+    DBUS_DEBUG( "call %d: signal %s", callId.id, memberName.c_str() );
+    return SignalId{callId};
+  }
+
+private:
+  /// \cond
+  std::vector< MethodInfo > methods;
+  std::vector< PropertyInfo > properties;
+  std::vector< SignalInfo > signals;
+  std::string interfaceName;
+
+  template < typename T >
+  std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > construct( detail::CallId callId,
+                                                                           typename detail::dbus_interface_traits< T >::SyncCB callback )
+  {
+    using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs;
+    return [=]( const DBusWrapper::MessagePtr &msg ) -> DBusWrapper::MessagePtr {
+      DBUS_DEBUG( "call %d: entering", callId.id );
+      DBusWrapper::MessagePtr ret = {};
+      auto args = detail::unpackValues< VEArgs >( callId, msg );
+      if( args )
+      {
+        try
+        {
+          auto v = detail::apply( callback, std::move( args.getValues() ) );
+          if( v )
+          {
+            DBUS_DEBUG( "call %d: success", callId.id );
+            ret = DBUS_W->eldbus_message_method_return_new_impl( msg );
+            detail::packValues( callId, ret, v );
+          }
+          else
+          {
+            DBUS_DEBUG( "call %d: failed: %s", callId.id, v.getError().message.c_str() );
+            ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", v.getError().message );
+          }
+        }
+        catch( std::exception& e )
+        {
+          auto txt = std::string( "unhandled exception (" ) + e.what() + ")";
+          DBUS_DEBUG( "call %d: failed: %s", callId.id, txt.c_str() );
+          ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", txt );
+        }
+        catch( ... )
+        {
+          DBUS_DEBUG( "call %d: failed: %s", callId.id, "unhandled exception" );
+          ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", "unhandled exception" );
+        }
+      }
+      else
+      {
+        std::ostringstream err;
+        err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << DBUS_W->eldbus_message_signature_get_impl( msg ) << "'";
+        auto str = err.str();
+        DBUS_DEBUG( "call %d: failed: %s", callId.id, str.c_str() );
+        ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.InvalidArgs", str );
+      }
+      return ret;
+    };
+  }
+  /// \endcond
+};
+
+/**
+ * @brief Class representing server's end of DBUS connection
+ *
+ * Allows listening (synchronously and asynchronosly) on methods on selected interface
+ * Allows listening (synchronously and asynchronosly) on setting / getting properties.
+ * Allows emiting signals.
+ */
+class DBusServer
+{
+public:
+  /**
+   * @brief Constructs non-connected dbus server.
+   */
+  DBusServer() = default;
+
+  /**
+   * @brief Constructs dbus server on either system or user dbus connection.
+   */
+  DBusServer( ConnectionType tp );
+
+  /**
+   * @brief Constructs dbus server on connection from getDBusConnectionByType
+   */
+  DBusServer( const DBusWrapper::ConnectionPtr &conn );
+
+  /**
+   * @brief Destructor
+   *
+   * Destructor will properly destroy everything. Destructor will cancel
+   * pending replies.
+   */
+  ~DBusServer() = default;
+
+  DBusServer( const DBusServer& ) = delete;
+  DBusServer( DBusServer&& ) = default;
+
+  DBusServer& operator=( DBusServer&& ) = default;
+  DBusServer& operator=( const DBusServer& ) = delete;
+
+  /**
+   * @brief Registers interface on given path name
+   *
+   * @param pathName path object to register interface on.
+   * @param dscr
+   * @param fallback
+   */
+  void addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false );
+
+  /**
+   * @brief Gets bus name of the current connection (must be connected)
+   */
+  std::string getBusName() const;
+
+  /**
+   * @brief Returns connection object for this dbus server object
+   *
+   * @return connection object
+   */
+  DBusWrapper::ConnectionPtr getConnection();
+
+  /**
+   * @brief Emits signal
+   *
+   * Emits signal based only on data passed to the function
+   *
+   * @param signal identifier of the signal
+   * @param args values to emit
+   */
+  template < typename... ARGS >
+  void emit2( const std::string& path, const std::string& interfaceName,
+              const std::string& signalName, const ARGS&... args )
+  {
+    auto msg = DBUS_W->eldbus_message_signal_new_impl( path, interfaceName, signalName );
+    detail::CallId id;
+    detail::packValues( id, msg, args... );
+    DBUS_W->eldbus_connection_send_impl( connection, msg );
+  }
+
+  /**
+   * @brief Returns current object path, when handling call to property / method
+   *
+   * User can call this function from inside callback used to handle property / method calls.
+   * It will retrieve object's path used in the call. Note, that in asynchronous handling
+   * of those calls user need to retrieve and store the current object / current connection
+   * as the value will change at the moment user's callback handling will exit. For example:
+   * \code{.cpp}
+   * DBusInterfaceDescription interface{"name"};
+   * auto handler_later = [](std::function<void(void)> done_cb) {
+   *   // process something later on
+   *   DBusServer::getCurrentObjectPath(); // this will return empty string
+   * };
+   * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
+   *   DBusServer::getCurrentObjectPath(); // this will current object's path
+   *
+   *   // do some processing later on and call done_cb, when it's done
+   *   register_to_call_sometime_later_on(std::move(done_cb));
+   * };
+   * \endcode
+   */
+  static std::string getCurrentObjectPath() { return currentObjectPath; }
+
+  /**
+   * @brief Returns current connection object, when handling call to property / method
+   *
+   * User can call this function from inside callback used to handle property / method calls.
+   * It will retrieve object's path used in the call. Note, that in asynchronous handling
+   * of those calls user need to retrieve and store the current object / current connection
+   * as the value will change at the moment user's callback handling will exit. For example:
+   * \code{.cpp}
+   * DBusInterfaceDescription interface{"name"};
+   * auto handler_later = [](std::function<void(void)> done_cb) {
+   *   // process something later on
+   *   DBusServer::getCurrentObjectPath(); // this will return empty string
+   * };
+   * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
+   *   DBusServer::getCurrentObjectPath(); // this will current object's path
+   *
+   *   // do some processing later on and call done_cb, when it's done
+   *   register_to_call_sometime_later_on(std::move(done_cb));
+   * };
+   * \endcode
+   */
+  static const DBusWrapper::ConnectionPtr &getCurrentConnection() { return currentConnection; }
+
+  /// \cond
+  class CurrentObjectSetter
+  {
+  public:
+    CurrentObjectSetter( DBusWrapper::ConnectionPtr con, std::string path )
+    {
+      currentObjectPath = std::move(path);
+      currentConnection = std::move( con );
+    }
+    ~CurrentObjectSetter()
+    {
+      currentObjectPath = "";
+      currentConnection = {};
+    }
+    CurrentObjectSetter( const CurrentObjectSetter& ) = delete;
+    CurrentObjectSetter( CurrentObjectSetter&& ) = delete;
+    void operator=( const CurrentObjectSetter& ) = delete;
+    void operator=( CurrentObjectSetter&& ) = delete;
+  };
+  /// \endcond
+
+private:
+  /// \cond
+  DBusWrapper::ConnectionPtr connection;
+  struct DestructorObject {
+    std::vector<std::function<void()>> destructors;
+    ~DestructorObject() {
+      for(auto &a : destructors) a();
+    }
+  };
+
+  std::unique_ptr<DestructorObject> destructorObject { new DestructorObject() };
+  static thread_local std::string currentObjectPath;
+  static thread_local DBusWrapper::ConnectionPtr currentConnection;
+
+  /// \endcond
+};
+
+/// \cond
+DBusWrapper::ConnectionPtr getDBusConnectionByType( ConnectionType tp );
+DBusWrapper::ConnectionPtr getDBusConnectionByName( const std::string& name );
+std::string getConnectionName( const DBusWrapper::ConnectionPtr& );
+/// \endcond
+}
+
+/// \cond
+namespace std
+{
+template < size_t INDEX, typename... ARGS >
+inline auto get( DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) ) &
+{
+  return std::get< INDEX >( v.getValues() );
+}
+
+template < size_t INDEX, typename... ARGS >
+inline auto get( const DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) )
+{
+  return std::get< INDEX >( v.getValues() );
+}
+}
+/// \endcond
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
diff --git a/dali/internal/accessibility/bridge/optional.h b/dali/internal/accessibility/bridge/optional.h
new file mode 100644 (file)
index 0000000..dffc3a6
--- /dev/null
@@ -0,0 +1,283 @@
+#ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OPTIONAL_H
+#define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OPTIONAL_H
+
+/*
+ * Copyright 2019  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <cassert>
+#include <new>
+#include <type_traits>
+#include <utility>
+
+/**
+ * Minimalistic implementation of standard library std::optional (c++17) for c++11 compiler.
+ *
+ * After project conversion to C++17 standard, this template class will be deleted and
+ * Optional will point to std::optional.
+ *
+ * Allowed operations (note, to make code simplier, than original, value class must have accessible copy and move constructor):
+ *  - constructing empty (valueless) object
+ *  - copying Optional (with and without value)
+ *  - moving Optional (with and without value)
+ *  - querying, if Optional has value (via explicit operator bool), for example:
+ *        Optional<int> v = ...;
+ *        if (v) ... // if v has value, then do something
+ *  - accessing value (via operator *), for example:
+ *        Optional<int> v = ...;
+ *        auto z = *v; // z now has the same int, as v (copied)
+ *        auto &y = *v; // y now has REFERENCE to int inside v, so modifying y modifies v
+ */
+
+template < typename A >
+class Optional
+{
+  /// \cond
+  union
+  {
+    A place;
+  };
+  bool hasValue = false;
+  /// \endcond
+
+public:
+  /**
+   * @brief Empty constructor.
+   * Creates empty Optional object, which will be false in boolean context.
+   * So:
+   *   \code{.cpp}
+   *   Optional<int> o;
+   *   if (o) printf("1\n");
+   *   \endcode
+   * won't print 1.
+   */
+  Optional() {}
+
+  /**
+   * @brief Single element constructor, when implicit convertion can be applied.
+   *
+   * This constructor will be selected, when type of given argument (U) is
+   * implicitly convertable to expected type A. In other words following
+   * code must be valid:
+   *   \code{.cpp}
+   *   A foo() {
+   *     return U();
+   *   }
+   *   \endcode
+   *
+   * @param a value held by Optional object will be initialized from a.
+   */
+  template < typename U = A, typename std::enable_if<
+                                 std::is_convertible< U&&, A >::value &&
+                                     std::is_constructible< A, U&& >::value &&
+                                     !std::is_same< typename std::decay< U >::type, Optional< A > >::value,
+                                 int* >::type = nullptr >
+  constexpr Optional( U&& a )
+      : place( std::forward< U >( a ) ), hasValue( true )
+  {
+  }
+
+  /**
+   * @brief Single element constructor, when only explicit convertion can be applied.
+   *
+   * This constructor will be selected, when type of given argument (U) is
+   * convertable to expected type A.
+   *
+   * @param a value held by Optional object will be initialized from a.
+   */
+  template < typename U = A, typename std::enable_if<
+                                 !std::is_convertible< U&&, A >::value &&
+                                     std::is_constructible< A, U&& >::value &&
+                                     !std::is_same< typename std::decay< U >::type, Optional< A > >::value,
+                                 int* >::type = nullptr >
+  explicit constexpr Optional( U&& a )
+      : place( std::forward< U >( a ) ), hasValue( true )
+  {
+  }
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param v Optional value to copy from. Will cause to copy data held by object v,
+   * if v has data.
+   */
+  Optional( const Optional& v ) : hasValue( v.hasValue )
+  {
+    if( hasValue )
+      new( &place ) A( v.place );
+  }
+
+  /**
+   * @brief Move constructor.
+   *
+   * @param v Optional value to copy from. Will move data help by v, if any.
+   * After construction \code{.cpp} bool(v) \endcode will be false.
+   */
+  Optional( Optional&& v ) : hasValue( v.hasValue )
+  {
+    if( hasValue )
+      new( &place ) A( std::move( v.place ) );
+  }
+
+  /**
+   * @brief Destructor.
+   */
+  ~Optional()
+  {
+    if( hasValue )
+    {
+      place.~A();
+    }
+  }
+
+  /**
+   * @brief Explicit bool operator
+   *
+   * Will return true if and only if object is helding data.
+   */
+  explicit operator bool() const
+  {
+    return hasValue;
+  }
+
+  /**
+   * @brief Accessor (*) operator
+   *
+   * Will return modifiable reference to held object. Will assert, if not object is held.
+   */
+  A& operator*()
+  {
+    assert( hasValue );
+    return place;
+  }
+
+  /**
+   * @brief Accessor (*) const operator
+   *
+   * Will return const reference to held object. Will assert, if not object is held.
+   */
+  const A& operator*() const
+  {
+    assert( hasValue );
+    return place;
+  }
+
+  /**
+   * @brief Accessor (->) operator
+   *
+   * Will return pointer to held object allowing access to the value's members.
+   * Will assert, if not object is held.
+   */
+  A* operator->()
+  {
+    assert( hasValue );
+    return &place;
+  }
+
+  /**
+   * @brief Accessor (->) operator
+   *
+   * Will return pointer to (const) held object allowing access to the value's members.
+   * Will assert, if not object is held.
+   */
+  const A* operator->() const
+  {
+    assert( hasValue );
+    return &place;
+  }
+
+  /**
+   * @brief Assignment operator
+   *
+   * Will copy held value from v, if any.
+   *
+   * @param v Value to copy from
+   */
+  Optional& operator=( const Optional& v )
+  {
+    if( this != &v )
+    {
+      if( hasValue != v.hasValue )
+      {
+        if( v.hasValue )
+          new( &place ) A( v.place );
+        else
+          place.~A();
+        hasValue = v.hasValue;
+      }
+      else if( hasValue )
+      {
+        place = v.place;
+      }
+    }
+    return *this;
+  }
+
+  /**
+   * @brief Assignment move operator
+   *
+   * Will move held value from v, if any. In all cases v won't held a value
+   * after assignment is done.
+   *
+   * @param v Value to copy from
+   */
+  Optional& operator=( Optional&& v )
+  {
+    if( this != &v )
+    {
+      if( hasValue != v.hasValue )
+      {
+        if( v.hasValue )
+          new( &place ) A( std::move( v.place ) );
+        else
+          place.~A();
+        hasValue = v.hasValue;
+      }
+      else if( hasValue )
+      {
+        place = std::move( v.place );
+      }
+    }
+    return *this;
+  }
+
+  /**
+   * @brief Assignment operator from value of type held.
+   *
+   * Will initialize held value from given parameter a.
+   * Type of the parameter must be the same (barring cv convertions),
+   * as the type of the value held.
+   *
+   * @param a Value to copy from
+   */
+  template < class U, class = typename std::enable_if<
+                          std::is_same< typename std::remove_reference< U >::type, A >::value &&
+                          std::is_constructible< A, U >::value &&
+                          std::is_assignable< A&, U >::value >::type >
+  Optional& operator=( U&& a )
+  {
+    if( hasValue )
+      place = std::forward< U >( a );
+    else
+    {
+      hasValue = true;
+      new( &place ) A( std::forward< U >( a ) );
+    }
+    return *this;
+  }
+};
+
+#endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OPTIONAL_H
diff --git a/dali/internal/accessibility/common/accessibility-adaptor-impl.cpp b/dali/internal/accessibility/common/accessibility-adaptor-impl.cpp
deleted file mode 100644 (file)
index d3eb43b..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/object/type-registry.h>
-#include <dali/integration-api/debug.h>
-#include <dali/integration-api/events/touch-event-integ.h>
-#include <dali/integration-api/events/hover-event-integ.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/adaptor/common/adaptor-impl.h>
-#include <dali/internal/system/common/system-settings.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-namespace // unnamed namespace
-{
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gAccessibilityAdaptorLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ACCESSIBILITY_ADAPTOR");
-#endif
-
-} // unnamed namespace
-
-AccessibilityAdaptor::AccessibilityAdaptor()
-: mReadPosition(),
-  mActionHandler( NULL ),
-  mIsEnabled( false )
-{
-  mAccessibilityGestureDetector = new AccessibilityGestureDetector();
-}
-
-void AccessibilityAdaptor::EnableAccessibility()
-{
-  if(mIsEnabled == false)
-  {
-    mIsEnabled = true;
-
-    if( mActionHandler )
-    {
-      mActionHandler->ChangeAccessibilityStatus();
-    }
-  }
-}
-
-void AccessibilityAdaptor::DisableAccessibility()
-{
-  if(mIsEnabled == true)
-  {
-    mIsEnabled = false;
-
-    if( mActionHandler )
-    {
-      mActionHandler->ChangeAccessibilityStatus();
-    }
-
-    // Destroy the TtsPlayer if exists.
-    if ( Adaptor::IsAvailable() )
-    {
-      Dali::Adaptor& adaptor = Dali::Adaptor::Get();
-      Adaptor& adaptorImpl = Adaptor::GetImplementation( adaptor );
-      adaptorImpl.DestroyTtsPlayer( Dali::TtsPlayer::SCREEN_READER );
-    }
-  }
-}
-
-bool AccessibilityAdaptor::IsEnabled() const
-{
-  return mIsEnabled;
-}
-
-Vector2 AccessibilityAdaptor::GetReadPosition() const
-{
-  return mReadPosition;
-}
-
-void AccessibilityAdaptor::SetActionHandler(AccessibilityActionHandler& handler)
-{
-  mActionHandler = &handler;
-}
-
-void AccessibilityAdaptor::SetGestureHandler(AccessibilityGestureHandler& handler)
-{
-  if( mAccessibilityGestureDetector )
-  {
-    mAccessibilityGestureDetector->SetGestureHandler(handler);
-  }
-}
-
-bool AccessibilityAdaptor::HandleActionNextEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionNext(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionPreviousEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionPrevious(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionActivateEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionActivate();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
-{
-  bool ret = false;
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %d , %d\n", __FUNCTION__, __LINE__, x, y);
-
-  mReadPosition.x = static_cast< float > (x);
-  mReadPosition.y = static_cast< float > (y);
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionRead( allowReadAgain );
-    DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-  }
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionReadNextEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadNext(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionReadPreviousEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadPrevious(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionUpEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionUp();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionDownEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionDown();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionClearFocusEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->ClearAccessibilityFocus();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionScrollEvent(const TouchPoint& point, uint32_t timeStamp)
-{
-  bool ret = false;
-
-  // We always need to emit a scroll signal, whether it's only a hover or not,
-  // so always send the action to the action handler.
-  if( mActionHandler )
-  {
-    Dali::TouchEvent event(timeStamp);
-    event.points.push_back(point);
-    ret = mActionHandler->AccessibilityActionScroll( event );
-  }
-
-  Integration::TouchEvent touchEvent;
-  Integration::HoverEvent hoverEvent;
-  Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent( Integration::Point( point ), timeStamp, touchEvent, hoverEvent );
-  if( type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth ) // hover event is ignored
-  {
-    // Process the touch event in accessibility gesture detector
-    if( mAccessibilityGestureDetector )
-    {
-      mAccessibilityGestureDetector->SendEvent( touchEvent );
-      ret = true;
-    }
-  }
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionTouchEvent(const TouchPoint& point, uint32_t timeStamp)
-{
-  bool ret = false;
-
-  Dali::TouchEvent touchEvent(timeStamp);
-  touchEvent.points.push_back(point);
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionTouch(touchEvent);
-  }
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionBackEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionBack();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-void AccessibilityAdaptor::HandleActionEnableEvent()
-{
-  EnableAccessibility();
-}
-
-void AccessibilityAdaptor::HandleActionDisableEvent()
-{
-  DisableAccessibility();
-}
-
-bool AccessibilityAdaptor::HandleActionScrollUpEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionScrollUp();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-
-bool AccessibilityAdaptor::HandleActionScrollDownEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionScrollDown();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionPageLeftEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionPageLeft();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionPageRightEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionPageRight();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionPageUpEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionPageUp();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionPageDownEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionPageDown();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionMoveToFirstEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionMoveToFirst();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionMoveToLastEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionMoveToLast();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionReadFromTopEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadFromTop();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionReadFromNextEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadFromNext();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionZoomEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionZoom();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionReadPauseResumeEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadPauseResume();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptor::HandleActionStartStopEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionStartStop();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-AccessibilityAdaptor::~AccessibilityAdaptor()
-{
-  // Do any platform specific clean-up in OnDestroy()
-  OnDestroy();
-}
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
diff --git a/dali/internal/accessibility/common/accessibility-adaptor-impl.h b/dali/internal/accessibility/common/accessibility-adaptor-impl.h
deleted file mode 100644 (file)
index d59f69f..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-#ifndef DALI_INTERNAL_ACCESSIBILITY_ADAPTOR_H
-#define DALI_INTERNAL_ACCESSIBILITY_ADAPTOR_H
-
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <string>
-
-#include <dali/public-api/object/base-object.h>
-#include <dali/public-api/math/vector2.h>
-#include <dali/public-api/events/touch-point.h>
-#include <dali/integration-api/events/touch-event-combiner.h>
-
-// INTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
-#include <dali/devel-api/adaptor-framework/accessibility-action-handler.h>
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-handler.h>
-#include <dali/internal/accessibility/common/accessibility-gesture-detector.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-/**
- * This class detects to accessibility action
- */
-class AccessibilityAdaptor : public Dali::BaseObject
-{
-public:
-
-  /**
-   * Constructor.
-   */
-  AccessibilityAdaptor();
-
-  /**
-   * @brief Get an instance of the AccessibilityAdaptor.
-   *
-   * @note This singleton-style getter can be reimplemented for different platforms.
-   * @return The instance of the AccessibilityAdaptor.
-   */
-  static Dali::AccessibilityAdaptor Get();
-
-  /**
-   * Turn on accessibility action
-   * This method should be called by vconf callback
-   */
-  void EnableAccessibility();
-
-  /**
-   * Turn off accessibility action
-   * This method should be called by vconf callback
-   */
-  void DisableAccessibility();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::IsEnabled()
-   */
-  bool IsEnabled() const;
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::GetReadPosition() const
-   */
-  Vector2 GetReadPosition() const;
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::SetActionHandler()
-   */
-  void SetActionHandler(AccessibilityActionHandler& handler);
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::SetGestureHandler()
-   */
-  void SetGestureHandler(AccessibilityGestureHandler& handler);
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionNextEvent()
-   */
-  virtual bool HandleActionNextEvent( bool allowEndFeedback = true);
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionPreviousEvent()
-   */
-  virtual bool HandleActionPreviousEvent( bool allowEndFeedback = true);
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionActivateEvent()
-   */
-  virtual bool HandleActionActivateEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionReadEvent()
-   */
-  virtual bool HandleActionReadEvent( unsigned int x, unsigned int y, bool allowReadAgain );
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionReadNextEvent()
-   */
-  virtual bool HandleActionReadNextEvent( bool allowEndFeedback = true);
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionReadPreviousEvent()
-   */
-  virtual bool HandleActionReadPreviousEvent( bool allowEndFeedback = true);
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionUpEvent()
-   */
-  virtual bool HandleActionUpEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionDownEvent()
-   */
-  virtual bool HandleActionDownEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionClearFocusEvent()
-   */
-  bool HandleActionClearFocusEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionScrollEvent()
-   */
-  bool HandleActionScrollEvent(const TouchPoint& point, uint32_t timeStamp);
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionTouchEvent()
-   */
-  bool HandleActionTouchEvent(const TouchPoint& point, uint32_t timeStamp);
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionBackEvent()
-   */
-  bool HandleActionBackEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionEnableEvent()
-   */
-  void HandleActionEnableEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionDisableEvent()
-   */
-  void HandleActionDisableEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionScrollUpEvent()
-   */
-  bool HandleActionScrollUpEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionScrollDownEvent()
-   */
-  bool HandleActionScrollDownEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionPageLeftEvent()
-   */
-  bool HandleActionPageLeftEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionPageRightEvent()
-   */
-  bool HandleActionPageRightEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionPageUpEvent()
-   */
-  bool HandleActionPageUpEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionPageDownEvent()
-   */
-  bool HandleActionPageDownEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionMoveToFirstEvent()
-   */
-  bool HandleActionMoveToFirstEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionMoveToLastEvent()
-   */
-  bool HandleActionMoveToLastEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionReadFromTopEvent()
-   */
-  bool HandleActionReadFromTopEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionReadFromNextEvent()
-   */
-  bool HandleActionReadFromNextEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionZoomEvent()
-   */
-  bool HandleActionZoomEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionReadPauseResumeEvent()
-   */
-  bool HandleActionReadPauseResumeEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionStartStopEvent()
-   */
-  bool HandleActionStartStopEvent();
-
-protected:
-
-  /**
-   * Destructor.
-   */
-  virtual ~AccessibilityAdaptor();
-
-private:
-
-  /**
-   * @brief Called when the singleton is destroyed.
-   *
-   * @note This can be reimplemented for different platforms.
-   * @return The instance of the AccessibilityAdaptor.
-   */
-  static void OnDestroy();
-
-  // Undefined
-  AccessibilityAdaptor( const AccessibilityAdaptor& );
-  AccessibilityAdaptor& operator=( AccessibilityAdaptor& );
-
-protected:
-
-  Dali::Integration::TouchEventCombiner mCombiner; ///< Combines multi-touch events.
-
-  Vector2 mReadPosition; ///< ActionRead position
-
-  AccessibilityActionHandler* mActionHandler; ///< The pointer of accessibility action handler
-
-  AccessibilityGestureDetectorPtr mAccessibilityGestureDetector; ///< The accessibility gesture detector
-
-  bool mIsEnabled        : 1; ///< enable/disable the accessibility action
-
-public:
-
-  // Helpers for public-api forwarding methods
-
-  inline static Internal::Adaptor::AccessibilityAdaptor& GetImplementation(Dali::AccessibilityAdaptor& adaptor)
-  {
-    DALI_ASSERT_ALWAYS( adaptor && "AccessibilityAdaptor handle is empty" );
-
-    BaseObject& handle = adaptor.GetBaseObject();
-
-    return static_cast<Internal::Adaptor::AccessibilityAdaptor&>(handle);
-  }
-
-  inline static const Internal::Adaptor::AccessibilityAdaptor& GetImplementation(const Dali::AccessibilityAdaptor& adaptor)
-  {
-    DALI_ASSERT_ALWAYS( adaptor && "AccessibilityAdaptor handle is empty" );
-
-    const BaseObject& handle = adaptor.GetBaseObject();
-
-    return static_cast<const Internal::Adaptor::AccessibilityAdaptor&>(handle);
-  }
-
-};
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // DALI_INTERNAL_ACCESSIBILITY_ADAPTOR_H
diff --git a/dali/internal/accessibility/common/accessibility-gesture-detector.cpp b/dali/internal/accessibility/common/accessibility-gesture-detector.cpp
deleted file mode 100644 (file)
index b872077..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/accessibility/common/accessibility-gesture-detector.h>
-
-// EXTERNAL INCLUDES
-#include <cmath>
-
-#include <dali/public-api/events/touch-point.h>
-
-#include <dali/integration-api/events/touch-event-integ.h>
-
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-namespace
-{
-  const float MINIMUM_MOTION_DISTANCE_BEFORE_PAN( 15.0f );
-  const float MINIMUM_MOTION_DISTANCE_BEFORE_PAN_SQUARED( MINIMUM_MOTION_DISTANCE_BEFORE_PAN * MINIMUM_MOTION_DISTANCE_BEFORE_PAN );
-  const float MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO( 2.0f / 3.0f );
-  const unsigned long MAXIMUM_TIME_DIFF_ALLOWED( 500 );
-  const unsigned long MINIMUM_TIME_BEFORE_THRESHOLD_ADJUSTMENTS( 100 );
-  const unsigned int MINIMUM_MOTION_EVENTS_BEFORE_PAN(2);
-  const unsigned int MINIMUM_TOUCHES_BEFORE_PAN(1);
-  const unsigned int MAXIMUM_TOUCHES_BEFORE_PAN(1);
-} // unnamed namespace
-
-
-AccessibilityGestureDetector::AccessibilityGestureDetector()
-: mState( Clear ),
-  mScene(nullptr),
-  mGestureHandler(nullptr),
-  mPanning(false),
-  mThresholdAdjustmentsRemaining( 0 ),
-  mThresholdTotalAdjustments( MINIMUM_MOTION_DISTANCE_BEFORE_PAN * MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO ),
-  mPrimaryTouchDownTime( 0 ),
-  mMinimumTouchesRequired( MINIMUM_TOUCHES_BEFORE_PAN ),
-  mMaximumTouchesRequired( MAXIMUM_TOUCHES_BEFORE_PAN ),
-  mMinimumDistanceSquared( MINIMUM_MOTION_DISTANCE_BEFORE_PAN_SQUARED ),
-  mMinimumMotionEvents( MINIMUM_MOTION_EVENTS_BEFORE_PAN ),
-  mMotionEvents( 0 )
-{
-}
-
-AccessibilityGestureDetector::~AccessibilityGestureDetector()
-{
-}
-
-void AccessibilityGestureDetector::SetGestureHandler(AccessibilityGestureHandler& handler)
-{
-  mGestureHandler = &handler;
-}
-
-void AccessibilityGestureDetector::EmitPan(const AccessibilityGestureEvent gesture)
-{
-  if( mGestureHandler )
-  {
-    if(gesture.state == AccessibilityGestureEvent::Started)
-    {
-      mPanning = true;
-    }
-
-    if( mPanning )
-    {
-      mGestureHandler->HandlePanGesture(gesture);
-
-      if( (gesture.state == AccessibilityGestureEvent::Finished) ||
-          (gesture.state == AccessibilityGestureEvent::Cancelled) )
-      {
-        mPanning = false;
-      }
-    }
-  }
-}
-
-void AccessibilityGestureDetector::SendEvent(const Integration::TouchEvent& event)
-{
-  PointState::Type primaryPointState(event.points[0].GetState());
-
-  if (primaryPointState == PointState::INTERRUPTED)
-  {
-    if ( ( mState == Started ) || ( mState == Possible ) )
-    {
-      // If our pan had started and we are interrupted, then tell Core that pan is cancelled.
-      mTouchEvents.push_back(event);
-      SendPan(AccessibilityGestureEvent::Cancelled, event);
-    }
-    mState = Clear; // We should change our state to Clear.
-    mTouchEvents.clear();
-  }
-  else
-  {
-    switch (mState)
-    {
-      case Clear:
-      {
-        if ( ( primaryPointState == PointState::DOWN ) || ( primaryPointState == PointState::STATIONARY ) )
-        {
-          mPrimaryTouchDownLocation = event.points[0].GetScreenPosition();
-          mPrimaryTouchDownTime = event.time;
-          mMotionEvents = 0;
-          if (event.GetPointCount() == mMinimumTouchesRequired)
-          {
-            // We have satisfied the minimum touches required for a pan, tell core that a gesture may be possible and change our state accordingly.
-            mState = Possible;
-            SendPan(AccessibilityGestureEvent::Possible, event);
-          }
-
-          mTouchEvents.push_back(event);
-        }
-        break;
-      }
-
-      case Possible:
-      {
-        unsigned int pointCount(event.GetPointCount());
-        if ( (pointCount >= mMinimumTouchesRequired)&&(pointCount <= mMaximumTouchesRequired) )
-        {
-          if (primaryPointState == PointState::MOTION)
-          {
-            mTouchEvents.push_back(event);
-            mMotionEvents++;
-
-            Vector2 delta(event.points[0].GetScreenPosition() - mPrimaryTouchDownLocation);
-
-            if ( ( mMotionEvents >= mMinimumMotionEvents ) &&
-                 ( delta.LengthSquared() >= static_cast<float>( mMinimumDistanceSquared ) ) )
-            {
-              // If the touch point(s) have moved enough distance to be considered a pan, then tell Core that the pan gesture has started and change our state accordingly.
-              mState = Started;
-              SendPan(AccessibilityGestureEvent::Started, event);
-            }
-          }
-          else if (primaryPointState == PointState::UP)
-          {
-            Vector2 delta(event.points[0].GetScreenPosition() - mPrimaryTouchDownLocation);
-            if (delta.LengthSquared() >= static_cast<float>( mMinimumDistanceSquared ) )
-            {
-              SendPan(AccessibilityGestureEvent::Started, event);
-              mTouchEvents.push_back(event);
-              SendPan(AccessibilityGestureEvent::Finished, event);
-            }
-            else
-            {
-              // If we have lifted the primary touch point then tell core the pan is cancelled and change our state to Clear.
-              SendPan(AccessibilityGestureEvent::Cancelled, event);
-            }
-            mState = Clear;
-            mTouchEvents.clear();
-          }
-        }
-        else
-        {
-          // We do not satisfy pan conditions, tell Core our Gesture has been cancelled.
-          SendPan(AccessibilityGestureEvent::Cancelled, event);
-
-          if (pointCount == 1 && primaryPointState == PointState::UP)
-          {
-            // If we have lifted the primary touch point, then change our state to Clear...
-            mState = Clear;
-            mTouchEvents.clear();
-          }
-          else
-          {
-            // ...otherwise change it to Failed.
-            mState = Failed;
-          }
-        }
-        break;
-      }
-
-      case Started:
-      {
-        mTouchEvents.push_back(event);
-
-        unsigned int pointCount(event.GetPointCount());
-        if ( (pointCount >= mMinimumTouchesRequired)&&(pointCount <= mMaximumTouchesRequired) )
-        {
-          switch (primaryPointState)
-          {
-            case PointState::MOTION:
-              // Pan is continuing, tell Core.
-              SendPan(AccessibilityGestureEvent::Continuing, event);
-              break;
-
-            case PointState::UP:
-              // Pan is finally finished when our primary point is lifted, tell Core and change our state to Clear.
-              SendPan(AccessibilityGestureEvent::Finished, event);
-              mState = Clear;
-              mTouchEvents.clear();
-              break;
-
-            case PointState::STATIONARY:
-              if (pointCount == mMinimumTouchesRequired)
-              {
-                Integration::PointContainerConstIterator iter = event.points.begin() + 1; // We already know the state of the first point
-                for(; iter != event.points.end(); ++iter)
-                {
-                  if(iter->GetState() == PointState::UP)
-                  {
-                    // The number of touch points will be less than the minimum required.  Inform core and change our state to Finished.
-                    SendPan(AccessibilityGestureEvent::Finished, event);
-                    mState = Finished;
-                    break;
-                  }
-                }
-              }
-              break;
-
-            default:
-              break;
-          }
-        }
-        else
-        {
-          // We have gone outside of the pan requirements, inform Core that the gesture is finished.
-          SendPan(AccessibilityGestureEvent::Finished, event);
-
-          if (pointCount == 1 && primaryPointState == PointState::UP)
-          {
-            // If this was the primary point being released, then we change our state back to Clear...
-            mState = Clear;
-            mTouchEvents.clear();
-          }
-          else
-          {
-            // ...otherwise we change it to Finished.
-            mState = Finished;
-          }
-        }
-        break;
-      }
-
-      case Finished:
-      case Failed:
-      {
-        if (primaryPointState == PointState::UP)
-        {
-          // Change our state back to clear when the primary touch point is released.
-          mState = Clear;
-          mTouchEvents.clear();
-        }
-        break;
-      }
-    }
-  }
-}
-
-void AccessibilityGestureDetector::SendPan(AccessibilityGestureEvent::State state, const Integration::TouchEvent& currentEvent)
-{
-  AccessibilityGestureEvent gesture(state);
-  gesture.currentPosition = currentEvent.points[0].GetScreenPosition();
-  gesture.numberOfTouches = currentEvent.GetPointCount();
-
-  if ( mTouchEvents.size() > 1 )
-  {
-    // Get the second last event in the queue, the last one is the current event
-    const Integration::TouchEvent& previousEvent( *( mTouchEvents.rbegin() + 1 ) );
-
-    Vector2 previousPosition( mPreviousPosition );
-    uint32_t previousTime( previousEvent.time );
-
-    // If we've just started then we want to remove the threshold from Core calculations.
-    if ( state == AccessibilityGestureEvent::Started )
-    {
-      previousPosition = mPrimaryTouchDownLocation;
-      previousTime = mPrimaryTouchDownTime;
-
-      // If it's a slow pan, we do not want to phase in the threshold over the first few pan-events
-      // A slow pan is defined as one that starts the specified number of milliseconds after the down-event
-      if ( ( currentEvent.time - previousTime ) > MINIMUM_TIME_BEFORE_THRESHOLD_ADJUSTMENTS )
-      {
-        mThresholdAdjustmentsRemaining = mThresholdTotalAdjustments;
-        mThresholdAdjustmentPerFrame = ( gesture.currentPosition - previousPosition ) / static_cast<float>( mThresholdTotalAdjustments );
-      }
-      else
-      {
-        mThresholdAdjustmentsRemaining = 0;
-        mThresholdAdjustmentPerFrame = Vector2::ZERO;
-      }
-    }
-
-    gesture.previousPosition = previousPosition;
-    gesture.timeDelta = currentEvent.time - previousTime;
-
-    // Apply the threshold with a phased approach
-    if ( mThresholdAdjustmentsRemaining > 0 )
-    {
-      --mThresholdAdjustmentsRemaining;
-      gesture.currentPosition -= mThresholdAdjustmentPerFrame * static_cast<float>( mThresholdAdjustmentsRemaining );
-    }
-
-    mPreviousPosition = gesture.currentPosition;
-  }
-  else
-  {
-    gesture.previousPosition = gesture.currentPosition;
-    gesture.timeDelta = 0;
-  }
-
-  gesture.time = currentEvent.time;
-
-  EmitPan(gesture);
-}
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
diff --git a/dali/internal/accessibility/common/accessibility-gesture-detector.h b/dali/internal/accessibility/common/accessibility-gesture-detector.h
deleted file mode 100644 (file)
index 616d76e..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-#ifndef DALI_INTERNAL_ACCESSIBILITY_GESTURE_DETECTOR_H
-#define DALI_INTERNAL_ACCESSIBILITY_GESTURE_DETECTOR_H
-
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-
-// INTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-handler.h>
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-event.h>
-#include <dali/integration-api/scene.h>
-#include <dali/public-api/events/touch-event.h>
-
-namespace Dali
-{
-
-namespace Integration
-{
-struct TouchEvent;
-}
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-/**
- * Detects an accessibility pan gesture and sends it to the gesture handler.
- */
-class AccessibilityGestureDetector : public RefObject
-{
-public:
-
-  /**
-   * Constructor
-   */
-  AccessibilityGestureDetector();
-
-  /**
-   * Virtual destructor.
-   */
-  virtual ~AccessibilityGestureDetector();
-
-  /**
-   * Set the handler to handle accessibility gestures.
-   * @param[in] handler The Accessibility gesture handler.
-   * @note Handlers should remove themselves when they are destroyed.
-   */
-  void SetGestureHandler(AccessibilityGestureHandler& handler);
-
-  void SendEvent(const Integration::TouchEvent& event);
-
-  void SendEvent(Integration::Scene& scene, const Integration::TouchEvent& event)
-  {
-    mScene = &scene;
-    SendEvent(event);
-  }
-
-private:
-
-  /**
-   * Emits the pan gesture event (performs some smoothing operation).
-   * @param[in]  state         The state of the pan.
-   * @param[in]  currentEvent  The latest touch event.
-   */
-  void SendPan(AccessibilityGestureEvent::State state, const Integration::TouchEvent& currentEvent);
-
-  /**
-   * Emits the pan gesture event to the gesture handler.
-   * @param[in] gesture The pan gesture event.
-   */
-  void EmitPan(const AccessibilityGestureEvent gesture);
-
-private:
-
-  /**
-   * Internal state machine.
-   */
-  enum State
-  {
-    Clear,    ///< No gesture detected.
-    Possible, ///< The current touch event data suggests that a gesture is possible.
-    Started,  ///< A gesture has been detected.
-    Finished, ///< A previously started pan gesture has finished.
-    Failed,   ///< Current touch event data suggests a pan gesture is not possible.
-  };
-
-  State mState; ///< The current state of the detector.
-
-  Integration::Scene* mScene;
-  AccessibilityGestureHandler* mGestureHandler; ///< The pointer of accessibility gesture handler
-  bool mPanning;    ///< Keep track of panning state, when panning is occuring, this is true.
-
-  std::vector<Integration::TouchEvent> mTouchEvents;     ///< A container of all touch events after an initial down event.
-
-  Vector2 mPrimaryTouchDownLocation;    ///< The initial touch down point.
-  Vector2 mThresholdAdjustmentPerFrame; ///< The adjustment per frame at the start of a slow pan.
-  Vector2 mPreviousPosition;            ///< The previous position.
-
-  unsigned int mThresholdAdjustmentsRemaining; ///< No. of threshold adjustments still to apply (for a slow-pan).
-  unsigned int mThresholdTotalAdjustments;     ///< The total number of adjustments required.
-
-  uint32_t mPrimaryTouchDownTime;       ///< The initial touch down time.
-  unsigned int mMinimumTouchesRequired; ///< The minimum touches required before a pan should be emitted.
-  unsigned int mMaximumTouchesRequired; ///< The maximum touches after which a pan should not be emitted.
-  unsigned int mMinimumDistanceSquared; ///< The minimum distance squared before pan should start.
-  unsigned int mMinimumMotionEvents;    ///< The minimum motion events before pan should start.
-  unsigned int mMotionEvents;           ///< The motion events received so far (before pan is emitted).
-};
-
-using AccessibilityGestureDetectorPtr = Dali::IntrusivePtr<AccessibilityGestureDetector>;
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // DALI_INTERNAL_ACCESSIBILITY_GESTURE_DETECTOR_H
index 00bd528..1c91f1b 100644 (file)
@@ -2,36 +2,28 @@
 
 # module: accessibility, backend: common
 adaptor_accessibility_common_src_files=\
+    ${adaptor_accessibility_dir}/accessibility-impl.cpp \
     ${adaptor_accessibility_dir}/common/tts-player-factory.cpp \
     ${adaptor_accessibility_dir}/common/tts-player-impl.cpp \
-    ${adaptor_accessibility_dir}/common/accessibility-adaptor-impl.cpp \
-    ${adaptor_accessibility_dir}/common/accessibility-gesture-detector.cpp
+    $(adaptor_accessibility_dir)/bridge/accessible.cpp \
+    $(adaptor_accessibility_dir)/bridge/component.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-accessible.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-collection.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-base.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-component.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-action.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-value.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-object.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-impl.cpp \
+    $(adaptor_accessibility_dir)/bridge/dbus.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-text.cpp \
+    $(adaptor_accessibility_dir)/bridge/bridge-editable-text.cpp
 
 # module: accessibility, backend: tizen-wayland
 adaptor_accessibility_tizen_wayland_src_files=\
     ${adaptor_accessibility_dir}/tizen-wayland/tts-player-factory-tizen.cpp \
     ${adaptor_accessibility_dir}/tizen-wayland/tts-player-impl-tizen.cpp
 
-# module: accessibility, backend: tizen-common profile
-adaptor_accessibility_tizen_common_src_files=\
-    ${adaptor_accessibility_dir}/tizen-wayland/tizen-common/accessibility-adaptor-impl-tizen.cpp
-
-# module: accessibility, backend: tizen-ivi profile
-adaptor_accessibility_tizen_ivi_src_files=\
-    ${adaptor_accessibility_dir}/tizen-wayland/tizen-ivi/accessibility-adaptor-impl-ivi.cpp
-
-# module: accessibility, backend: tizen-mobile profile
-adaptor_accessibility_tizen_mobile_src_files=\
-    ${adaptor_accessibility_dir}/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.cpp
-
-# module: accessibility, backend: tizen-tv profile
-adaptor_accessibility_tizen_tv_src_files=\
-    ${adaptor_accessibility_dir}/tizen-wayland/tizen-tv/accessibility-adaptor-impl-tv.cpp
-
-# module: accessibility, backend: tizen-wearable profile
-adaptor_accessibility_tizen_wearable_src_files=\
-    ${adaptor_accessibility_dir}/tizen-wayland/tizen-wearable/accessibility-adaptor-impl-wearable.cpp
-
 # module: accessibility, backend: generic
 adaptor_accessibility_ubuntu_src_files=\
     ${adaptor_accessibility_dir}/generic/accessibility-adaptor-impl-generic.cpp \
diff --git a/dali/internal/accessibility/generic/accessibility-adaptor-impl-generic.cpp b/dali/internal/accessibility/generic/accessibility-adaptor-impl-generic.cpp
deleted file mode 100644 (file)
index 05dda37..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
-
-// EXTERNAL INCLUDES
-#include <dali/public-api/object/type-registry.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/system/common/singleton-service-impl.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-Dali::AccessibilityAdaptor AccessibilityAdaptor::Get()
-{
-  Dali::AccessibilityAdaptor adaptor;
-
-  Dali::SingletonService service( SingletonService::Get() );
-  if ( service )
-  {
-    // Check whether the singleton is already created
-    Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AccessibilityAdaptor ) );
-    if(handle)
-    {
-      // If so, downcast the handle
-      adaptor = Dali::AccessibilityAdaptor( dynamic_cast< AccessibilityAdaptor* >( handle.GetObjectPtr() ) );
-    }
-    else
-    {
-      adaptor = Dali::AccessibilityAdaptor( new AccessibilityAdaptor() );
-      service.Register( typeid( adaptor ), adaptor );
-    }
-  }
-
-  return adaptor;
-}
-
-void AccessibilityAdaptor::OnDestroy()
-{
-  // Nothing to do here
-}
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
diff --git a/dali/internal/accessibility/tizen-wayland/tizen-common/accessibility-adaptor-impl-tizen.cpp b/dali/internal/accessibility/tizen-wayland/tizen-common/accessibility-adaptor-impl-tizen.cpp
deleted file mode 100644 (file)
index 18d57df..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
-
-// EXTERNAL INCLUDES
-#include <vconf.h>
-
-#include <dali/public-api/object/type-registry.h>
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/system/common/singleton-service-impl.h>
-#include <dali/internal/system/common/system-settings.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-namespace
-{
-
-const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS = "db/setting/accessibility/atspi";
-
-// Disabled Accessibility temporarily in Tizen platform
-bool GetEnabledVConf()
-{
-  int isEnabled = 0;
-  //vconf_get_bool( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, &isEnabled );
-
-  if( isEnabled == 0 )
-  {
-    //vconf_get_bool( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &isEnabled );
-  }
-
-  return static_cast<bool>(isEnabled);
-}
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gAccessibilityAdaptorLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_ACCESSIBILITY_ADAPTOR" );
-#endif
-
-void AccessibilityOnOffNotification(keynode_t* node, void* data)
-{
-  AccessibilityAdaptor* adaptor = static_cast<AccessibilityAdaptor*>( data );
-
-  bool isEnabled = GetEnabledVConf();
-
-  DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-  if( isEnabled )
-  {
-    adaptor->EnableAccessibility();
-  }
-  else
-  {
-    adaptor->DisableAccessibility();
-  }
-}
-
-} // unnamed namespace
-
-Dali::AccessibilityAdaptor AccessibilityAdaptor::Get()
-{
-  Dali::AccessibilityAdaptor adaptor;
-
-  Dali::SingletonService service( SingletonService::Get() );
-  if ( service )
-  {
-    // Check whether the singleton is already created
-    Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AccessibilityAdaptor ) );
-    if(handle)
-    {
-      // If so, downcast the handle
-      adaptor = Dali::AccessibilityAdaptor( dynamic_cast< AccessibilityAdaptor* >( handle.GetObjectPtr() ) );
-    }
-    else
-    {
-      adaptor = Dali::AccessibilityAdaptor( new AccessibilityAdaptor() );
-      AccessibilityAdaptor& adaptorImpl = AccessibilityAdaptor::GetImplementation( adaptor );
-
-      bool isEnabled = GetEnabledVConf();
-
-      if( isEnabled )
-      {
-        adaptorImpl.EnableAccessibility();
-      }
-      DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-      vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-      vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-
-      service.Register( typeid( adaptor ), adaptor );
-    }
-  }
-
-  return adaptor;
-}
-
-void AccessibilityAdaptor::OnDestroy()
-{
-  vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification );
-  vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification );
-}
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
diff --git a/dali/internal/accessibility/tizen-wayland/tizen-ivi/accessibility-adaptor-impl-ivi.cpp b/dali/internal/accessibility/tizen-wayland/tizen-ivi/accessibility-adaptor-impl-ivi.cpp
deleted file mode 100644 (file)
index f75eff9..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.h>
-
-// EXTERNAL INCLUDES
-#include <vconf.h>
-
-#ifndef WAYLAND
-#include <dali/internal/system/linux/dali-ecore-x.h>
-#include <dali/internal/system/linux/dali-elementary.h>
-#endif
-
-#include <vconf.h>
-
-#include <dali/public-api/object/type-registry.h>
-#include <dali/integration-api/debug.h>
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/system/common/singleton-service-impl.h>
-#include <dali/internal/system/common/system-settings.h>
-
-#ifndef WAYLAND
-#define MSG_DOMAIN_CONTROL_ACCESS static_cast< int >( ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL )
-#endif
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-namespace // unnamed namespace
-{
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gAccessibilityAdaptorLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ACCESSIBILITY_ADAPTOR");
-#endif
-
-const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS = "db/setting/accessibility/atspi";
-
-bool GetEnabledVConf()
-{
-  int isEnabled = 0;
-  vconf_get_bool( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, &isEnabled );
-
-  if( isEnabled == 0 )
-  {
-    vconf_get_bool( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &isEnabled );
-  }
-
-  return bool( isEnabled );
-}
-
-
-void AccessibilityOnOffNotification(keynode_t* node, void* data)
-{
-  AccessibilityAdaptor* adaptor = static_cast<AccessibilityAdaptor*>( data );
-
-  bool isEnabled = GetEnabledVConf();
-
-  DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-  if( isEnabled )
-  {
-    adaptor->EnableAccessibility();
-  }
-  else
-  {
-    adaptor->DisableAccessibility();
-  }
-}
-
-} // unnamed namespace
-
-Dali::AccessibilityAdaptor AccessibilityAdaptor::Get()
-{
-  Dali::AccessibilityAdaptor adaptor;
-
-  Dali::SingletonService service( SingletonService::Get() );
-  if ( service )
-  {
-    // Check whether the singleton is already created
-    Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AccessibilityAdaptor ) );
-    if(handle)
-    {
-      // If so, downcast the handle
-      adaptor = Dali::AccessibilityAdaptor( dynamic_cast< AccessibilityAdaptor* >( handle.GetObjectPtr() ) );
-    }
-    else
-    {
-      adaptor = Dali::AccessibilityAdaptor( new AccessibilityAdaptorMobile() );
-      AccessibilityAdaptorMobile& adaptorImpl = AccessibilityAdaptorMobile::GetImplementation( adaptor );
-
-      bool isEnabled = GetEnabledVConf();
-
-      if( isEnabled )
-      {
-        adaptorImpl.EnableAccessibility();
-      }
-      DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-      vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-      vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-
-      service.Register( typeid( adaptor ), adaptor );
-    }
-  }
-
-  return adaptor;
-}
-
-void AccessibilityAdaptor::OnDestroy()
-{
-  vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification );
-  vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification );
-}
-
-AccessibilityAdaptorMobile::AccessibilityAdaptorMobile()
-{
-}
-
-bool AccessibilityAdaptorMobile::HandleActionNextEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionNext(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionPreviousEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionPrevious(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionActivateEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionActivate();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
-{
-  bool ret = false;
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %d , %d\n", __FUNCTION__, __LINE__, x, y);
-
-  mReadPosition.x = x;
-  mReadPosition.y = y;
-
-  if( mActionHandler )
-  {
-    // The accessibility actions should be handled by the registered accessibility action handler (e.g. focus manager)
-    ret = mActionHandler->AccessibilityActionRead(allowReadAgain);
-    DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-  }
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionReadNextEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadNext(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionReadPreviousEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadPrevious(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionUpEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionUp();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionDownEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionDown();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-AccessibilityAdaptorMobile::~AccessibilityAdaptorMobile()
-{
-}
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
diff --git a/dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.cpp b/dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.cpp
deleted file mode 100644 (file)
index f75eff9..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.h>
-
-// EXTERNAL INCLUDES
-#include <vconf.h>
-
-#ifndef WAYLAND
-#include <dali/internal/system/linux/dali-ecore-x.h>
-#include <dali/internal/system/linux/dali-elementary.h>
-#endif
-
-#include <vconf.h>
-
-#include <dali/public-api/object/type-registry.h>
-#include <dali/integration-api/debug.h>
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/system/common/singleton-service-impl.h>
-#include <dali/internal/system/common/system-settings.h>
-
-#ifndef WAYLAND
-#define MSG_DOMAIN_CONTROL_ACCESS static_cast< int >( ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL )
-#endif
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-namespace // unnamed namespace
-{
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gAccessibilityAdaptorLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ACCESSIBILITY_ADAPTOR");
-#endif
-
-const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS = "db/setting/accessibility/atspi";
-
-bool GetEnabledVConf()
-{
-  int isEnabled = 0;
-  vconf_get_bool( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, &isEnabled );
-
-  if( isEnabled == 0 )
-  {
-    vconf_get_bool( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &isEnabled );
-  }
-
-  return bool( isEnabled );
-}
-
-
-void AccessibilityOnOffNotification(keynode_t* node, void* data)
-{
-  AccessibilityAdaptor* adaptor = static_cast<AccessibilityAdaptor*>( data );
-
-  bool isEnabled = GetEnabledVConf();
-
-  DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-  if( isEnabled )
-  {
-    adaptor->EnableAccessibility();
-  }
-  else
-  {
-    adaptor->DisableAccessibility();
-  }
-}
-
-} // unnamed namespace
-
-Dali::AccessibilityAdaptor AccessibilityAdaptor::Get()
-{
-  Dali::AccessibilityAdaptor adaptor;
-
-  Dali::SingletonService service( SingletonService::Get() );
-  if ( service )
-  {
-    // Check whether the singleton is already created
-    Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AccessibilityAdaptor ) );
-    if(handle)
-    {
-      // If so, downcast the handle
-      adaptor = Dali::AccessibilityAdaptor( dynamic_cast< AccessibilityAdaptor* >( handle.GetObjectPtr() ) );
-    }
-    else
-    {
-      adaptor = Dali::AccessibilityAdaptor( new AccessibilityAdaptorMobile() );
-      AccessibilityAdaptorMobile& adaptorImpl = AccessibilityAdaptorMobile::GetImplementation( adaptor );
-
-      bool isEnabled = GetEnabledVConf();
-
-      if( isEnabled )
-      {
-        adaptorImpl.EnableAccessibility();
-      }
-      DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-      vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-      vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-
-      service.Register( typeid( adaptor ), adaptor );
-    }
-  }
-
-  return adaptor;
-}
-
-void AccessibilityAdaptor::OnDestroy()
-{
-  vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification );
-  vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification );
-}
-
-AccessibilityAdaptorMobile::AccessibilityAdaptorMobile()
-{
-}
-
-bool AccessibilityAdaptorMobile::HandleActionNextEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionNext(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionPreviousEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionPrevious(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionActivateEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionActivate();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
-{
-  bool ret = false;
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %d , %d\n", __FUNCTION__, __LINE__, x, y);
-
-  mReadPosition.x = x;
-  mReadPosition.y = y;
-
-  if( mActionHandler )
-  {
-    // The accessibility actions should be handled by the registered accessibility action handler (e.g. focus manager)
-    ret = mActionHandler->AccessibilityActionRead(allowReadAgain);
-    DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-  }
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionReadNextEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadNext(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionReadPreviousEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadPrevious(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionUpEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionUp();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionDownEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionDown();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-AccessibilityAdaptorMobile::~AccessibilityAdaptorMobile()
-{
-}
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
diff --git a/dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.h b/dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.h
deleted file mode 100644 (file)
index fd2939e..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef DALI_INTERNAL_ACCESSIBILITY_ADAPTOR_MOBILE_H
-#define DALI_INTERNAL_ACCESSIBILITY_ADAPTOR_MOBILE_H
-
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
-#include <dali/devel-api/adaptor-framework/accessibility-action-handler.h>
-#include <dali/devel-api/adaptor-framework/accessibility-gesture-handler.h>
-#include <dali/internal/accessibility/common/accessibility-gesture-detector.h>
-#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-/**
- * This mobile version is different since it forwards events to the indicator.
- */
-class AccessibilityAdaptorMobile : public AccessibilityAdaptor
-{
-public:
-
-  /**
-   * Constructor.
-   */
-  AccessibilityAdaptorMobile();
-
-  // From AccessibilityAdaptor base class
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionNextEvent()
-   */
-  virtual bool HandleActionNextEvent( bool allowEndFeedback );
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionPreviousEvent()
-   */
-  virtual bool HandleActionPreviousEvent( bool allowEndFeedback );
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionActivateEvent()
-   */
-  virtual bool HandleActionActivateEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionReadEvent()
-   */
-  virtual bool HandleActionReadEvent( unsigned int x, unsigned int y, bool allowReadAgain );
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionReadNextEvent()
-   */
-  virtual bool HandleActionReadNextEvent( bool allowEndFeedback );
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionReadPreviousEvent()
-   */
-  virtual bool HandleActionReadPreviousEvent( bool allowEndFeedback );
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionUpEvent()
-   */
-  virtual bool HandleActionUpEvent();
-
-  /**
-   * @copydoc Dali::AccessibilityAdaptor::HandleActionDownEvent()
-   */
-  virtual bool HandleActionDownEvent();
-
-private:
-
-  /**
-   * Destructor.
-   */
-  virtual ~AccessibilityAdaptorMobile();
-
-  // Undefined
-  AccessibilityAdaptorMobile( const AccessibilityAdaptorMobile& );
-  AccessibilityAdaptorMobile& operator=( AccessibilityAdaptorMobile& );
-
-public:
-
-  // Helpers for public-api forwarding methods
-
-  inline static Internal::Adaptor::AccessibilityAdaptorMobile& GetImplementation(Dali::AccessibilityAdaptor& adaptor)
-  {
-    DALI_ASSERT_ALWAYS( adaptor && "AccessibilityAdaptorMobile handle is empty" );
-
-    BaseObject& handle = adaptor.GetBaseObject();
-
-    return static_cast<Internal::Adaptor::AccessibilityAdaptorMobile&>(handle);
-  }
-
-  inline static const Internal::Adaptor::AccessibilityAdaptorMobile& GetImplementation(const Dali::AccessibilityAdaptor& adaptor)
-  {
-    DALI_ASSERT_ALWAYS( adaptor && "AccessibilityAdaptorMobile handle is empty" );
-
-    const BaseObject& handle = adaptor.GetBaseObject();
-
-    return static_cast<const Internal::Adaptor::AccessibilityAdaptorMobile&>(handle);
-  }
-
-};
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // DALI_INTERNAL_ACCESSIBILITY_ADAPTOR_MOBILE_H
diff --git a/dali/internal/accessibility/tizen-wayland/tizen-tv/accessibility-adaptor-impl-tv.cpp b/dali/internal/accessibility/tizen-wayland/tizen-tv/accessibility-adaptor-impl-tv.cpp
deleted file mode 100644 (file)
index 18d57df..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
-
-// EXTERNAL INCLUDES
-#include <vconf.h>
-
-#include <dali/public-api/object/type-registry.h>
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/system/common/singleton-service-impl.h>
-#include <dali/internal/system/common/system-settings.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-namespace
-{
-
-const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS = "db/setting/accessibility/atspi";
-
-// Disabled Accessibility temporarily in Tizen platform
-bool GetEnabledVConf()
-{
-  int isEnabled = 0;
-  //vconf_get_bool( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, &isEnabled );
-
-  if( isEnabled == 0 )
-  {
-    //vconf_get_bool( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &isEnabled );
-  }
-
-  return static_cast<bool>(isEnabled);
-}
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gAccessibilityAdaptorLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_ACCESSIBILITY_ADAPTOR" );
-#endif
-
-void AccessibilityOnOffNotification(keynode_t* node, void* data)
-{
-  AccessibilityAdaptor* adaptor = static_cast<AccessibilityAdaptor*>( data );
-
-  bool isEnabled = GetEnabledVConf();
-
-  DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-  if( isEnabled )
-  {
-    adaptor->EnableAccessibility();
-  }
-  else
-  {
-    adaptor->DisableAccessibility();
-  }
-}
-
-} // unnamed namespace
-
-Dali::AccessibilityAdaptor AccessibilityAdaptor::Get()
-{
-  Dali::AccessibilityAdaptor adaptor;
-
-  Dali::SingletonService service( SingletonService::Get() );
-  if ( service )
-  {
-    // Check whether the singleton is already created
-    Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AccessibilityAdaptor ) );
-    if(handle)
-    {
-      // If so, downcast the handle
-      adaptor = Dali::AccessibilityAdaptor( dynamic_cast< AccessibilityAdaptor* >( handle.GetObjectPtr() ) );
-    }
-    else
-    {
-      adaptor = Dali::AccessibilityAdaptor( new AccessibilityAdaptor() );
-      AccessibilityAdaptor& adaptorImpl = AccessibilityAdaptor::GetImplementation( adaptor );
-
-      bool isEnabled = GetEnabledVConf();
-
-      if( isEnabled )
-      {
-        adaptorImpl.EnableAccessibility();
-      }
-      DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-      vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-      vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-
-      service.Register( typeid( adaptor ), adaptor );
-    }
-  }
-
-  return adaptor;
-}
-
-void AccessibilityAdaptor::OnDestroy()
-{
-  vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification );
-  vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification );
-}
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
diff --git a/dali/internal/accessibility/tizen-wayland/tizen-wearable/accessibility-adaptor-impl-wearable.cpp b/dali/internal/accessibility/tizen-wayland/tizen-wearable/accessibility-adaptor-impl-wearable.cpp
deleted file mode 100644 (file)
index d382759..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.h>
-
-// EXTERNAL INCLUDES
-#include <vconf.h>
-
-#ifndef WAYLAND
-#include <dali/internal/system/linux/dali-ecore-x.h>
-#include <dali/internal/system/linux/dali-elementary.h>
-#endif
-
-#include <vconf.h>
-
-#include <dali/public-api/object/type-registry.h>
-#include <dali/integration-api/debug.h>
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-#include <dali/internal/system/common/singleton-service-impl.h>
-#include <dali/internal/system/common/system-settings.h>
-
-#ifndef WAYLAND
-#define MSG_DOMAIN_CONTROL_ACCESS static_cast< int >( ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL )
-#endif
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace Adaptor
-{
-
-namespace // unnamed namespace
-{
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gAccessibilityAdaptorLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ACCESSIBILITY_ADAPTOR");
-#endif
-
-const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS = "db/setting/accessibility/atspi";
-
-bool GetEnabledVConf()
-{
-  int isEnabled = 0;
-  vconf_get_bool( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, &isEnabled );
-
-  if( isEnabled == 0 )
-  {
-    vconf_get_bool( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &isEnabled );
-  }
-
-  return bool( isEnabled );
-}
-
-
-void AccessibilityOnOffNotification(keynode_t* node, void* data)
-{
-  AccessibilityAdaptor* adaptor = static_cast<AccessibilityAdaptor*>( data );
-
-  bool isEnabled = GetEnabledVConf();
-
-  DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-  if( isEnabled )
-  {
-    adaptor->EnableAccessibility();
-  }
-  else
-  {
-    adaptor->DisableAccessibility();
-  }
-}
-
-} // unnamed namespace
-
-Dali::AccessibilityAdaptor AccessibilityAdaptor::Get()
-{
-  Dali::AccessibilityAdaptor adaptor;
-
-  Dali::SingletonService service( SingletonService::Get() );
-  if ( service )
-  {
-    // Check whether the singleton is already created
-    Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AccessibilityAdaptor ) );
-    if(handle)
-    {
-      // If so, downcast the handle
-      adaptor = Dali::AccessibilityAdaptor( dynamic_cast< AccessibilityAdaptor* >( handle.GetObjectPtr() ) );
-    }
-    else
-    {
-      adaptor = Dali::AccessibilityAdaptor( new AccessibilityAdaptorMobile() );
-      AccessibilityAdaptorMobile& adaptorImpl = AccessibilityAdaptorMobile::GetImplementation( adaptor );
-
-      bool isEnabled = GetEnabledVConf();
-
-      if( isEnabled )
-      {
-        adaptorImpl.EnableAccessibility();
-      }
-      DALI_LOG_INFO( gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled ? "ENABLED" : "DISABLED" );
-
-      vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-      vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification, &adaptorImpl );
-
-      service.Register( typeid( adaptor ), adaptor );
-    }
-  }
-
-  return adaptor;
-}
-
-void AccessibilityAdaptor::OnDestroy()
-{
-  vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, AccessibilityOnOffNotification );
-  vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, AccessibilityOnOffNotification );
-}
-
-AccessibilityAdaptorMobile::AccessibilityAdaptorMobile()
-{
-}
-
-bool AccessibilityAdaptorMobile::HandleActionNextEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionNext(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionPreviousEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionPrevious(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionActivateEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionActivate();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
-{
-  bool ret = false;
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %d , %d\n", __FUNCTION__, __LINE__, x, y);
-
-  mReadPosition.x = x;
-  mReadPosition.y = y;
-
-  if( mActionHandler)
-  {
-    // The accessibility actions should be handled by the registered accessibility action handler (e.g. focus manager)
-    ret = mActionHandler->AccessibilityActionRead(allowReadAgain);
-    DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-  }
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionReadNextEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadNext(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionReadPreviousEvent(bool allowEndFeedback)
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionReadPrevious(allowEndFeedback);
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionUpEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionUp();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-bool AccessibilityAdaptorMobile::HandleActionDownEvent()
-{
-  bool ret = false;
-
-  if( mActionHandler )
-  {
-    ret = mActionHandler->AccessibilityActionDown();
-  }
-
-  DALI_LOG_INFO(gAccessibilityAdaptorLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
-
-  return ret;
-}
-
-AccessibilityAdaptorMobile::~AccessibilityAdaptorMobile()
-{
-}
-
-} // namespace Adaptor
-
-} // namespace Internal
-
-} // namespace Dali
index bff490a..c9eeb03 100755 (executable)
@@ -49,7 +49,6 @@
 
 #include <dali/internal/system/common/callback-manager.h>
 #include <dali/internal/accessibility/common/tts-player-impl.h>
-#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
 #include <dali/internal/window-system/common/event-handler.h>
 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
 #include <dali/internal/graphics/gles/gl-implementation.h>
@@ -61,6 +60,7 @@
 #include <dali/internal/window-system/common/window-impl.h>
 #include <dali/internal/window-system/common/window-render-surface.h>
 
+#include <dali/devel-api/adaptor-framework/accessibility.h>
 #include <dali/internal/system/common/logging.h>
 
 #include <dali/internal/system/common/locale-utils.h>
@@ -322,10 +322,36 @@ void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration:
       DALI_LOG_ERROR( "Fail to open file : %s\n", ( systemCachePath + "gpu-environment.conf" ).c_str() );
     }
   }
+  auto appName = GetApplicationPackageName();
+  auto bridge = Accessibility::Bridge::GetCurrentBridge();
+  bridge->SetApplicationName( appName );
+  bridge->Initialize();
+  Dali::Stage stage = Dali::Stage::GetCurrent();
+  Dali::Stage::GetCurrent().KeyEventSignal().Connect( &accessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent );
+}
+
+void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent( const KeyEvent& event )
+{
+  Accessibility::KeyEventType type;
+  if( event.state == KeyEvent::Down )
+  {
+    type = Accessibility::KeyEventType::KEY_PRESSED;
+  }
+  else if( event.state == KeyEvent::Up )
+  {
+    type = Accessibility::KeyEventType::KEY_RELEASED;
+  }
+  else
+  {
+    return;
+  }
+  Dali::Accessibility::Bridge::GetCurrentBridge()->Emit( type, event.keyCode, event.keyPressedName, event.time, !event.keyPressed.empty() );
 }
 
 Adaptor::~Adaptor()
 {
+  Accessibility::Bridge::GetCurrentBridge()->Terminate();
+
   // Ensure stop status
   Stop();
 
@@ -918,6 +944,8 @@ void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
 
 void Adaptor::OnWindowShown()
 {
+  Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationShown();
+
   if( PAUSED_WHILE_HIDDEN == mState )
   {
     // Adaptor can now be resumed
@@ -943,6 +971,8 @@ void Adaptor::OnWindowShown()
 
 void Adaptor::OnWindowHidden()
 {
+  Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationHidden();
+
   if( RUNNING == mState || READY == mState )
   {
     bool allWindowsHidden = true;
index 74f7ab3..1f65fb1 100755 (executable)
 #include <dali/integration-api/trigger-event-factory.h>
 #include <dali/internal/network/common/socket-factory.h>
 
+#include <string>
 
 namespace Dali
 {
 
 class RenderSurfaceInterface;
+namespace Accessibility
+{
+class Bridge;
+}
 
 namespace Integration
 {
@@ -180,6 +185,8 @@ public:
    */
   void SceneCreated();
 
+  static std::string GetApplicationPackageName();
+
 public: // AdaptorInternalServices implementation
   /**
    * @copydoc Dali::Adaptor::Start()
@@ -685,6 +692,13 @@ private: // Data
   const bool                            mEnvironmentOptionsOwned:1;   ///< Whether we own the EnvironmentOptions (and thus, need to delete it)
   bool                                  mUseRemoteSurface;            ///< whether the remoteSurface is used or not
 
+  class AccessibilityObserver : public ConnectionTracker
+  {
+  public:
+    void OnAccessibleKeyEvent( const KeyEvent& event );
+  };
+  AccessibilityObserver accessibilityObserver;
+
 public:
   inline static Adaptor& GetImplementation(Dali::Adaptor& adaptor) { return *adaptor.mImpl; }
 };
index 195f936..59230bc 100755 (executable)
@@ -22,7 +22,6 @@
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
 #include <dali/devel-api/adaptor-framework/style-monitor.h>
 #include <dali/integration-api/render-surface.h>
 #include <dali/internal/adaptor/common/adaptor-impl.h>
index 94196b7..40b16d9 100755 (executable)
@@ -22,6 +22,7 @@
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/accessibility.h>
 #include <dali/devel-api/adaptor-framework/style-monitor.h>
 #include <dali/devel-api/text-abstraction/font-client.h>
 #include <dali/internal/adaptor/common/adaptor-impl.h>
@@ -219,6 +220,8 @@ void Application::Quit()
 
 void Application::QuitFromMainLoop()
 {
+  Accessibility::Bridge::GetCurrentBridge()->Terminate();
+
   mAdaptor->Stop();
 
   mFramework->Quit();
index 1b05919..2a983ee 100644 (file)
@@ -27,6 +27,11 @@ namespace Internal
 namespace Adaptor
 {
 
+std::string Adaptor::GetApplicationPackageName()
+{
+  return "";
+}
+
 void Adaptor::GetDataStoragePath( std::string& path)
 {
   path = "";
index 3e2865d..d1761bf 100644 (file)
@@ -33,6 +33,9 @@
 #endif
 
 
+#include <aul.h>
+#include <unistd.h>
+
 namespace Dali
 {
 
@@ -66,6 +69,14 @@ static void OnSystemLanguageChanged( system_settings_key_e key, void* data )
 
 } // namesapce
 
+std::string Adaptor::GetApplicationPackageName()
+{
+  char appname[4096] = {0};
+  int pid = getpid();
+  aul_app_get_pkgname_bypid( pid, appname, sizeof( appname ) );
+  return appname;
+}
+
 void Adaptor::GetDataStoragePath( std::string& path)
 {
 #ifdef USE_APPFW
index 8721844..06851f2 100644 (file)
@@ -63,6 +63,7 @@ struct Clipboard::Impl
   Impl()
   {
     Eldbus_Object *eldbus_obj;
+               eldbus_init();
     cbhm_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
     eldbus_obj = eldbus_object_get(cbhm_conn, CBHM_DBUS_INTERFACE, CBHM_DBUS_OBJPATH);
     eldbus_proxy = eldbus_proxy_get(eldbus_obj, CBHM_DBUS_INTERFACE);
@@ -76,6 +77,7 @@ struct Clipboard::Impl
   {
     if (cbhm_conn)
       eldbus_connection_unref(cbhm_conn);
+               eldbus_shutdown();
   }
 
   Eldbus_Proxy* cbhm_proxy_get()
index b44a024..46ab713 100755 (executable)
@@ -1726,7 +1726,7 @@ void PointSample( const unsigned char * inPixels,
     }
     else
     {
-      DALI_ASSERT_DEBUG( 0 == "Inner branch conditions don't match outer branch." );
+      DALI_ASSERT_DEBUG( false && "Inner branch conditions don't match outer branch." );
     }
   }
   else
@@ -2135,7 +2135,7 @@ void LinearSample( const unsigned char * __restrict__ inPixels,
     }
     else
     {
-      DALI_ASSERT_DEBUG( 0 == "Inner branch conditions don't match outer branch." );
+      DALI_ASSERT_DEBUG( false && "Inner branch conditions don't match outer branch." );
     }
   }
   else
index 6ddc44b..ff83c38 100644 (file)
@@ -139,7 +139,7 @@ std::size_t ObjectProfiler::GetMemorySize( const std::string& name, uint32_t cou
   struct MemoryMemorySize
   {
     std::string name;
-    std::size_t memorySize;
+    decltype(ANIMATION_MEMORY_SIZE) memorySize;
   };
   MemoryMemorySize memoryMemorySizes[] =
     {
@@ -161,7 +161,7 @@ std::size_t ObjectProfiler::GetMemorySize( const std::string& name, uint32_t cou
   {
     if( memoryMemorySizes[i].name.compare(name) == 0 )
     {
-      return count * memoryMemorySizes[i].memorySize;
+      return count * static_cast<size_t>( memoryMemorySizes[i].memorySize );
     }
   }
   return 0;
index 99f1796..f8c8fc0 100755 (executable)
@@ -52,7 +52,7 @@ Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::N
 } // unnamed namespace
 #endif
 
-#ifdef DALI_ELDBUS_AVAILABLE
+#if 0 and defined DALI_ELDBUS_AVAILABLE
 namespace
 {
 
@@ -98,7 +98,6 @@ static uint32_t GetCurrentMilliSeconds(void)
 EventHandler::EventHandler( WindowRenderSurface* surface, DamageObserver& damageObserver )
 : mStyleMonitor( StyleMonitor::Get() ),
   mDamageObserver( damageObserver ),
-  mAccessibilityAdaptor( AccessibilityAdaptor::Get() ),
   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
   mClipboard( Clipboard::Get() ),
   mPaused( false )
@@ -117,7 +116,6 @@ EventHandler::EventHandler( WindowRenderSurface* surface, DamageObserver& damage
     windowBase->SelectionDataSendSignal().Connect( this, &EventHandler::OnSelectionDataSend );
     windowBase->SelectionDataReceivedSignal().Connect( this, &EventHandler::OnSelectionDataReceived );
     windowBase->StyleChangedSignal().Connect( this, &EventHandler::OnStyleChanged );
-    windowBase->AccessibilitySignal().Connect( this, &EventHandler::OnAccessibilityNotification );
   }
 }
 
@@ -246,260 +244,6 @@ void EventHandler::OnStyleChanged( StyleChange::Type styleChange )
   SendEvent( styleChange );
 }
 
-void EventHandler::OnAccessibilityNotification( const WindowBase::AccessibilityInfo& info )
-{
-#ifdef DALI_ELDBUS_AVAILABLE
-  if( mPaused )
-  {
-    return;
-  }
-
-  if( !mAccessibilityAdaptor )
-  {
-    DALI_LOG_ERROR( "Invalid accessibility adaptor\n" );
-    return;
-  }
-
-  AccessibilityAdaptor* accessibilityAdaptor( &AccessibilityAdaptor::GetImplementation( mAccessibilityAdaptor ) );
-  if( !accessibilityAdaptor )
-  {
-    DALI_LOG_ERROR( "Cannot access accessibility adaptor\n" );
-    return;
-  }
-
-  // Create a touch point object.
-  TouchPoint::State touchPointState( TouchPoint::Down );
-  if( info.state == 0 )
-  {
-    touchPointState = TouchPoint::Down; // Mouse down.
-  }
-  else if( info.state == 1 )
-  {
-    touchPointState = TouchPoint::Motion; // Mouse move.
-  }
-  else if( info.state == 2 )
-  {
-    touchPointState = TouchPoint::Up; // Mouse up.
-  }
-  else
-  {
-    touchPointState = TouchPoint::Interrupted; // Error.
-  }
-
-  // Send touch event to accessibility adaptor.
-  TouchPoint point( 0, touchPointState, static_cast< float >( info.startX ), static_cast< float >( info.startY ) );
-
-  // Perform actions based on received gestures.
-  // Note: This is seperated from the reading so we can have other input readers without changing the below code.
-  switch( info.gestureValue )
-  {
-    case 0: // OneFingerHover
-    {
-      // Focus, read out.
-      accessibilityAdaptor->HandleActionReadEvent( static_cast< unsigned int >( info.startX ), static_cast< unsigned int >( info.startY ), true /* allow read again */ );
-      break;
-    }
-    case 1: // TwoFingersHover
-    {
-      // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
-      accessibilityAdaptor->HandleActionScrollEvent( point, GetCurrentMilliSeconds() );
-      break;
-    }
-    case 2: // ThreeFingersHover
-    {
-      // Read from top item on screen continuously.
-      accessibilityAdaptor->HandleActionReadFromTopEvent();
-      break;
-    }
-    case 3: // OneFingerFlickLeft
-    {
-      // Move to previous item.
-      accessibilityAdaptor->HandleActionReadPreviousEvent();
-      break;
-    }
-    case 4: // OneFingerFlickRight
-    {
-      // Move to next item.
-      accessibilityAdaptor->HandleActionReadNextEvent();
-      break;
-    }
-    case 5: // OneFingerFlickUp
-    {
-      // Move to previous item.
-      accessibilityAdaptor->HandleActionPreviousEvent();
-      break;
-    }
-    case 6: // OneFingerFlickDown
-    {
-      // Move to next item.
-      accessibilityAdaptor->HandleActionNextEvent();
-      break;
-    }
-    case 7: // TwoFingersFlickUp
-    {
-      // Scroll up the list.
-      accessibilityAdaptor->HandleActionScrollUpEvent();
-      break;
-    }
-    case 8: // TwoFingersFlickDown
-    {
-      // Scroll down the list.
-      accessibilityAdaptor->HandleActionScrollDownEvent();
-      break;
-    }
-    case 9: // TwoFingersFlickLeft
-    {
-      // Scroll left to the previous page
-      accessibilityAdaptor->HandleActionPageLeftEvent();
-      break;
-    }
-    case 10: // TwoFingersFlickRight
-    {
-      // Scroll right to the next page
-      accessibilityAdaptor->HandleActionPageRightEvent();
-      break;
-    }
-    case 11: // ThreeFingersFlickLeft
-    {
-      // Not exist yet
-      break;
-    }
-    case 12: // ThreeFingersFlickRight
-    {
-      // Not exist yet
-      break;
-    }
-    case 13: // ThreeFingersFlickUp
-    {
-      // Not exist yet
-      break;
-    }
-    case 14: // ThreeFingersFlickDown
-    {
-      // Not exist yet
-      break;
-    }
-    case 15: // OneFingerSingleTap
-    {
-      // Focus, read out.
-      accessibilityAdaptor->HandleActionReadEvent( static_cast< unsigned int >( info.startX ), static_cast< unsigned int >( info.startY ), true /* allow read again */ );
-      break;
-    }
-    case 16: // OneFingerDoubleTap
-    {
-      // Activate selected item / active edit mode.
-      accessibilityAdaptor->HandleActionActivateEvent();
-      break;
-    }
-    case 17: // OneFingerTripleTap
-    {
-      // Zoom
-      accessibilityAdaptor->HandleActionZoomEvent();
-      break;
-    }
-    case 18: // TwoFingersSingleTap
-    {
-      // Pause/Resume current speech
-      accessibilityAdaptor->HandleActionReadPauseResumeEvent();
-      break;
-    }
-    case 19: // TwoFingersDoubleTap
-    {
-      // Start/Stop current action
-      accessibilityAdaptor->HandleActionStartStopEvent();
-      break;
-    }
-    case 20: // TwoFingersTripleTap
-    {
-      // Read information from indicator
-      // Not supported
-      break;
-    }
-    case 21: // ThreeFingersSingleTap
-    {
-      // Read from top item on screen continuously.
-      accessibilityAdaptor->HandleActionReadFromTopEvent();
-      break;
-    }
-    case 22: // ThreeFingersDoubleTap
-    {
-      // Read from next item continuously.
-      accessibilityAdaptor->HandleActionReadFromNextEvent();
-      break;
-    }
-    case 23: // ThreeFingersTripleTap
-    {
-      // Not exist yet
-      break;
-    }
-    case 24: // OneFingerFlickLeftReturn
-    {
-      // Scroll up to the previous page
-      accessibilityAdaptor->HandleActionPageUpEvent();
-      break;
-    }
-    case 25: // OneFingerFlickRightReturn
-    {
-      // Scroll down to the next page
-      accessibilityAdaptor->HandleActionPageDownEvent();
-      break;
-    }
-    case 26: // OneFingerFlickUpReturn
-    {
-      // Move to the first item on screen
-      accessibilityAdaptor->HandleActionMoveToFirstEvent();
-      break;
-    }
-    case 27: // OneFingerFlickDownReturn
-    {
-      // Move to the last item on screen
-      accessibilityAdaptor->HandleActionMoveToLastEvent();
-      break;
-    }
-    case 28: // TwoFingersFlickLeftReturn
-    {
-      // Not exist yet
-      break;
-    }
-    case 29: // TwoFingersFlickRightReturn
-    {
-      // Not exist yet
-      break;
-    }
-    case 30: // TwoFingersFlickUpReturn
-    {
-      // Not exist yet
-      break;
-    }
-    case 31: // TwoFingersFlickDownReturn
-    {
-      // Not exist yet
-      break;
-    }
-    case 32: // ThreeFingersFlickLeftReturn
-    {
-      // Not exist yet
-      break;
-    }
-    case 33: // ThreeFingersFlickRightReturn
-    {
-      // Not exist yet
-      break;
-    }
-    case 34: // ThreeFingersFlickUpReturn
-    {
-      // Not exist yet
-      break;
-    }
-    case 35: // ThreeFingersFlickDownReturn
-    {
-      // Not exist yet
-      break;
-    }
-  }
-#endif
-}
-
 void EventHandler::AddObserver( Observer& observer )
 {
   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
index 795a919..96d6283 100755 (executable)
 #include <cstdint> // uint32_t
 #include <dali/public-api/common/intrusive-ptr.h>
 
+#include <dali/integration-api/events/key-event-integ.h>
+#include <dali/integration-api/events/point.h>
+#include <dali/integration-api/events/touch-event-combiner.h>
+#include <dali/integration-api/scene.h>
 #include <dali/devel-api/adaptor-framework/clipboard.h>
 #include <dali/devel-api/adaptor-framework/style-monitor.h>
+#include <dali/devel-api/adaptor-framework/clipboard.h>
 
 // INTERNAL INCLUDES
-#include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
+#include <dali/internal/window-system/common/damage-observer.h>
 #include <dali/internal/clipboard/common/clipboard-event-notifier-impl.h>
 #include <dali/internal/window-system/common/damage-observer.h>
 #include <dali/internal/window-system/common/window-base.h>
+#include <dali/internal/system/common/core-event-interface.h>
 
 namespace Dali
 {
@@ -204,11 +210,6 @@ private:
    */
   void OnStyleChanged( StyleChange::Type styleChange );
 
-  /**
-   * Called when Ecore ElDBus accessibility event is received.
-   */
-  void OnAccessibilityNotification( const WindowBase::AccessibilityInfo& info );
-
 private:
 
   // Undefined
@@ -222,7 +223,6 @@ private:
   Dali::StyleMonitor mStyleMonitor; ///< Handle to the style monitor, set on construction, to send font size and font change events to.
   DamageObserver& mDamageObserver; ///< Reference to the DamageObserver, set on construction, to sent damage events to.
 
-  Dali::AccessibilityAdaptor mAccessibilityAdaptor; ///< Pointer to the accessibility adaptor
   Dali::ClipboardEventNotifier mClipboardEventNotifier; ///< Pointer to the clipboard event notifier
   Dali::Clipboard mClipboard;///< Pointer to the clipboard
 
index fdb01bd..2ef0962 100644 (file)
@@ -43,6 +43,7 @@
 #include <dali/internal/window-system/common/window-base.h>
 #include <dali/internal/window-system/common/window-render-surface.h>
 #include <dali/internal/window-system/common/window-visibility-observer.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
 
 namespace Dali
 {
@@ -92,6 +93,17 @@ Window::Window()
 
 Window::~Window()
 {
+  if ( mAdaptor )
+  {
+               auto bridge = Accessibility::Bridge::GetCurrentBridge();
+               auto accessible2 = mScene.GetRootLayer();
+               auto accessible = Accessibility::Accessible::Get( accessible2 );
+               bridge->RemoveTopLevelWindow( accessible );
+
+    mAdaptor->RemoveWindow( this );
+    mAdaptor = NULL;
+  }
+
   if ( mEventHandler )
   {
     mEventHandler->RemoveObserver( *this );
@@ -133,6 +145,14 @@ void Window::OnAdaptorSet(Dali::Adaptor& adaptor)
 {
   mEventHandler = EventHandlerPtr(new EventHandler( mWindowSurface, *mAdaptor ) );
   mEventHandler->AddObserver( *this );
+
+  auto bridge = Accessibility::Bridge::GetCurrentBridge();
+  auto v = mScene.GetRootLayer();
+  auto accessible = Accessibility::Accessible::Get( v, true );
+  bridge->AddTopLevelWindow( accessible );
+
+  //FIXME: line below is temporary solution for missing "activate" signal and should be removed
+  Show();
 }
 
 void Window::OnSurfaceSet( Dali::RenderSurfaceInterface* surface )
@@ -598,6 +618,18 @@ void Window::OnFocusChanged( bool focusIn )
   Dali::Window handle( this );
   mFocusChangedSignal.Emit( focusIn );
   mFocusChangeSignal.Emit( handle, focusIn );
+
+  if (auto b = Dali::Accessibility::Bridge::GetCurrentBridge())
+  {
+    if (focusIn)
+    {
+      b->ApplicationShown();
+    }
+    else
+    {
+      b->ApplicationHidden();
+    }
+  }
 }
 
 void Window::OnOutputTransformed()
diff --git a/dali/public-api/adaptor-framework/accessibility.cpp b/dali/public-api/adaptor-framework/accessibility.cpp
new file mode 100644 (file)
index 0000000..beb5c4e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/public-api/dali-adaptor-common.h>
+#include <dali/public-api/adaptor-framework/accessibility.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali/internal/accessibility/bridge/accessibility-common.h>
+#include <mutex>
+
+#include <Eldbus.h>
+#include <Ecore_Input.h>
+
+void Dali::Accessibility::PauseResume( bool pause )
+{
+       if( auto b = Bridge::GetCurrentBridge() )
+         {
+           b->PauseResume( pause );
+         }
+}
+
+void Dali::Accessibility::Say( const std::string &text, bool discardable, std::function<void(std::string)> callback )
+{
+       if( auto b = Bridge::GetCurrentBridge() )
+         {
+           b->Say( text, discardable, callback );
+         }
+}
+
+
diff --git a/dali/public-api/adaptor-framework/accessibility.h b/dali/public-api/adaptor-framework/accessibility.h
new file mode 100644 (file)
index 0000000..b373cc7
--- /dev/null
@@ -0,0 +1,811 @@
+#ifndef DALI_ACCESSIBILITY_H
+#define DALI_ACCESSIBILITY_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/math/rect.h>
+
+#include <atomic>
+#include <bitset>
+#include <exception>
+#include <functional>
+#include <memory>
+#include <string>
+#include <map>
+#include <unordered_map>
+#include <vector>
+#include <list>
+#include <cassert>
+#include <sstream>
+#include <string.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/dali-adaptor-common.h>
+
+namespace Dali
+{
+/**
+ * @addtogroup dali_adaptor_framework
+ * @{
+ */
+class Actor;
+
+namespace Accessibility
+{
+
+/**
+ * @brief Enumeration describing a relation between accessible objects
+ *
+ * 1 to 0..N relation model is supported. By default relation is not symmetrical.
+ * Symmetry must be explicitly maintained.
+ */
+enum class RelationType : uint32_t
+{
+  NULL_,
+  LABEL_FOR,
+  LABELLED_BY,
+  CONTROLLER_FOR,
+  CONTROLLED_BY,
+  MEMBER_OF,
+  TOOLTIP_FOR,
+  NODE_CHILD_OF,
+  NODE_PARENT_OF,
+  EXTENDED,
+  FLOWS_TO,
+  FLOWS_FROM,
+  SUBWINDOW_OF,
+  EMBEDS,
+  EMBEDDED_BY,
+  POPUP_FOR,
+  PARENT_WINDOW_OF,
+  DESCRIPTION_FOR,
+  DESCRIBED_BY,
+  DETAILS,
+  DETAILS_FOR,
+  ERROR_MESSAGE,
+  ERROR_FOR,
+  LAST_DEFINED
+};
+
+/**
+ * @brief Enumeration describing if coordinates are relative to screen or window
+ *
+ * @see Accessibility::Component::GetExtents
+ * @see Accessibility::Component::Contains
+ */
+enum class CoordType
+{
+  SCREEN,
+  WINDOW
+};
+
+/**
+ * @brief Enumeration indicating relative stacking order
+ *
+ * ComponentLayer allows to describe visibility of all parts of UI
+ * basing on the concrete stacking order
+ *
+ * @see Accessibility::Component::GetLayer
+ *
+ * @note currently only ComponentLayer::Window is supported
+ */
+enum class ComponentLayer
+{
+  INVALID,
+  BACKGROUND,
+  CANVAS,
+  WIDGET,
+  MDI,
+  POPUP,
+  OVERLAY,
+  WINDOW,
+  LAST_DEFINED,
+};
+
+/**
+ * @brief Enumeration describing role of the Accessibility object
+ *
+ * Object can be described by only one role.
+ *
+ * @see Accessibility::Accessible::GetRole
+ */
+enum class Role : uint32_t
+{
+  INVALID,
+  ACCELERATOR_LABEL,
+  ALERT,
+  ANIMATION,
+  ARROW,
+  CALENDAR,
+  CANVAS,
+  CHECK_BOX,
+  CHECK_MENU_ITEM,
+  COLOR_CHOOSER,
+  COLUMN_HEADER,
+  COMBO_BOX,
+  DATE_EDITOR,
+  DESKTOP_ICON,
+  DESKTOP_FRAME,
+  DIAL,
+  DIALOG,
+  DIRECTORY_PANE,
+  DRAWING_AREA,
+  FILE_CHOOSER,
+  FILLER,
+  FOCUS_TRAVERSABLE,
+  FONT_CHOOSER,
+  FRAME,
+  GLASS_PANE,
+  HTML_CONTAINER,
+  ICON,
+  IMAGE,
+  INTERNAL_FRAME,
+  LABEL,
+  LAYERED_PANE,
+  LIST,
+  LIST_ITEM,
+  MENU,
+  MENU_BAR,
+  MENU_ITEM,
+  OPTION_PANE,
+  PAGE_TAB,
+  PAGE_TAB_LIST,
+  PANEL,
+  PASSWORD_TEXT,
+  POPUP_MENU,
+  PROGRESS_BAR,
+  PUSH_BUTTON,
+  RADIO_BUTTON,
+  RADIO_MENU_ITEM,
+  ROOT_PANE,
+  ROW_HEADER,
+  SCROLL_BAR,
+  SCROLL_PANE,
+  SEPARATOR,
+  SLIDER,
+  SPIN_BUTTON,
+  SPLIT_PANE,
+  STATUS_BAR,
+  TABLE,
+  TABLE_CELL,
+  TABLE_COLUMN_HEADER,
+  TABLE_ROW_HEADER,
+  TEAROFF_MENU_ITEM,
+  TERMINAL,
+  TEXT,
+  TOGGLE_BUTTON,
+  TOOL_BAR,
+  TOOL_TIP,
+  TREE,
+  TREE_TABLE,
+  UNKNOWN,
+  VIEWPORT,
+  WINDOW,
+  EXTENDED,
+  HEADER,
+  FOOTER,
+  PARAGRAPH,
+  RULER,
+  APPLICATION,
+  AUTOCOMPLETE,
+  EDITBAR,
+  EMBEDDED,
+  ENTRY,
+  CHART,
+  CAPTION,
+  DOCUMENT_FRAME,
+  HEADING,
+  PAGE,
+  SECTION,
+  REDUNDANT_OBJECT,
+  FORM,
+  LINK,
+  INPUT_METHOD_WINDOW,
+  TABLE_ROW,
+  TREE_ITEM,
+  DOCUMENT_SPREADSHEET,
+  DOCUMENT_PRESENTATION,
+  DOCUMENT_TEXT,
+  DOCUMENT_WEB,
+  DOCUMENT_EMAIL,
+  COMMENT,
+  LIST_BOX,
+  GROUPING,
+  IMAGE_MAP,
+  NOTIFICATION,
+  INFO_BAR,
+  LEVEL_BAR,
+  TITLE_BAR,
+  BLOCK_QUOTE,
+  AUDIO,
+  VIDEO,
+  DEFINITION,
+  ARTICLE,
+  LANDMARK,
+  LOG,
+  MARQUEE,
+  MATH,
+  RATING,
+  TIMER,
+  STATIC,
+  MATH_FRACTION,
+  MATH_ROOT,
+  SUBSCRIPT,
+  SUPERSCRIPT,
+  _COUNT,
+};
+
+/**
+ * @brief Enumeration describing states of the Accessibility object
+ *
+ * Object can be in many states at the same time.
+ *
+ * @see Accessibility::Accessible::GetStates
+ */
+enum class State : uint32_t
+{
+  INVALID,
+  ACTIVE,
+  ARMED,
+  BUSY,
+  CHECKED,
+  COLLAPSED,
+  DEFUNCT,
+  EDITABLE,
+  ENABLED,
+  EXPANDABLE,
+  EXPANDED,
+  FOCUSABLE,
+  FOCUSED,
+  HAS_TOOLTIP,
+  HORIZONTAL,
+  ICONIFIED,
+  MODAL,
+  MULTI_LINE,
+  MULTI_SELECTABLE,
+  OPAQUE,
+  PRESSED,
+  RESIZEABLE,
+  SELECTABLE,
+  SELECTED,
+  SENSITIVE,
+  SHOWING,
+  SINGLE_LINE,
+  STALE,
+  TRANSIENT,
+  VERTICAL,
+  VISIBLE,
+  MANAGES_DESCENDANTS,
+  INDETERMINATE,
+  REQUIRED,
+  TRUNCATED,
+  ANIMATED,
+  INVALID_ENTRY,
+  SUPPORTS_AUTOCOMPLETION,
+  SELECTABLE_TEXT,
+  IS_DEFAULT,
+  VISITED,
+  CHECKABLE,
+  HAS_POPUP,
+  READ_ONLY,
+  HIGHLIGHTED,
+  HIGHLIGHTABLE,
+  _COUNT
+};
+
+/**
+ * @brief Enumeration describing change of text object
+ */
+enum class TextChangedState : uint32_t
+{
+  INSERT,
+  DELETE,
+  _COUNT
+};
+
+enum class ObjectPropertyChangeEvent {
+   NAME,
+   DESCRIPTION,
+   VALUE,
+   ROLE,
+   PARENT,
+};
+
+/**
+ * @brief Enumeration describing change of window object
+ *
+ * @see Accessibility::Accessible::Emit
+ */
+enum class WindowEvent
+{
+  PROPERTY_CHANGE,
+  MINIMIZE,
+  MAXIMIZE,
+  RESTORE,
+  CLOSE,
+  CREATE,
+  REPARENT,
+  DESKTOP_CREATE,
+  DESKTOP_DESTROY,
+  DESTROY,
+  ACTIVATE,
+  DEACTIVATE,
+  RAISE,
+  LOWER,
+  MOVE,
+  RESIZE,
+  SHADE,
+  UU_SHADE,
+  RESTYLE,
+};
+
+/**
+ * @brief Enumeration used to acquire bounded text from accessible object having textual content.
+ *
+ * @see Accessibility::Text::GetTextAtOffset
+ *
+ * @note Currently only TextBoundary::Character is supported
+ */
+enum class TextBoundary : uint32_t
+{
+  /**
+   * Only one character is acquired.
+   */
+  CHARACTER,
+
+  /**
+   * Not supported.
+   */
+  WORD,
+
+  /**
+   * Not supported.
+   */
+  SENTENCE,
+
+  /**
+   * Not supported.
+   */
+  LINE,
+
+  /**
+   * Not supported.
+   */
+  PARAGRAPH,
+  _COUNT
+};
+
+/**
+ * @brief Enumeration describing type of gesture
+ *
+ * @see Accessibility::Accessible::DoGesture
+ */
+enum class Gesture : int32_t
+{
+  ONE_FINGER_HOVER,
+  TWO_FINGER_HOVER,
+  THREE_FINGER_HOVER,
+  ONE_FINGER_FLICK_LEFT,
+  ONE_FINGER_FLICK_RIGHT,
+  ONE_FINGER_FLICK_UP,
+  ONE_FINGER_FLICK_DOWN,
+  TWO_FINGERS_FLICK_LEFT,
+  TWO_FINGERS_FLICK_RIGHT,
+  TWO_FINGERS_FLICK_UP,
+  TWO_FINGERS_FLICK_DOWN,
+  THREE_FINGERS_FLICK_LEFT,
+  THREE_FINGERS_FLICK_RIGHT,
+  THREE_FINGERS_FLICK_UP,
+  THREE_FINGERS_FLICK_DOWN,
+  ONE_FINGER_SINGLE_TAP,
+  ONE_FINGER_DOUBLE_TAP,
+  ONE_FINGER_TRIPLE_TAP,
+  TWO_FINGERS_SINGLE_TAP,
+  TWO_FINGERS_DOUBLE_TAP,
+  TWO_FINGERS_TRIPLE_TAP,
+  THREE_FINGERS_SINGLE_TAP,
+  THREE_FINGERS_DOUBLE_TAP,
+  THREE_FINGERS_TRIPLE_TAP,
+  ONE_FINGER_FLICK_LEFT_RETURN,
+  ONE_FINGER_FLICK_RIGHT_RETURN,
+  ONE_FINGER_FLICK_UP_RETURN,
+  ONE_FINGER_FLICK_DOWN_RETURN,
+  TWO_FINGERS_FLICK_LEFT_RETURN,
+  TWO_FINGERS_FLICK_RIGHT_RETURN,
+  TWO_FINGERS_FLICK_UP_RETURN,
+  TWO_FINGERS_FLICK_DOWN_RETURN,
+  THREE_FINGERS_FLICK_LEFT_RETURN,
+  THREE_FINGERS_FLICK_RIGHT_RETURN,
+  THREE_FINGERS_FLICK_UP_RETURN,
+  THREE_FINGERS_FLICK_DOWN_RETURN,
+  ONE_FINGER_DOUBLE_TAP_N_HOLD,
+  TWO_FINGERS_DOUBLE_TAP_N_HOLD,
+  THREE_FINGERS_DOUBLE_TAP_N_HOLD,
+  _COUNT
+};
+
+/**
+ * @brief Enumeration indicating current state of gesture
+ *
+ * @see Dali::Accessibility::GestureInfo
+ */
+enum class GestureState : int32_t
+{
+  BEGIN,
+  ONGOING,
+  ENDED,
+  ABORTED
+};
+
+enum class ReadingInfoType
+{
+  NAME,
+  ROLE,
+  DESCRIPTION,
+  STATE
+};
+
+/**
+ * @brief Helper class for storing values treated as bit sets
+ *
+ * This class provides all bitset-like methods for bitset size larger, than long long int
+ *
+ * @see Dali::Accessibility::Accessible::GetStates
+ * @see Dali::Accessibility::Accessible::GetRoles
+ */
+template < size_t I, typename S >
+class BitSets
+{
+  std::array< uint32_t, I > data;
+
+  void _set() { }
+  static constexpr bool _accepts() { return true; }
+  template < typename T > static constexpr bool _accepts()
+  {
+    return std::is_enum< T >::value;
+  }
+  template < typename T, typename T2, typename ... ARGS > static constexpr bool _accepts()
+  {
+    return std::is_enum< T >::value && _accepts< T2, ARGS... >();
+  }
+  template < typename T, typename ... ARGS > void _set( T t, ARGS ... args )
+  {
+    ( *this )[ t ] = true;
+    _set( args... );
+  }
+public:
+  BitSets()
+  {
+    for( auto& u : data )
+      u = 0;
+  }
+  BitSets( const BitSets & ) = default;
+  BitSets( BitSets&& ) = default;
+  template < typename T, typename ... ARGS, typename std::enable_if< _accepts< T, ARGS... >() >::type* = nullptr >BitSets(T t, ARGS ... args) {
+    for(auto& u : data)
+      u = 0;
+    _set(t, args...);
+  }
+  explicit BitSets( std::array< uint32_t, I > d ) {
+    for( auto i = 0u; i < I; ++i )
+      data[ i ] = d[ i ];
+  }
+  explicit BitSets( std::array< int32_t, I > d ) {
+    for( auto i = 0u; i < I; ++i )
+      data[ i ] = static_cast< uint32_t >( d[ i ]);
+  }
+  BitSets &operator = ( const BitSets& ) = default;
+  BitSets &operator = ( BitSets&& ) = default;
+
+  struct reference
+  {
+    std::array< uint32_t, I >& data;
+    size_t pos;
+    reference &operator=( reference r )
+    {
+      ( *this ) = static_cast< bool >( r );
+      return *this;
+    }
+    reference &operator=( bool v )
+    {
+      if( v )
+        data[ pos / 32 ] |= 1 << ( pos & 31 );
+      else
+        data[ pos / 32 ] &= ~( 1 << ( pos & 31 ) );
+      return *this;
+    }
+    operator bool() const
+    {
+      auto i = static_cast< size_t >( pos );
+      return ( data[i / 32] & ( 1 << ( i & 31 ) ) ) != 0;
+    }
+  };
+  reference operator[]( S index ) { return {data, static_cast< size_t >( index )}; }
+  bool operator[]( S index ) const
+  {
+    auto i = static_cast< size_t >( index );
+    return ( data[i / 32] & ( 1 << ( i & 31 ) ) ) != 0;
+  }
+  std::array< uint32_t, I > GetRawData() const { return data; }
+
+  BitSets operator|( BitSets b ) const
+  {
+    BitSets r;
+    for( auto i = 0u; i < I; ++i )
+      r.data[i] = data[i] | b.data[i];
+    return r;
+  }
+  BitSets operator^( BitSets b ) const
+  {
+    BitSets r;
+    for( auto i = 0u; i < I; ++i )
+      r.data[i] = data[i] ^ b.data[i];
+    return r;
+  }
+  BitSets operator&( BitSets b ) const
+  {
+    BitSets r;
+    for( auto i = 0u; i < I; ++i )
+      r.data[i] = data[i] & b.data[i];
+    return r;
+  }
+  bool operator==( BitSets b ) const
+  {
+    for( auto i = 0u; i < I; ++i )
+      if( data[i] != b.data[i] )
+        return false;
+    return true;
+  }
+  bool operator!=( BitSets b ) const
+  {
+    return !((*this) == b);
+  }
+  explicit operator bool() const
+  {
+    for( auto& u : data )
+      if( u )
+        return true;
+    return false;
+  }
+  size_t size() const { return I; }
+};
+
+using ReadingInfoTypes = BitSets<1, ReadingInfoType>;
+using States = BitSets< 2, State >;
+using Attributes = std::unordered_map< std::string, std::string >;
+
+/**
+ * @brief Class representing unique object address on accessibility bus
+ *
+ * @see Dali::Accessibility::Accessible::GetAddress
+ */
+class DALI_ADAPTOR_API Address
+{
+public:
+  Address() = default;
+  Address( std::string bus, std::string path ) : bus( std::move( bus ) ), path( std::move( path ) ) {}
+
+  explicit operator bool() const { return !path.empty(); }
+  std::string ToString() const
+  {
+    return *this ? bus + ":" + path : "::null";
+  }
+  const std::string& GetBus() const;
+  const std::string& GetPath() const { return path; }
+
+  bool operator == (const Address &a) const {
+    return bus == a.bus && path == a.path;
+  }
+  bool operator != (const Address &a) const {
+    return !(*this == a);
+  }
+private:
+  mutable std::string bus, path;
+};
+
+/**
+ * @brief Enumeration describing type of key event
+ *
+ * @see Adaptor::AccessibilityObserver::OnAccessibleKeyEvent
+ */
+enum class KeyEventType
+{
+  KEY_PRESSED,
+  KEY_RELEASED,
+};
+
+/**
+ * @brief Enumeration with human readable values describing state of event
+ *
+ * @see Dali::Accessibility::Bridge::Emit
+ */
+enum class Consumed
+{
+  NO,
+  YES
+};
+
+/**
+ * @brief Helper class representing two dimensional point with integer coordinates
+ */
+struct DALI_ADAPTOR_API Point
+{
+  int x = 0;
+  int y = 0;
+
+  Point() = default;
+  Point( int x, int y ) : x( x ), y( y ) {}
+
+  bool operator==( Point p ) const
+  {
+    return x == p.x && y == p.y;
+  }
+  bool operator!=( Point p ) const
+  {
+    return !( *this == p );
+  }
+};
+
+/**
+ * @brief Helper class representing size of rectangle object with usage of two integer values
+ */
+struct DALI_ADAPTOR_API Size
+{
+  int width = 0;
+  int height = 0;
+
+  Size() = default;
+  Size( int w, int h ) : width( w ), height( h ) {}
+
+  bool operator==( Size p ) const
+  {
+    return width == p.width && height == p.height;
+  }
+  bool operator!=( Size p ) const
+  {
+    return !( *this == p );
+  }
+};
+
+/**
+ * @brief Helper class used to store data related with Accessibility::Text interface
+ *
+ * @see Dali::Accessibility::Text::GetTextAtOffset
+ * @see Dali::Accessibility::Text::GetSelection
+ */
+struct DALI_ADAPTOR_API Range
+{
+  int startOffset = 0;
+  int endOffset = 0;
+  std::string content;
+
+  Range() = default;
+  Range( size_t start, size_t end ) : startOffset( start ), endOffset( end )
+  {
+  }
+  Range( size_t start, size_t end, std::string content ) : startOffset( start ), endOffset( end ), content( content )
+  {
+  }
+};
+
+/**
+ * @brief Structure containing all values needed to invoke Accessible::DoGesture
+ *
+ * type
+ *     enumerated gesture type
+ * xBeg, yBeg
+ *     point where gesture begins
+ * xEnd, yEnd
+ *     point where gesture ends
+ * state
+ *     enumerated state of gesture
+ * eventTime
+ *     time when event occured
+ *
+ * @see Dali::Accessibility::Accessible::DoGesture
+ */
+struct DALI_ADAPTOR_API GestureInfo
+{
+  GestureInfo() = default;
+  GestureInfo(Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, GestureState state, uint32_t eventTime)
+    : type(type), xBeg(xBeg), xEnd(xEnd), yBeg(yBeg), yEnd(yEnd), state(state), eventTime(eventTime)
+  {}
+
+  Gesture type{};
+  int32_t xBeg{};
+  int32_t xEnd{};
+  int32_t yBeg{};
+  int32_t yEnd{};
+  GestureState state{};
+  uint32_t eventTime{};
+};
+
+class Accessible;
+
+/**
+ * @brief Class representing accessibility relations
+ *
+ * Class connecting one source object with multiple target objects with usage
+ * of specific relation type.
+ *
+ * @note std::string representing source and targets are string values of Accessibility::Address
+ *
+ * @see Dali::Accessibility::Accessible::Address
+ * @see Dali::Accessibility::Accessible::RelationType
+ */
+struct DALI_ADAPTOR_API Relation
+{
+  Relation(RelationType relationType, std::vector<Address> targets)
+    : relationType(relationType), targets(targets)
+  {}
+  RelationType relationType;
+  std::vector<Address> targets;
+};
+
+/**
+ * @brief Reads given text by screen reader
+ *
+ * @param text The text to read
+ * @param discardable If TRUE, reading can be discarded by subsequent reading requests,
+ * if FALSE the reading must finish before next reading request can be started
+ * @param callback the callback function that is called on reading signals emitted
+ * during processing of this reading request.
+ * Callback can be one of the following signals:
+ * “ReadingCancelled”
+ * “ReadingStopped”
+ * “ReadingSkipped”
+ */
+DALI_ADAPTOR_API void Say( const std::string &text, bool discardable, std::function<void(std::string)> callback );
+
+/**
+ * @brief Force accessibility client to pause / resume.
+ *
+ * @param[in] pause true if you want to pause, false if you want to resume
+ */
+DALI_ADAPTOR_API void PauseResume( bool pause );
+
+/// \endcond
+} // namespace Accessibility
+/**
+ * @}
+ */
+} // namespace Dali
+
+namespace std
+{
+template <>
+struct hash< Dali::Accessibility::Point >
+{
+  size_t operator()( Dali::Accessibility::Point p )
+  {
+    return static_cast< size_t >( p.x ) ^ ( static_cast< size_t >( p.y ) * 11 );
+  }
+};
+template <>
+struct hash< Dali::Accessibility::Size >
+{
+  size_t operator()( Dali::Accessibility::Size p )
+  {
+    return static_cast< size_t >( p.width ) ^ ( static_cast< size_t >( p.height ) * 11 );
+  }
+};
+}
+
+#endif // DALI_ACCESSIBILITY_H
index 55cef69..2251026 100755 (executable)
@@ -42,6 +42,7 @@ class TtsPlayer;
 
 /**
  * @brief The Text-to-speech (TTS) Player.
+ * @deprecated Instead of this class use Dali::Accessibility::Say() method
  * @SINCE_1_0.0
  */
 class DALI_ADAPTOR_API TtsPlayer : public BaseHandle
index cf91bee..a1c361f 100755 (executable)
@@ -1,4 +1,5 @@
 adaptor_public_api_src_files = \
+  $(adaptor_public_api_dir)/adaptor-framework/accessibility.cpp \
   $(adaptor_public_api_dir)/adaptor-framework/application.cpp \
   $(adaptor_public_api_dir)/adaptor-framework/key.cpp \
   $(adaptor_public_api_dir)/adaptor-framework/window.cpp \
@@ -22,6 +23,7 @@ public_api_adaptor_framework_header_files = \
   $(adaptor_public_api_dir)/adaptor-framework/device-status.h \
   $(adaptor_public_api_dir)/adaptor-framework/input-method.h \
   $(adaptor_public_api_dir)/adaptor-framework/key.h \
+  $(adaptor_public_api_dir)/adaptor-framework/accessibility.h \
   $(adaptor_public_api_dir)/adaptor-framework/key-grab.h \
   $(adaptor_public_api_dir)/adaptor-framework/style-change.h \
   $(adaptor_public_api_dir)/adaptor-framework/timer.h \
index 49e5b8c..ad8a7ee 100644 (file)
@@ -99,6 +99,8 @@ BuildRequires:  pkgconfig(capi-system-system-settings)
 # for autofill
 %if 0%{?tizen_version_major} >= 5 && 0%{?tizen_version_minor} >= 5
 BuildRequires:  pkgconfig(capi-ui-autofill)
+# for ATSPI (Accessibility) support
+BuildRequires:  pkgconfig(eldbus)
 %endif
 
 # for feedback plugin