1 #ifndef DALI_INTERNAL_ATSPI_ACCESSIBILITY_IMPL_H
2 #define DALI_INTERNAL_ATSPI_ACCESSIBILITY_IMPL_H
5 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <dali/public-api/actors/actor.h>
23 #include <dali/public-api/math/rect.h>
30 #include <unordered_map>
31 #include <unordered_set>
36 #include <dali/devel-api/adaptor-framework/atspi-accessibility.h>
37 #include <dali/internal/accessibility/tizen-wayland/atspi/accessibility.h>
38 #include <dali/integration-api/debug.h>
42 namespace Accessibility
52 * @brief Base class for different accessibility bridges
54 * Bridge is resposible for initializing and managing connection on accessibility bus.
55 * Accessibility clients will not get any information about UI without initialized and upraised bridge.
56 * Concrete implementation depends on the accessibility technology available on the platform.
58 * @note This class is singleton.
62 enum class ForceUpResult
71 virtual ~Bridge() = default;
74 * @brief Get bus name which bridge is initialized on
76 virtual const std::string& GetBusName() const = 0;
79 * @brief Registers top level window
81 * Hierarchy of objects visible for accessibility clients is based on tree-like
82 * structure created from Actors objects. This method allows to connect chosen
83 * object as direct ancestor of application and therefore make it visible for
84 * accessibility clients.
86 virtual void AddTopLevelWindow( Accessible* ) = 0;
89 * @brief Removes top level window
91 * Hierarchy of objects visible for accessibility clients is based on tree-like
92 * structure created from Actors objects. This method removes previously added
93 * window from visible accessibility objects.
95 virtual void RemoveTopLevelWindow( Accessible* ) = 0;
98 * @brief Adds popup window
100 * Hierarchy of objects visible for accessibility clients is based on tree-like
101 * structure created from Actors objects. This method adds new popup to the tree.
103 virtual void AddPopup( Accessible* ) = 0;
106 * @brief Removes popup window
108 * Hierarchy of objects visible for accessibility clients is based on tree-like
109 * structure created from Actors objects. This method removes previously added
112 virtual void RemovePopup( Accessible* ) = 0;
115 * @brief Set name of current application which will be visible on accessibility bus
117 virtual void SetApplicationName( std::string ) = 0;
120 * @brief Get object being root of accessibility tree
122 * @return handler to accessibility object
124 virtual Accessible* GetApplication() const = 0;
127 * @brief Find an object in accessibility tree
129 * @param[in] s path to object
131 * @return handler to accessibility object
133 virtual Accessible* FindByPath( const std::string& s) const = 0;
136 * @brief Show application on accessibility bus
138 virtual void ApplicationShown() = 0;
141 * @brief Hide application on accessibility bus
143 virtual void ApplicationHidden() = 0;
146 * @brief Initialize accessibility bus
148 virtual void Initialize() = 0;
151 * @brief Terminate accessibility bus
153 virtual void Terminate() = 0;
156 * @brief This method is called, when bridge is being activated.
158 virtual ForceUpResult ForceUp()
162 return ForceUpResult::ALREADY_UP;
164 data = std::make_shared< Data >();
166 return ForceUpResult::JUST_STARTED;
170 * @brief This method is called, when bridge is being deactivated.
172 virtual void ForceDown() = 0;
175 * @brief Check if bridge is activated or not.
176 * @return True if brige is activated.
184 * @brief Emits caret-moved event on at-spi bus.
186 virtual void EmitCaretMoved( Accessible* obj, unsigned int cursorPosition ) = 0;
189 * @brief Emits active-descendant-changed event on at-spi bus.
191 virtual void EmitActiveDescendantChanged( Accessible* obj, Accessible *child ) = 0;
194 * @brief Emits text-changed event on at-spi bus.
196 virtual void EmitTextChanged( Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string &content ) = 0;
199 * @brief Emits state-changed event on at-spi bus.
201 virtual void EmitStateChanged( Accessible* obj, State state, int val1, int val2 = 0 ) = 0;
204 * @brief Emits window event on at-spi bus.
206 virtual void Emit( Accessible* obj, WindowEvent we, unsigned int detail1 = 0 ) = 0;
209 * @brief Emits property-changed event on at-spi bus.
211 virtual void Emit( Accessible* obj, ObjectPropertyChangeEvent event ) = 0;
214 * @brief Emits bounds-changed event on at-spi bus.
216 virtual void EmitBoundsChanged( Accessible* obj, Rect<> rect ) = 0;
219 * @brief Emits key event on at-spi bus.
221 * Screen-reader might receive this event and reply, that given keycode is consumed. In that case
222 * further processing of the keycode should be ignored.
224 virtual Consumed Emit( KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText ) = 0;
227 * @brief Reads given text by screen reader
229 * @param text The text to read
230 * @param discardable If TRUE, reading can be discarded by subsequent reading requests,
231 * if FALSE the reading must finish before next reading request can be started
232 * @param callback the callback function that is called on reading signals emitted
233 * during processing of this reading request.
234 * Callback can be one of the following signals:
235 * ReadingCancelled, ReadingStopped, ReadingSkipped
237 virtual void Say( const std::string& text, bool discardable, std::function<void(std::string)> callback ) = 0;
240 * @brief Force accessibility client to pause.
242 virtual void Pause() = 0;
245 * @brief Force accessibility client to resume.
247 virtual void Resume() = 0;
250 * @brief Get screen reader status.
252 virtual bool GetScreenReaderEnabled() = 0;
255 * @brief Get ATSPI status.
257 virtual bool GetIsEnabled() = 0;
260 * @brief Returns instance of bridge singleton object.
262 static Bridge* GetCurrentBridge();
267 std::unordered_set< Accessible* > knownObjects;
269 Bridge* bridge = nullptr;
270 Actor highlightActor, currentlyHighlightedActor;
272 std::shared_ptr< Data > data;
273 friend class Accessible;
276 * @brief Registers accessible object to be known in bridge object
278 * Bridge must known about all currently alive accessible objects, as some requst
279 * might come and object will be identified by number id (it's memory address).
280 * To avoid memory corruption number id is checked against set of known objects.
282 void RegisterOnBridge( Accessible* );
285 * @brief Tells bridge, that given object is considered root (doesn't have any parents).
287 * All root objects will have the same parent - application object. Application object
288 * is controlled by bridge and private.
290 void SetIsOnRootLevel( Accessible* );
294 * @brief Check if ATSPI is activated or not.
295 * @return True if ATSPI is activated.
299 if( Bridge::GetCurrentBridge() == nullptr )
303 if( Bridge::GetCurrentBridge()->GetIsEnabled() == false )
307 return Bridge::GetCurrentBridge()->IsUp();
311 * @brief Basic interface implemented by all accessibility objects
316 virtual ~Accessible();
318 using utf8_t = unsigned char;
321 * @brief Calculaties word boundaries in given utf8 text.
323 * s and length represents source text pointer and it's length respectively. langauge represents
324 * language to use. Word boundaries are returned as non-zero values in table breaks, which
325 * must be of size at least length.
327 void FindWordSeparationsUtf8( const utf8_t *s, size_t length, const char *language, char *breaks );
330 * @brief Calculaties line boundaries in given utf8 text.
332 * s and length represents source text pointer and it's length respectively. langauge represents
333 * language to use. Line boundaries are returned as non-zero values in table breaks, which
334 * must be of size at least length.
336 void FindLineSeparationsUtf8( const utf8_t *s, size_t length, const char *language, char *breaks );
339 * @brief Helper function for emiting active-descendant-changed event
341 void EmitActiveDescendantChanged( Accessible* obj, Accessible *child );
344 * @brief Helper function for emiting state-changed event
346 void EmitStateChanged( State state, int newValue1, int newValue2 = 0 );
349 * @brief Helper function for emiting bounds-changed event
351 void EmitBoundsChanged( Rect<> rect );
354 * @brief Emit "showing" event.
355 * The method inform accessibility clients about "showing" state
357 * @param[in] showing flag pointing if object is showing
359 void EmitShowing( bool showing );
362 * @brief Emit "visible" event.
363 * The method inform accessibility clients about "visible" state
365 * @param[in] visible flag pointing if object is visible
367 void EmitVisible( bool visible );
370 * @brief Emit "highlighted" event.
371 * The method inform accessibility clients about "highlighted" state
373 * @param[in] set flag pointing if object is highlighted
375 void EmitHighlighted( bool set );
378 * @brief Emit "focused" event.
379 * The method inform accessibility clients about "focused" state
381 * @param[in] set flag pointing if object is focused
383 void EmitFocused( bool set );
386 * @brief Emit "text inserted" event
388 * @param[in] position caret position
389 * @param[in] length text length
390 * @param[in] content inserted text
392 void EmitTextInserted( unsigned int position, unsigned int length, const std::string &content );
395 * @brief Emit "text deleted" event
397 * @param[in] position caret position
398 * @param[in] length text length
399 * @param[in] content deleted text
401 void EmitTextDeleted( unsigned int position, unsigned int length, const std::string &content );
404 * @brief Emit "caret moved" event
406 * @param[in] cursorPosition new caret position
408 void EmitTextCaretMoved( unsigned int cursorPosition );
411 * @brief Emit "highlighted" event
413 * @param[in] we enumerated window event
414 * @param[in] detail1 additional parameter which interpretation depends on chosen event
416 void Emit( WindowEvent we, unsigned int detail1 = 0 );
419 * @brief Emits property-changed event
420 * @param[in] Property changed event
422 void Emit( ObjectPropertyChangeEvent event );
425 * @brief Get accessibility name
427 * @return string with name
429 virtual std::string GetName() = 0;
432 * @brief Get accessibility description
434 * @return string with description
436 virtual std::string GetDescription() = 0;
441 * @return handler to accessibility object
443 virtual Accessible* GetParent() = 0;
446 * @brief Get count of children
448 * @return unsigned integer value
450 virtual size_t GetChildCount() = 0;
453 * @brief Get collection with all children
455 * @return collection of accessibility objects
457 virtual std::vector< Accessible* > GetChildren();
460 * @brief Get nth child
462 * @return accessibility object
464 virtual Accessible* GetChildAtIndex( size_t index ) = 0;
467 * @brief Get index that current object has in its parent's children collection
469 * @return unsigned integer index
471 virtual size_t GetIndexInParent() = 0;
474 * @brief Get accessibility role
476 * @return Role enumeration
478 * @see Dali::Accessibility::Role
480 virtual Role GetRole() = 0;
483 * @brief Get name of accessibility role
485 * @return string with human readable role converted from enumeration
487 * @see Dali::Accessibility::Role
488 * @see Accessibility::Accessible::GetRole
490 virtual std::string GetRoleName();
493 * @brief Get localized name of accessibility role
495 * @return string with human readable role translated according to current
498 * @see Dali::Accessibility::Role
499 * @see Accessibility::Accessible::GetRole
500 * @see Accessibility::Accessible::GetRoleName
502 * @note translation is not supported in this version
504 virtual std::string GetLocalizedRoleName();
507 * @brief Get accessibility states
509 * @return collection of states
511 * @note States class is instatation of ArrayBitset template class
513 * @see Dali::Accessibility::State
514 * @see Dali::Accessibility::ArrayBitset
516 virtual States GetStates() = 0;
519 * @brief Get accessibility attributes
521 * @return map of attributes and their values
523 virtual Attributes GetAttributes() = 0;
526 * @brief Check if this is proxy
528 * @return True if this is proxy
530 virtual bool IsProxy();
533 * @brief Get unique address on accessibility bus
535 * @return class containing address
537 * @see Dali::Accessibility::Address
539 virtual Address GetAddress();
542 * @brief Get accessibility object, which is "default label" for this object
544 virtual Accessible* GetDefaultLabel();
547 * @brief Depute an object to perform provided gesture
549 * @param[in] gestureInfo structure describing the gesture
551 * @return true on success, false otherwise
553 * @see Dali::Accessibility::GestureInfo
555 virtual bool DoGesture(const GestureInfo &gestureInfo) = 0;
558 * @brief Re-emits selected states of an Accessibility Object
560 * @param[in] states chosen states to re-emit
561 * @param[in] doRecursive if true all children of the Accessibility Object will also re-emit the states
563 void NotifyAccessibilityStateChange( Dali::Accessibility::States states, bool doRecursive );
566 * @brief Get information about current object and all relations that connects
567 * it with other accessibility objects
569 * @return iterable collection of Relation objects
571 * @see Dali::Accessibility::Relation
573 virtual std::vector<Relation> GetRelationSet() = 0;
576 * @brief Get all implemented interfaces
578 * @return collection of strings with implemented interfaces
580 std::vector< std::string > GetInterfaces();
583 * @brief Check if object is on root level
585 bool GetIsOnRootLevel() const { return isOnRootLevel; }
588 * @brief The method registers functor resposible for converting Actor into Accessible
589 * @param functor returning Accessible handle from Actor object
591 static void RegisterControlAccessibilityGetter( std::function< Accessible*( Dali::Actor ) > functor);
594 * @brief Acquire Accessible object from Actor object
596 * @param[in] actor Actor object
597 * @param[in] root true, if it's top level object (window)
599 * @return handle to Accessible object
601 static Accessible* Get( Dali::Actor actor, bool root = false );
605 Accessible( const Accessible& ) = delete;
606 Accessible( Accessible&& ) = delete;
607 Accessible& operator=( const Accessible& ) = delete;
608 Accessible& operator=( Accessible&& ) = delete;
609 std::shared_ptr< Bridge::Data > GetBridgeData();
610 static Dali::Actor GetHighlightActor();
611 static void SetHighlightActor(Dali::Actor actor);
612 static Dali::Actor GetCurrentlyHighlightedActor();
613 static void SetCurrentlyHighlightedActor(Dali::Actor);
618 std::weak_ptr< Bridge::Data > bridgeData;
619 bool isOnRootLevel = false;
623 * @brief Interface enabling to perform provided actions
625 class Action : public virtual Accessible
629 * @brief Get name of action with given index
631 * @param[in] index index of action
633 * @return string with name of action
635 virtual std::string GetActionName( size_t index ) = 0;
638 * @brief Get translated name of action with given index
640 * @param[in] index index of action
642 * @return string with name of action translated according to current translation domain
644 * @note translation is not supported in this version
646 virtual std::string GetLocalizedActionName( size_t index ) = 0;
649 * @brief Get description of action with given index
651 * @param[in] index index of action
653 * @return string with description of action
655 virtual std::string GetActionDescription( size_t index ) = 0;
658 * @brief Get key code binded to action with given index
660 * @param[in] index index of action
662 * @return string with key name
664 virtual std::string GetActionKeyBinding( size_t index ) = 0;
667 * @brief Get number of provided actions
669 * @return unsigned integer with number of actions
671 virtual size_t GetActionCount() = 0;
674 * @brief Perform an action with given index
676 * @param index index of action
678 * @return true on success, false otherwise
680 virtual bool DoAction( size_t index ) = 0;
683 * @brief Perform an action with given name
685 * @param name name of action
687 * @return true on success, false otherwise
689 virtual bool DoAction( const std::string& name ) = 0;
694 * @brief Interface enabling advanced quering of accessibility objects
696 * @note since all mathods can be implemented inside bridge,
697 * none methods have to be overrided
699 class Collection : public virtual Accessible
705 * @brief Interface representing objects having screen coordinates
707 class Component : public virtual Accessible
711 * @brief Get rectangle describing size
713 * @param[in] ctype enumeration with type of coordinate systems
715 * @return Rect<> object
719 virtual Rect<> GetExtents( CoordType ctype ) = 0;
722 * @brief Get layer current object is localized on
724 * @return enumeration pointing layer
726 * @see Dali::Accessibility::ComponentLayer
728 virtual ComponentLayer GetLayer() = 0;
731 * @brief Get value of z-order
733 * @return value of z-order
735 virtual int16_t GetMdiZOrder() = 0;
738 * @brief Set current object as "focused"
740 * @return true on success, false otherwise
742 virtual bool GrabFocus() = 0;
745 * @brief Get value of alpha channel
747 * @return alpha channel value in range [0.0, 1.0]
749 virtual double GetAlpha() = 0;
752 * @brief Set current object as "highlighted"
754 * The method assings "highlighted" state, simultaneously removing it
755 * from currently highlighted object.
757 * @return true on success, false otherwise
759 virtual bool GrabHighlight() = 0;
762 * @brief Set current object as "unhighlighted"
764 * The method removes "highlighted" state from object.
766 * @return true on success, false otherwise
768 * @see Dali:Accessibility::State
770 virtual bool ClearHighlight() = 0;
773 * @brief Get index of "highlighted" object
775 * @return The index of "highlighted" object
777 * @see Dali:Accessibility::State
779 virtual int GetHighlightIndex() = 0;
782 * @brief Check whether object can be scrolled
784 * @return true if object is scrollable, false otherwise
786 * @see Dali:Accessibility::State
788 virtual bool IsScrollable();
791 * @brief Get Accessible object containing given point
793 * @param[in] p two-dimensional point
794 * @param[in] ctype enumeration with type of coordinate system
796 * @return handle to last child of current object which contains given point
798 * @see Dali::Accessibility::Point
800 virtual Accessible* GetAccessibleAtPoint( Point p, CoordType ctype );
803 * @brief Check if current object contains given point
805 * @param[in] p two-dimensional point
806 * @param[in] ctype enumeration with type of coordinate system
808 * @return handle to Accessible object
810 * @see Dali::Accessibility::Point
812 virtual bool Contains( Point p, CoordType ctype );
816 * @brief Interface representing objects which can store numeric value
818 class Value : public virtual Accessible
822 * @brief Get the lowest possible value
824 * @return double value
826 virtual double GetMinimum() = 0;
829 * @brief Get current value
831 * @return double value
833 virtual double GetCurrent() = 0;
836 * @brief Get the highest possible value
838 * @return double value
840 virtual double GetMaximum() = 0;
845 * @param[in] val double value
847 * @return true if value could have been assigned, false otherwise
849 virtual bool SetCurrent( double val) = 0;
852 * @brief Get the lowest increment that can be distinguished
854 * @return double value
856 virtual double GetMinimumIncrement() = 0;
860 * @brief Interface representing objects which can store immutable texts
862 * @see Dali::Accessibility::EditableText
864 class Text : public virtual Accessible
868 * @brief Get stored text in given range
870 * @param[in] startOffset index of first character
871 * @param[in] endOffset index of first character after the last one expected
873 * @return substring of stored text
875 virtual std::string GetText( size_t startOffset, size_t endOffset ) = 0;
878 * @brief Get number of all stored characters
880 * @return number of characters
882 virtual size_t GetCharacterCount() = 0;
885 * @brief Get caret offset
887 * @return Value of caret offset
889 virtual size_t GetCaretOffset() = 0;
892 * @brief Set caret offset
894 * @param[in] caret offset
896 * @return True if successful
898 virtual bool SetCaretOffset(size_t offset) = 0;
901 * @brief Get substring of stored text truncated in concrete gradation
903 * @param[in] offset position in stored text
904 * @param[in] boundary enumeration describing text gradation
906 * @return Range structure containing acquired text and offsets in original string
908 * @see Dali::Accessibility::Range
910 virtual Range GetTextAtOffset( size_t offset, TextBoundary boundary ) = 0;
913 * @brief Get selected text
915 * @param[in] selectionNum selection index
916 * @note Currently only one selection (i.e. with index = 0) is supported
918 * @return Range structure containing acquired text and offsets in original string
920 * @see Dali::Accessibility::Range
922 virtual Range GetSelection( size_t selectionNum ) = 0;
925 * @brief Remove selection
927 * @param[in] selectionNum selection index
928 * @note Currently only one selection (i.e. with index = 0) is supported
930 * @return bool on success, false otherwise
932 virtual bool RemoveSelection( size_t selectionNum ) = 0;
935 * @brief Get selected text
937 * @param[in] selectionNum selection index
938 * @param[in] startOffset index of first character
939 * @param[in] endOffset index of first character after the last one expected
941 * @note Currently only one selection (i.e. with index = 0) is supported
943 * @return true on success, false otherwise
945 virtual bool SetSelection( size_t selectionNum, size_t startOffset, size_t endOffset ) = 0;
949 * @brief Interface representing objects which can store editable texts
951 * @note Paste method is entirely implemented inside bridge
953 * @see Dali::Accessibility::EditableText
955 class EditableText : public virtual Accessible
959 * @brief Copy text in range to system clipboard
961 * @param[in] startPosition index of first character
962 * @param[in] endPosition index of first character after the last one expected
964 * @return true on success, false otherwise
966 virtual bool CopyText( size_t startPosition, size_t endPosition ) = 0;
969 * @brief Cut text in range to system clipboard
971 * @param[in] startPosition index of first character
972 * @param[in] endPosition index of first character after the last one expected
974 * @return true on success, false otherwise
976 virtual bool CutText( size_t startPosition, size_t endPosition ) = 0;
980 * @brief minimalistic, always empty Accessible object with settable address
982 * For those situations, where you want to return address in different bridge
983 * (embedding for example), but the object itself ain't planned to be used otherwise.
984 * This object has null parent, no children, empty name and so on
986 class EmptyAccessibleWithAddress : public virtual Accessible
989 EmptyAccessibleWithAddress() = default;
990 EmptyAccessibleWithAddress( Address address ) : address( std::move( address ) ) {}
992 void SetAddress( Address address ) { this->address = std::move( address ); }
994 std::string GetName() override { return ""; }
995 std::string GetDescription() override { return ""; }
996 Accessible* GetParent() override { return nullptr; }
997 size_t GetChildCount() override { return 0; }
998 std::vector< Accessible* > GetChildren() override { return {}; }
999 Accessible* GetChildAtIndex( size_t index ) override
1001 throw std::domain_error{"out of bounds index (" + std::to_string( index ) + ") - no children"};
1003 size_t GetIndexInParent() override { return static_cast< size_t >( -1 ); }
1004 Role GetRole() override { return {}; }
1005 std::string GetRoleName() override;
1006 States GetStates() override { return {}; }
1007 Attributes GetAttributes() override { return {}; }
1008 Address GetAddress() override
1012 bool DoGesture(const GestureInfo &gestureInfo) override
1016 std::vector<Relation> GetRelationSet() override
1028 #endif // DALI_INTERNAL_ATSPI_ACCESSIBILITY_IMPL_H