1 #ifndef DALI_ADAPTOR_ACCESSIBILITY_BRIDGE_H
2 #define DALI_ADAPTOR_ACCESSIBILITY_BRIDGE_H
5 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <dali/public-api/actors/actor.h>
23 #include <dali/public-api/math/rect.h>
28 #include <unordered_set>
31 #include <dali/devel-api/adaptor-framework/accessibility.h>
32 #include <dali/public-api/adaptor-framework/window.h>
36 namespace Accessibility
41 * @brief Base class for different accessibility bridges.
43 * Bridge is resposible for initializing and managing connection on accessibility bus.
44 * Accessibility clients will not get any information about UI without initialized and upraised bridge.
45 * Concrete implementation depends on the accessibility technology available on the platform.
47 * @note This class is singleton.
49 struct DALI_ADAPTOR_API Bridge
51 enum class ForceUpResult
60 virtual ~Bridge() = default;
63 * @brief Gets bus name which bridge is initialized on.
65 * @return The bus name
67 virtual const std::string& GetBusName() const = 0;
70 * @brief Registers top level window.
72 * Hierarchy of objects visible for accessibility clients is based on tree-like
73 * structure created from Actors objects. This method allows to connect chosen
74 * object as direct ancestor of application and therefore make it visible for
75 * accessibility clients.
77 * @param[in] object The accessible object
79 virtual void AddTopLevelWindow(Accessible* object) = 0;
82 * @brief Removes top level window.
84 * Hierarchy of objects visible for accessibility clients is based on tree-like
85 * structure created from Actors objects. This method removes previously added
86 * window from visible accessibility objects.
88 * @param[in] object The accessible object
90 virtual void RemoveTopLevelWindow(Accessible* object) = 0;
93 * @brief Adds object on the top of the stack of "default label" sourcing objects.
95 * @see GetDefaultLabel
97 * @param[in] object The accessible object
99 virtual void RegisterDefaultLabel(Accessible* object) = 0;
102 * @brief Removes object from the stack of "default label" sourcing objects.
104 * @see GetDefaultLabel
106 * @param[in] object The accessible object
108 virtual void UnregisterDefaultLabel(Accessible* object) = 0;
111 * @brief Gets the top-most object from the stack of "default label" sourcing objects.
113 * The "default label" is a reading material (text) derived from an accesibility object
114 * that could be read by screen-reader immediately after the navigation context has changed
115 * (window activates, popup shows up, tab changes) and before first UI element is highlighted.
117 * @return The handler to accessibility object
118 * @note This is a Tizen only feature not present in upstream ATSPI.
119 * Feature can be enabled/disabled for particular context root object
120 * by setting value of its accessibility attribute "default_label".
121 * Following strings are valid values for "default_label" attribute: "enabled", "disabled".
122 * Any other value will be interpreted as "enabled".
124 virtual Accessible* GetDefaultLabel() const = 0;
127 * @brief Sets name of current application which will be visible on accessibility bus.
129 * @param[in] name The application name
131 virtual void SetApplicationName(std::string name) = 0;
134 * @brief Gets object being root of accessibility tree.
136 * @return handler to accessibility object
138 virtual Accessible* GetApplication() const = 0;
141 * @brief Finds an object in accessibility tree.
143 * @param[in] path The path to object
145 * @return The handler to accessibility object
147 virtual Accessible* FindByPath(const std::string& path) const = 0;
150 * @brief Notifies accessibility dbus that window has just been shown.
152 * @param[in] window The window to be shown
154 virtual void WindowShown(Window window) = 0;
157 * @brief Notifies accessibility dbus that window has just been hidden.
159 * @param[in] window The window to be hidden
161 virtual void WindowHidden(Window window) = 0;
164 * @brief Notifies accessibility dbus that window has just been focused.
166 * @param[in] window The window to be focused
168 virtual void WindowFocused(Window window) = 0;
171 * @brief Notifies accessibility dbus that window has just been out of focus.
173 * @param[in] window The window to be out of focus
175 virtual void WindowUnfocused(Window window) = 0;
178 * @brief Initializes accessibility bus.
180 virtual void Initialize() = 0;
183 * @brief Terminates accessibility bus.
185 virtual void Terminate() = 0;
188 * @brief This method is called, when bridge is being activated.
190 virtual ForceUpResult ForceUp()
194 return ForceUpResult::ALREADY_UP;
196 mData = std::make_shared<Data>();
197 mData->mBridge = this;
198 return ForceUpResult::JUST_STARTED;
202 * @brief This method is called, when bridge is being deactivated.
204 virtual void ForceDown() = 0;
207 * @brief Checks if bridge is activated or not.
208 * @return True if brige is activated.
216 * @brief Emits cursor-moved event on at-spi bus.
218 * @param[in] obj The accessible object
219 * @param[in] cursorPosition The new cursor position
221 virtual void EmitCursorMoved(Accessible* obj, unsigned int cursorPosition) = 0;
224 * @brief Emits active-descendant-changed event on at-spi bus.
226 * @param[in] obj The accessible object
227 * @param[in] child The child of the object
229 virtual void EmitActiveDescendantChanged(Accessible* obj, Accessible* child) = 0;
232 * @brief Emits text-changed event on at-spi bus.
234 * @param[in] obj The accessible object
235 * @param[in] state The changed state for text, such as Inserted or Deleted
236 * @param[in] position The cursor position
237 * @param[in] length The text length
238 * @param[in] content The changed text
240 virtual void EmitTextChanged(Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string& content) = 0;
243 * @brief Emits MoveOuted event on at-spi bus.
245 * @param[in] obj Accessible object
246 * @param[in] type Direction type when an Accessible object moves out of screen
248 virtual void EmitMovedOutOfScreen(Accessible* obj, ScreenRelativeMoveType type) = 0;
251 * @brief Emits state-changed event on at-spi bus.
253 * @param[in] obj The accessible object
254 * @param[in] state The accessibility state (SHOWING, HIGHLIGHTED, etc)
255 * @param[in] newValue Whether the state value is changed to new value or not.
256 * @param[in] reserved Reserved. (Currently, this argument is not implemented in dali)
258 virtual void EmitStateChanged(Accessible* obj, State state, int newValue, int reserved = 0) = 0;
261 * @brief Emits window event on at-spi bus.
263 * @param[in] obj The accessible object
264 * @param[in] event The enumerated window event
265 * @param[in] detail The additional parameter which interpretation depends on chosen event
267 virtual void Emit(Accessible* obj, WindowEvent event, unsigned int detail = 0) = 0;
270 * @brief Emits property-changed event on at-spi bus.
272 * @param[in] obj The accessible object
273 * @param[in] event Property changed event
275 virtual void Emit(Accessible* obj, ObjectPropertyChangeEvent event) = 0;
278 * @brief Emits bounds-changed event on at-spi bus.
280 * @param[in] obj The accessible object
281 * @param[in] rect The rectangle for changed bounds
283 virtual void EmitBoundsChanged(Accessible* obj, Rect<> rect) = 0;
286 * @brief Emits key event on at-spi bus.
288 * Screen-reader might receive this event and reply, that given keycode is consumed. In that case
289 * further processing of the keycode should be ignored.
291 * @param[in] type Key event type
292 * @param[in] keyCode Key code
293 * @param[in] keyName Key name
294 * @param[in] timeStamp Time stamp
295 * @param[in] isText Whether it's text or not
296 * @return Whether this event is consumed or not
298 virtual Consumed Emit(KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText) = 0;
301 * @brief Reads given text by screen reader
303 * @param[in] text The text to read
304 * @param[in] discardable If TRUE, reading can be discarded by subsequent reading requests,
305 * if FALSE the reading must finish before next reading request can be started
306 * @param[in] callback the callback function that is called on reading signals emitted
307 * during processing of this reading request.
308 * Callback can be one of the following signals:
309 * ReadingCancelled, ReadingStopped, ReadingSkipped
311 virtual void Say(const std::string& text, bool discardable, std::function<void(std::string)> callback) = 0;
314 * @brief Force accessibility client to pause.
316 virtual void Pause() = 0;
319 * @brief Force accessibility client to resume.
321 virtual void Resume() = 0;
324 * @brief Cancels anything screen-reader is reading / has queued to read
326 * @param[in] alsoNonDiscardable whether to cancel non-discardable readings as well
328 virtual void StopReading(bool alsoNonDiscardable) = 0;
331 * @brief Suppresses reading of screen-reader
333 * @param[in] suppress whether to suppress reading of screen-reader
335 virtual void SuppressScreenReader(bool suppress) = 0;
338 * @brief Gets screen reader status.
340 * @return True if screen reader is enabled
342 virtual bool GetScreenReaderEnabled() = 0;
345 * @brief Gets ATSPI status.
347 * @return True if ATSPI is enabled
349 virtual bool IsEnabled() = 0;
352 * @brief Returns instance of bridge singleton object.
354 * @return The current bridge object
356 static Bridge* GetCurrentBridge();
359 * @brief Blocks auto-initialization of AT-SPI bridge
361 * Use this only if your application starts before DBus does, and call it early in main()
362 * (before GetCurrentBridge() is called by anyone). GetCurrentBridge() will then return an
363 * instance of DummyBridge.
365 * When DBus is ready, call EnableAutoInit(). Please note that GetCurrentBridge() may still
366 * return an instance of DummyBridge if AT-SPI was disabled at compile time or using an
367 * environment variable, or if creating the real bridge failed.
369 * @see Dali::Accessibility::DummyBridge
370 * @see Dali::Accessibility::Bridge::EnableAutoInit
372 static void DisableAutoInit();
375 * @brief Re-enables auto-initialization of AT-SPI bridge
377 * Normal applications do not have to call this function. GetCurrentBridge() tries to
378 * initialize the AT-SPI bridge when it is called for the first time.
380 * @see Dali::Accessibility::Bridge::DisableAutoInit
381 * @see Dali::Accessibility::Bridge::AddTopLevelWindow
382 * @see Dali::Accessibility::Bridge::SetApplicationName
384 static void EnableAutoInit();
386 static Signal<void()>& EnabledSignal()
388 return mEnabledSignal;
391 static Signal<void()>& DisabledSignal()
393 return mDisabledSignal;
399 std::unordered_set<Accessible*> mKnownObjects;
400 std::string mBusName;
401 Bridge* mBridge = nullptr;
402 Actor mHighlightActor;
403 Actor mCurrentlyHighlightedActor;
405 std::shared_ptr<Data> mData;
406 friend class Accessible;
408 enum class AutoInitState
414 inline static AutoInitState mAutoInitState = AutoInitState::ENABLED;
416 inline static Signal<void()> mEnabledSignal;
417 inline static Signal<void()> mDisabledSignal;
420 * @brief Registers accessible object to be known in bridge object.
422 * Bridge must known about all currently alive accessible objects, as some requst
423 * might come and object will be identified by number id (it's memory address).
424 * To avoid memory corruption number id is checked against set of known objects.
426 * @param[in] object The accessible object
428 void RegisterOnBridge(Accessible* object);
431 * @brief Tells bridge, that given object is considered root (doesn't have any parents).
433 * All root objects will have the same parent - application object. Application object
434 * is controlled by bridge and private.
436 * @param[in] owner The accessible object
438 void SetIsOnRootLevel(Accessible* owner);
442 * @brief Checks if ATSPI is activated or not.
443 * @return True if ATSPI is activated.
447 if(Bridge::GetCurrentBridge() == nullptr)
452 if(Bridge::GetCurrentBridge()->IsEnabled() == false)
457 return Bridge::GetCurrentBridge()->IsUp();
460 } // namespace Accessibility
463 #endif // DALI_ADAPTOR_ACCESSIBILITY_BRIDGE_H