2 * Copyright(c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Collections.Generic;
20 using System.ComponentModel;
21 using System.Diagnostics.CodeAnalysis;
22 using System.Runtime.InteropServices;
23 using Tizen.NUI.BaseComponents;
25 namespace Tizen.NUI.Accessibility
28 /// Accessibility provides Dali-ATSPI interface which has functionality of Screen-Reader and general accessibility
30 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
31 [SuppressMessage("Microsoft.Design", "CA1724: Type names should not match namespaces")]
32 [SuppressMessage("Microsoft.Design", "CA1001:Types that own disposable fields should be disposable", Justification = "This is a singleton class and is not disposed")]
33 [EditorBrowsable(EditorBrowsableState.Never)]
34 public static class Accessibility
37 [SuppressMessage("Microsoft.Performance", "CA1810: Initialize reference type static fields inline", Justification = "Need to call native code")]
38 static Accessibility()
40 enabledSignalHandler = () =>
42 Enabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
45 disabledSignalHandler = () =>
47 Disabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
50 screenReaderEnabledSignalHandler = () =>
52 ScreenReaderEnabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
55 screenReaderDisabledSignalHandler = () =>
57 ScreenReaderDisabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
60 Interop.Accessibility.RegisterEnabledDisabledSignalHandler(enabledSignalHandler, disabledSignalHandler);
61 Interop.Accessibility.RegisterScreenReaderEnabledDisabledSignalHandler(screenReaderEnabledSignalHandler, screenReaderDisabledSignalHandler);
63 #endregion Constructor
67 /// Flag to check whether the state of Accessibility is enabled or not.
70 /// Getter returns true if Accessibility is enabled, false otherwise.
72 /// This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
73 [EditorBrowsable(EditorBrowsableState.Never)]
74 public static bool IsEnabled
78 return (bool)Interop.Accessibility.IsEnabled();
83 /// Flag to check whether the state of Screen Reader is enabled or not.
86 /// Getter returns true if Screen Reader is enabled, false otherwise.
88 /// This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
89 [EditorBrowsable(EditorBrowsableState.Never)]
90 public static bool IsScreenReaderEnabled
94 return (bool)Interop.Accessibility.IsScreenReaderEnabled();
104 /// <param name="sentence">Content to be spoken</param>
105 /// <param name="discardable">true to be stopped and discarded when other Say is triggered</param>
106 /// <returns></returns>
107 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
108 [EditorBrowsable(EditorBrowsableState.Never)]
109 public static void Say(string sentence, bool discardable)
111 Interop.Accessibility.Say(sentence, discardable, SayFinishedEventCallback);
112 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
116 /// To make Say be paused or resumed
118 /// <param name="pause">true to be paused, false to be resumed</param>
119 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
120 [EditorBrowsable(EditorBrowsableState.Never)]
121 public static void PauseResume(bool pause)
123 Interop.Accessibility.PauseResume(pause);
124 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
128 /// Cancels anything screen-reader is reading / has queued to read
130 /// <param name="alsoNonDiscardable">whether to cancel non-discardable readings as well</param>
131 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
132 [EditorBrowsable(EditorBrowsableState.Never)]
133 public static void StopReading(bool alsoNonDiscardable)
135 Interop.Accessibility.StopReading(alsoNonDiscardable);
136 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
140 /// Suppress reading of screen-reader
142 /// <param name="suppress">whether to suppress reading of screen-reader</param>
143 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
144 [EditorBrowsable(EditorBrowsableState.Never)]
145 public static bool SuppressScreenReader(bool suppress)
147 bool ret = Interop.Accessibility.SuppressScreenReader(suppress);
148 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
153 /// Re-enables auto-initialization of AT-SPI bridge
156 /// Normal applications do not have to call this function. The AT-SPI bridge is initialized on demand.
158 [EditorBrowsable(EditorBrowsableState.Never)]
159 public static void BridgeEnableAutoInit()
161 Interop.Accessibility.BridgeEnableAutoInit();
162 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
166 /// Blocks auto-initialization of AT-SPI bridge
169 /// Use this only if your application starts before DBus does, and call it early in Main().
170 /// When DBus is ready, call BridgeEnableAutoInit().
172 [EditorBrowsable(EditorBrowsableState.Never)]
173 public static void BridgeDisableAutoInit()
175 Interop.Accessibility.BridgeDisableAutoInit();
176 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
180 /// Get View that is used to highlight widget.
182 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
183 [EditorBrowsable(EditorBrowsableState.Never)]
184 public static View GetHighlightFrameView()
186 var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetHighlightActor();
187 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
188 if (ptr == IntPtr.Zero)
190 return new View(ptr, true);
194 /// Set view that will be used to highlight widget.
196 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
197 [EditorBrowsable(EditorBrowsableState.Never)]
198 public static void SetHighlightFrameView(View view)
200 Interop.ControlDevel.DaliAccessibilityAccessibleSetHighlightActor(View.getCPtr(view));
201 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
205 /// Get highligted View.
207 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
208 [EditorBrowsable(EditorBrowsableState.Never)]
209 public static View GetCurrentlyHighlightedView()
211 var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetCurrentlyHighlightedActor();
213 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
215 return dummyHandle.GetInstanceSafely<View>(ptr);
221 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
222 [EditorBrowsable(EditorBrowsableState.Never)]
223 public static bool ClearCurrentlyHighlightedView()
225 var view = GetCurrentlyHighlightedView();
227 return view?.ClearAccessibilityHighlight() ?? false;
232 #region Event, Enum, Struct, ETC
234 /// Enum of Say finished event argument status
236 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
237 [EditorBrowsable(EditorBrowsableState.Never)]
238 public enum SayFinishedState
243 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
244 [EditorBrowsable(EditorBrowsableState.Never)]
249 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
250 [EditorBrowsable(EditorBrowsableState.Never)]
255 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
256 [EditorBrowsable(EditorBrowsableState.Never)]
261 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
262 [EditorBrowsable(EditorBrowsableState.Never)]
267 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
268 [EditorBrowsable(EditorBrowsableState.Never)]
273 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
274 [EditorBrowsable(EditorBrowsableState.Never)]
279 /// When Say is finished, this event is triggered
281 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
282 [EditorBrowsable(EditorBrowsableState.Never)]
283 public static event EventHandler<SayFinishedEventArgs> SayFinished;
286 /// Triggered whenever the value of IsEnabled would change from false to true
288 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
289 [EditorBrowsable(EditorBrowsableState.Never)]
290 public static event EventHandler Enabled;
293 /// Triggered whenever the value of IsEnabled would change from true to false
295 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
296 [EditorBrowsable(EditorBrowsableState.Never)]
297 public static event EventHandler Disabled;
300 /// Triggered whenever the value of IsScreenReaderEnabled would change from false to true
302 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
303 [EditorBrowsable(EditorBrowsableState.Never)]
304 public static event EventHandler ScreenReaderEnabled;
307 /// Triggered whenever the value of IsScreenReaderEnabled would change from true to false
309 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
310 [EditorBrowsable(EditorBrowsableState.Never)]
311 public static event EventHandler ScreenReaderDisabled;
313 #endregion Event, Enum, Struct, ETC
316 private static Interop.Accessibility.EnabledDisabledSignalHandler enabledSignalHandler = null;
318 private static Interop.Accessibility.EnabledDisabledSignalHandler disabledSignalHandler = null;
320 private static Interop.Accessibility.EnabledDisabledSignalHandler screenReaderEnabledSignalHandler = null;
322 private static Interop.Accessibility.EnabledDisabledSignalHandler screenReaderDisabledSignalHandler = null;
324 private static readonly IReadOnlyDictionary<string, SayFinishedState> sayFinishedStateDictionary = new Dictionary<string, SayFinishedState>
326 ["ReadingCancelled"] = SayFinishedState.Cancelled,
327 ["ReadingStopped"] = SayFinishedState.Stopped,
328 ["ReadingSkipped"] = SayFinishedState.Skipped,
329 ["ReadingPaused"] = SayFinishedState.Paused,
330 ["ReadingResumed"] = SayFinishedState.Resumed,
333 private static void SayFinishedEventCallback(string status)
335 var result = sayFinishedStateDictionary.GetValueOrDefault(status, SayFinishedState.Invalid);
336 NUILog.Debug($"sayFinishedEventCallback(res={result}) called!");
338 SayFinished?.Invoke(typeof(Accessibility), new SayFinishedEventArgs(result));
341 private static BaseHandle dummyHandle = new BaseHandle();
347 /// Say Finished event arguments
349 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
350 [EditorBrowsable(EditorBrowsableState.Never)]
351 public class SayFinishedEventArgs : EventArgs
354 /// The state of Say finished
356 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
357 [EditorBrowsable(EditorBrowsableState.Never)]
358 public Accessibility.SayFinishedState State
364 internal SayFinishedEventArgs(Accessibility.SayFinishedState state)
367 NUILog.Debug($"SayFinishedEventArgs Constructor! State={State}");