Add a callback for navigation policy in web engine.
[platform/core/uifw/dali-adaptor.git] / dali / devel-api / adaptor-framework / accessibility-bridge.h
1 #ifndef DALI_ADAPTOR_ACCESSIBILITY_BRIDGE_H
2 #define DALI_ADAPTOR_ACCESSIBILITY_BRIDGE_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/actors/actor.h>
23 #include <dali/public-api/math/rect.h>
24 #include <functional>
25 #include <memory>
26 #include <stdexcept>
27 #include <string>
28 #include <unordered_set>
29
30 // INTERNAL INCLUDES
31 #include <dali/devel-api/adaptor-framework/accessibility.h>
32 #include <dali/public-api/adaptor-framework/window.h>
33
34 namespace Dali
35 {
36 namespace Accessibility
37 {
38 class Accessible;
39
40 /**
41  * @brief Base class for different accessibility bridges.
42  *
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.
46  *
47  * @note This class is singleton.
48  */
49 struct DALI_ADAPTOR_API Bridge
50 {
51   enum class ForceUpResult
52   {
53     JUST_STARTED,
54     ALREADY_UP
55   };
56
57   /**
58    * @brief Destructor
59    */
60   virtual ~Bridge() = default;
61
62   /**
63    * @brief Gets bus name which bridge is initialized on.
64    *
65    * @return The bus name
66    */
67   virtual const std::string& GetBusName() const = 0;
68
69   /**
70    * @brief Registers top level window.
71    *
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.
76    *
77    * @param[in] object The accessible object
78    */
79   virtual void AddTopLevelWindow(Accessible* object) = 0;
80
81   /**
82    * @brief Removes top level window.
83    *
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.
87    *
88    * @param[in] object The accessible object
89    */
90   virtual void RemoveTopLevelWindow(Accessible* object) = 0;
91
92   /**
93    * @brief Adds object on the top of the stack of "default label" sourcing objects.
94    *
95    * @see GetDefaultLabel
96    *
97    * @param[in] object The accessible object
98    */
99   virtual void RegisterDefaultLabel(Accessible* object) = 0;
100
101   /**
102    * @brief Removes object from the stack of "default label" sourcing objects.
103    *
104    * @see GetDefaultLabel
105    *
106    * @param[in] object The accessible object
107    */
108   virtual void UnregisterDefaultLabel(Accessible* object) = 0;
109
110   /**
111    * @brief Gets the top-most object from the stack of "default label" sourcing objects.
112    *
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.
116    *
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".
123    */
124   virtual Accessible* GetDefaultLabel() const = 0;
125
126   /**
127    * @brief Sets name of current application which will be visible on accessibility bus.
128    *
129    * @param[in] name The application name
130    */
131   virtual void SetApplicationName(std::string name) = 0;
132
133   /**
134    * @brief Gets object being root of accessibility tree.
135    *
136    * @return handler to accessibility object
137    */
138   virtual Accessible* GetApplication() const = 0;
139
140   /**
141    * @brief Finds an object in accessibility tree.
142    *
143    * @param[in] path The path to object
144    *
145    * @return The handler to accessibility object
146    */
147   virtual Accessible* FindByPath(const std::string& path) const = 0;
148
149   /**
150    * @brief Notifies accessibility dbus that window has just been shown.
151    *
152    * @param[in] window The window to be shown
153    */
154   virtual void WindowShown(Window window) = 0;
155
156   /**
157    * @brief Notifies accessibility dbus that window has just been hidden.
158    *
159    * @param[in] window The window to be hidden
160    */
161   virtual void WindowHidden(Window window) = 0;
162
163   /**
164    * @brief Notifies accessibility dbus that window has just been focused.
165    *
166    * @param[in] window The window to be focused
167    */
168   virtual void WindowFocused(Window window) = 0;
169
170   /**
171    * @brief Notifies accessibility dbus that window has just been out of focus.
172    *
173    * @param[in] window The window to be out of focus
174    */
175   virtual void WindowUnfocused(Window window) = 0;
176
177   /**
178    * @brief Initializes accessibility bus.
179    */
180   virtual void Initialize() = 0;
181
182   /**
183    * @brief Terminates accessibility bus.
184    */
185   virtual void Terminate() = 0;
186
187   /**
188    * @brief This method is called, when bridge is being activated.
189    */
190   virtual ForceUpResult ForceUp()
191   {
192     if(mData)
193     {
194       return ForceUpResult::ALREADY_UP;
195     }
196     mData          = std::make_shared<Data>();
197     mData->mBridge = this;
198     return ForceUpResult::JUST_STARTED;
199   }
200
201   /**
202    * @brief This method is called, when bridge is being deactivated.
203    */
204   virtual void ForceDown() = 0;
205
206   /**
207    * @brief Checks if bridge is activated or not.
208    * @return True if brige is activated.
209    */
210   bool IsUp() const
211   {
212     return bool(mData);
213   }
214
215   /**
216    * @brief Emits cursor-moved event on at-spi bus.
217    *
218    * @param[in] obj The accessible object
219    * @param[in] cursorPosition The new cursor position
220    **/
221   virtual void EmitCursorMoved(Accessible* obj, unsigned int cursorPosition) = 0;
222
223   /**
224    * @brief Emits active-descendant-changed event on at-spi bus.
225    *
226    * @param[in] obj The accessible object
227    * @param[in] child The child of the object
228    **/
229   virtual void EmitActiveDescendantChanged(Accessible* obj, Accessible* child) = 0;
230
231   /**
232    * @brief Emits text-changed event on at-spi bus.
233    *
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
239    **/
240   virtual void EmitTextChanged(Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string& content) = 0;
241
242   /**
243    * @brief Emits MoveOuted event on at-spi bus.
244    *
245    * @param[in] obj Accessible object
246    * @param[in] type Direction type when an Accessible object moves out of screen
247    **/
248   virtual void EmitMovedOutOfScreen(Accessible* obj, ScreenRelativeMoveType type) = 0;
249
250   /**
251    * @brief Emits state-changed event on at-spi bus.
252    *
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)
257    **/
258   virtual void EmitStateChanged(Accessible* obj, State state, int newValue, int reserved = 0) = 0;
259
260   /**
261    * @brief Emits window event on at-spi bus.
262    *
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
266    **/
267   virtual void Emit(Accessible* obj, WindowEvent event, unsigned int detail = 0) = 0;
268
269   /**
270    * @brief Emits property-changed event on at-spi bus.
271    *
272    * @param[in] obj The accessible object
273    * @param[in] event Property changed event
274    **/
275   virtual void Emit(Accessible* obj, ObjectPropertyChangeEvent event) = 0;
276
277   /**
278    * @brief Emits bounds-changed event on at-spi bus.
279    *
280    * @param[in] obj The accessible object
281    * @param[in] rect The rectangle for changed bounds
282    **/
283   virtual void EmitBoundsChanged(Accessible* obj, Rect<> rect) = 0;
284
285   /**
286    * @brief Emits key event on at-spi bus.
287    *
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.
290    *
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
297    **/
298   virtual Consumed Emit(KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText) = 0;
299
300   /**
301    * @brief Reads given text by screen reader
302    *
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
310    */
311   virtual void Say(const std::string& text, bool discardable, std::function<void(std::string)> callback) = 0;
312
313   /**
314    * @brief Force accessibility client to pause.
315    */
316   virtual void Pause() = 0;
317
318   /**
319    * @brief Force accessibility client to resume.
320    */
321   virtual void Resume() = 0;
322
323   /**
324    * @brief Cancels anything screen-reader is reading / has queued to read
325    *
326    * @param[in] alsoNonDiscardable whether to cancel non-discardable readings as well
327    */
328   virtual void StopReading(bool alsoNonDiscardable) = 0;
329
330   /**
331    * @brief Suppresses reading of screen-reader
332    *
333    * @param[in] suppress whether to suppress reading of screen-reader
334    */
335   virtual void SuppressScreenReader(bool suppress) = 0;
336
337   /**
338    * @brief Gets screen reader status.
339    *
340    * @return True if screen reader is enabled
341    */
342   virtual bool GetScreenReaderEnabled() = 0;
343
344   /**
345    * @brief Gets ATSPI status.
346    *
347    * @return True if ATSPI is enabled
348    */
349   virtual bool IsEnabled() = 0;
350
351   /**
352    * @brief Returns instance of bridge singleton object.
353    *
354    * @return The current bridge object
355    **/
356   static std::shared_ptr<Bridge> GetCurrentBridge();
357
358   /**
359    * @brief Blocks auto-initialization of AT-SPI bridge
360    *
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.
364    *
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.
368    *
369    * @see Dali::Accessibility::DummyBridge
370    * @see Dali::Accessibility::Bridge::EnableAutoInit
371    */
372   static void DisableAutoInit();
373
374   /**
375    * @brief Re-enables auto-initialization of AT-SPI bridge
376    *
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.
379    *
380    * @see Dali::Accessibility::Bridge::DisableAutoInit
381    * @see Dali::Accessibility::Bridge::AddTopLevelWindow
382    * @see Dali::Accessibility::Bridge::SetApplicationName
383    */
384   static void EnableAutoInit();
385
386   static Signal<void()>& EnabledSignal()
387   {
388     return mEnabledSignal;
389   }
390
391   static Signal<void()>& DisabledSignal()
392   {
393     return mDisabledSignal;
394   }
395
396 protected:
397   struct Data
398   {
399     std::unordered_set<Accessible*> mKnownObjects;
400     std::string                     mBusName;
401     Bridge*                         mBridge = nullptr;
402     Actor                           mHighlightActor;
403     Actor                           mCurrentlyHighlightedActor;
404   };
405   std::shared_ptr<Data> mData;
406   friend class Accessible;
407
408   enum class AutoInitState
409   {
410     DISABLED,
411     ENABLED
412   };
413
414   inline static AutoInitState mAutoInitState = AutoInitState::ENABLED;
415
416   inline static Signal<void()> mEnabledSignal;
417   inline static Signal<void()> mDisabledSignal;
418
419   /**
420    * @brief Registers accessible object to be known in bridge object.
421    *
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.
425    *
426    * @param[in] object The accessible object
427    **/
428   void RegisterOnBridge(Accessible* object);
429
430   /**
431    * @brief Tells bridge, that given object is considered root (doesn't have any parents).
432    *
433    * All root objects will have the same parent - application object. Application object
434    * is controlled by bridge and private.
435    *
436    * @param[in] owner The accessible object
437    **/
438   void SetIsOnRootLevel(Accessible* owner);
439 };
440
441 /**
442  * @brief Checks if ATSPI is activated or not.
443  * @return True if ATSPI is activated.
444  */
445 inline bool IsUp()
446 {
447   if(Bridge::GetCurrentBridge() == nullptr)
448   {
449     return false;
450   }
451
452   if(Bridge::GetCurrentBridge()->IsEnabled() == false)
453   {
454     return false;
455   }
456
457   return Bridge::GetCurrentBridge()->IsUp();
458 }
459
460 } // namespace Accessibility
461 } // namespace Dali
462
463 #endif // DALI_ADAPTOR_ACCESSIBILITY_BRIDGE_H