[NUI][AT-SPI] Store AccessibilityAttributes in NUI (#4389)
authorArtur Świgoń <aswigon@yandex.com>
Fri, 8 Jul 2022 09:44:15 +0000 (11:44 +0200)
committerJaehyun Cho <jaehyun0cho@gmail.com>
Tue, 12 Jul 2022 02:41:27 +0000 (11:41 +0900)
Having a modifiable attribute dictionary in NUI removes the performance
penalty of having to go through interops on every modification. A new
override for GetAttributes in NUIViewAccessible will now collect the
attributes stored in NUI.

Co-authored-by: Artur Świgoń <a.swigon@samsung.com>
src/Tizen.NUI.Components/Controls/AlertDialog.cs
src/Tizen.NUI.Components/Controls/Dialog.cs
src/Tizen.NUI.Components/Controls/Menu.cs
src/Tizen.NUI.Components/Controls/Pagination.cs
src/Tizen.NUI.Components/Controls/Popup.cs
src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs
src/Tizen.NUI/src/public/BaseComponents/CustomView.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityProperties.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs

index 754c88a..26a4b46 100755 (executable)
@@ -472,7 +472,7 @@ namespace Tizen.NUI.Components
         {
             base.OnInitialize();
             AccessibilityRole = Role.Dialog;
-            AppendAccessibilityAttribute("sub-role", "Alert");
+            AccessibilityAttributes["sub-role"] = "Alert";
             Show(); // calls RegisterDefaultLabel(); Hide() will call UnregisterDefaultLabel()
         }
 
index 00fce27..7ba4cb6 100755 (executable)
@@ -134,7 +134,7 @@ namespace Tizen.NUI.Components
         {
             base.OnInitialize();
             AccessibilityRole = Role.Dialog;
-            AppendAccessibilityAttribute("sub-role", "Alert");
+            AccessibilityAttributes["sub-role"] = "Alert";
             Show(); // calls RegisterDefaultLabel(); Hide() will call UnregisterDefaultLabel()
         }
 
index b3851ca..29e2214 100755 (executable)
@@ -697,7 +697,7 @@ namespace Tizen.NUI.Components
         {
             base.OnInitialize();
             AccessibilityRole = Role.PopupMenu;
-            AppendAccessibilityAttribute("sub-role", "Alert");
+            AccessibilityAttributes["sub-role"] = "Alert";
         }
 
         /// <summary>
index ad914bc..5e6e78c 100755 (executable)
@@ -512,7 +512,7 @@ namespace Tizen.NUI.Components
             base.OnInitialize();
             AccessibilityRole = Role.ScrollBar;
             AccessibilityHighlightable = true;
-            AppendAccessibilityAttribute("style", "pagecontrolbyvalue");
+            AccessibilityAttributes["style"] = "pagecontrolbyvalue";
 
             container = new View()
             {
index 2ebe2ab..e76fb5a 100755 (executable)
@@ -783,7 +783,7 @@ namespace Tizen.NUI.Components
         {
             base.OnInitialize();
             AccessibilityRole = Role.Dialog;
-            AppendAccessibilityAttribute("sub-role", "Alert");
+            AccessibilityAttributes["sub-role"] = "Alert";
 
             container.Add(this);
             container.SetTouchConsumed(true);
index 1879c7d..22a02d5 100755 (executable)
@@ -84,18 +84,6 @@ namespace Tizen.NUI
             public static extern void DaliToolkitDevelControlClearAccessibilityRelations(HandleRef arg1);
 
             [EditorBrowsable(EditorBrowsableState.Never)]
-            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Toolkit_DevelControl_AppendAccessibilityAttribute")]
-            public static extern void DaliToolkitDevelControlAppendAccessibilityAttribute(HandleRef arg1, string arg2, string arg3);
-
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Toolkit_DevelControl_RemoveAccessibilityAttribute")]
-            public static extern void DaliToolkitDevelControlRemoveAccessibilityAttribute(HandleRef arg1, string arg2);
-
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Toolkit_DevelControl_ClearAccessibilityAttributes")]
-            public static extern void DaliToolkitDevelControlClearAccessibilityAttributes(HandleRef arg1);
-
-            [EditorBrowsable(EditorBrowsableState.Never)]
             [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Toolkit_DevelControl_SetAccessibilityReadingInfoType2")]
             public static extern void DaliToolkitDevelControlSetAccessibilityReadingInfoTypes(HandleRef arg1, int arg2);
 
@@ -387,6 +375,14 @@ namespace Tizen.NUI
                 public delegate IntPtr AccessibilityGetRangeExtents(IntPtr self, int startOffset, int endOffset, int coordType);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetRangeExtents GetRangeExtents; // 36
+
+                [EditorBrowsable(EditorBrowsableState.Never)]
+                [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+                public delegate void AccessibilityGetAttributesCallback(string key, string value, IntPtr userData);
+                [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+                public delegate void AccessibilityGetAttributes(IntPtr self, AccessibilityGetAttributesCallback callback, IntPtr userData);
+                [EditorBrowsable(EditorBrowsableState.Never)]
+                public AccessibilityGetAttributes GetAttributes; // 37
             }
 
             [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Accessibility_DuplicateString")]
index 972bdd8..92edb87 100755 (executable)
@@ -146,7 +146,6 @@ namespace Tizen.NUI.BaseComponents
         public virtual void OnInitialize()
         {
             AccessibilityRole = Role.Unknown;
-            AppendAccessibilityAttribute("class", this.GetType().Name);
         }
 
         /// <summary>
index 461c496..2bf62df 100755 (executable)
@@ -56,40 +56,10 @@ namespace Tizen.NUI.BaseComponents
         ///////////////////////////////////////////////////////////////////
 
         /// <summary>
-        /// Adds or modifies the value matched with given key.
+        /// Dictionary of accessibility attributes (key-value pairs of strings).
         /// </summary>
-        /// <remarks>
-        /// Modification takes place if key was previously set.
-        /// </remarks>
-        /// <param name="key">The key to insert</param>
-        /// <param name="value">The value to insert</param>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public void AppendAccessibilityAttribute(string key, string value)
-        {
-            Interop.ControlDevel.DaliToolkitDevelControlAppendAccessibilityAttribute(SwigCPtr, key, value);
-            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-        }
-
-        /// <summary>
-        /// Erases a key with its value from accessibility attributes.
-        /// </summary>
-        /// <param name="key">The key to remove</param>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public void RemoveAccessibilityAttribute(string key)
-        {
-            Interop.ControlDevel.DaliToolkitDevelControlRemoveAccessibilityAttribute(SwigCPtr, key);
-            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-        }
-
-        /// <summary>
-        /// Clears accessibility attributes.
-        /// </summary>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public void ClearAccessibilityAttributes()
-        {
-            Interop.ControlDevel.DaliToolkitDevelControlClearAccessibilityAttributes(SwigCPtr);
-            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-        }
+        protected Dictionary<string, string> AccessibilityAttributes { get; } = new Dictionary<string, string>();
 
         ///////////////////////////////////////////////////////////////////
         // ************************** Highlight ************************ //
index b738c15..5eb7340 100755 (executable)
@@ -160,7 +160,7 @@ namespace Tizen.NUI.BaseComponents
             set
             {
                 base.AutomationId = value;
-                AppendAccessibilityAttribute("automationId", value);
+                AccessibilityAttributes["automationId"] = value;
             }
         }
     }
index e4a86e0..f867cec 100644 (file)
@@ -87,6 +87,7 @@ namespace Tizen.NUI.BaseComponents
             var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
 
             ad.CalculateStates = AccessibilityCalculateStatesWrapper;
+            ad.GetAttributes   = AccessibilityGetAttributes; // Not a wrapper, entirely private implementation
             ad.GetDescription  = AccessibilityGetDescriptionWrapper;
             ad.GetInterfaces   = AccessibilityGetInterfaces; // Not a wrapper, entirely private implementation
             ad.GetName         = AccessibilityGetNameWrapper;
@@ -97,7 +98,7 @@ namespace Tizen.NUI.BaseComponents
             View view = GetViewFromRefObject(self);
             if (view == null)
                 return 0UL;
-            
+
             ulong bitMask = 0UL;
 
             lock (AccessibilityInitialStates)
@@ -110,6 +111,23 @@ namespace Tizen.NUI.BaseComponents
             return bitMask;
         }
 
+        private static void AccessibilityGetAttributes(IntPtr self, Interop.ControlDevel.AccessibilityDelegate.AccessibilityGetAttributesCallback callback, IntPtr userData)
+        {
+            var view = GetViewFromRefObject(self);
+            var attributes = view.AccessibilityAttributes;
+            var classKey = "class";
+
+            if (!attributes.ContainsKey(classKey))
+            {
+                attributes[classKey] = view.GetType().Name;
+            }
+
+            foreach (var attribute in attributes)
+            {
+                callback(attribute.Key, attribute.Value, userData);
+            }
+        }
+
         private static IntPtr AccessibilityGetDescriptionWrapper(IntPtr self)
         {
             string description = GetViewFromRefObject(self).AccessibilityGetDescription();