[NUI][AT-SPI] Singleton AccessibilityDelegate (#3899)
authorArtur Świgoń <aswigon@yandex.com>
Thu, 17 Feb 2022 10:45:25 +0000 (11:45 +0100)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Tue, 22 Feb 2022 06:15:10 +0000 (15:15 +0900)
Co-authored-by: Artur Świgoń <a.swigon@samsung.com>
src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs
src/Tizen.NUI/src/public/BaseComponents/View.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs
src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs [new file with mode: 0644]

index ee59e07..5ddeac6 100755 (executable)
@@ -184,18 +184,40 @@ namespace Tizen.NUI
             [StructLayout(LayoutKind.Sequential)]
             public class AccessibilityDelegate
             {
+                private AccessibilityDelegate()
+                {
+                }
+
+                [EditorBrowsable(EditorBrowsableState.Never)]
+                public static AccessibilityDelegate Instance { get; } = new AccessibilityDelegate();
+
+                // TODO (C# 9.0):
+                // Replace the following syntax (3 lines of code per field):
+                //
+                //     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+                //     public delegate ReturnType AccessibilityMethodName(IntPtr self, ArgumentTypes...)
+                //     public AccessibilityMethodName MethodName;
+                //
+                // with the function pointer syntax (1 line of code per field):
+                //
+                //     public delegate* unmanaged[Cdecl]<ReturnType, ArgumentTypes...> MethodName;
+                //
+                // This will make it easier to verify that the structures are compatible between C# and C++
+                // when adding new fields (preferably at the end), because the C# syntax will look very similar
+                // to the C++ syntax.
+
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate IntPtr AccessibilityGetName();
+                public delegate IntPtr AccessibilityGetName(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetName GetName; // 1
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate IntPtr AccessibilityGetDescription();
+                public delegate IntPtr AccessibilityGetDescription(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetDescription GetDescription; // 2
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityDoAction(IntPtr name);
+                public delegate bool AccessibilityDoAction(IntPtr self, IntPtr name);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityDoAction DoAction; // 3
 
@@ -204,171 +226,174 @@ namespace Tizen.NUI
                 // calculated by ControlAccessible::CalculateStates are passed here
                 // as a parameter.
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate ulong AccessibilityCalculateStates(ulong states);
+                public delegate ulong AccessibilityCalculateStates(IntPtr self, ulong states);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityCalculateStates CalculateStates; // 4
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate int AccessibilityGetActionCount();
+                public delegate int AccessibilityGetActionCount(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetActionCount GetActionCount; // 5
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate IntPtr AccessibilityGetActionName(int index);
+                public delegate IntPtr AccessibilityGetActionName(IntPtr self, int index);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetActionName GetActionName; // 6
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityShouldReportZeroChildren();
+                public delegate bool AccessibilityShouldReportZeroChildren(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityShouldReportZeroChildren ShouldReportZeroChildren; // 7
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate double AccessibilityGetMinimum();
+                public delegate double AccessibilityGetMinimum(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetMinimum GetMinimum; // 8
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate double AccessibilityGetCurrent();
+                public delegate double AccessibilityGetCurrent(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetCurrent GetCurrent; // 9
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate double AccessibilityGetMaximum();
+                public delegate double AccessibilityGetMaximum(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetMaximum GetMaximum; // 10
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilitySetCurrent(double value);
+                public delegate bool AccessibilitySetCurrent(IntPtr self, double value);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilitySetCurrent SetCurrent; // 11
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate double AccessibilityGetMinimumIncrement();
+                public delegate double AccessibilityGetMinimumIncrement(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetMinimumIncrement GetMinimumIncrement; // 12
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityIsScrollable();
+                public delegate bool AccessibilityIsScrollable(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityIsScrollable IsScrollable; // 13
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate IntPtr AccessibilityGetText(int startOffset, int endOffset);
+                public delegate IntPtr AccessibilityGetText(IntPtr self, int startOffset, int endOffset);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetText GetText; // 14
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate int AccessibilityGetCharacterCount();
+                public delegate int AccessibilityGetCharacterCount(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetCharacterCount GetCharacterCount; // 15
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate int AccessibilityGetCursorOffset();
+                public delegate int AccessibilityGetCursorOffset(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetCursorOffset GetCursorOffset; // 16
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilitySetCursorOffset(int offset);
+                public delegate bool AccessibilitySetCursorOffset(IntPtr self, int offset);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilitySetCursorOffset SetCursorOffset; // 17
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate IntPtr AccessibilityGetTextAtOffset(int offset, int boundary);
+                public delegate IntPtr AccessibilityGetTextAtOffset(IntPtr self, int offset, int boundary);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetTextAtOffset GetTextAtOffset; // 18
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate IntPtr AccessibilityGetSelection(int selectionNum);
+                public delegate IntPtr AccessibilityGetSelection(IntPtr self, int selectionNum);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetSelection GetSelection; // 19
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityRemoveSelection(int selectionNum);
+                public delegate bool AccessibilityRemoveSelection(IntPtr self, int selectionNum);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityRemoveSelection RemoveSelection; // 20
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilitySetSelection(int selectionNum, int startOffset, int endOffset);
+                public delegate bool AccessibilitySetSelection(IntPtr self, int selectionNum, int startOffset, int endOffset);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilitySetSelection SetSelection; // 21
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityCopyText(int startPosition, int endPosition);
+                public delegate bool AccessibilityCopyText(IntPtr self, int startPosition, int endPosition);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityCopyText CopyText; // 22
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityCutText(int startPosition, int endPosition);
+                public delegate bool AccessibilityCutText(IntPtr self, int startPosition, int endPosition);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityCutText CutText; // 23
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityInsertText(int startPosition, IntPtr text);
+                public delegate bool AccessibilityInsertText(IntPtr self, int startPosition, IntPtr text);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityInsertText InsertText; // 24
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilitySetTextContents(IntPtr newContents);
+                public delegate bool AccessibilitySetTextContents(IntPtr self, IntPtr newContents);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilitySetTextContents SetTextContents; // 25
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityDeleteText(int startPosition, int endPosition);
+                public delegate bool AccessibilityDeleteText(IntPtr self, int startPosition, int endPosition);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityDeleteText DeleteText; // 26
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityScrollToChild(IntPtr child);
+                public delegate bool AccessibilityScrollToChild(IntPtr self, IntPtr child);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityScrollToChild ScrollToChild; // 27
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate int AccessibilityGetSelectedChildrenCount();
+                public delegate int AccessibilityGetSelectedChildrenCount(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetSelectedChildrenCount GetSelectedChildrenCount; // 28
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate IntPtr AccessibilityGetSelectedChild(int selectedChildIndex);
+                public delegate IntPtr AccessibilityGetSelectedChild(IntPtr self, int selectedChildIndex);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityGetSelectedChild GetSelectedChild; // 29
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilitySelectChild(int childIndex);
+                public delegate bool AccessibilitySelectChild(IntPtr self, int childIndex);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilitySelectChild SelectChild; // 30
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityDeselectSelectedChild(int selectedChildIndex);
+                public delegate bool AccessibilityDeselectSelectedChild(IntPtr self, int selectedChildIndex);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityDeselectSelectedChild DeselectSelectedChild; // 31
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityIsChildSelected(int childIndex);
+                public delegate bool AccessibilityIsChildSelected(IntPtr self, int childIndex);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityIsChildSelected IsChildSelected; // 32
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilitySelectAll();
+                public delegate bool AccessibilitySelectAll(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilitySelectAll SelectAll; // 33
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityClearSelection();
+                public delegate bool AccessibilityClearSelection(IntPtr self);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityClearSelection ClearSelection; // 34
 
                 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-                public delegate bool AccessibilityDeselectChild(int childIndex);
+                public delegate bool AccessibilityDeselectChild(IntPtr self, int childIndex);
                 [EditorBrowsable(EditorBrowsableState.Never)]
                 public AccessibilityDeselectChild DeselectChild; // 35
             }
 
             [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Toolkit_DevelControl_SetAccessibilityConstructor_NUI")]
-            public static extern void DaliToolkitDevelControlSetAccessibilityConstructor(HandleRef arg1_self, int arg2_role, int arg3_iface, IntPtr arg4_vtable, int arg5_vtableSize);
+            public static extern void DaliToolkitDevelControlSetAccessibilityConstructor(HandleRef arg1_self, int arg2_role, int arg3_iface);
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Accessibility_DuplicateString")]
+            public static extern IntPtr DaliAccessibilityDuplicateString(string arg);
 
-            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Toolkit_DevelControl_AccessibleImpl_NUI_DuplicateString")]
-            public static extern IntPtr DaliToolkitDevelControlAccessibleImplNUIDuplicateString(string arg);
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Accessibility_SetAccessibilityDelegate")]
+            public static extern IntPtr DaliAccessibilitySetAccessibilityDelegate(IntPtr arg1_accessibilityDelegate, int arg2_accessibilityDelegateSize);
         }
     }
 }
index ae91e16..d4e66d1 100755 (executable)
@@ -84,6 +84,8 @@ namespace Tizen.NUI.BaseComponents
             RegisterPropertyGroup(ScaleXProperty, scalePropertyGroup);
             RegisterPropertyGroup(ScaleYProperty, scalePropertyGroup);
             RegisterPropertyGroup(ScaleZProperty, scalePropertyGroup);
+
+            RegisterAccessibilityDelegate();
         }
 
         /// <summary>
index 0c854a9..c4bd853 100755 (executable)
@@ -452,31 +452,6 @@ namespace Tizen.NUI.BaseComponents
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
-        private IntPtr DuplicateString(string value)
-        {
-            return Interop.ControlDevel.DaliToolkitDevelControlAccessibleImplNUIDuplicateString(value ?? "");
-        }
-
-        private IntPtr DuplicateRange(AccessibilityRange range)
-        {
-            return Interop.ControlDevel.DaliAccessibilityNewRange(range.StartOffset, range.EndOffset, range.Content);
-        }
-
-        private static AccessibilityStates AccessibilityInitialStates = new AccessibilityStates();
-
-        private ulong AccessibilityCalculateStatesWrapper(ulong initialStates)
-        {
-            lock (AccessibilityInitialStates)
-            {
-                AccessibilityInitialStates.BitMask = initialStates;
-
-                return AccessibilityCalculateStates().BitMask;
-            }
-        }
-
-        private Interop.ControlDevel.AccessibilityDelegate accessibilityDelegate = null;
-        private IntPtr accessibilityDelegatePtr;
-
         /// <summary>
         /// Sets the specific constructor for creating accessibility structure with its role and interface.
         /// </summary>
@@ -488,55 +463,7 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         public void SetAccessibilityConstructor(Role role, AccessibilityInterface accessibilityInterface = AccessibilityInterface.None)
         {
-            var size = Marshal.SizeOf<Interop.ControlDevel.AccessibilityDelegate>();
-
-            if (accessibilityDelegate == null)
-            {
-                accessibilityDelegate = new Interop.ControlDevel.AccessibilityDelegate()
-                {
-                    GetName = () => DuplicateString(AccessibilityGetName()),
-                    GetDescription = () => DuplicateString(AccessibilityGetDescription()),
-                    DoAction = (name) => AccessibilityDoAction(Marshal.PtrToStringAnsi(name)),
-                    CalculateStates = (states) => AccessibilityCalculateStatesWrapper(states),
-                    GetActionCount = () => AccessibilityGetActionCount(),
-                    GetActionName = (index) => DuplicateString(AccessibilityGetActionName(index)),
-                    ShouldReportZeroChildren = () => AccessibilityShouldReportZeroChildren(),
-                    GetMinimum = () => AccessibilityGetMinimum(),
-                    GetCurrent = () => AccessibilityGetCurrent(),
-                    GetMaximum = () => AccessibilityGetMaximum(),
-                    SetCurrent = (value) => AccessibilitySetCurrent(value),
-                    GetMinimumIncrement = () => AccessibilityGetMinimumIncrement(),
-                    IsScrollable = () => AccessibilityIsScrollable(),
-                    GetText = (startOffset, endOffset) => DuplicateString(AccessibilityGetText(startOffset, endOffset)),
-                    GetCharacterCount = () => AccessibilityGetCharacterCount(),
-                    GetCursorOffset = () => AccessibilityGetCursorOffset(),
-                    SetCursorOffset = (offset) => AccessibilitySetCursorOffset(offset),
-                    GetTextAtOffset = (offset, boundary) => DuplicateRange(AccessibilityGetTextAtOffset(offset, (AccessibilityTextBoundary)boundary)),
-                    GetSelection = (selectionNumber) => DuplicateRange(AccessibilityGetSelection(selectionNumber)),
-                    RemoveSelection = (selectionNumber) => AccessibilityRemoveSelection(selectionNumber),
-                    SetSelection = (selectionNumber, startOffset, endOffset) => AccessibilitySetSelection(selectionNumber, startOffset, endOffset),
-                    CopyText = (startPosition, endPosition) => AccessibilityCopyText(startPosition, endPosition),
-                    CutText = (startPosition, endPosition) => AccessibilityCutText(startPosition, endPosition),
-                    InsertText = (startPosition, text) => AccessibilityInsertText(startPosition, Marshal.PtrToStringAnsi(text)),
-                    SetTextContents = (newContents) => AccessibilitySetTextContents(Marshal.PtrToStringAnsi(newContents)),
-                    DeleteText = (startPosition, endPosition) => AccessibilityDeleteText(startPosition, endPosition),
-                    ScrollToChild = (child) => AccessibilityScrollToChild(this.GetInstanceSafely<View>(child)),
-                    GetSelectedChildrenCount = () => AccessibilityGetSelectedChildrenCount(),
-                    GetSelectedChild = (selectedChildIndex) => View.getCPtr(AccessibilityGetSelectedChild(selectedChildIndex)).Handle,
-                    SelectChild = (childIndex) => AccessibilitySelectChild(childIndex),
-                    DeselectSelectedChild = (selectedChildIndex) => AccessibilityDeselectSelectedChild(selectedChildIndex),
-                    IsChildSelected = (childIndex) => AccessibilityIsChildSelected(childIndex),
-                    SelectAll = () => AccessibilitySelectAll(),
-                    ClearSelection = () => AccessibilityClearSelection(),
-                    DeselectChild = (childIndex) => AccessibilityDeselectChild(childIndex),
-                };
-
-                accessibilityDelegatePtr = Marshal.AllocHGlobal(size);
-                Marshal.StructureToPtr(accessibilityDelegate, accessibilityDelegatePtr, false);
-            }
-
-            Interop.ControlDevel.DaliToolkitDevelControlSetAccessibilityConstructor(SwigCPtr, (int)role, (int)accessibilityInterface, accessibilityDelegatePtr, size);
-
+            Interop.ControlDevel.DaliToolkitDevelControlSetAccessibilityConstructor(SwigCPtr, (int)role, (int)accessibilityInterface);
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
@@ -563,13 +490,6 @@ namespace Tizen.NUI.BaseComponents
                 Unparent();
             }
 
-            if (accessibilityDelegate != null)
-            {
-                Marshal.DestroyStructure<Interop.ControlDevel.AccessibilityDelegate>(accessibilityDelegatePtr);
-                Marshal.FreeHGlobal(accessibilityDelegatePtr);
-                accessibilityDelegate = null;
-            }
-
             base.Dispose(disposing);
         }
 
diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs
new file mode 100644 (file)
index 0000000..3fbc45c
--- /dev/null
@@ -0,0 +1,377 @@
+/*
+ * Copyright(c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.NUI.BaseComponents
+{
+    public partial class View
+    {
+        private static AccessibilityStates AccessibilityInitialStates = new AccessibilityStates();
+
+        private static void RegisterAccessibilityDelegate()
+        {
+            InitializeAccessibilityDelegateAccessibleInterface();
+            InitializeAccessibilityDelegateActionInterface();
+            InitializeAccessibilityDelegateComponentInterface();
+            InitializeAccessibilityDelegateEditableTextInterface();
+            InitializeAccessibilityDelegateSelectionInterface();
+            InitializeAccessibilityDelegateTextInterface();
+            InitializeAccessibilityDelegateValueInterface();
+            InitializeAccessibilityDelegateTizenExtensions();
+
+            var ad   = Interop.ControlDevel.AccessibilityDelegate.Instance;
+            var size = Marshal.SizeOf<Interop.ControlDevel.AccessibilityDelegate>();
+            var ptr  = Marshal.AllocHGlobal(size);
+
+            Marshal.StructureToPtr(ad, ptr, false);
+            Interop.ControlDevel.DaliAccessibilitySetAccessibilityDelegate(ptr, size);
+        }
+
+        private static View GetViewFromRefObject(IntPtr refObjectPtr)
+        {
+            return Registry.GetManagedBaseHandleFromRefObject(refObjectPtr) as View;
+        }
+
+        private static IntPtr DuplicateString(string value)
+        {
+            return Interop.ControlDevel.DaliAccessibilityDuplicateString(value ?? "");
+        }
+
+        private static IntPtr DuplicateAccessibilityRange(AccessibilityRange range)
+        {
+            return Interop.ControlDevel.DaliAccessibilityNewRange(range.StartOffset, range.EndOffset, range.Content);
+        }
+
+        //
+        // Accessible interface
+        //
+
+        private static void InitializeAccessibilityDelegateAccessibleInterface()
+        {
+            var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
+
+            ad.CalculateStates = AccessibilityCalculateStatesWrapper;
+            ad.GetDescription  = AccessibilityGetDescriptionWrapper;
+            ad.GetName         = AccessibilityGetNameWrapper;
+        }
+
+        private static ulong AccessibilityCalculateStatesWrapper(IntPtr self, ulong initialStates)
+        {
+            View view = GetViewFromRefObject(self);
+            ulong bitMask = 0UL;
+
+            lock (AccessibilityInitialStates)
+            {
+                AccessibilityInitialStates.BitMask = initialStates;
+                bitMask = view.AccessibilityCalculateStates().BitMask;
+                AccessibilityInitialStates.BitMask = 0UL;
+            }
+
+            return bitMask;
+        }
+
+        private static IntPtr AccessibilityGetDescriptionWrapper(IntPtr self)
+        {
+            string description = GetViewFromRefObject(self).AccessibilityGetDescription();
+
+            return DuplicateString(description);
+        }
+
+        private static IntPtr AccessibilityGetNameWrapper(IntPtr self)
+        {
+            string name = GetViewFromRefObject(self).AccessibilityGetName();
+
+            return DuplicateString(name);
+        }
+
+        //
+        // Action interface
+        //
+
+        private static void InitializeAccessibilityDelegateActionInterface()
+        {
+            var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
+
+            ad.DoAction       = AccessibilityDoActionWrapper;
+            ad.GetActionCount = AccessibilityGetActionCountWrapper;
+            ad.GetActionName  = AccessibilityGetActionNameWrapper;
+        }
+
+        private static bool AccessibilityDoActionWrapper(IntPtr self, IntPtr name)
+        {
+            return GetViewFromRefObject(self).AccessibilityDoAction(Marshal.PtrToStringAnsi(name));
+        }
+
+        private static int AccessibilityGetActionCountWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityGetActionCount();
+        }
+
+        private static IntPtr AccessibilityGetActionNameWrapper(IntPtr self, int index)
+        {
+            string name = GetViewFromRefObject(self).AccessibilityGetActionName(index);
+
+            return DuplicateString(name);
+        }
+
+        //
+        // Component interface
+        //
+
+        private static void InitializeAccessibilityDelegateComponentInterface()
+        {
+            var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
+
+            ad.IsScrollable = AccessibilityIsScrollableWrapper;
+        }
+
+        private static bool AccessibilityIsScrollableWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityIsScrollable();
+        }
+
+        //
+        // EditableText interface
+        //
+
+        private static void InitializeAccessibilityDelegateEditableTextInterface()
+        {
+            var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
+
+            ad.CopyText        = AccessibilityCopyTextWrapper;
+            ad.CutText         = AccessibilityCutTextWrapper;
+            ad.DeleteText      = AccessibilityDeleteTextWrapper;
+            ad.InsertText      = AccessibilityInsertTextWrapper;
+            ad.SetTextContents = AccessibilitySetTextContentsWrapper;
+        }
+
+        private static bool AccessibilityCopyTextWrapper(IntPtr self, int startPosition, int endPosition)
+        {
+            return GetViewFromRefObject(self).AccessibilityCopyText(startPosition, endPosition);
+        }
+
+        private static bool AccessibilityCutTextWrapper(IntPtr self, int startPosition, int endPosition)
+        {
+            return GetViewFromRefObject(self).AccessibilityCutText(startPosition, endPosition);
+        }
+
+        private static bool AccessibilityDeleteTextWrapper(IntPtr self, int startPosition, int endPosition)
+        {
+            return GetViewFromRefObject(self).AccessibilityDeleteText(startPosition, endPosition);
+        }
+
+        private static bool AccessibilityInsertTextWrapper(IntPtr self, int startPosition, IntPtr text)
+        {
+            return GetViewFromRefObject(self).AccessibilityInsertText(startPosition, Marshal.PtrToStringAnsi(text));
+        }
+
+        private static bool AccessibilitySetTextContentsWrapper(IntPtr self, IntPtr newContents)
+        {
+            return GetViewFromRefObject(self).AccessibilitySetTextContents(Marshal.PtrToStringAnsi(newContents));
+        }
+
+        //
+        // Selection interface
+        //
+
+        private static void InitializeAccessibilityDelegateSelectionInterface()
+        {
+            var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
+
+            ad.ClearSelection           = AccessibilityClearSelectionWrapper;
+            ad.DeselectChild            = AccessibilityDeselectChildWrapper;
+            ad.DeselectSelectedChild    = AccessibilityDeselectSelectedChildWrapper;
+            ad.GetSelectedChild         = AccessibilityGetSelectedChildWrapper;
+            ad.GetSelectedChildrenCount = AccessibilityGetSelectedChildrenCountWrapper;
+            ad.IsChildSelected          = AccessibilityIsChildSelectedWrapper;
+            ad.SelectAll                = AccessibilitySelectAllWrapper;
+            ad.SelectChild              = AccessibilitySelectChildWrapper;
+        }
+
+        private static bool AccessibilityClearSelectionWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityClearSelection();
+        }
+
+        private static bool AccessibilityDeselectChildWrapper(IntPtr self, int childIndex)
+        {
+            return GetViewFromRefObject(self).AccessibilityDeselectChild(childIndex);
+        }
+
+        private static bool AccessibilityDeselectSelectedChildWrapper(IntPtr self, int selectedChildIndex)
+        {
+            return GetViewFromRefObject(self).AccessibilityDeselectSelectedChild(selectedChildIndex);
+        }
+
+        private static IntPtr AccessibilityGetSelectedChildWrapper(IntPtr self, int selectedChildIndex)
+        {
+            View child = GetViewFromRefObject(self).AccessibilityGetSelectedChild(selectedChildIndex);
+
+            return View.getCPtr(child).Handle;
+        }
+
+        private static int AccessibilityGetSelectedChildrenCountWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityGetSelectedChildrenCount();
+        }
+
+        private static bool AccessibilityIsChildSelectedWrapper(IntPtr self, int childIndex)
+        {
+            return GetViewFromRefObject(self).AccessibilityIsChildSelected(childIndex);
+        }
+
+        private static bool AccessibilitySelectAllWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilitySelectAll();
+        }
+
+        private static bool AccessibilitySelectChildWrapper(IntPtr self, int childIndex)
+        {
+            return GetViewFromRefObject(self).AccessibilitySelectChild(childIndex);
+        }
+
+        //
+        // Text interface
+        //
+
+        private static void InitializeAccessibilityDelegateTextInterface()
+        {
+            var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
+
+            ad.GetCharacterCount = AccessibilityGetCharacterCountWrapper;
+            ad.GetCursorOffset   = AccessibilityGetCursorOffsetWrapper;
+            ad.GetSelection      = AccessibilityGetSelectionWrapper;
+            ad.GetText           = AccessibilityGetTextWrapper;
+            ad.GetTextAtOffset   = AccessibilityGetTextAtOffsetWrapper;
+            ad.RemoveSelection   = AccessibilityRemoveSelectionWrapper;
+            ad.SetCursorOffset   = AccessibilitySetCursorOffsetWrapper;
+            ad.SetSelection      = AccessibilitySetSelectionWrapper;
+        }
+
+        private static int AccessibilityGetCharacterCountWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityGetCharacterCount();
+        }
+
+        private static int AccessibilityGetCursorOffsetWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityGetCursorOffset();
+        }
+
+        private static IntPtr AccessibilityGetSelectionWrapper(IntPtr self, int selectionNumber)
+        {
+            AccessibilityRange range = GetViewFromRefObject(self).AccessibilityGetSelection(selectionNumber);
+
+            return DuplicateAccessibilityRange(range);
+        }
+
+        private static IntPtr AccessibilityGetTextWrapper(IntPtr self, int startOffset, int endOffset)
+        {
+            string text = GetViewFromRefObject(self).AccessibilityGetText(startOffset, endOffset);
+
+            return DuplicateString(text);
+        }
+
+        private static IntPtr AccessibilityGetTextAtOffsetWrapper(IntPtr self, int offset, int boundary)
+        {
+            AccessibilityRange range = GetViewFromRefObject(self).AccessibilityGetTextAtOffset(offset, (AccessibilityTextBoundary)boundary);
+
+            return DuplicateAccessibilityRange(range);
+        }
+
+        private static bool AccessibilityRemoveSelectionWrapper(IntPtr self, int selectionNumber)
+        {
+            return GetViewFromRefObject(self).AccessibilityRemoveSelection(selectionNumber);
+        }
+
+        private static bool AccessibilitySetCursorOffsetWrapper(IntPtr self, int offset)
+        {
+            return GetViewFromRefObject(self).AccessibilitySetCursorOffset(offset);
+        }
+
+        private static bool AccessibilitySetSelectionWrapper(IntPtr self, int selectionNumber, int startOffset, int endOffset)
+        {
+            return GetViewFromRefObject(self).AccessibilitySetSelection(selectionNumber, startOffset, endOffset);
+        }
+
+        //
+        // Value interface
+        //
+
+        private static void InitializeAccessibilityDelegateValueInterface()
+        {
+            var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
+
+            ad.GetCurrent          = AccessibilityGetCurrentWrapper;
+            ad.GetMaximum          = AccessibilityGetMaximumWrapper;
+            ad.GetMinimum          = AccessibilityGetMinimumWrapper;
+            ad.GetMinimumIncrement = AccessibilityGetMinimumIncrementWrapper;
+            ad.SetCurrent          = AccessibilitySetCurrentWrapper;
+        }
+
+        private static double AccessibilityGetCurrentWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityGetCurrent();
+        }
+
+        private static double AccessibilityGetMaximumWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityGetMaximum();
+        }
+
+        private static double AccessibilityGetMinimumWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityGetMinimum();
+        }
+
+        private static double AccessibilityGetMinimumIncrementWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityGetMinimumIncrement();
+        }
+
+        private static bool AccessibilitySetCurrentWrapper(IntPtr self, double value)
+        {
+            return GetViewFromRefObject(self).AccessibilitySetCurrent(value);
+        }
+
+        //
+        // Tizen extensions
+        //
+
+        private static void InitializeAccessibilityDelegateTizenExtensions()
+        {
+            var ad = Interop.ControlDevel.AccessibilityDelegate.Instance;
+
+            ad.ScrollToChild            = AccessibilityScrollToChildWrapper;
+            ad.ShouldReportZeroChildren = AccessibilityShouldReportZeroChildrenWrapper;
+        }
+
+        private static bool AccessibilityScrollToChildWrapper(IntPtr self, IntPtr child)
+        {
+            View view = GetViewFromRefObject(self);
+
+            return view.AccessibilityScrollToChild(view.GetInstanceSafely<View>(child));
+        }
+
+        private static bool AccessibilityShouldReportZeroChildrenWrapper(IntPtr self)
+        {
+            return GetViewFromRefObject(self).AccessibilityShouldReportZeroChildren();
+        }
+    }
+}