X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2FTizen.NUI%2Fsrc%2Fpublic%2FAccessibility%2FAccessibility.cs;h=77ac71117af35500e04f673d7cc835ba0c75d65b;hb=8024def7eb53ab6c88704ac719a607ff7ab7f396;hp=7631c62cae5fedb3c678cd9e2f77c2d636c2572f;hpb=2b76b598e86f61c2b1e195c24dc7ccfc93c423f3;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git diff --git a/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs b/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs index 7631c62..77ac711 100755 --- a/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs +++ b/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs @@ -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. @@ -15,133 +15,228 @@ * */ -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 { /// - /// 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 /// // 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 /// - /// destructor. This is HiddenAPI. recommended not to use in public. + /// Flag to check whether the state of Accessibility is enabled or not. /// - ~Accessibility() + /// + /// Getter returns true if Accessibility is enabled, false otherwise. + /// + /// 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(); + } + } + + /// + /// Flag to check whether the state of Screen Reader is enabled or not. + /// + /// + /// Getter returns true if Screen Reader is enabled, false otherwise. + /// + /// 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 /// - /// Instance for singleton + /// Start to speak /// + /// Content to be spoken + /// true to be stopped and discarded when other Say is triggered + /// // 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(callback)); + + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + return ret; } - #endregion Property + /// + /// To make Say be paused or resumed + /// + /// true to be paused, false to be resumed + // 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 /// - /// Get the current status + /// Cancels anything screen-reader is reading / has queued to read /// - /// Current enabled status + /// whether to cancel non-discardable readings as well // 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(); } /// - /// Start to speak + /// Suppress reading of screen-reader /// - /// Content to be spoken - /// true to be stopped and discarded when other Say is triggered - /// + /// whether to suppress reading of screen-reader // 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(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; } /// - /// To make Say be paused or resumed + /// Re-enables auto-initialization of AT-SPI bridge + /// + /// + /// Normal applications do not have to call this function. The AT-SPI bridge is initialized on demand. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void BridgeEnableAutoInit() + { + Interop.Accessibility.BridgeEnableAutoInit(); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Blocks auto-initialization of AT-SPI bridge + /// + /// + /// Use this only if your application starts before DBus does, and call it early in Main(). + /// When DBus is ready, call BridgeEnableAutoInit(). + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static void BridgeDisableAutoInit() + { + Interop.Accessibility.BridgeDisableAutoInit(); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); + } + + /// + /// Get View that is used to highlight widget. /// - /// true to be paused, false to be resumed // 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 + /// + /// Set view that will be used to highlight widget. + /// + // 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 /// - /// Say Finished event arguments + /// Get highligted View. /// // 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() { - /// - /// The state of Say finished - /// - // 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(ptr); } /// + /// Clear highlight. + /// + // 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 + /// /// Enum of Say finished event argument status /// // 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 { /// /// Invalid @@ -166,7 +261,19 @@ namespace Tizen.NUI.Accessibility /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - Skipped = 3 + Skipped = 3, + /// + /// Paused + /// + // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) + [EditorBrowsable(EditorBrowsableState.Never)] + Paused = 4, + /// + /// Resumed + /// + // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) + [EditorBrowsable(EditorBrowsableState.Never)] + Resumed = 5 } /// @@ -174,55 +281,86 @@ namespace Tizen.NUI.Accessibility /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public event EventHandler SayFinished - { - add => _sayFinishedEventHandler += value; - remove => _sayFinishedEventHandler -= value; - } - #endregion Event, Enum, Struct, ETC + public static event EventHandler SayFinished; + /// + /// Triggered whenever the value of IsEnabled would change from false to true + /// + // 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(); - } + /// + /// Triggered whenever the value of IsEnabled would change from true to false + /// + // 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(callback); - } - bool ret = Interop.Accessibility.Say(View.getCPtr(target), sentence, discardable, callbackIntPtr); - if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); - return ret; - } - #endregion Internal + /// + /// Triggered whenever the value of IsScreenReaderEnabled would change from false to true + /// + // 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; + /// + /// Triggered whenever the value of IsScreenReaderEnabled would change from true to false + /// + // 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 _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 } + + /// + /// Say Finished event arguments + /// + // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) + [EditorBrowsable(EditorBrowsableState.Never)] + public class SayFinishedEventArgs : EventArgs + { + /// + /// The state of Say finished + /// + // 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}"); + } + } }