[NUI][AT-SPI] Fix Accessibility.Say interop (#5612)
authorArtur Świgoń <aswigon@yandex.com>
Mon, 16 Oct 2023 09:31:42 +0000 (11:31 +0200)
committerEunki Hong <h.pichulia@gmail.com>
Wed, 25 Oct 2023 12:48:44 +0000 (21:48 +0900)
This is one of the oldest interops and was actually problematic for
multiple reasons; the return type didn't match and the third parameter
was expected to have exactly the same value in every invocation. While
fixing these issues, parsing the status string was moved from C++ to C#
for readability.

Co-authored-by: Artur Świgoń <a.swigon@samsung.com>
src/Tizen.NUI/src/internal/Interop/Interop.Accessibility.cs
src/Tizen.NUI/src/public/Accessibility/Accessibility.cs

index f296e1f..4ef8e47 100755 (executable)
@@ -24,9 +24,11 @@ namespace Tizen.NUI
     {
         internal static partial class Accessibility
         {
+            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+            public delegate void SayCallback(string status);
+
             [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_say")]
-            [return: MarshalAs(UnmanagedType.U1)]
-            public static extern bool Say(string jarg1, bool jarg2, IntPtr jarg3);
+            public static extern void Say(string arg1_text, bool arg2_discardable, SayCallback arg3_callback);
 
             [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_pause_resume")]
             public static extern void PauseResume(bool jarg1);
index 77ac711..425c3bc 100755 (executable)
  */
 
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
 using System.Runtime.InteropServices;
 using Tizen.NUI.BaseComponents;
-using System.Diagnostics.CodeAnalysis;
 
 namespace Tizen.NUI.Accessibility
 {
@@ -105,12 +106,10 @@ namespace Tizen.NUI.Accessibility
         /// <returns></returns>
         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public static bool Say(string sentence, bool discardable)
+        public static void Say(string sentence, bool discardable)
         {
-            bool ret = Interop.Accessibility.Say(sentence, discardable, Marshal.GetFunctionPointerForDelegate<Delegate>(callback));
-
+            Interop.Accessibility.Say(sentence, discardable, SayFinishedEventCallback);
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-            return ret;
         }
 
         /// <summary>
@@ -314,12 +313,6 @@ namespace Tizen.NUI.Accessibility
         #endregion Event, Enum, Struct, ETC
 
         #region Private
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        private delegate void SayFinishedEventCallbackType(int result);
-
-        private static SayFinishedEventCallbackType callback = SayFinishedEventCallback;
-
         private static Interop.Accessibility.EnabledDisabledSignalHandler enabledSignalHandler = null;
 
         private static Interop.Accessibility.EnabledDisabledSignalHandler disabledSignalHandler = null;
@@ -328,9 +321,20 @@ namespace Tizen.NUI.Accessibility
 
         private static Interop.Accessibility.EnabledDisabledSignalHandler screenReaderDisabledSignalHandler = null;
 
-        private static void SayFinishedEventCallback(int result)
+        private static readonly IReadOnlyDictionary<string, SayFinishedState> sayFinishedStateDictionary = new Dictionary<string, SayFinishedState>
         {
+            ["ReadingCancelled"] = SayFinishedState.Cancelled,
+            ["ReadingStopped"] = SayFinishedState.Stopped,
+            ["ReadingSkipped"] = SayFinishedState.Skipped,
+            ["ReadingPaused"] = SayFinishedState.Paused,
+            ["ReadingResumed"] = SayFinishedState.Resumed,
+        };
+
+        private static void SayFinishedEventCallback(string status)
+        {
+            var result = sayFinishedStateDictionary.GetValueOrDefault(status, SayFinishedState.Invalid);
             NUILog.Debug($"sayFinishedEventCallback(res={result}) called!");
+
             SayFinished?.Invoke(typeof(Accessibility), new SayFinishedEventArgs(result));
         }
 
@@ -357,9 +361,9 @@ namespace Tizen.NUI.Accessibility
             get;
         }
 
-        internal SayFinishedEventArgs(int result)
+        internal SayFinishedEventArgs(Accessibility.SayFinishedState state)
         {
-            State = (Accessibility.SayFinishedState)(result);
+            State = state;
             NUILog.Debug($"SayFinishedEventArgs Constructor! State={State}");
         }
     }