[NUI][AT-SPI] Support multiple AT-SPI interfaces for View
authorArtur Świgoń <a.swigon@samsung.com>
Thu, 10 Feb 2022 09:27:12 +0000 (10:27 +0100)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Fri, 4 Mar 2022 05:31:52 +0000 (14:31 +0900)
This patch adds GetInterfaces to AccessibilityDelegate which will allow
to report any number of AT-SPI interfaces in any combinations back to
DALi. Complementary changes to DALi make the AT-SPI bridge use
GetInterfaces instead of dynamic_cast (which stops at the C++ language
boundary).

Note however, that it is not yet possible to declare more than one
AT-SPI interface for a given Control in NUI. There are more changes
needed, such as removing SetAccessibilityConstructor and switching to
native C# interfaces, and they will be done in separate PRs.

src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEnum.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs

index 5ddeac6..29499c5 100755 (executable)
@@ -384,10 +384,15 @@ namespace Tizen.NUI
                 public delegate bool AccessibilityDeselectChild(IntPtr self, int childIndex);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityDeselectChild DeselectChild; // 35
+
+                [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+                public delegate uint AccessibilityGetInterfaces(IntPtr self);
+                [EditorBrowsable(EditorBrowsableState.Never)]
+                public AccessibilityGetInterfaces GetInterfaces; // 36
             }
 
             [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Toolkit_DevelControl_SetAccessibilityConstructor_NUI")]
-            public static extern void DaliToolkitDevelControlSetAccessibilityConstructor(HandleRef arg1_self, int arg2_role, int arg3_iface);
+            public static extern void DaliToolkitDevelControlSetAccessibilityConstructor(HandleRef arg1_self, int arg2_role);
 
             [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Accessibility_DuplicateString")]
             public static extern IntPtr DaliAccessibilityDuplicateString(string arg);
index c4bd853..6388e2f 100755 (executable)
@@ -463,7 +463,9 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public void SetAccessibilityConstructor(Role role, AccessibilityInterface accessibilityInterface = AccessibilityInterface.None)
         {
-            Interop.ControlDevel.DaliToolkitDevelControlSetAccessibilityConstructor(SwigCPtr, (int)role, (int)accessibilityInterface);
+            // We have to store the interface flags until we remove SetAccessibilityConstructor and switch to native C# interfaces
+            AtspiInterfaceFlags = (1U << (int)accessibilityInterface);
+            Interop.ControlDevel.DaliToolkitDevelControlSetAccessibilityConstructor(SwigCPtr, (int)role);
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
index 0da2876..31a19e6 100755 (executable)
@@ -25,6 +25,7 @@ namespace Tizen.NUI.BaseComponents
     /// <summary>
     /// Accessibility interface.
     /// </summary>
+    // Values are from Dali::Accessibility::AtspiInterface
     [EditorBrowsable(EditorBrowsableState.Never)]
     public enum AccessibilityInterface
     {
@@ -37,17 +38,17 @@ namespace Tizen.NUI.BaseComponents
         /// Accessibility interface which can store numeric value
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        Value = 1,
+        Value = 26,
         /// <summary>
         /// Accessibility interface which can store editable texts
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        EditableText = 2,
+        EditableText = 9,
         /// <summary>
         /// Accessibility interface which can store a set of selected items
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        Selection = 3,
+        Selection = 21,
     }
 
     /// <summary>
index 3fbc45c..6dfe09c 100644 (file)
@@ -24,6 +24,9 @@ namespace Tizen.NUI.BaseComponents
     {
         private static AccessibilityStates AccessibilityInitialStates = new AccessibilityStates();
 
+        // To be removed when native C# AT-SPI interfaces are implemented.
+        private uint? AtspiInterfaceFlags = null;
+
         private static void RegisterAccessibilityDelegate()
         {
             InitializeAccessibilityDelegateAccessibleInterface();
@@ -68,6 +71,7 @@ namespace Tizen.NUI.BaseComponents
 
             ad.CalculateStates = AccessibilityCalculateStatesWrapper;
             ad.GetDescription  = AccessibilityGetDescriptionWrapper;
+            ad.GetInterfaces   = AccessibilityGetInterfaces; // Not a wrapper, entirely private implementation
             ad.GetName         = AccessibilityGetNameWrapper;
         }
 
@@ -93,6 +97,29 @@ namespace Tizen.NUI.BaseComponents
             return DuplicateString(description);
         }
 
+        private static uint AccessibilityGetInterfaces(IntPtr self)
+        {
+            // Currently a maximum of one AccessibilityInterface per View is supported.
+            // This will change when we implement AT-SPI interfaces as native C# interfaces.
+            // Then, this method will look like:
+            //
+            // uint flags = 0U;
+            // if (view is IAtspiSelection) flags |= (1U << (int)AccessibilityInterface.Selection)
+            // if (view is IAtspiValue) flags |= (1U << (int)AccessibilityInterface.Value)
+            // ...
+            // return flags;
+
+            View view = GetViewFromRefObject(self);
+
+            if (!view.AtspiInterfaceFlags.HasValue)
+            {
+                NUILog.Error("AtspiInterfaceFlags are not set!");
+                return 0U;
+            }
+
+            return view.AtspiInterfaceFlags.Value;
+        }
+
         private static IntPtr AccessibilityGetNameWrapper(IntPtr self)
         {
             string name = GetViewFromRefObject(self).AccessibilityGetName();