[NUI] Change all CallingConvention to `Cdecl`
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Accessibility / Accessibility.cs
index 99a9d22..77ac711 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  */
 
-using global::System;
+using System;
 using System.ComponentModel;
 using System.Runtime.InteropServices;
 using Tizen.NUI.BaseComponents;
 using System.Diagnostics.CodeAnalysis;
-#if (NUI_DEBUG_ON)
-using tlog = Tizen.Log;
-#endif
 
 namespace Tizen.NUI.Accessibility
 {
     /// <summary>
-    /// Accessibility provides Dali-ATSPI interface which has funtionality of Screen-Reader and general accessibility
+    /// Accessibility provides Dali-ATSPI interface which has functionality of Screen-Reader and general accessibility
     /// </summary>
     // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
     [SuppressMessage("Microsoft.Design", "CA1724: Type names should not match namespaces")]
     [SuppressMessage("Microsoft.Design", "CA1001:Types that own disposable fields should be disposable", Justification = "This is a singleton class and is not disposed")]
     [EditorBrowsable(EditorBrowsableState.Never)]
-    public class Accessibility
+    public static class Accessibility
     {
-        #region Constructor, Distructor, Dispose
-        private Accessibility()
+        #region Constructor
+        [SuppressMessage("Microsoft.Performance", "CA1810: Initialize reference type static fields inline", Justification = "Need to call native code")]
+        static Accessibility()
         {
-            dummy = new View();
-            dummy.Name = "dali-atspi-singleton";
+            enabledSignalHandler = () =>
+            {
+                Enabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
+            };
+
+            disabledSignalHandler = () =>
+            {
+                Disabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
+            };
+
+            screenReaderEnabledSignalHandler = () =>
+            {
+                ScreenReaderEnabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
+            };
+
+            screenReaderDisabledSignalHandler = () =>
+            {
+                ScreenReaderDisabled?.Invoke(typeof(Accessibility), EventArgs.Empty);
+            };
+
+            Interop.Accessibility.RegisterEnabledDisabledSignalHandler(enabledSignalHandler, disabledSignalHandler);
+            Interop.Accessibility.RegisterScreenReaderEnabledDisabledSignalHandler(screenReaderEnabledSignalHandler, screenReaderDisabledSignalHandler);
         }
+        #endregion Constructor
+
+        #region Property
         /// <summary>
-        /// destructor. This is HiddenAPI. recommended not to use in public.
+        /// Flag to check whether the state of Accessibility is enabled or not.
         /// </summary>
-        ~Accessibility()
+        /// <remarks>
+        /// Getter returns true if Accessibility is enabled, false otherwise.
+        /// </remarks>
+        /// This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsEnabled
+        {
+            get
+            {
+                return (bool)Interop.Accessibility.IsEnabled();
+            }
+        }
+
+        /// <summary>
+        /// Flag to check whether the state of Screen Reader is enabled or not.
+        /// </summary>
+        /// <remarks>
+        /// Getter returns true if Screen Reader is enabled, false otherwise.
+        /// </remarks>
+        /// This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool IsScreenReaderEnabled
         {
-            Tizen.Log.Debug("NUI",$"Accessibility is destroyed\n");
+            get
+            {
+                return (bool)Interop.Accessibility.IsScreenReaderEnabled();
+            }
         }
-        #endregion Constructor, Distructor, Dispose
 
+        #endregion Property
 
-        #region Property
+        #region Method
         /// <summary>
-        /// Instance for singleton
+        /// Start to speak
         /// </summary>
+        /// <param name="sentence">Content to be spoken</param>
+        /// <param name="discardable">true to be stopped and discarded when other Say is triggered</param>
+        /// <returns></returns>
         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public static Accessibility Instance
+        public static bool Say(string sentence, bool discardable)
         {
-            get => _accessibility;
+            bool ret = Interop.Accessibility.Say(sentence, discardable, Marshal.GetFunctionPointerForDelegate<Delegate>(callback));
+
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            return ret;
         }
-        #endregion Property
 
+        /// <summary>
+        /// To make Say be paused or resumed
+        /// </summary>
+        /// <param name="pause">true to be paused, false to be resumed</param>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void PauseResume(bool pause)
+        {
+            Interop.Accessibility.PauseResume(pause);
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
 
-        #region Method
         /// <summary>
-        /// Get the current status
+        /// Cancels anything screen-reader is reading / has queued to read
         /// </summary>
-        /// <returns>Current enabled status</returns>
+        /// <param name="alsoNonDiscardable">whether to cancel non-discardable readings as well</param>
         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
         [EditorBrowsable(EditorBrowsableState.Never)]
-        static public bool GetStatus()
+        public static void StopReading(bool alsoNonDiscardable)
         {
-            return true;
+            Interop.Accessibility.StopReading(alsoNonDiscardable);
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
         /// <summary>
-        /// Start to speak
+        /// Suppress reading of screen-reader
         /// </summary>
-        /// <param name="sentence">Content to be spoken</param>
-        /// <param name="discardable">true to be stopped and discarded when other Say is triggered</param>
-        /// <returns></returns>
+        /// <param name="suppress">whether to suppress reading of screen-reader</param>
         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public bool Say(string sentence, bool discardable)
+        public static bool SuppressScreenReader(bool suppress)
         {
-            IntPtr callbackIntPtr = IntPtr.Zero;
-            if (_sayFinishedEventHandler != null)
-            {
-                callback = _sayFinishedEventCallback;
-                callbackIntPtr = Marshal.GetFunctionPointerForDelegate<Delegate>(callback);
-            }
-            bool ret = Interop.Accessibility.Say(View.getCPtr(dummy), sentence, discardable, callbackIntPtr);
+            bool ret = Interop.Accessibility.SuppressScreenReader(suppress);
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             return ret;
         }
 
         /// <summary>
-        /// To make Say be paused or resumed
+        /// Re-enables auto-initialization of AT-SPI bridge
+        /// </summary>
+        /// <remarks>
+        /// Normal applications do not have to call this function. The AT-SPI bridge is initialized on demand.
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void BridgeEnableAutoInit()
+        {
+            Interop.Accessibility.BridgeEnableAutoInit();
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        /// <summary>
+        /// Blocks auto-initialization of AT-SPI bridge
+        /// </summary>
+        /// <remarks>
+        /// Use this only if your application starts before DBus does, and call it early in Main().
+        /// When DBus is ready, call BridgeEnableAutoInit().
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void BridgeDisableAutoInit()
+        {
+            Interop.Accessibility.BridgeDisableAutoInit();
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        /// <summary>
+        ///  Get View that is used to highlight widget.
         /// </summary>
-        /// <param name="pause">true to be paused, false to be resumed</param>
         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public void PauseResume(bool pause)
+        public static View GetHighlightFrameView()
         {
-            Interop.Accessibility.PauseResume(View.getCPtr(dummy), pause);
+            var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetHighlightActor();
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            if (ptr == IntPtr.Zero)
+                return null;
+            return new View(ptr, true);
         }
-        #endregion Method
 
+        /// <summary>
+        ///  Set view that will be used to highlight widget.
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void SetHighlightFrameView(View view)
+        {
+            Interop.ControlDevel.DaliAccessibilityAccessibleSetHighlightActor(View.getCPtr(view));
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
 
-        #region Event, Enum, Struct, ETC
         /// <summary>
-        ///  Say Finished event arguments
+        ///  Get highligted View.
         /// </summary>
         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public class SayFinishedEventArgs : EventArgs
+        public static View GetCurrentlyHighlightedView()
         {
-            /// <summary>
-            /// The state of Say finished
-            /// </summary>
-            // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            public SayFinishedStates State
-            {
-                private set;
-                get;
-            }
+            var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetCurrentlyHighlightedActor();
 
-            internal SayFinishedEventArgs(int result)
-            {
-                State = (SayFinishedStates)(result);
-                tlog.Fatal(tag, $"SayFinishedEventArgs Constructor! State={State}");
-            }
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+
+            return dummyHandle.GetInstanceSafely<View>(ptr);
         }
 
         /// <summary>
+        ///  Clear highlight.
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static bool ClearCurrentlyHighlightedView()
+        {
+            var view = GetCurrentlyHighlightedView();
+
+            return view?.ClearAccessibilityHighlight() ?? false;
+        }
+        #endregion Method
+
+
+        #region Event, Enum, Struct, ETC
+        /// <summary>
         /// Enum of Say finished event argument status
         /// </summary>
         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public enum SayFinishedStates
+        public enum SayFinishedState
         {
             /// <summary>
             /// Invalid
@@ -167,7 +261,19 @@ namespace Tizen.NUI.Accessibility
             /// </summary>
             // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
             [EditorBrowsable(EditorBrowsableState.Never)]
-            Skipped = 3
+            Skipped = 3,
+            /// <summary>
+            /// Paused
+            /// </summary>
+            // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            Paused = 4,
+            /// <summary>
+            /// Resumed
+            /// </summary>
+            // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            Resumed = 5
         }
 
         /// <summary>
@@ -175,55 +281,86 @@ namespace Tizen.NUI.Accessibility
         /// </summary>
         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public event EventHandler<SayFinishedEventArgs> SayFinished
-        {
-            add => _sayFinishedEventHandler += value;
-            remove => _sayFinishedEventHandler -= value;
-        }
-        #endregion Event, Enum, Struct, ETC
+        public static event EventHandler<SayFinishedEventArgs> SayFinished;
 
+        /// <summary>
+        /// Triggered whenever the value of IsEnabled would change from false to true
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static event EventHandler Enabled;
 
-        #region Internal
-        internal void PauseResume(View target, bool pause)
-        {
-            Interop.Accessibility.PauseResume(View.getCPtr(target), pause);
-            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-        }
+        /// <summary>
+        /// Triggered whenever the value of IsEnabled would change from true to false
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static event EventHandler Disabled;
 
-        internal bool Say(View target, string sentence, bool discardable)
-        {
-            IntPtr callbackIntPtr = IntPtr.Zero;
-            if (_sayFinishedEventHandler != null)
-            {
-                callback = _sayFinishedEventCallback;
-                callbackIntPtr = Marshal.GetFunctionPointerForDelegate<Delegate>(callback);
-            }
-            bool ret = Interop.Accessibility.Say(View.getCPtr(target), sentence, discardable, callbackIntPtr);
-            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-            return ret;
-        }
-        #endregion Internal
+        /// <summary>
+        /// Triggered whenever the value of IsScreenReaderEnabled would change from false to true
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static event EventHandler ScreenReaderEnabled;
 
+        /// <summary>
+        /// Triggered whenever the value of IsScreenReaderEnabled would change from true to false
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static event EventHandler ScreenReaderDisabled;
+
+        #endregion Event, Enum, Struct, ETC
 
         #region Private
-        private static readonly Accessibility _accessibility = new Accessibility();
 
-        private event EventHandler<SayFinishedEventArgs> _sayFinishedEventHandler;
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        private delegate void SayFinishedEventCallbackType(int result);
 
-        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
-        private delegate void _sayFinishedEventCallbackType(int result);
+        private static SayFinishedEventCallbackType callback = SayFinishedEventCallback;
 
-        private _sayFinishedEventCallbackType callback = null;
+        private static Interop.Accessibility.EnabledDisabledSignalHandler enabledSignalHandler = null;
 
-        private void _sayFinishedEventCallback(int result)
+        private static Interop.Accessibility.EnabledDisabledSignalHandler disabledSignalHandler = null;
+
+        private static Interop.Accessibility.EnabledDisabledSignalHandler screenReaderEnabledSignalHandler = null;
+
+        private static Interop.Accessibility.EnabledDisabledSignalHandler screenReaderDisabledSignalHandler = null;
+
+        private static void SayFinishedEventCallback(int result)
         {
-            tlog.Fatal(tag, $"_sayFinishedEventCallback(res={result}) called!");
-            _sayFinishedEventHandler?.Invoke(this, new SayFinishedEventArgs(result));
+            NUILog.Debug($"sayFinishedEventCallback(res={result}) called!");
+            SayFinished?.Invoke(typeof(Accessibility), new SayFinishedEventArgs(result));
         }
 
-        private View dummy;
+        private static BaseHandle dummyHandle = new BaseHandle();
 
-        private static string tag = "NUITEST";
         #endregion Private
     }
+
+    /// <summary>
+    ///  Say Finished event arguments
+    /// </summary>
+    // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class SayFinishedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// The state of Say finished
+        /// </summary>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Accessibility.SayFinishedState State
+        {
+            private set;
+            get;
+        }
+
+        internal SayFinishedEventArgs(int result)
+        {
+            State = (Accessibility.SayFinishedState)(result);
+            NUILog.Debug($"SayFinishedEventArgs Constructor! State={State}");
+        }
+    }
 }