Merge remote-tracking branch 'origin/master' into tizen
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Accessibility / Accessibility.cs
1 /*
2  * Copyright(c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 using System;
19 using System.ComponentModel;
20 using System.Runtime.InteropServices;
21 using Tizen.NUI.BaseComponents;
22 using System.Diagnostics.CodeAnalysis;
23
24 namespace Tizen.NUI.Accessibility
25 {
26     /// <summary>
27     /// Accessibility provides Dali-ATSPI interface which has functionality of Screen-Reader and general accessibility
28     /// </summary>
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 static class Accessibility
34     {
35         #region Constructor
36         [SuppressMessage("Microsoft.Performance", "CA1810: Initialize reference type static fields inline", Justification = "Need to call native code")]
37         static Accessibility()
38         {
39             enabledSignalHandler = () =>
40             {
41                 Enabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
42             };
43
44             disabledSignalHandler = () =>
45             {
46                 Disabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
47             };
48
49             Interop.Accessibility.RegisterEnabledDisabledSignalHandler(enabledSignalHandler, disabledSignalHandler);
50         }
51         #endregion Constructor
52
53         #region Property
54         /// <summary>
55         /// Flag to check whether the state of Accessibility is enabled or not.
56         /// </summary>
57         /// <remarks>
58         /// Getter returns true if Accessibility is enabled, false otherwise.
59         /// </remarks>
60         /// This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         public static bool IsEnabled
63         {
64             get
65             {
66                 return (bool)Interop.Accessibility.IsEnabled();
67             }
68         }
69
70         #endregion Property
71
72         #region Method
73         /// <summary>
74         /// Start to speak
75         /// </summary>
76         /// <param name="sentence">Content to be spoken</param>
77         /// <param name="discardable">true to be stopped and discarded when other Say is triggered</param>
78         /// <returns></returns>
79         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
80         [EditorBrowsable(EditorBrowsableState.Never)]
81         public static bool Say(string sentence, bool discardable)
82         {
83             bool ret = Interop.Accessibility.Say(sentence, discardable, Marshal.GetFunctionPointerForDelegate<Delegate>(callback));
84
85             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
86             return ret;
87         }
88
89         /// <summary>
90         /// To make Say be paused or resumed
91         /// </summary>
92         /// <param name="pause">true to be paused, false to be resumed</param>
93         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
94         [EditorBrowsable(EditorBrowsableState.Never)]
95         public static void PauseResume(bool pause)
96         {
97             Interop.Accessibility.PauseResume(pause);
98             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
99         }
100
101         /// <summary>
102         /// Cancels anything screen-reader is reading / has queued to read
103         /// </summary>
104         /// <param name="alsoNonDiscardable">whether to cancel non-discardable readings as well</param>
105         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
106         [EditorBrowsable(EditorBrowsableState.Never)]
107         public static void StopReading(bool alsoNonDiscardable)
108         {
109             Interop.Accessibility.StopReading(alsoNonDiscardable);
110             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
111         }
112
113         /// <summary>
114         /// Suppress reading of screen-reader
115         /// </summary>
116         /// <param name="suppress">whether to suppress reading of screen-reader</param>
117         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
118         [EditorBrowsable(EditorBrowsableState.Never)]
119         public static bool SuppressScreenReader(bool suppress)
120         {
121             bool ret = Interop.Accessibility.SuppressScreenReader(suppress);
122             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
123             return ret;
124         }
125
126         /// <summary>
127         /// Re-enables auto-initialization of AT-SPI bridge
128         /// </summary>
129         /// <remarks>
130         /// Normal applications do not have to call this function. The AT-SPI bridge is initialized on demand.
131         /// </remarks>
132         [EditorBrowsable(EditorBrowsableState.Never)]
133         public static void BridgeEnableAutoInit()
134         {
135             Interop.Accessibility.BridgeEnableAutoInit();
136             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
137         }
138
139         /// <summary>
140         /// Blocks auto-initialization of AT-SPI bridge
141         /// </summary>
142         /// <remarks>
143         /// Use this only if your application starts before DBus does, and call it early in Main().
144         /// When DBus is ready, call BridgeEnableAutoInit().
145         /// </remarks>
146         [EditorBrowsable(EditorBrowsableState.Never)]
147         public static void BridgeDisableAutoInit()
148         {
149             Interop.Accessibility.BridgeDisableAutoInit();
150             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
151         }
152
153         /// <summary>
154         ///  Get View that is used to highlight widget.
155         /// </summary>
156         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
157         [EditorBrowsable(EditorBrowsableState.Never)]
158         public static View GetHighlightFrameView()
159         {
160             var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetHighlightActor();
161             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
162             if (ptr == IntPtr.Zero)
163                 return null;
164             return new View(ptr, true);
165         }
166
167         /// <summary>
168         ///  Set view that will be used to highlight widget.
169         /// </summary>
170         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
171         [EditorBrowsable(EditorBrowsableState.Never)]
172         public static void SetHighlightFrameView(View view)
173         {
174             Interop.ControlDevel.DaliAccessibilityAccessibleSetHighlightActor(View.getCPtr(view));
175             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
176         }
177
178         /// <summary>
179         ///  Get highligted View.
180         /// </summary>
181         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
182         [EditorBrowsable(EditorBrowsableState.Never)]
183         public static View GetCurrentlyHighlightedView()
184         {
185             var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetCurrentlyHighlightedActor();
186
187             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
188
189             return dummyHandle.GetInstanceSafely<View>(ptr);
190         }
191
192         /// <summary>
193         ///  Clear highlight.
194         /// </summary>
195         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
196         [EditorBrowsable(EditorBrowsableState.Never)]
197         public static bool ClearCurrentlyHighlightedView()
198         {
199             var view = GetCurrentlyHighlightedView();
200
201             return view?.ClearAccessibilityHighlight() ?? false;
202         }
203         #endregion Method
204
205
206         #region Event, Enum, Struct, ETC
207         /// <summary>
208         /// Enum of Say finished event argument status
209         /// </summary>
210         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
211         [EditorBrowsable(EditorBrowsableState.Never)]
212         public enum SayFinishedState
213         {
214             /// <summary>
215             /// Invalid
216             /// </summary>
217             // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
218             [EditorBrowsable(EditorBrowsableState.Never)]
219             Invalid = -1,
220             /// <summary>
221             /// Cancelled
222             /// </summary>
223             // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
224             [EditorBrowsable(EditorBrowsableState.Never)]
225             Cancelled = 1,
226             /// <summary>
227             /// Stopped
228             /// </summary>
229             // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
230             [EditorBrowsable(EditorBrowsableState.Never)]
231             Stopped = 2,
232             /// <summary>
233             /// Skipped
234             /// </summary>
235             // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
236             [EditorBrowsable(EditorBrowsableState.Never)]
237             Skipped = 3,
238             /// <summary>
239             /// Paused
240             /// </summary>
241             // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
242             [EditorBrowsable(EditorBrowsableState.Never)]
243             Paused = 4,
244             /// <summary>
245             /// Resumed
246             /// </summary>
247             // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
248             [EditorBrowsable(EditorBrowsableState.Never)]
249             Resumed = 5
250         }
251
252         /// <summary>
253         /// When Say is finished, this event is triggered
254         /// </summary>
255         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
256         [EditorBrowsable(EditorBrowsableState.Never)]
257         public static event EventHandler<SayFinishedEventArgs> SayFinished;
258
259         /// <summary>
260         /// Triggered whenever the value of IsEnabled would change from false to true
261         /// </summary>
262         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
263         [EditorBrowsable(EditorBrowsableState.Never)]
264         public static event EventHandler Enabled;
265
266         /// <summary>
267         /// Triggered whenever the value of IsEnabled would change from true to false
268         /// </summary>
269         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
270         [EditorBrowsable(EditorBrowsableState.Never)]
271         public static event EventHandler Disabled;
272
273         #endregion Event, Enum, Struct, ETC
274
275         #region Private
276
277         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
278         private delegate void SayFinishedEventCallbackType(int result);
279
280         private static SayFinishedEventCallbackType callback = SayFinishedEventCallback;
281
282         private static Interop.Accessibility.EnabledDisabledSignalHandler enabledSignalHandler = null;
283
284         private static Interop.Accessibility.EnabledDisabledSignalHandler disabledSignalHandler = null;
285
286         private static void SayFinishedEventCallback(int result)
287         {
288             NUILog.Debug($"sayFinishedEventCallback(res={result}) called!");
289             SayFinished?.Invoke(typeof(Accessibility), new SayFinishedEventArgs(result));
290         }
291
292         private static BaseHandle dummyHandle = new BaseHandle();
293
294         #endregion Private
295     }
296
297     /// <summary>
298     ///  Say Finished event arguments
299     /// </summary>
300     // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
301     [EditorBrowsable(EditorBrowsableState.Never)]
302     public class SayFinishedEventArgs : EventArgs
303     {
304         /// <summary>
305         /// The state of Say finished
306         /// </summary>
307         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
308         [EditorBrowsable(EditorBrowsableState.Never)]
309         public Accessibility.SayFinishedState State
310         {
311             private set;
312             get;
313         }
314
315         internal SayFinishedEventArgs(int result)
316         {
317             State = (Accessibility.SayFinishedState)(result);
318             NUILog.Debug($"SayFinishedEventArgs Constructor! State={State}");
319         }
320     }
321 }