From: dongsug.song Date: Mon, 23 Sep 2019 06:08:23 +0000 (+0900) Subject: Revert "[Tizen](ATSPI) squashed implementation" X-Git-Tag: accepted/tizen/unified/20190924.071746~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git;a=commitdiff_plain;h=15cb030e9396d29dab2de0bd298c1daf810bcf5f Revert "[Tizen](ATSPI) squashed implementation" This reverts commit 94544683debb6c663293c39eac5e091f27e1a4e7. Change-Id: Iad441ffee194908571733594e548eadef5ca43b5 --- diff --git a/.gitignore b/.gitignore index 7ac2864..3480ca9 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,3 @@ tags /debuglinks.list /debugsources.list /dali/internal/adaptor/common/system-cache-path.cpp -/.vscode/* diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/adaptor-test-application.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/adaptor-test-application.h index 86a9809..99f24d7 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/adaptor-test-application.h +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/adaptor-test-application.h @@ -21,7 +21,6 @@ // INTERNAL INCLUDES #include "test-application.h" #include "adaptor-test-adaptor-impl.h" -#include namespace Dali { @@ -39,8 +38,6 @@ public: float verticalDpi = DEFAULT_VERTICAL_DPI ) : TestApplication( surfaceWidth, surfaceHeight, horizontalDpi, verticalDpi ) { - //Dali::Accessibility::DBusWrapper::Install(std::unique_ptr(new Dali::Accessibility::TestDBusWrapper())); - Internal::Adaptor::Adaptor::SetAvailable(); } diff --git a/build/tizen/adaptor/Makefile.am b/build/tizen/adaptor/Makefile.am index b549138..aec1ab8 100644 --- a/build/tizen/adaptor/Makefile.am +++ b/build/tizen/adaptor/Makefile.am @@ -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,13 +87,14 @@ 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) \ @@ -152,13 +153,14 @@ 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) \ @@ -218,13 +220,14 @@ 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) \ @@ -282,13 +285,14 @@ 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) \ @@ -348,6 +352,8 @@ 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) \ @@ -355,7 +361,6 @@ 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) \ diff --git a/build/tizen/adaptor/configure.ac b/build/tizen/adaptor/configure.ac index 2dedcbe..b182ba7 100644 --- a/build/tizen/adaptor/configure.ac +++ b/build/tizen/adaptor/configure.ac @@ -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, required for ATSPI -PKG_CHECK_MODULES(ELDBUS, eldbus, [ eldbus_available=yes ]) +# Check for EldBus.h in ECore +PKG_CHECK_MODULES(ELDBUS, eldbus, [ eldbus_available=yes ], [ eldbus_available=no ] ) 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 new file mode 100644 index 0000000..f635aba --- /dev/null +++ b/dali/devel-api/adaptor-framework/accessibility-adaptor.cpp @@ -0,0 +1,205 @@ +/* + * 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 + +// INTERNAL INCLUDES +#include + +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 new file mode 100755 index 0000000..251f591 --- /dev/null +++ b/dali/devel-api/adaptor-framework/accessibility-adaptor.h @@ -0,0 +1,341 @@ +#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 +#include +#include + +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 new file mode 100644 index 0000000..4b8c859 --- /dev/null +++ b/dali/devel-api/adaptor-framework/accessibility-gesture-handler.h @@ -0,0 +1,46 @@ +#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 + +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 deleted file mode 100644 index 8ffe231..0000000 --- a/dali/devel-api/adaptor-framework/accessibility.h +++ /dev/null @@ -1,965 +0,0 @@ -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//INTERNAL INCLUDES -#include - -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 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 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 GetRelationSet() override - { - return {}; - } - -private: - Address address; -}; - -} -} - -#endif // DALI_ACCESSIBILITY_DEVEL_H diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list index e0851be..7f88752 100755 --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -1,4 +1,5 @@ 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 \ @@ -38,6 +39,10 @@ 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 \ @@ -81,8 +86,7 @@ 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/accessibility.h + $(adaptor_devel_api_dir)/adaptor-framework/window-devel.h devel_api_text_abstraction_src_files = \ $(adaptor_devel_api_dir)/text-abstraction/bidirectional-support.cpp \ @@ -111,3 +115,4 @@ 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 deleted file mode 100644 index 2a7da00..0000000 --- a/dali/internal/accessibility/accessibility-impl.cpp +++ /dev/null @@ -1,765 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include - -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 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 deleted file mode 100644 index 03f3146..0000000 --- a/dali/internal/accessibility/bridge/accessibility-common.h +++ /dev/null @@ -1,339 +0,0 @@ -#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 -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include - -#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 deleted file mode 100644 index c30116d..0000000 --- a/dali/internal/accessibility/bridge/accessible.cpp +++ /dev/null @@ -1,229 +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 - -//INTERNAL INCLUDES -#include -#include -#include - -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 deleted file mode 100644 index c7cbcb3..0000000 --- a/dali/internal/accessibility/bridge/bridge-accessible.cpp +++ /dev/null @@ -1,803 +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 - -// EXTERNAL INCLUDES -#include - -//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( 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> BridgeAccessible::GetRelationSet() -{ - auto relations = FindSelf()->GetRelationSet(); - std::vector< BridgeAccessible::Relation > ret; - - for (auto &it : relations) - ret.emplace_back(Relation{static_cast(it.relationType), it.targets}); - - return ret; -} diff --git a/dali/internal/accessibility/bridge/bridge-accessible.h b/dali/internal/accessibility/bridge/bridge-accessible.h deleted file mode 100644 index 9abdd36..0000000 --- a/dali/internal/accessibility/bridge/bridge-accessible.h +++ /dev/null @@ -1,105 +0,0 @@ -#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 -#include -#include -#include - -// 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> 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 deleted file mode 100644 index 47c5eae..0000000 --- a/dali/internal/accessibility/bridge/bridge-action.cpp +++ /dev/null @@ -1,94 +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 - -// EXTERNAL INCLUDES -#include - -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 deleted file mode 100644 index a47eb82..0000000 --- a/dali/internal/accessibility/bridge/bridge-action.h +++ /dev/null @@ -1,47 +0,0 @@ -#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 -#include - -// INTERNAL INCLUDES -#include - -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 deleted file mode 100644 index 1662b98..0000000 --- a/dali/internal/accessibility/bridge/bridge-base.cpp +++ /dev/null @@ -1,273 +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 - -// EXTERNAL INCLUDES -#include -#include -#include - -// INTERNAL INCLUDES -#include - -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 functor) -{ - if (delay < 0) - delay = 0; - auto it = filteredEvents.insert({ { kind, obj }, { static_cast(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( p ) ); - if( it == data->knownObjects.end() ) - throw std::domain_error{"unknown object '" + path + "'"}; - return static_cast( 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 deleted file mode 100644 index 7c413db..0000000 --- a/dali/internal/accessibility/bridge/bridge-base.h +++ /dev/null @@ -1,274 +0,0 @@ -#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 -#include - -// INTERNAL INCLUDES -#include - -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 GetRelationSet() override - { - return {}; - } - Dali::Accessibility::Address GetAddress() override { - return { "", "root" }; - } -}; - -enum class FilteredEvents { - boundsChanged -}; - -namespace std { - template <> struct hash> { - size_t operator () (std::pair v) const { - return (static_cast(v.first) * 131) ^ reinterpret_cast(v.second); - } - }; -} - -class BridgeBase : public Dali::Accessibility::Bridge, public Dali::ConnectionTracker -{ - std::unordered_map, std::pair>> filteredEvents; - - bool tickFilteredEvents(); -public: - - void addFilteredEvent(FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function 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 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 deleted file mode 100644 index 8c590ef..0000000 --- a/dali/internal/accessibility/bridge/bridge-collection.cpp +++ /dev/null @@ -1,386 +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 - -// EXTERNAL INCLUDES -#include -#include -#include -#include - -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 deleted file mode 100644 index c4a279d..0000000 --- a/dali/internal/accessibility/bridge/bridge-collection.h +++ /dev/null @@ -1,68 +0,0 @@ -#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 -#include -#include -#include - -// INTERNAL INCLUDES -#include - -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 deleted file mode 100644 index 1e65ddc..0000000 --- a/dali/internal/accessibility/bridge/bridge-component.cpp +++ /dev/null @@ -1,105 +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 - -// EXTERNAL INCLUDES -#include - -#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(p.x), static_cast(p.y) }; -} -DBus::ValueOrError< int32_t, int32_t > BridgeComponent::GetSize( uint32_t coordType ) -{ - auto p = FindSelf()->GetExtents( static_cast< CoordType >( coordType ) ); - return { static_cast(p.width), static_cast(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 deleted file mode 100644 index dcc8f49..0000000 --- a/dali/internal/accessibility/bridge/bridge-component.h +++ /dev/null @@ -1,54 +0,0 @@ -#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 -#include -#include -#include -#include - -// INTERNAL INCLUDES -#include - -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 deleted file mode 100644 index 5f18775..0000000 --- a/dali/internal/accessibility/bridge/bridge-editable-text.cpp +++ /dev/null @@ -1,64 +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 - -// INTERNAL INCLUDES -#include -//#include - -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 deleted file mode 100644 index e7d707b..0000000 --- a/dali/internal/accessibility/bridge/bridge-editable-text.h +++ /dev/null @@ -1,39 +0,0 @@ -#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 - -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 deleted file mode 100644 index 3f621c1..0000000 --- a/dali/internal/accessibility/bridge/bridge-impl.cpp +++ /dev/null @@ -1,235 +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 - -// EXTERNAL INCLUDES -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include -#include -#include -#include -#include - -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 > directReadingCallbacks; - Dali::Actor highlightedActor; - std::function 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 deleted file mode 100644 index 762329e..0000000 --- a/dali/internal/accessibility/bridge/bridge-object.cpp +++ /dev/null @@ -1,571 +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 - -// EXTERNAL INCLUDES -#include -#include - -using namespace Dali::Accessibility; - -BridgeObject::BridgeObject() -{ -} - -void BridgeObject::RegisterInterfaces() -{ - // DBus::DBusInterfaceDescription desc{ AtspiDbusInterfaceEventObject }; - // stateChanged = addSignal, 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 > tmp { - std::tuple{ rect.x, rect.y, rect.width, rect.height } }; - addFilteredEvent(FilteredEvents::boundsChanged, obj, 1.0f, [=]() { - dbusServer.emit2< std::string, int, int, DBus::EldbusVariant< std::tuple >, 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 deleted file mode 100644 index 18fa86b..0000000 --- a/dali/internal/accessibility/bridge/bridge-object.h +++ /dev/null @@ -1,64 +0,0 @@ -#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 -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include - -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 deleted file mode 100644 index 0c3ed82..0000000 --- a/dali/internal/accessibility/bridge/bridge-text.cpp +++ /dev/null @@ -1,90 +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 - -// INTERNAL INCLUDES -#include - -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 deleted file mode 100644 index f8661a7..0000000 --- a/dali/internal/accessibility/bridge/bridge-text.h +++ /dev/null @@ -1,44 +0,0 @@ -#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 - -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 deleted file mode 100644 index aa1a34c..0000000 --- a/dali/internal/accessibility/bridge/bridge-value.cpp +++ /dev/null @@ -1,68 +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 - -// EXTERNAL INCLUDES -#include - -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 deleted file mode 100644 index 0fb921f..0000000 --- a/dali/internal/accessibility/bridge/bridge-value.h +++ /dev/null @@ -1,48 +0,0 @@ -#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 -#include -#include -#include -#include - -// INTERNAL INCLUDES -#include - -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 deleted file mode 100644 index 73334a1..0000000 --- a/dali/internal/accessibility/bridge/component.cpp +++ /dev/null @@ -1,51 +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 - -// EXTERNAL INCLUDES -#include - -// INTERNAL INCLUDES -#include - -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 deleted file mode 100644 index 1bfb8ec..0000000 --- a/dali/internal/accessibility/bridge/dbus-locators.h +++ /dev/null @@ -1,98 +0,0 @@ -#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 deleted file mode 100644 index 6353296..0000000 --- a/dali/internal/accessibility/bridge/dbus.cpp +++ /dev/null @@ -1,1075 +0,0 @@ -/* - * 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 - -#include - -// EXTERNAL INCLUDES -#include -#include -#include - -#include -#include - -// INTERNAL INCLUDES -#include - -#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(v), dst); -} - -/// \cond -static std::unique_ptr 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 &a) { \ - return static_cast(a.get())->Value; \ - } \ - static eldbus_name *release(const std::shared_ptr &a) { \ - auto z = static_cast(a.get())->Value; \ - static_cast(a.get())->Value = nullptr; \ - return z; \ - } \ - template static std::shared_ptr create(const eldbus_name *v, ARGS && ... args) { \ - return std::make_shared(const_cast(v), std::forward(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 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 &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(0) -#define EINA_TRUE static_cast(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> &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> &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 w) -{ - InstalledWrapper = std::move(w); -} - -/* -// struct TestDBusWrapper::ConnectionImpl : public TestDBusWrapper::Connection { -// }; - -// TestDBusWrapper::TestDBusWrapper() -// { -// eina_init(); -// connection = std::make_shared(); -// testMethods[std::tuple{"/org/a11y/bus", "org.a11y.Status", "ScreenReaderEnabled", MethodType::Getter}] = -// testMethods[std::tuple{"/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{ 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::iterator it; -// MessageIterImpl(MessagePtr msg, Element *elem, bool write) : msg(std::move(msg)), elem(elem), write(write) { -// if (!write) it = elem->get().begin(); -// } -// MessageIterImpl(MessagePtr msg, Element *elem, bool write, std::list::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(v.get()); } -// DEFINE_TYPE(Connection) -// DEFINE_TYPE(Proxy) -// DEFINE_TYPE(Object) -// DEFINE_TYPE(Message) -// DEFINE_TYPE(MessageIter) -// #undef DEFINE_TYPE - -// template 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().push_back(TestDBusWrapper::Element{ src }); -// } -// template 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(); -// if (m->it == lst.end()) return false; -// if (!m->it->is()) return false; -// src = m->it->get(); -// ++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(); -// if (type == 'r' || type == 'e' || type == 'a' || type == 'v') { -// lst.push_back({ ElementList{}, type }); -// return std::make_shared(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(); -// if (m->it == lst.end()) return {}; -// if (m->it->signature() != type) return {}; -// auto v = std::make_shared(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{ it, &m->data, write, m->data.get().begin() }); -// } - -// bool TestDBusWrapper::completed(const MessageIterPtr &iter) -// { -// auto m = get(iter); -// assert(!m->write); -// return m->it == m->elem->get().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{ -// p->bus, p->path, p->interface, funcName, false -// }); -// } -// TestDBusWrapper::MessagePtr TestDBusWrapper::call( -// std::unordered_map, std::function> &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 { 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(); -// assert(lst.size() >= 2); -// iname = lst.front().get(); -// lst.pop_front(); -// name = lst.front().get(); -// 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(e.signature()); -// if (e.isContainer()) { -// ostr << "("; -// auto &lst = e.get(); -// 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()) -// 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 &cb) { -// auto p = get(proxy); -// daliSignals[std::tuple { 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(); -// 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{ -// 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{ -// 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 TestDBusWrapper::createEinaValue(bool b) { -// Eina_Value *value = eina_value_new(EINA_VALUE_TYPE_UCHAR); -// eina_value_set(value, b); -// return std::shared_ptr(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{ -// "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{ -// "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{ -// 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{ 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{ p->path, interface, name }] = cb; -// } -// void TestDBusWrapper::add_interface_impl( bool fallback, const std::string& path_, -// const ConnectionPtr &connection, -// std::vector> &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{ -// "bus", path, interface, m.memberName, true -// }); -// auto v = m.getCallback(msg, std::make_shared(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{ msg, &get(msg)->data, false })); -// return v.empty() ? std::make_shared(MessageImpl{ -// "bus", path, interface, m.memberName, true, -// }) : std::make_shared(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{ "/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 deleted file mode 100644 index 4aa28fb..0000000 --- a/dali/internal/accessibility/bridge/dbus.h +++ /dev/null @@ -1,3322 +0,0 @@ -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include - -#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; \ - using name ## WeakPtr = std::weak_ptr; \ - - 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; - 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 &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 > 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 > 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> &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); - - StringStorage Strings; -}; - -namespace detail { - enum class MethodType { - Method, Getter, Setter - }; -} - -namespace std { - template <> struct hash> { - size_t operator () (const std::tuple &a) const { - auto a1 = std::hash()(std::get<0>(a)); - auto a2 = std::hash()(std::get<1>(a)); - auto a3 = std::hash()(std::get<2>(a)); - size_t v = a1; - v = (v * 11400714819323198485llu) + a2; - v = (v * 11400714819323198485llu) + a3; - return v; - } - }; - template <> struct hash> { - size_t operator () (const std::tuple &a) const { - auto a1 = std::hash()(std::get<0>(a)); - auto a2 = std::hash()(std::get<1>(a)); - auto a3 = std::hash()(std::get<2>(a)); - auto a4 = static_cast(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> { - size_t operator () (const std::tuple &a) const { - auto a1 = std::hash()(std::get<0>(a)); - auto a2 = std::hash()(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 struct DBusSigImpl { enum { value = 0, end = 0 }; }; - template struct DBusSig { enum { value = DBusSigImpl::type>::value, end = DBusSigImpl::type>::end }; }; - template struct IndexFromTypeTupleImpl { - enum { value = std::is_same::type>::type, Q>::value ? I : IndexFromTypeTupleImpl::value }; - }; - template struct IndexFromTypeTupleImpl { enum { value = S }; }; - template struct IndexFromTypeTuple { - enum { value = IndexFromTypeTupleImpl::type, 0, std::tuple_size::value>::value }; - }; - template struct Encoder; - template struct EncoderTuple; -} -struct DALI_ADAPTOR_API TestDBusWrapper : public DBusWrapper -{ - using MethodType = detail::MethodType; - ConnectionPtr connection; - std::unordered_map, std::function> testMethods; - std::unordered_map, std::function> daliMethods; - std::unordered_map, std::string> daliSignalsMap; - std::unordered_map, std::function> daliSignals; - std::unordered_map, std::function> propertyChangeListeners; - - std::vector> asyncCalls; - - template struct Variant { - T value; - Variant() = default; - Variant(T t) : value(std::move(t)) { } - }; - template void Encode(const MessagePtr &m, const std::tuple &args) { - auto iter = eldbus_message_iter_get_impl(m, true); - detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(*this, iter, args); - } - template void Decode(const MessagePtr &m, std::tuple &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 void fromTestEmitSignal(std::string path, const std::string &interface, const std::string &name, const std::tuple &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{ path, interface, name }); - if (it == daliSignals.end()) throw error{}; - it->second(msg); - } - static std::shared_ptr<_Eina_Value> createEinaValue(bool); - template 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{ path, interface, name }); - if (it == propertyChangeListeners.end()) throw error{}; - it->second(v.get()); - } - template std::tuple fromTestCall(const std::string &path, const std::string &interface, const std::string &name, const std::tuple &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 tmp; - Decode(res, tmp); - return tmp; - } - template 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 tmp; - Decode(res, tmp); - return std::move(std::get<0>(tmp)); - } - template std::tuple 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{ 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 tmp; - Decode(res, tmp); - return tmp; - } - - TestDBusWrapper(); - ~TestDBusWrapper(); - - class error : public std::exception { - std::shared_ptr temp = std::make_shared(); - mutable std::string text; - public: - error() = default; - - template error &operator << (T &&t) { - *temp << std::forward(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; - using ElementMap = std::map; - 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 void set(T &&t, char signature = detail::DBusSig::value) { - signature_ = signature; - end_ = detail::DBusSig::end; - index_ = static_cast(detail::IndexFromTypeTuple::value); - get() = std::forward(t); - } - public: - template Element(T &&t, typename std::enable_if::value != 0>::type* = nullptr) { set(std::forward(t)); } - Element(ElementList t, int signature) { set(std::move(t), static_cast(signature)); } - - char signature() const { return signature_; } - char end() const { return end_; } - char index() const { return index_; } - bool isContainer() const { return index_ == detail::IndexFromTypeTuple::value; } - template ::value != 0>::type> - bool is() const { return index_ == detail::IndexFromTypeTuple::value; } - template ::value != 0>::type> - const T &get() const { if (!is()) throw error{}; return std::get::value>(data); } - template ::value != 0>::type> - T &get() { if (!is()) throw error{}; return std::get::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 &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> &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::function> &mp, const std::string &name, const MessagePtr &msg, MethodType type); -}; - -namespace detail { - template <> struct DBusSigImpl { enum { value = 'y', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 'q', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 'u', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 't', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 'n', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 'i', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 'x', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 'd', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 'b', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 's', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = 'o', end = 0 }; }; - template <> struct DBusSigImpl { enum { value = '(', end = ')' }; }; - template <> struct DBusSigImpl { enum { value = '{', end = '}' }; }; - - template struct Encoder { - 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 struct Encoder::value>::type> { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) { - Encoder::type>::encode(w, tgt, static_cast::type>(src)); - } - static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) { - typename std::underlying_type::type v = 0; - Encoder::type>::decode(w, v, src); - tgt = static_cast(v); - } - }; - template struct Encoder { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) { - Encoder::encode(w, tgt, src); - } - static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) { - Encoder::decode(w, tgt, src); - } - }; - template struct Encoder { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) { - Encoder::encode(w, tgt, src); - } - static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) { - Encoder::decode(w, tgt, src); - } - }; - template struct Encoder { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) { - Encoder::encode(w, tgt, src); - } - static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) { - Encoder::decode(w, tgt, src); - } - }; - template struct EncoderTuple { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple &src) { - Encoder>::type>::encode(w, tgt, std::get(src)); - EncoderTuple::encode(w, tgt, src); - } - static void decode(TestDBusWrapper &w, std::tuple &tgt, const TestDBusWrapper::MessageIterPtr &src) { - Encoder>::type>::decode(w, std::get(tgt), src); - EncoderTuple::decode(w, tgt, src); - } - }; - template struct EncoderTuple { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple &src) { } - static void decode(TestDBusWrapper &w, std::tuple &tgt, const TestDBusWrapper::MessageIterPtr &src) { } - }; - template struct Encoder> { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple &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 &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 struct Encoder> { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::pair &src, char type = 'r') { - auto var = w.eldbus_message_iter_container_new_impl( tgt, type, ""); - Encoder::encode(w, var, src.first); - Encoder::encode(w, var, src.second); - } - static void decode(TestDBusWrapper &w, std::pair &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::decode(w, tgt.first, s); - Encoder::decode(w, tgt.second, s); - } - }; - template struct Encoder> { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const TestDBusWrapper::Variant &src) { - //w.eldbus_message_iter_arguments_append_impl(tgt, src); - auto var = w.eldbus_message_iter_container_new_impl( tgt, 'v', ""); - Encoder::encode(w, var, src.value); - } - static void decode(TestDBusWrapper &w, TestDBusWrapper::Variant &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::decode(w, tgt.value, s); - } - }; - template struct Encoder> { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::vector &src) { - auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', ""); - for(auto &q : src) - Encoder::encode(w, var, q); - } - static void decode(TestDBusWrapper &w, std::vector &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::decode(w, tgt.back(), s); - } - } - }; - template struct Encoder> { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::unordered_map &src) { - auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', ""); - for(auto &q : src){ - Encoder::value_type>::encode(w, var, q, 'e'); - } - } - static void decode(TestDBusWrapper &w, std::unordered_map &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 tmp; - Encoder>::decode(w, tmp, s, 'e'); - tgt.insert(std::move(tmp)); - } - } - }; - template struct Encoder> { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::array &src) { - auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', ""); - for(auto &q : src) - Encoder::encode(w, var, q); - } - static void decode(TestDBusWrapper &w, std::array &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::decode(w, tgt[i], s); - ++i; - } - if( i!=tgt.size()) throw TestDBusWrapper::error{}; - } - }; - template <> struct Encoder { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const Dali::Accessibility::Address &src) { - Encoder>::encode(w, tgt,std::tuple { - src.GetBus(), ObjectPath{ "/org/a11y/atspi/accessible/" + src.GetPath() } } - ); - } - static void decode(TestDBusWrapper &w, Dali::Accessibility::Address &tgt, const TestDBusWrapper::MessageIterPtr &src) { - std::tuple tmp; - Encoder>::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 { - static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const char *src) { - Encoder::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(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, which gives signature (id) - std::tuple acts - * as struct container. Returned value v will be of type ValueOrError>.\n - * Slightly different (asynchronous) example: - * \code{.cpp} - * auto dbus = DBusClient{ ... }; - * std::function)> callback; - * dbus.method(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 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::type>::sig(); - } - - /** - * @brief Marshals value v as marshalled type into message - */ - static void set( const DBusWrapper::MessageIterPtr &iter, T v ) - { - signature::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::type q = 0; - if (!signature::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> \endcode - * While (ss(s)) is represented as - * \code{.cpp} std::tuple> \endcode - * or - * \code{.cpp} ValueOrError>> \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 type - */ -template <> -struct signature< ValueOrError< void > > -{ - /** - * @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< 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 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 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 >& 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::add( r ); - } -}; - -template <> -struct EldbusArgGenerator_Helper< void > -{ - static void add( std::vector< std::pair >& ) - { - } -}; - -template <> -struct EldbusArgGenerator_Helper< ValueOrError< void >, void > -{ - static void add( std::vector< std::pair >& ) - { - } -}; -template <> -struct EldbusArgGenerator_Helper< ValueOrError<>, void > -{ - static void add( std::vector< std::pair >& ) - { - } -}; - -template < typename... ARGS > -struct EldbusArgGenerator_Helper< std::tuple< ARGS... > > -{ - static void add( std::vector< std::pair >& 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 > get() - { - std::vector< std::pair > 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 > get( ) - { - std::vector< std::pair > 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 > 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 \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 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 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 \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 done_cb) { - * // process something later on - * DBusServer::getCurrentObjectPath(); // this will return empty string - * }; - * interface.addAsyncMethod("m", [=](std::function 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 done_cb) { - * // process something later on - * DBusServer::getCurrentObjectPath(); // this will return empty string - * }; - * interface.addAsyncMethod("m", [=](std::function 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> destructors; - ~DestructorObject() { - for(auto &a : destructors) a(); - } - }; - - std::unique_ptr 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 deleted file mode 100644 index dffc3a6..0000000 --- a/dali/internal/accessibility/bridge/optional.h +++ /dev/null @@ -1,283 +0,0 @@ -#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 -#include -#include -#include - -/** - * 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 v = ...; - * if (v) ... // if v has value, then do something - * - accessing value (via operator *), for example: - * Optional 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 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 new file mode 100644 index 0000000..d3eb43b --- /dev/null +++ b/dali/internal/accessibility/common/accessibility-adaptor-impl.cpp @@ -0,0 +1,504 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include + +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 new file mode 100644 index 0000000..d59f69f --- /dev/null +++ b/dali/internal/accessibility/common/accessibility-adaptor-impl.h @@ -0,0 +1,294 @@ +#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 + +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include + +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(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(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 new file mode 100644 index 0000000..b872077 --- /dev/null +++ b/dali/internal/accessibility/common/accessibility-gesture-detector.cpp @@ -0,0 +1,332 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include + +#include + +#include + + +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( 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( 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( 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( 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 new file mode 100644 index 0000000..616d76e --- /dev/null +++ b/dali/internal/accessibility/common/accessibility-gesture-detector.h @@ -0,0 +1,135 @@ +#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 +#include +#include +#include + +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 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; + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali + +#endif // DALI_INTERNAL_ACCESSIBILITY_GESTURE_DETECTOR_H diff --git a/dali/internal/accessibility/file.list b/dali/internal/accessibility/file.list index 1c91f1b..00bd528 100644 --- a/dali/internal/accessibility/file.list +++ b/dali/internal/accessibility/file.list @@ -2,28 +2,36 @@ # 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)/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 + ${adaptor_accessibility_dir}/common/accessibility-adaptor-impl.cpp \ + ${adaptor_accessibility_dir}/common/accessibility-gesture-detector.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 new file mode 100644 index 0000000..05dda37 --- /dev/null +++ b/dali/internal/accessibility/generic/accessibility-adaptor-impl-generic.cpp @@ -0,0 +1,69 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include + +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 new file mode 100644 index 0000000..18d57df --- /dev/null +++ b/dali/internal/accessibility/tizen-wayland/tizen-common/accessibility-adaptor-impl-tizen.cpp @@ -0,0 +1,130 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include + +#include +#include + +// INTERNAL INCLUDES +#include +#include + +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(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( 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 new file mode 100644 index 0000000..f75eff9 --- /dev/null +++ b/dali/internal/accessibility/tizen-wayland/tizen-ivi/accessibility-adaptor-impl-ivi.cpp @@ -0,0 +1,267 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include + +#ifndef WAYLAND +#include +#include +#endif + +#include + +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include + +#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( 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 new file mode 100644 index 0000000..f75eff9 --- /dev/null +++ b/dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.cpp @@ -0,0 +1,267 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include + +#ifndef WAYLAND +#include +#include +#endif + +#include + +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include + +#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( 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 new file mode 100644 index 0000000..fd2939e --- /dev/null +++ b/dali/internal/accessibility/tizen-wayland/tizen-mobile/accessibility-adaptor-impl-mobile.h @@ -0,0 +1,132 @@ +#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 +#include +#include +#include +#include + +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(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(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 new file mode 100644 index 0000000..18d57df --- /dev/null +++ b/dali/internal/accessibility/tizen-wayland/tizen-tv/accessibility-adaptor-impl-tv.cpp @@ -0,0 +1,130 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include + +#include +#include + +// INTERNAL INCLUDES +#include +#include + +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(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( 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 new file mode 100644 index 0000000..d382759 --- /dev/null +++ b/dali/internal/accessibility/tizen-wayland/tizen-wearable/accessibility-adaptor-impl-wearable.cpp @@ -0,0 +1,267 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include + +#ifndef WAYLAND +#include +#include +#endif + +#include + +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include + +#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( 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/adaptor/common/adaptor-impl.cpp b/dali/internal/adaptor/common/adaptor-impl.cpp index addc893..189ac3b 100755 --- a/dali/internal/adaptor/common/adaptor-impl.cpp +++ b/dali/internal/adaptor/common/adaptor-impl.cpp @@ -49,6 +49,7 @@ #include #include +#include #include #include #include @@ -60,7 +61,6 @@ #include #include -#include #include #include @@ -324,36 +324,10 @@ 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(); @@ -950,8 +924,6 @@ void Adaptor::RequestProcessEventsOnIdle( bool forceProcess ) void Adaptor::OnWindowShown() { - Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationShown(); - if( PAUSED_WHILE_HIDDEN == mState ) { // Adaptor can now be resumed @@ -977,8 +949,6 @@ void Adaptor::OnWindowShown() void Adaptor::OnWindowHidden() { - Dali::Accessibility::Bridge::GetCurrentBridge()->ApplicationHidden(); - if( RUNNING == mState || READY == mState ) { bool allWindowsHidden = true; diff --git a/dali/internal/adaptor/common/adaptor-impl.h b/dali/internal/adaptor/common/adaptor-impl.h index b6f41af..99e4a0c 100755 --- a/dali/internal/adaptor/common/adaptor-impl.h +++ b/dali/internal/adaptor/common/adaptor-impl.h @@ -52,16 +52,11 @@ #include #include -#include namespace Dali { class RenderSurfaceInterface; -namespace Accessibility -{ -class Bridge; -} namespace Integration { @@ -185,8 +180,6 @@ public: */ void SceneCreated(); - static std::string GetApplicationPackageName(); - public: // AdaptorInternalServices implementation /** * @copydoc Dali::Adaptor::Start() @@ -687,13 +680,6 @@ 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; } }; diff --git a/dali/internal/adaptor/common/adaptor.cpp b/dali/internal/adaptor/common/adaptor.cpp index bde2864..73fe2b3 100755 --- a/dali/internal/adaptor/common/adaptor.cpp +++ b/dali/internal/adaptor/common/adaptor.cpp @@ -22,6 +22,7 @@ #include // INTERNAL INCLUDES +#include #include #include #include diff --git a/dali/internal/adaptor/common/application-impl.cpp b/dali/internal/adaptor/common/application-impl.cpp index 40b16d9..94196b7 100755 --- a/dali/internal/adaptor/common/application-impl.cpp +++ b/dali/internal/adaptor/common/application-impl.cpp @@ -22,7 +22,6 @@ #include // INTERNAL INCLUDES -#include #include #include #include @@ -220,8 +219,6 @@ void Application::Quit() void Application::QuitFromMainLoop() { - Accessibility::Bridge::GetCurrentBridge()->Terminate(); - mAdaptor->Stop(); mFramework->Quit(); diff --git a/dali/internal/adaptor/generic/adaptor-impl-generic.cpp b/dali/internal/adaptor/generic/adaptor-impl-generic.cpp index 2a983ee..1b05919 100644 --- a/dali/internal/adaptor/generic/adaptor-impl-generic.cpp +++ b/dali/internal/adaptor/generic/adaptor-impl-generic.cpp @@ -27,11 +27,6 @@ namespace Internal namespace Adaptor { -std::string Adaptor::GetApplicationPackageName() -{ - return ""; -} - void Adaptor::GetDataStoragePath( std::string& path) { path = ""; diff --git a/dali/internal/adaptor/tizen-wayland/adaptor-impl-tizen.cpp b/dali/internal/adaptor/tizen-wayland/adaptor-impl-tizen.cpp index d1761bf..3e2865d 100644 --- a/dali/internal/adaptor/tizen-wayland/adaptor-impl-tizen.cpp +++ b/dali/internal/adaptor/tizen-wayland/adaptor-impl-tizen.cpp @@ -33,9 +33,6 @@ #endif -#include -#include - namespace Dali { @@ -69,14 +66,6 @@ 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 diff --git a/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp b/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp index 06851f2..8721844 100644 --- a/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp +++ b/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp @@ -63,7 +63,6 @@ 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); @@ -77,7 +76,6 @@ struct Clipboard::Impl { if (cbhm_conn) eldbus_connection_unref(cbhm_conn); - eldbus_shutdown(); } Eldbus_Proxy* cbhm_proxy_get() diff --git a/dali/internal/imaging/common/image-operations.cpp b/dali/internal/imaging/common/image-operations.cpp index 46ab713..b44a024 100755 --- a/dali/internal/imaging/common/image-operations.cpp +++ b/dali/internal/imaging/common/image-operations.cpp @@ -1726,7 +1726,7 @@ void PointSample( const unsigned char * inPixels, } else { - DALI_ASSERT_DEBUG( false && "Inner branch conditions don't match outer branch." ); + DALI_ASSERT_DEBUG( 0 == "Inner branch conditions don't match outer branch." ); } } else @@ -2135,7 +2135,7 @@ void LinearSample( const unsigned char * __restrict__ inPixels, } else { - DALI_ASSERT_DEBUG( false && "Inner branch conditions don't match outer branch." ); + DALI_ASSERT_DEBUG( 0 == "Inner branch conditions don't match outer branch." ); } } else diff --git a/dali/internal/system/common/object-profiler.cpp b/dali/internal/system/common/object-profiler.cpp index ff83c38..6ddc44b 100644 --- a/dali/internal/system/common/object-profiler.cpp +++ b/dali/internal/system/common/object-profiler.cpp @@ -139,7 +139,7 @@ std::size_t ObjectProfiler::GetMemorySize( const std::string& name, uint32_t cou struct MemoryMemorySize { std::string name; - decltype(ANIMATION_MEMORY_SIZE) memorySize; + std::size_t 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 * static_cast( memoryMemorySizes[i].memorySize ); + return count * memoryMemorySizes[i].memorySize; } } return 0; diff --git a/dali/internal/window-system/common/event-handler.cpp b/dali/internal/window-system/common/event-handler.cpp index f8c8fc0..99f1796 100755 --- a/dali/internal/window-system/common/event-handler.cpp +++ b/dali/internal/window-system/common/event-handler.cpp @@ -52,7 +52,7 @@ Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::N } // unnamed namespace #endif -#if 0 and defined DALI_ELDBUS_AVAILABLE +#ifdef DALI_ELDBUS_AVAILABLE namespace { @@ -98,6 +98,7 @@ 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 ) @@ -116,6 +117,7 @@ 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 ); } } @@ -244,6 +246,260 @@ 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) ); diff --git a/dali/internal/window-system/common/event-handler.h b/dali/internal/window-system/common/event-handler.h index 96d6283..795a919 100755 --- a/dali/internal/window-system/common/event-handler.h +++ b/dali/internal/window-system/common/event-handler.h @@ -22,20 +22,14 @@ #include // uint32_t #include -#include -#include -#include -#include #include #include -#include // INTERNAL INCLUDES -#include +#include #include #include #include -#include namespace Dali { @@ -210,6 +204,11 @@ private: */ void OnStyleChanged( StyleChange::Type styleChange ); + /** + * Called when Ecore ElDBus accessibility event is received. + */ + void OnAccessibilityNotification( const WindowBase::AccessibilityInfo& info ); + private: // Undefined @@ -223,6 +222,7 @@ 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 diff --git a/dali/internal/window-system/common/window-impl.cpp b/dali/internal/window-system/common/window-impl.cpp index 2ef0962..fdb01bd 100644 --- a/dali/internal/window-system/common/window-impl.cpp +++ b/dali/internal/window-system/common/window-impl.cpp @@ -43,7 +43,6 @@ #include #include #include -#include namespace Dali { @@ -93,17 +92,6 @@ 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 ); @@ -145,14 +133,6 @@ 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 ) @@ -618,18 +598,6 @@ 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 deleted file mode 100644 index beb5c4e..0000000 --- a/dali/public-api/adaptor-framework/accessibility.cpp +++ /dev/null @@ -1,44 +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 -#include -#include -#include -#include - -#include -#include - -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 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 deleted file mode 100644 index b373cc7..0000000 --- a/dali/public-api/adaptor-framework/accessibility.h +++ /dev/null @@ -1,811 +0,0 @@ -#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 -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// INTERNAL INCLUDES -#include - -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
targets) - : relationType(relationType), targets(targets) - {} - RelationType relationType; - std::vector
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 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 diff --git a/dali/public-api/adaptor-framework/tts-player.h b/dali/public-api/adaptor-framework/tts-player.h index 2251026..55cef69 100755 --- a/dali/public-api/adaptor-framework/tts-player.h +++ b/dali/public-api/adaptor-framework/tts-player.h @@ -42,7 +42,6 @@ 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 diff --git a/dali/public-api/file.list b/dali/public-api/file.list index a1c361f..cf91bee 100755 --- a/dali/public-api/file.list +++ b/dali/public-api/file.list @@ -1,5 +1,4 @@ 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 \ @@ -23,7 +22,6 @@ 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 \ diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index ad8a7ee..49e5b8c 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -99,8 +99,6 @@ 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