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.ComponentModel;
20 using System.Runtime.InteropServices;
21 using Tizen.NUI.BaseComponents;
22 using System.Diagnostics.CodeAnalysis;
24 namespace Tizen.NUI.Accessibility
27 /// Accessibility provides Dali-ATSPI interface which has functionality of Screen-Reader and general accessibility
29 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
30 [SuppressMessage("Microsoft.Design", "CA1724: Type names should not match namespaces")]
31 [SuppressMessage("Microsoft.Design", "CA1001:Types that own disposable fields should be disposable", Justification = "This is a singleton class and is not disposed")]
32 [EditorBrowsable(EditorBrowsableState.Never)]
33 public class Accessibility
35 #region Constructor, Destructor, Dispose
36 private Accessibility()
39 dummy.Name = "dali-atspi-singleton";
42 /// destructor. This is HiddenAPI. recommended not to use in public.
46 Tizen.Log.Debug("NUI", $"Accessibility is destroyed\n");
48 #endregion Constructor, Destructor, Dispose
53 /// Instance for singleton
55 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
56 [EditorBrowsable(EditorBrowsableState.Never)]
57 public static Accessibility Instance
63 /// Flag to check whether the state of Accessibility is enabled or not.
66 /// Getter returns true if Accessibility is enabled, false otherwise.
68 /// This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
69 [EditorBrowsable(EditorBrowsableState.Never)]
70 public static bool Enabled
74 return (bool)Interop.Accessibility.IsEnabled();
83 /// Get the current status
85 /// <returns>Current enabled status</returns>
86 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
87 [EditorBrowsable(EditorBrowsableState.Never)]
88 static public bool GetStatus()
96 /// <param name="sentence">Content to be spoken</param>
97 /// <param name="discardable">true to be stopped and discarded when other Say is triggered</param>
98 /// <returns></returns>
99 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
100 [EditorBrowsable(EditorBrowsableState.Never)]
101 public bool Say(string sentence, bool discardable)
103 IntPtr callbackIntPtr = IntPtr.Zero;
104 if (sayFinishedEventHandler != null)
106 callback = SayFinishedEventCallback;
107 callbackIntPtr = Marshal.GetFunctionPointerForDelegate<Delegate>(callback);
109 bool ret = Interop.Accessibility.Say(View.getCPtr(dummy), sentence, discardable, callbackIntPtr);
110 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
115 /// To make Say be paused or resumed
117 /// <param name="pause">true to be paused, false to be resumed</param>
118 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
119 [EditorBrowsable(EditorBrowsableState.Never)]
120 public void PauseResume(bool pause)
122 Interop.Accessibility.PauseResume(View.getCPtr(dummy), pause);
123 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
127 /// Cancels anything screen-reader is reading / has queued to read
129 /// <param name="alsoNonDiscardable">whether to cancel non-discardable readings as well</param>
130 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
131 [EditorBrowsable(EditorBrowsableState.Never)]
132 public void StopReading(bool alsoNonDiscardable)
134 Interop.Accessibility.StopReading(View.getCPtr(dummy), alsoNonDiscardable);
135 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
139 /// Suppress reading of screen-reader
141 /// <param name="suppress">whether to suppress reading of screen-reader</param>
142 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
143 [EditorBrowsable(EditorBrowsableState.Never)]
144 public bool SuppressScreenReader(bool suppress)
146 bool ret = Interop.Accessibility.SuppressScreenReader(View.getCPtr(dummy), suppress);
147 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
152 /// Re-enables auto-initialization of AT-SPI bridge
155 /// Normal applications do not have to call this function. The AT-SPI bridge is initialized on demand.
157 [EditorBrowsable(EditorBrowsableState.Never)]
158 public static void BridgeEnableAutoInit()
160 Interop.Accessibility.BridgeEnableAutoInit();
161 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
165 /// Blocks auto-initialization of AT-SPI bridge
168 /// Use this only if your application starts before DBus does, and call it early in Main().
169 /// When DBus is ready, call BridgeEnableAutoInit().
171 [EditorBrowsable(EditorBrowsableState.Never)]
172 public static void BridgeDisableAutoInit()
174 Interop.Accessibility.BridgeDisableAutoInit();
175 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
179 /// Get View that is used to highlight widget.
181 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
182 [EditorBrowsable(EditorBrowsableState.Never)]
183 public View GetHighlightFrameView()
185 var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetHighlightActor();
186 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
187 if (ptr == IntPtr.Zero)
189 return new View(ptr, true);
193 /// Set view that will be used to highlight widget.
195 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
196 [EditorBrowsable(EditorBrowsableState.Never)]
197 public void SetHighlightFrameView(View view)
199 Interop.ControlDevel.DaliAccessibilityAccessibleSetHighlightActor(View.getCPtr(view));
200 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
204 /// Get highligted View.
206 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
207 [EditorBrowsable(EditorBrowsableState.Never)]
208 public View GetCurrentlyHighlightedView()
210 var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetCurrentlyHighlightedActor();
211 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
212 if (ptr == IntPtr.Zero)
214 return new View(ptr, true);
220 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
221 [EditorBrowsable(EditorBrowsableState.Never)]
222 public bool ClearCurrentlyHighlightedView()
224 using (View view = GetCurrentlyHighlightedView())
226 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 event EventHandler<SayFinishedEventArgs> SayFinished
285 add => sayFinishedEventHandler += value;
286 remove => sayFinishedEventHandler -= value;
288 #endregion Event, Enum, Struct, ETC
292 internal void PauseResume(View target, bool pause)
294 Interop.Accessibility.PauseResume(View.getCPtr(target), pause);
295 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
298 internal bool Say(View target, string sentence, bool discardable)
300 IntPtr callbackIntPtr = IntPtr.Zero;
301 if (sayFinishedEventHandler != null)
303 callback = SayFinishedEventCallback;
304 callbackIntPtr = Marshal.GetFunctionPointerForDelegate<Delegate>(callback);
306 bool ret = Interop.Accessibility.Say(View.getCPtr(target), sentence, discardable, callbackIntPtr);
307 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
314 private static readonly Accessibility accessibility = new Accessibility();
316 private event EventHandler<SayFinishedEventArgs> sayFinishedEventHandler;
318 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
319 private delegate void SayFinishedEventCallbackType(int result);
321 private SayFinishedEventCallbackType callback = null;
323 private void SayFinishedEventCallback(int result)
325 NUILog.Debug($"sayFinishedEventCallback(res={result}) called!");
326 sayFinishedEventHandler?.Invoke(this, new SayFinishedEventArgs(result));
331 private static string tag = "NUITEST";
336 /// Say Finished event arguments
338 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
339 [EditorBrowsable(EditorBrowsableState.Never)]
340 public class SayFinishedEventArgs : EventArgs
343 /// The state of Say finished
345 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
346 [EditorBrowsable(EditorBrowsableState.Never)]
347 public Accessibility.SayFinishedState State
353 internal SayFinishedEventArgs(int result)
355 State = (Accessibility.SayFinishedState)(result);
356 NUILog.Debug($"SayFinishedEventArgs Constructor! State={State}");