目录

Integrating Accessibility Through Custom Drawing

For third-party framework platforms that are accessed through custom drawing, the NDK provides functions for interoperability with accessibility services, enabling third-party framework components to support basic accessibility features in ArkUI. These include focus acquisition, accessibility node retrieval, and operation response.

Since API version 13, the self-drawing integration method based on XComponent is supported.

Since API version 23, the self-drawing integration method that builds a rendering node tree based on CustomNode is supported.

A third-party framework obtains the ArkUI_AccessibilityProvider from the drawing container component, adapts to the operation Action sent by the accessibility system by implementing the callback function for accessibility interconnection, and sends the accessibility event Event to the accessibility subsystem based on the component interaction behavior. In this way, the interaction experience of the accessibility application is implemented.

In the self-drawing mode based on XComponent, use OH_NativeXComponent_GetNativeAccessibilityProvider to obtain ArkUI_AccessibilityProvider for accessibility integration.

If you build a rendering node tree based on CustomNode, use OH_ArkUI_NativeModule_GetNativeAccessibilityProvider to obtain ArkUI_AccessibilityProvider for accessibility integration.

To support a single instance, use OH_ArkUI_AccessibilityProviderRegisterCallback to register the necessary callback function ArkUI_AccessibilityProviderCallbacks for accessibility integration.

For multi-instance scenarios, register callback functions ArkUI_AccessibilityProviderCallbacksWithInstance using OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance.

Integrating Accessibility Through Custom Drawing Based on XComponent

This example demonstrates accessibility integration. For the complete implementation, see AccessibilityCapiSample. Once integrated, third-party framework components in XComponent will support accessibility interactions when accessibility features are enabled.

  1. Create a project based on OH_ArkUI_SurfaceHolder for surface lifecycle management in custom rendering (XComponent).

  2. Obtain the accessibility Provider and register callbacks (the following uses the multi-instance scenario as an example).

    #include <arkui/native_interface_accessibility.h>
    #include <string>
    #include "common/common.h"
    // For details about the complete implementation, see AccessibilityCapiSample.
    #include "fakenode/fake_node.h"
    // For details about the complete implementation, see AccessibilityCapiSample.
    #include "AccessibilityManager.h"
    
    // ...
    AccessibilityManager::AccessibilityManager()
    {
    // Multi-instance scenario
        accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosById = FindAccessibilityNodeInfosById;
        accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosByText = FindAccessibilityNodeInfosByText;
        accessibilityProviderCallbacksWithInstance_.findFocusedAccessibilityNode = FindFocusedAccessibilityNode;
        accessibilityProviderCallbacksWithInstance_.findNextFocusAccessibilityNode = FindNextFocusAccessibilityNode;
        accessibilityProviderCallbacksWithInstance_.executeAccessibilityAction = ExecuteAccessibilityAction;
        accessibilityProviderCallbacksWithInstance_.clearFocusedFocusAccessibilityNode = ClearFocusedFocusAccessibilityNode;
        accessibilityProviderCallbacksWithInstance_.getAccessibilityNodeCursorPosition = GetAccessibilityNodeCursorPosition;
    // Single-instance scenario
        accessibilityProviderCallbacks_.findAccessibilityNodeInfosById = FindAccessibilityNodeInfosById;
        accessibilityProviderCallbacks_.findAccessibilityNodeInfosByText = FindAccessibilityNodeInfosByText;
        accessibilityProviderCallbacks_.findFocusedAccessibilityNode = FindFocusedAccessibilityNode;
        accessibilityProviderCallbacks_.findNextFocusAccessibilityNode = FindNextFocusAccessibilityNode;
        accessibilityProviderCallbacks_.executeAccessibilityAction = ExecuteAccessibilityAction;
        accessibilityProviderCallbacks_.clearFocusedFocusAccessibilityNode = ClearFocusedFocusAccessibilityNode;
        accessibilityProviderCallbacks_.getAccessibilityNodeCursorPosition = GetAccessibilityNodeCursorPosition;
    }
    
    void AccessibilityManager::Initialize(const std::string &id, OH_NativeXComponent *nativeXComponent)
    {
        int32_t ret = OH_NativeXComponent_GetNativeAccessibilityProvider(nativeXComponent, &provider);
        if (provider == nullptr) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_PRINT_TEXT, "get provider is null");
            return;
        }
        // 2. Register callbacks.
        ret = OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance(id.c_str(), provider,
            &accessibilityProviderCallbacksWithInstance_);
        if (ret != 0) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, LOG_PRINT_TEXT,
                         "OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance failed");
            return;
        }
        g_provider = provider;
    }
    
    // ...
  3. Third-party frameworks must implement the following callbacks:

After the provider is successfully connected using the OH_ArkUI_AccessibilityProviderRegisterCallback or OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance callback, the accessibility function can be enabled.

Integrating Accessibility Through Custom Drawing Based on CustomNode

  • The custom drawing container component based on CustomNode only supports ArkUI_Node whose type is ARKUI_NODE_CUSTOM and that have no other child nodes. The width and height of the drawing container component must not be 0, to avoid being ignored by accessibility applications or causing incorrect handling of the child node tree.

This example demonstrates accessibility integration. For the complete implementation, see AccessibilityCustomCapi. For details about how to implement a callback, see Integrating Accessibility Through Custom Drawing Based on XComponent. After implementing the callback, enable the accessibility function. The third-party framework that builds the rendering node tree based on CustomNode can then integrate with the accessibility service to implement accessibility interaction and information query for the component tree.

  1. Create a pre-integration project by referring to Building a Rendering Node Based on CustomNode.

  2. Obtain the accessibility integration Provider instance, bind the callback to the Provider instance, and complete the registration.

    int32_t AccessibilityMaker::GetAccessibilityProvider(ArkUI_NodeHandle* customNode, const char* id)
    {
        AccessibilityMaker::accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosById =
            FindAccessibilityNodeInfosById;
        AccessibilityMaker::accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosByText =
            FindAccessibilityNodeInfosByText;
        AccessibilityMaker::accessibilityProviderCallbacksWithInstance_.findFocusedAccessibilityNode =
            FindFocusedAccessibilityNode;
        AccessibilityMaker::accessibilityProviderCallbacksWithInstance_.findNextFocusAccessibilityNode =
            FindNextFocusAccessibilityNode;
        AccessibilityMaker::accessibilityProviderCallbacksWithInstance_.executeAccessibilityAction =
            ExecuteAccessibilityAction;
        AccessibilityMaker::accessibilityProviderCallbacksWithInstance_.clearFocusedFocusAccessibilityNode =
            ClearFocusedFocusAccessibilityNode;
        AccessibilityMaker::accessibilityProviderCallbacksWithInstance_.getAccessibilityNodeCursorPosition =
            GetAccessibilityNodeCursorPosition;
    
        // Obtain the accessibility provider provided by the native layer and register the callback.
        OH_ArkUI_NativeModule_GetNativeAccessibilityProvider(customNode, &accessibilityProvider_);
        if (accessibilityProvider_ == nullptr) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "AccessibilityMaker", "accessibilityProvider_ is null");
            return -1;
        }
    
        int32_t ret = OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance(id, accessibilityProvider_,
            &AccessibilityMaker::accessibilityProviderCallbacksWithInstance_);
        if (ret != 0) {
            return ret;
        }
        return 0;
    }
  3. A third-party framework must implement the callback. For details, see Integrating Accessibility Through Custom Drawing Based on XComponent.