diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index 5972d4aee99239553df92eb69c069d6c293b26ac..cdd348a5dd96297f0e99565e3d0f197a760f3df1 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -6,13 +6,13 @@ #include +#include "flutter/fml/trace_event.h" #include "flutter/lib/ui/compositing/scene.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_message_response_dart.h" #include "flutter/lib/ui/window/platform_message_response_dart_port.h" #include "flutter/lib/ui/window/viewport_metrics.h" #include "flutter/lib/ui/window/window.h" -#include "flutter/fml/trace_event.h" #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/dart_args.h" #include "third_party/tonic/dart_library_natives.h" @@ -118,6 +118,9 @@ void PlatformConfiguration::UpdateLifecycleState(const std::string& data) { void PlatformConfiguration::UpdateSemanticsEnabled(bool enabled) { std::shared_ptr dart_state = update_semantics_enabled_.dart_state().lock(); + FML_DLOG(INFO) + << "PlatformConfiguration::UpdateSemanticsEnabled is called, enabled:" + << enabled; if (!dart_state) { return; } @@ -131,6 +134,9 @@ void PlatformConfiguration::UpdateSemanticsEnabled(bool enabled) { void PlatformConfiguration::UpdateAccessibilityFeatures(int32_t values) { std::shared_ptr dart_state = update_accessibility_features_.dart_state().lock(); + FML_DLOG(INFO) + << "PlatformConfiguration::UpdateAccessibilityFeatures is called, values:" + << values; if (!dart_state) { return; } @@ -145,9 +151,7 @@ void PlatformConfiguration::DispatchPlatformMessage( std::shared_ptr dart_state = dispatch_platform_message_.dart_state().lock(); - FML_DLOG(INFO) - << "DispatchPlatformMessage channel: " - << message->channel(); + FML_DLOG(INFO) << "DispatchPlatformMessage channel: " << message->channel(); if (!dart_state) { FML_DLOG(WARNING) << "Dropping platform message for lack of DartState on channel: " @@ -181,9 +185,7 @@ void PlatformConfiguration::DispatchSemanticsAction(int32_t id, fml::MallocMapping args) { std::shared_ptr dart_state = dispatch_semantics_action_.dart_state().lock(); - FML_DLOG(INFO) - << "DispatchSemanticsAction : " - << id ; + FML_DLOG(INFO) << "PlatformConfiguration::DispatchSemanticsAction : " << id; if (!dart_state) { return; } @@ -361,7 +363,8 @@ Dart_Handle PlatformConfigurationNativeApi::SendPortPlatformMessage( void PlatformConfigurationNativeApi::RespondToPlatformMessage( int response_id, const tonic::DartByteData& data) { - FML_DLOG(INFO)<<"PlatformConfigurationNativeApi::RespondToPlatformMessage:" << response_id; + FML_DLOG(INFO) << "PlatformConfigurationNativeApi::RespondToPlatformMessage:" + << response_id; if (Dart_IsNull(data.dart_handle())) { UIDartState::Current() ->platform_configuration() @@ -421,6 +424,7 @@ void PlatformConfigurationNativeApi::UpdateSemantics(SemanticsUpdate* update) { UIDartState::ThrowIfUIOperationsProhibited(); UIDartState::Current()->platform_configuration()->client()->UpdateSemantics( update); + FML_DLOG(INFO) << "PlatformConfigurationNativeApi::UpdateSemantics is called"; } Dart_Handle PlatformConfigurationNativeApi::ComputePlatformResolvedLocale( diff --git a/runtime/platform_data.h b/runtime/platform_data.h index ca7b683a1e8e6a7e84d84c89e7e4bcd874286a2d..92dfdf5da7bedd879932faf35ba6c6b9770ef7ab 100644 --- a/runtime/platform_data.h +++ b/runtime/platform_data.h @@ -38,7 +38,7 @@ struct PlatformData { std::vector locale_data; std::string user_settings_data = "{}"; std::string lifecycle_state; - bool semantics_enabled = false; + bool semantics_enabled = true; //debug bool assistive_technology_enabled = false; int32_t accessibility_feature_flags_ = 0; }; diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 9870d5e7804cac6949eb105dee2346bc702ee731..540ad7452b7b7e7d8f18b26181c5925ef7494d67 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -175,6 +175,7 @@ bool RuntimeController::SetSemanticsEnabled(bool enabled) { if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { platform_configuration->UpdateSemanticsEnabled( platform_data_.semantics_enabled); + FML_DLOG(INFO)<<"RuntimeController::SetSemanticsEnabled, enable="<UpdateAccessibilityFeatures( platform_data_.accessibility_feature_flags_); + FML_DLOG(INFO)<<"RuntimeController::SetAccessibilityFeatures="; return true; } @@ -286,6 +288,7 @@ bool RuntimeController::DispatchSemanticsAction(int32_t id, if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { platform_configuration->DispatchSemanticsAction(id, action, std::move(args)); + FML_DLOG(INFO) << "RuntimeController::DispatchSemanticsAction, id="<takeNodes(), update->takeActions()); + FML_DLOG(INFO) << "RuntimeController::UpdateSemantics is called"; } + FML_DLOG(INFO) << "RuntimeController::UpdateSemantics, platform_data_.semantics_enabled = false"; } // |PlatformConfigurationClient| diff --git a/shell/common/engine.cc b/shell/common/engine.cc index bbdf61cac7194f7b779497f4e7d85ee76d0a8b14..a5852039388c670700810ab9724ba08012ca8632 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -419,14 +419,17 @@ void Engine::DispatchPointerDataPacket( void Engine::DispatchSemanticsAction(int id, SemanticsAction action, fml::MallocMapping args) { + FML_DLOG(INFO)<<"Engine::DispatchSemanticsAction, id="<DispatchSemanticsAction(id, action, std::move(args)); } void Engine::SetSemanticsEnabled(bool enabled) { + FML_DLOG(INFO)<<"Engine::SetSemanticsEnabled, enabled="<SetSemanticsEnabled(enabled); } void Engine::SetAccessibilityFeatures(int32_t flags) { + FML_DLOG(INFO)<<"Engine::SetAccessibilityFeatures, flags="<SetAccessibilityFeatures(flags); } @@ -466,6 +469,7 @@ void Engine::Render(std::shared_ptr layer_tree) { void Engine::UpdateSemantics(SemanticsNodeUpdates update, CustomAccessibilityActionUpdates actions) { + FML_DLOG(INFO)<<"Engine::UpdateSemantics is called"; delegate_.OnEngineUpdateSemantics(std::move(update), std::move(actions)); } diff --git a/shell/common/shell.cc b/shell/common/shell.cc index bdaf8c234d889328cd00e64a223024d12589585d..c2a626b0c3922a0cc9b57885f3077c81e4651e28 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1005,6 +1005,7 @@ void Shell::OnPlatformViewDispatchSemanticsAction(int32_t id, fml::MakeCopyable([engine = engine_->GetWeakPtr(), id, action, args = std::move(args)]() mutable { if (engine) { + FML_DLOG(INFO) << "Shell::OnPlatformViewDispatchSemanticsAction, id="<DispatchSemanticsAction(id, action, std::move(args)); } })); @@ -1018,6 +1019,7 @@ void Shell::OnPlatformViewSetSemanticsEnabled(bool enabled) { task_runners_.GetUITaskRunner()->PostTask( [engine = engine_->GetWeakPtr(), enabled] { if (engine) { + FML_DLOG(INFO) << "Shell::OnPlatformViewSetSemanticsEnabled, enabled="<SetSemanticsEnabled(enabled); } }); @@ -1031,6 +1033,7 @@ void Shell::OnPlatformViewSetAccessibilityFeatures(int32_t flags) { task_runners_.GetUITaskRunner()->PostTask( [engine = engine_->GetWeakPtr(), flags] { if (engine) { + FML_DLOG(INFO) << "Shell::OnPlatformViewSetAccessibilityFeatures, flags="<SetAccessibilityFeatures(flags); } }); @@ -1214,6 +1217,7 @@ void Shell::OnEngineUpdateSemantics(SemanticsNodeUpdates update, [view = platform_view_->GetWeakPtr(), update = std::move(update), actions = std::move(actions)] { if (view) { + FML_DLOG(INFO) << "Shell::OnEngineUpdateSemantics is called"; view->UpdateSemantics(update, actions); } }); diff --git a/shell/platform/embedder/platform_view_embedder.cc b/shell/platform/embedder/platform_view_embedder.cc index 1cedc22810a50e5495f3580ccf56502269ee4765..12c3f83dbd3fae8da5b52e657129b2cf31ea3b16 100644 --- a/shell/platform/embedder/platform_view_embedder.cc +++ b/shell/platform/embedder/platform_view_embedder.cc @@ -122,6 +122,7 @@ void PlatformViewEmbedder::UpdateSemantics( if (platform_dispatch_table_.update_semantics_callback != nullptr) { platform_dispatch_table_.update_semantics_callback(std::move(update), std::move(actions)); + FML_DLOG(INFO) << "PlatformViewEmbedder::UpdateSemantics is called"; } } diff --git a/shell/platform/ohos/BUILD.gn b/shell/platform/ohos/BUILD.gn index 689f5015c2a163805cc04cd776451815973c7ac3..f10efdbb73f53decbcb4dbd385817d5c0552b2ae 100644 --- a/shell/platform/ohos/BUILD.gn +++ b/shell/platform/ohos/BUILD.gn @@ -84,6 +84,9 @@ source_set("flutter_ohos_sources") { "ohos_surface_gl_skia.h", "types.h", "ohos_logging.h", + "platform_view_ohos_delegate.h", + "./accessibility/ohos_accessibility_bridge.h", + "./accessibility/ohos_accessibility_manager.h", ] #configs += [ "//flutter/shell/platform/ohos/config:gtk" ] @@ -114,6 +117,9 @@ source_set("flutter_ohos_sources") { "ohos_image_generator.cpp", "ohos_external_texture_gl.cpp", "./surface/ohos_snapshot_surface_producer.cpp", + "platform_view_ohos_delegate.cpp", + "./accessibility/ohos_accessibility_bridge.cpp", + "./accessibility/ohos_accessibility_manager.cpp", ] # Set flag to stop headers being directly included (library users should not do this) diff --git a/shell/platform/ohos/accessibility/native_interface_accessibility.cpp b/shell/platform/ohos/accessibility/native_interface_accessibility.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b56cac970409083439a07a94b7b2b6b8ce157bc6 --- /dev/null +++ b/shell/platform/ohos/accessibility/native_interface_accessibility.cpp @@ -0,0 +1,5 @@ +#include "flutter/shell/platform/ohos/accessibility/native_interface_accessibility.h" + +namespace flutter { + +} \ No newline at end of file diff --git a/shell/platform/ohos/accessibility/native_interface_accessibility.h b/shell/platform/ohos/accessibility/native_interface_accessibility.h new file mode 100644 index 0000000000000000000000000000000000000000..3ea3ef9d2680f4974d7fea9eaa16713353c9ff6d --- /dev/null +++ b/shell/platform/ohos/accessibility/native_interface_accessibility.h @@ -0,0 +1,923 @@ +/* + * Copyright (c) 2024 Huawei Device 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. + */ + +/** + * @addtogroup ArkUI_Accessibility + * @{ + * + * @brief + * + * @since 13 + * @version 1.0 + */ + +/** + * @file native_interface_accessibility.h + * + * @brief + * + * @since 13 + * @version 1.0 + */ +#ifndef _NATIVE_INTERFACE_ACCESSIBILITY_H +#define _NATIVE_INTERFACE_ACCESSIBILITY_H + +#include + +#ifdef __cplusplus +extern "C"{ +#endif + +/** + * @brief Provides an encapsulated ArkUI_AccessibilityElementInfo instance. + * + * @since 13 + */ +typedef struct ArkUI_AccessibilityElementInfo ArkUI_AccessibilityElementInfo; + +/** + * @brief Defines the accessibility event info. + * + * @since 13 + */ +typedef struct ArkUI_AccessibilityEventInfo ArkUI_AccessibilityEventInfo; + +/** + * @brief Definesthe accessibility native provider. + * + * @since 13 + */ +typedef struct ArkUI_AccessibilityProvider ArkUI_AccessibilityProvider; + +/** + * @brief Provides an encapsulated OH_NativeAccessibilityDictionary instance, Implement the function of cpp dictionary. + * + * @since 13 + * @version 1.0 + */ +typedef struct ArkUI_AccessibilityActionArguments ArkUI_AccessibilityActionArguments; + +/** + * @brief Enumerates the API accessibility actions. + * + * @since 13 + * @version 1.0 + */ +typedef enum { + /** Invalid */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_INVALID = 0, + /** After receiving the event, the component needs to respond to the click. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_CLICK = 0x00000010, + /** After receiving the event, the component needs to respond to the long click. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_LONG_CLICK = 0x00000020, + /** Indicates the operation of obtaining the accessibility focus. The specific component is focused */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS = 0x00000040, + /** Indicates the operation of clearing the accessibility focus. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000080, + /** The scrolling component responds to forward scrolling action. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_SCROLL_FORWARD = 0x00000100, + /** The scrolling component responds to backwrad scrolling action. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_SCROLL_BACKWARD = 0x00000200, + /** Coping the selected content for the text component. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_COPY = 0x00000400, + /** Paste the selected content for the text component. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_PASTE = 0x00000800, + /** Cut the selected content for the text component. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_CUT = 0x00001000, + /** Indicates the selection operation. The selectTextBegin, selectTextEnd, and selectTextInForWard parameters need to be set. Select a text segment in the edit box. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_SET_SELECTION = 0x00002000, + /** Set the text Content for the text component. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_SET_TEXT = 0x00004000, + /** Set the cursor position for the text component. */ + ARKUI_NATIVE_ACCESSIBILITY_ACTION_SET_CURSOR_POSITION = 0x00100000, +} ArkUI_Accessibility_ActionType; + +/** + * @brief Enumerates the API accessibility event types. + * + * @since 13 + * @version 1.0 + */ +typedef enum { + /** Invalid */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_INVALID = 0, + /** Clicked event, which is sent after the UI component responds. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_CLICKED_EVENT = 0x00000001, + /** Long-Clicked event, which is sent after the UI component responds. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_LONG_CLICKED_EVENT = 0x00000002, + /** Selected event, which is sent after the UI component responds. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_SELECTED_EVENT = 0x00000004, + /** Text update event, needs to be send when the text is updated. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_TEXT_UPDATE_EVENT = 0x00000010, + /** Page update event, which is sent when the page jumps, switchs, changes in size, or moves. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_PAGE_STATE_UPDATE = 0x00000020, + /** Content update event, which is sent when the page content changes. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_PAGE_CONTENT_UPDATE = 0x00000800, + /** scrolled event, this event is send when a scrolling event occurs on a component that can be scrolled. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_SCROLLED_EVENT = 0x000001000, + /** Accessibility focus event, which is send after the UI component responds. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_ACCESSIBILITY_FOCUSED_EVENT = 0x00008000, + /** Accessibility focus clear event, which is send after the UI component responds. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED_EVENT = 0x00010000, + /** Request focus for accessibility event, proactively reqeust to focus on a specified node. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_REQUEST_FOCUS_FOR_ACCESSIBILITY = 0x02000000, + /** Page open event. the event is reported when the UI component */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_PAGE_OPEN = 0x20000000, + /** Page close event. the event is reported when the UI component */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_PAGE_CLOSE = 0x08000000, + /** Announce for accessibility event, requesting to actively play the specified content event. */ + ARKUI_NATIVE_ACCESSIBILITY_TYPE_VIEW_ANNOUNCE_FOR_ACCESSIBILITY = 0x10000000, +} ArkUI_AccessibilityEventType; + +/** + * @brief Defines the accessible of action + * + * @since 13 + * @version 1.0 + */ +typedef struct { + /** action type. */ + ArkUI_Accessibility_ActionType actionType; + /** the description message of action. */ + const char* description; +} ArkUI_AccessibleAction; + +/** + * @brief Defines the accessible of rect. + * + * @since 13 + * @version 1.0 + */ +typedef struct { + /** the left top x pixel corrdinates. */ + int32_t leftTopX; + /** the left top y pixel corrdinates. */ + int32_t leftTopY; + /** the right bottom x pixel corrdinates. */ + int32_t rightBottomX; + /** the right bottom y pixel corrdinates. */ + int32_t rightBottomY; +} ArkUI_AccessibleRect; + +/** + * @brief Defines the accessible of range info. + * + * @since 13 + * @version 1.0 + */ +typedef struct { + /** the min value. */ + double min; + /** the max value. */ + double max; + /** the current value. */ + double current; +} ArkUI_AccessibleRangeInfo; + +/** + * @brief Defines the accessible of grid info. + * + * @since 13 + * @version 1.0 + */ +typedef struct { + /** The number of row. */ + int32_t rowCount; + /** The number of column. */ + int32_t columnCount; + /** 0: select one line only, otherwise select multilines. */ + int32_t selectionMode; +} ArkUI_AccessibleGridInfo; + +/** + * @brief Defines the accessible of grid item info. + * + * @since 13 + * @version 1.0 + */ +typedef struct { + /** true: The item isHeading, otherwise is not */ + bool heading; + /** true: The item selected, otherwise is not */ + bool selected; + /** the index of column */ + int32_t columnIndex; + /** the index of row */ + int32_t rowIndex; + /** the column spanned */ + int32_t columnSpan; + /** the row spanned */ + int32_t rowSpan; +} ArkUI_AccessibleGridItemInfo; + +/** + * @brief Enumerates the API accessibility ErrorCode states. + * + * @since 13 + * @version 1.0 + */ +enum AcessbilityErrorCode{ + /** Successful. */ + OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS = 0, + /** Failed. */ + OH_ARKUI_ACCESSIBILITY_RESULT_FAILED = -1, + /** Invalid parameters. */ + OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER = -2, + /** Out of memory. */ + OH_ARKUI_ACCESSIBILITY_RESULT_OUT_OF_MEMORY = -3, +} ; + +/** + * @brief Enumerates the API accessibility search mode. + * + * @since 13 + * @version 1.0 + */ +typedef enum { + /** predecessors */ + NATIVE_SEARCH_MODE_PREFETCH_PREDECESSORS = 1 << 0, + /** slbings */ + NATIVE_SEARCH_MODE_PREFETCH_SIBLINGS = 1 << 1, + /** children */ + NATIVE_SEARCH_MODE_PREFETCH_CHILDREN = 1 << 2, + /** recusive children */ + NATIVE_SEARCH_MODE_PREFETCH_RECURSIVE_CHILDREN = 1 << 3, +} ArkUI_AccessibilitySearchMode; + +/** + * @brief Enumerates the API accessibility focus type. + * + * @since 13 + * @version 1.0 + */ +typedef enum { + /** Invalid */ + NATIVE_FOCUS_TYPE_INVALID = -1, + /** Input focus type */ + NATIVE_FOCUS_TYPE_INPUT = 1 << 0, + /** Accessibility focus type */ + NATIVE_FOCUS_TYPE_ACCESSIBILITY = 1 << 1, +} ArkUI_AccessibilityFocusType; + +/** + * @brief Enumerates the API accessibility focus move direction. + * + * @since 13 + * @version 1.0 + */ +typedef enum { + /** Invalid */ + NATIVE_DIRECTION_INVALID = 0, + /** up direction. */ + NATIVE_DIRECTION_UP = 0x00000001, + /** down direction. */ + NATIVE_DIRECTION_DOWN = 0x00000002, + /** left direction. */ + NATIVE_DIRECTION_LEFT = 0x00000004, + /** right direction. */ + NATIVE_DIRECTION_RIGHT = 0x00000008, + /** forward direction. */ + NATIVE_DIRECTION_FORWARD = 0x00000010, + /** backward direction. */ + NATIVE_DIRECTION_BACKWARD = 0x00000020, +} ArkUI_AccessibilityFocusMoveDirection; + +/** + * @brief Provides an encapsulated ArkUI_AccessibilityElementInfoList instance. + * + * @since 13 + * @version 1.0 + */ +typedef struct ArkUI_AccessibilityElementInfoList ArkUI_AccessibilityElementInfoList; + +/** + * @brief Registers the accessibility provider callbacks + * + * @since 13 + * @version 1.0 + */ +typedef struct ArkUI_AccessibilityProviderCallbacks { + /** Called when need to get element infos based on a specified node. */ + int32_t (*FindAccessibilityNodeInfosById)(int64_t elementId, ArkUI_AccessibilitySearchMode mode, int32_t requestId, ArkUI_AccessibilityElementInfoList* elementList); + /** Called when need to get element infos based on a specified node and text content. */ + int32_t (*FindAccessibilityNodeInfosByText)(int64_t elementId, const char* text, int32_t requestId, ArkUI_AccessibilityElementInfoList* elementList); + /** Called when need to get the focused element info based on a specified node. */ + int32_t (*FindFocusedAccessibilityNode)(int64_t elementId, ArkUI_AccessibilityFocusType focusType, int32_t requestId, ArkUI_AccessibilityElementInfo* elementinfo); + /** Query the node that can be focused based on the reference node. Query the next node that can be focused based on the mode and direction. */ + int32_t (*FindNextFocusAccessibilityNode)(int64_t elementId, ArkUI_AccessibilityFocusMoveDirection direction, int32_t requestId, ArkUI_AccessibilityElementInfo* elementList); + /** Performing the Action operation on a specified node. */ + int32_t (*ExecuteAccessibilityAction)(int64_t elementId, ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments actionArguments, int32_t requestId); + /** Clears the focus status of the currently focused node */ + int32_t (*ClearFocusedFocusAccessibilityNode)(); + /** Queries the current cursor position of a specified node. */ + int32_t (*GetAccessibilityNodeCursorPosition)(int64_t elementId, int32_t requestId, int32_t* index); +} ArkUI_AccessibilityProviderCallbacks; + +/** + * @brief Registers a callback for this ArkUI_AccessibilityProvider instance. + * + * @param provider Indicates the pointer to this ArkUI_AccessibilityProvider instance. + * @param callbacks Indicates the pointer to a GetAccessibilityNodeCursorPosition callback. + * @return Returns the status code of the execution. + * @since 13 + * @version 1.0 + */ +int32_t OH_ArkUI_AccessibilityProviderRegisterCallback( + ArkUI_AccessibilityProvider* provider, ArkUI_AccessibilityProviderCallbacks* callbacks); + +/** + * @brief send accessibility event info. + * + * @param provider Indicates the pointer to this ArkUI_AccessibilityProvider instance. + * @param eventInfo Indicates the pointer to the accessibility event info. + * @param callback Indicates the pointer to a SendAccessibilityAsyncEvent callback. + * @return Returns the status code of the execution. + * @since 13 + * @version 1.0 + */ +void OH_ArkUI_SendAccessibilityAsyncEvent( + ArkUI_AccessibilityProvider* provider, ArkUI_AccessibilityEventInfo* eventInfo, void (*callback)(int32_t errorCode)); + +/** + * @brief Adds an element to the list. + * + * @param list Indicates the pointer to the accessibility element list. + * @return Returns the pointer to the accessibility elementInfo. + * @since 13 + * @version 1.0 + */ +ArkUI_AccessibilityElementInfo* OH_ArkUI_AddAndGetAccessibilityElementInfo(ArkUI_AccessibilityElementInfoList* list); + +/** +* @brief Sets the page id of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param pageId Indicates the page id. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoPageId(ArkUI_AccessibilityElementInfo* elementInfo, int32_t pageId); + +/** +* @brief Sets the page id of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param componentId Indicates the component id. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoComponentId(ArkUI_AccessibilityElementInfo* elementInfo, int32_t componentId); + +/** +* @brief Sets the parent id of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param parentId Indicates the parent id. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoParentId(ArkUI_AccessibilityElementInfo* elementInfo, int32_t parentId); + +/** +* @brief Sets the component type of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param componentType Indicates the component type. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoComponentType(ArkUI_AccessibilityElementInfo* elementInfo, const char* componentType); + +/** +* @brief Sets the component contents of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param contents Indicates the component contents. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoContents(ArkUI_AccessibilityElementInfo* elementInfo, const char* contents); + +/** +* @brief Sets the hint text of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param hintText Indicates the hint text. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoHintText(ArkUI_AccessibilityElementInfo* elementInfo, const char* hintText); + +/** +* @brief Sets the accessibility text of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param accessibilityText Indicates the accessibility text. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoAccessibilityText(ArkUI_AccessibilityElementInfo* elementInfo, const char* accessibilityText); + +/** +* @brief Sets the accessibility description of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param accessibilityDescription Indicates the accessibility description. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoAccessibilityDescription(ArkUI_AccessibilityElementInfo* elementInfo, const char* accessibilityDescription); + +/** +* @brief Sets the child node ids of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param childCount Indicates the child count. +* @param childNodeIds Indicates the child node ids. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoChildNodeIds(ArkUI_AccessibilityElementInfo* elementInfo, int32_t childCount, int64_t* childNodeIds); + +/** +* @brief Sets the child count of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param operationActions Indicates All actions supported by the element. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoOperationActions(ArkUI_AccessibilityElementInfo* elementInfo, int32_t operationCount, ArkUI_AccessibleAction* operationActions); + +/** +* @brief Sets the screen rect of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param screenRect Indicates screen rect. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoScreenRect(ArkUI_AccessibilityElementInfo* elementInfo, ArkUI_AccessibleRect* screenRect); + +/** +* @brief Sets the checkable of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param checkable Indicates checkable. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoCheckable(ArkUI_AccessibilityElementInfo* elementInfo, bool checkable); + +/** +* @brief Sets the checked of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param checked Indicates whether the element is checked. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoChecked(ArkUI_AccessibilityElementInfo* elementInfo, bool checked); + +/** +* @brief Sets the focusable of the accessibility element information. +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param focusable Indicates whether the element is focusable. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoFocusable(ArkUI_AccessibilityElementInfo* elementInfo, bool focusable); + +/** +* @brief Sets the isFocused of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param isFocused Indicates whether the element is focused. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoFocused(ArkUI_AccessibilityElementInfo* elementInfo, bool isFocused); + +/** +* @brief Sets the isVisible of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param isVisible Indicates whether the element is visible. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoVisible(ArkUI_AccessibilityElementInfo* elementInfo, bool isVisible); + +/** +* @brief Sets the accessibilityFocused of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param accessibilityFocused Indicates whether the element is accessibility focused. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoAccessibilityFocused(ArkUI_AccessibilityElementInfo* elementInfo, bool accessibilityFocused); + +/** +* @brief Sets the selected of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param selected Indicates whether the element is selected. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoSelected(ArkUI_AccessibilityElementInfo* elementInfo, bool selected); + +/** +* @brief Sets the clickable of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param clickable Indicates whether the element is clickable. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoClickable(ArkUI_AccessibilityElementInfo* elementInfo, bool clickable); + +/** +* @brief Sets the longClickable of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param longClickable Indicates whether the element is long clickable. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoLongClickable(ArkUI_AccessibilityElementInfo* elementInfo, bool longClickable); + +/** +* @brief Sets the isEnabled of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param isEnable Indicates whether the element is enable. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoEnabled(ArkUI_AccessibilityElementInfo* elementInfo, bool isEnabled); + +/** +* @brief Sets the isPassword of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param isPassword Indicates whether the element is a password. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoIsPassword(ArkUI_AccessibilityElementInfo* elementInfo, bool isPassword); + +/** +* @brief Sets the scrollable of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param scrollable Indicates whether the element is scrollable. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoScrollable(ArkUI_AccessibilityElementInfo* elementInfo, bool scrollable); + +/** +* @brief Sets the editable of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param editable Indicates whether the element is editable. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoEditable(ArkUI_AccessibilityElementInfo* elementInfo, bool editable); + +/** +* @brief Sets the isHint of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param isHint Indicates whether the element is in the hint state. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoIsHint(ArkUI_AccessibilityElementInfo* elementInfo, bool isHint); + +/** +* @brief Sets the rangeInfo of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param rangeInfo Indicates element's range info. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoRangeInfo(ArkUI_AccessibilityElementInfo* elementInfo, ArkUI_AccessibleRangeInfo* rangeInfo); + +/** +* @brief Sets the grid of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param gridInfo Indicates element's grid info. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoGridInfo(ArkUI_AccessibilityElementInfo* elementInfo, ArkUI_AccessibleGridInfo* gridInfo); + +/** +* @brief Sets the gridItem of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param gridItem Indicates element's grid item info. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoGridItemInfo(ArkUI_AccessibilityElementInfo* elementInfo, ArkUI_AccessibleGridItemInfo* gridItem); + +/** +* @brief Sets the textBeginSelected of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param textBeginSelected Indicates the start position of the selection. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoTextBeginSelected(ArkUI_AccessibilityElementInfo* elementInfo, int32_t textBeginSelected); + +/** +* @brief Sets the textEndSelected of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param textEndSelected Indicates the end position of the selection. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoTextEndSelected(ArkUI_AccessibilityElementInfo* elementInfo, int32_t textEndSelected); + +/** +* @brief Sets the currentItemIndex of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param currentItemIndex Indicates index of the current item. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoCurrentItemIndex(ArkUI_AccessibilityElementInfo* elementInfo, int32_t currentItemIndex); + +/** +* @brief Sets the beginItemIndex of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param beginItemIndex Indicates index of the begin item. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoBeginItemIndex(ArkUI_AccessibilityElementInfo* elementInfo, int32_t beginItemIndex); + +/** +* @brief Sets the endItemIndex of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param endItemIndex Indicates index of the end item. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoEndItemIndex(ArkUI_AccessibilityElementInfo* elementInfo, int32_t endItemIndex); + +/** +* @brief Sets the itemCount of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param itemCount Indicates total number of items. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoItemCount(ArkUI_AccessibilityElementInfo* elementInfo, int32_t itemCount); + +/** +* @brief Sets the offset of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param offset Indicates pixel offset for scrolling relative to the top coordinate of the element. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoAccessibilityOffset(ArkUI_AccessibilityElementInfo* elementInfo, int32_t offset); + +/** +* @brief Sets the accessibilityGroup of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param accessibilityGroup Indicates accessibility group. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoAccessibilityGroup(ArkUI_AccessibilityElementInfo* elementInfo, bool accessibilityGroup); + +/** +* @brief Sets the accessibilityLevel of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param accessibilityLevel Indicates accessibility level. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoAccessibilityLevel(ArkUI_AccessibilityElementInfo* elementInfo, const char* accessibilityLevel); + +/** +* @brief Sets the zIndex of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param zIndex Indicates z index. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoZIndex(ArkUI_AccessibilityElementInfo* elementInfo, int32_t zIndex); + +/** +* @brief Sets the opacity of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param opacity Indicates opacity. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoAccessibilityOpacity(ArkUI_AccessibilityElementInfo* elementInfo, float opacity); + +/** +* @brief Sets the backgroundColor of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param backgroundColor Indicates background color. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoBackgroundColor(ArkUI_AccessibilityElementInfo* elementInfo, const char* backgroundColor); + +/** +* @brief Sets the backgroundImage of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param backgroundImage Indicates background image. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoBackgroundImage(ArkUI_AccessibilityElementInfo* elementInfo, const char* backgroundImage); + +/** +* @brief Sets the blur of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param blur Indicates blur. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoBlur(ArkUI_AccessibilityElementInfo* elementInfo, const char* blur); + +/** +* @brief Sets the hitTestBehavior of the accessibility element information. +* +* @param elementInfo Indicates the pointer to the accessibility element information. +* @param hitTestBehavior Indicates hitTest behavior. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityElementInfoHitTestBehavior(ArkUI_AccessibilityElementInfo* elementInfo, const char* hitTestBehavior); + +/** + * @brief Create an accessibility eventInfo. + * + * @return Returns the pointer to the accessibility event info. + * @since 13 + * @version 1.0 + */ +ArkUI_AccessibilityEventInfo* OH_ArkUI_CreateAccessibilityEventInfo(void); + +/** + * @brief Destorys an accessibility eventInfo. + * + * @param eventInfo Indicates the pointer to to the accessibility event info to be destoryed. + * @since 13 + * @version 1.0 + */ +void OH_ArkUI_DestoryAccessibilityEventInfo(ArkUI_AccessibilityEventInfo* eventInfo); + +/** +* @brief Sets the eventType of the accessibility event information. +* +* @param eventInfo Indicates the pointer to the accessibility event information. +* @param eventType Indicates event type. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityEventEventType(ArkUI_AccessibilityEventInfo* eventInfo, ArkUI_AccessibilityEventType eventType); + +/** +* @brief Sets the pageId of the accessibility event information. +* +* @param eventInfo Indicates the pointer to the accessibility event information. +* @param pageId Indicates page id. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityEventPageId(ArkUI_AccessibilityEventInfo* eventInfo, int32_t pageId); + +/** +* @brief Sets the textAnnouncedForAccessibility of the accessibility event information. +* +* @param eventInfo Indicates the pointer to the accessibility event information. +* @param textAnnouncedForAccessibility Indicates text announced for accessibility. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityEventTextAnnouncedForAccessibility(ArkUI_AccessibilityEventInfo* eventInfo, const char* textAnnouncedForAccessibility); + +/** +* @brief Sets the requestFocusId of the accessibility event information. +* +* @param eventInfo Indicates the pointer to the accessibility event information. +* @param requestFocusId Indicates ID of the request for active focus. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityEventRequestFocusId(ArkUI_AccessibilityEventInfo* eventInfo, int32_t requestFocusId); + +/** +* @brief Sets the elementInfo of the accessibility event information. +* +* @param eventInfo Indicates the pointer to the accessibility event information. +* @param elementInfo Indicates element Info. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_SetAccessibilityEventElementInfo(ArkUI_AccessibilityEventInfo* eventInfo, ArkUI_AccessibilityElementInfo* elementInfo); + +/** +* @brief Gets the value of the accessibility action argument by key. +* +* @param arguments Indicates the pointer to the accessibility action arguments. +* @param key Indicates key. +* @param value Indicates value. +* @return Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_SUCCESS} if success. +* Returns {@link OH_ARKUI_ACCESSIBILITY_RESULT_BAD_PARAMETER} if a parameter exception occurs. +* @since 13 +*/ +int32_t OH_ArkUI_FindAccessibilityActionArgumentByKey(ArkUI_AccessibilityActionArguments* arguments, const char* key, char* value); +#ifdef __cplusplus +}; +#endif +#endif // _NATIVE_INTERFACE_ACCESSIBILITY_H diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2b7498833877feca6119ed8b3efc14622e0221c0 --- /dev/null +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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. + */ + +#include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" +#include "flutter/fml/logging.h" + +namespace flutter { + +OhosAccessibilityBridge::OhosAccessibilityBridge() { + // 判断是否开启无障碍服务 + bool isAccessibilityEnabled = + this->ax_manager_->getOhosAccessibilityEnabled(); + if (isAccessibilityEnabled) { + FML_DLOG(INFO) << "OhosAccessibilityBridge::OhosAccessibilityBridge " + "isOhosAccessibilityEnabled = true"; + } +} +OhosAccessibilityBridge::~OhosAccessibilityBridge() {}; + +OhosAccessibilityBridge& OhosAccessibilityBridge::GetInstance() { + static OhosAccessibilityBridge ohosAccessibilityBridge; + return ohosAccessibilityBridge; +} + +void OhosAccessibilityBridge::announce(std::unique_ptr& message) { + FML_DLOG(INFO) << ("Native C++ OhosAccessibilityBridge::announce message: ") + << (message.get()); + return; +} + +flutter::SemanticsNode OhosAccessibilityBridge::getOrCreateSemanticsNode( + int32_t id) { + flutter::SemanticsNode node; + if (flutterSemanticsTree_.find(id) != flutterSemanticsTree_.end()) { + node = flutterSemanticsTree_.at(id); + } else { + flutterSemanticsTree_[id] = node; + } + return node; +} + +void OhosAccessibilityBridge::updateSemantics( + flutter::SemanticsNodeUpdates update, + flutter::CustomAccessibilityActionUpdates actions) { + FML_DLOG(INFO) + << ("Native C++ OhosAccessibilityBridge::updateSemantics is called"); + + // 遍历更新的actions,并将所有的actions的id添加进actionMap + for (const auto& item : actions) { + const flutter::CustomAccessibilityAction action = item.second; + actions_mp_[action.id] = action; + } + + for (auto& item : update) { + const flutter::SemanticsNode& node = item.second; + // todo:根据nodeId获取当前os对应的真实节点 + // currentNode = + // ArkUI_AccessibilityElementInfo::createAccessibilityElementInfo(node.id); + + // todo:获取当前节点的全部子节点数量,并构建当前节点的全部更新子节点 + int32_t newChildCount = node.childrenInTraversalOrder.size(); + // todo:声明并创建当前节点的新的子节点 + // declare一个newChildren + for (int32_t i = 0; i < newChildCount; i++) { + // todo:通过遍历当前节点的子节点,并对所有子节点进行逐一构建os对应的elementinfo + // AccessibilityElementInfo child = + // createAccessibilityElementInfo(node.childrenInTraversalOrder[i]); + // todo:将所有的新child节点加入到os对应的elementInfoList中 + } + // TODO: 将更新后的全部子节点赋值给当前真实节点 + // currentNode = newChildren + + // todo: 是否触发滑动操作 + bool didScroll = true; + if (didScroll) { + // 1. 声明并创建accessibilityEvent类型,比如滑动事件 + // 2. + // 获取semanticsNode里scrollPosition、scrollExtensionMax、scrollExtensionMin字段 + // 3. 发送事件中包含上述scroll位置变动信息(如下所示) + // int32_t scrollChildren = 0; + // int32_t scrollIndex = 0; + // double scrollPosition = std::nan(""); + // double scrollExtentMax = std::nan(""); + // double scrollExtentMin = std::nan(""); + int32_t scrollChildren = 0; + if (scrollChildren > 0) { + // todo 发送事件,包含scrollChildren数量、scrollIndex + // int visibleChildren = 0; + // // handle hidden children at the beginning and end of the list. + // for (flutter::SemanticsNode child : node.childrenInHitTestOrder) { + // if (!child.hasFlag(Flag.IS_HIDDEN)) { + // visibleChildren += 1; + // } + // } + } + // sendAccessibilityEvent(event) + } + // todo: 判断是否触发liveRegion活动区,是否活跃 + if (node.HasFlag(FLAGS_::kIsLiveRegion)) { + // sendWindowContentChangeEvent(object.id); + } + + // todo:当前焦点语义节点 + bool isHadFlag = false; // 这里判断previousFlag和当前flag是否相同 + std::shared_ptr accessibilityFocusedSemanticsNode; + if (accessibilityFocusedSemanticsNode != nullptr && + accessibilityFocusedSemanticsNode->id == node.id && !isHadFlag && + node.HasFlag(FLAGS_::kIsSelected)) { + // todo:创建并发送事件 + // AccessibilityEvent event = obtainAccessibilityEvent( + // node.id, AccessibilityEvent.TYPE_VIEW_SELECTED); + // event.getText().add(object.label); + // sendAccessibilityEvent(event); + } + + // todo: 若该对象是输入焦点节点,且发生更新变化,则发送给os有关它的信息 + std::shared_ptr + inputFocusedSemanticsNode; // 当前输入焦点节点 + std::shared_ptr + lastInputFocusedSemanticsNode; // 上一个输入焦点节点 + if (inputFocusedSemanticsNode != nullptr && + inputFocusedSemanticsNode->id == node.id && + (lastInputFocusedSemanticsNode == nullptr || + lastInputFocusedSemanticsNode->id != inputFocusedSemanticsNode->id)) { + // 上次输入焦点节点 -> 当前输入焦点节点 + lastInputFocusedSemanticsNode = inputFocusedSemanticsNode; + // 发送相应的输入焦点改变事件 + // sendAccessibilityEvent(obtainAccessibilityEvent(object.id, + // AccessibilityEvent.TYPE_VIEW_FOCUSED)); + } else if (inputFocusedSemanticsNode == nullptr) { + // There's no TYPE_VIEW_CLEAR_FOCUSED event, so if the current input focus + // becomes null, then we just set the last one to null too, so that it + // sends the event again when something regains focus. + lastInputFocusedSemanticsNode = nullptr; + } + + if (inputFocusedSemanticsNode != nullptr && + inputFocusedSemanticsNode->id == node.id && isHadFlag && + node.HasFlag(FLAGS_::kIsTextField) + // If we have a TextField that has InputFocus, we should avoid + // announcing it if something else we track has a11y focus. This needs + // to still work when, e.g., IME has a11y focus or the "PASTE" popup is + // used though. See more discussion at + // https://github.com/flutter/flutter/issues/23180 + && (accessibilityFocusedSemanticsNode == nullptr || + (accessibilityFocusedSemanticsNode->id == + inputFocusedSemanticsNode->id))) { + // 这里写输入框更新文字内容,将老旧的文本替换为新输入文字,并发送textchange事件 + // AccessibilityEvent event = createTextChangedEvent(object.id, oldValue, + // newValue); sendAccessibilityEvent(event); + + // todo:若当前textselection部分和之前的textselection部分不同,则触发 + int32_t previousTextSelectionBase = 0; + int32_t previousTextSelectionExtent = 1; + if (previousTextSelectionBase != node.textSelectionBase || + previousTextSelectionExtent != node.textSelectionExtent) { + // 创建并发送textselection改变事件 + // AccessibilityEvent selectionEvent = obtainAccessibilityEvent( + // object.id, AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED); + // selectionEvent.getText().add(newValue); + // selectionEvent.setFromIndex(object.textSelectionBase); + // selectionEvent.setToIndex(object.textSelectionExtent); + // selectionEvent.setItemCount(newValue.length()); + // sendAccessibilityEvent(selectionEvent); + } + } + } +} +// kTap = 1 << 0, +// kLongPress = 1 << 1, +// kScrollLeft = 1 << 2, +// kScrollRight = 1 << 3, +// kScrollUp = 1 << 4, +// kScrollDown = 1 << 5, +// kIncrease = 1 << 6, +// kDecrease = 1 << 7, +// kShowOnScreen = 1 << 8, +// kMoveCursorForwardByCharacter = 1 << 9, +// kMoveCursorBackwardByCharacter = 1 << 10, +// kSetSelection = 1 << 11, +// kCopy = 1 << 12, +// kCut = 1 << 13, +// kPaste = 1 << 14, +// kDidGainAccessibilityFocus = 1 << 15, +// kDidLoseAccessibilityFocus = 1 << 16, +// kCustomAction = 1 << 17, +// kDismiss = 1 << 18, +// kMoveCursorForwardByWord = 1 << 19, +// kMoveCursorBackwardByWord = 1 << 20, +// kSetText = 1 << 21, + +int32_t convertToInt32(flutter::SemanticsAction inputAction) { + return static_cast(inputAction); +} +void OhosAccessibilityBridge::performAction(int32_t virtualViewId, + int32_t inputAction) { + // TODO 根据输入的action进行相应的响应操作 + switch (inputAction) { + case 0: + break; + case 1: + break; + case 2: + break; + // ... + default: + break; + } +} + +flutter::SemanticsNode OhosAccessibilityBridge::getRootSemanticsNode() { + return flutterSemanticsTree_.at(0); +} +// 找到当前焦点触发节点 +int32_t OhosAccessibilityBridge::FindFocusedAccessibilityNode( + int64_t elementId, + int32_t focusType, + int32_t requestId, + int32_t elementinfo) { + return 0; +} +// 找到下一个焦点触发节点 +int32_t OhosAccessibilityBridge::FindNextFocusAccessibilityNode( + int64_t elementId, + int32_t direction, + int32_t requestId, + int32_t elementList) { + return 0; +} + +void ArkUI_AccessibilityElementInfo::createAccessibilityElementInfo(int vid) { + // TODO ohos和flutter虚拟节点交互,根据虚拟节点id创建真实elementinfo + // ArkUI_AccessibilityElementInfo相当于安卓的view +} + +} // namespace flutter diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h new file mode 100644 index 0000000000000000000000000000000000000000..518544e1fd1e01c0d4a63db38c2c45abab240f9d --- /dev/null +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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. + */ + +#ifndef OHOS_ACCESSIBILITY_BRIDGE_H +#define OHOS_ACCESSIBILITY_BRIDGE_H +#include +#include +#include +#include + +#include "flutter/fml/log_level.h" +#include "flutter/lib/ui/semantics/custom_accessibility_action.h" +#include "flutter/lib/ui/semantics/semantics_node.h" +#include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_manager.h" +#include "flutter/shell/platform/ohos/napi/platform_view_ohos_napi.h" + +namespace flutter { + +typedef flutter::SemanticsFlags FLAGS_; +typedef flutter::SemanticsAction ACTIONS_; + +/** + * flutter和ohos的无障碍服务桥接 + */ +class OhosAccessibilityBridge { + private: + OhosAccessibilityBridge(); + + public: + ~OhosAccessibilityBridge(); + static OhosAccessibilityBridge& GetInstance(); + + void announce(std::unique_ptr& message); + + void updateSemantics(flutter::SemanticsNodeUpdates update, + flutter::CustomAccessibilityActionUpdates actions); + + // obtain the flutter semnatics node + flutter::SemanticsNode getOrCreateSemanticsNode(int32_t id); + + void performAction(int32_t virtualViewId, int32_t inputAction); + + private: + std::shared_ptr ax_manager_; + std::unordered_map flutterSemanticsTree_; + std::unordered_map actions_mp_; + flutter::SemanticsNode semanticsNode_; + + + + flutter::SemanticsNode getRootSemanticsNode(); + int32_t convertToInt32(flutter::SemanticsAction inputAction); + + + // native os interfaces + int32_t FindFocusedAccessibilityNode(int64_t elementId, + int32_t focusType, + int32_t requestId, + int32_t elementinfo); + int32_t FindNextFocusAccessibilityNode(int64_t elementId, + int32_t direction, + int32_t requestId, + int32_t elementList); +}; + +class ArkUI_AccessibilityElementInfo { + public: + ArkUI_AccessibilityElementInfo() = default; + ~ArkUI_AccessibilityElementInfo() = default; + void createAccessibilityElementInfo(int vid); +}; +/** +struct SemanticsNode { + SemanticsNode(); + + SemanticsNode(const SemanticsNode& other); + + ~SemanticsNode(); + + bool HasAction(SemanticsAction action) const; + bool HasFlag(SemanticsFlags flag) const; + + // Whether this node is for embedded platform views. + bool IsPlatformViewNode() const; + + int32_t id = 0; + int32_t flags = 0; + int32_t actions = 0; + int32_t maxValueLength = -1; + int32_t currentValueLength = -1; + int32_t textSelectionBase = -1; + int32_t textSelectionExtent = -1; + int32_t platformViewId = -1; + int32_t scrollChildren = 0; + int32_t scrollIndex = 0; + double scrollPosition = std::nan(""); + double scrollExtentMax = std::nan(""); + double scrollExtentMin = std::nan(""); + double elevation = 0.0; + double thickness = 0.0; + std::string label; + StringAttributes labelAttributes; + std::string hint; + StringAttributes hintAttributes; + std::string value; + StringAttributes valueAttributes; + std::string increasedValue; + StringAttributes increasedValueAttributes; + std::string decreasedValue; + StringAttributes decreasedValueAttributes; + std::string tooltip; + int32_t textDirection = 0; // 0=unknown, 1=rtl, 2=ltr + + SkRect rect = SkRect::MakeEmpty(); // Local space, relative to parent. + SkM44 transform = SkM44{}; // Identity + std::vector childrenInTraversalOrder; + std::vector childrenInHitTestOrder; + std::vector customAccessibilityActions; +}; +*/ + +/** + enum class SemanticsFlags : int32_t { + kHasCheckedState = 1 << 0, + kIsChecked = 1 << 1, + kIsSelected = 1 << 2, + kIsButton = 1 << 3, + kIsTextField = 1 << 4, + kIsFocused = 1 << 5, + kHasEnabledState = 1 << 6, + kIsEnabled = 1 << 7, + kIsInMutuallyExclusiveGroup = 1 << 8, + kIsHeader = 1 << 9, + kIsObscured = 1 << 10, + kScopesRoute = 1 << 11, + kNamesRoute = 1 << 12, + kIsHidden = 1 << 13, + kIsImage = 1 << 14, + kIsLiveRegion = 1 << 15, + kHasToggledState = 1 << 16, + kIsToggled = 1 << 17, + kHasImplicitScrolling = 1 << 18, + kIsMultiline = 1 << 19, + kIsReadOnly = 1 << 20, + kIsFocusable = 1 << 21, + kIsLink = 1 << 22, + kIsSlider = 1 << 23, + kIsKeyboardKey = 1 << 24, + kIsCheckStateMixed = 1 << 25, +}; + */ + +/** + enum class SemanticsAction : int32_t { + kTap = 1 << 0, + kLongPress = 1 << 1, + kScrollLeft = 1 << 2, + kScrollRight = 1 << 3, + kScrollUp = 1 << 4, + kScrollDown = 1 << 5, + kIncrease = 1 << 6, + kDecrease = 1 << 7, + kShowOnScreen = 1 << 8, + kMoveCursorForwardByCharacter = 1 << 9, + kMoveCursorBackwardByCharacter = 1 << 10, + kSetSelection = 1 << 11, + kCopy = 1 << 12, + kCut = 1 << 13, + kPaste = 1 << 14, + kDidGainAccessibilityFocus = 1 << 15, + kDidLoseAccessibilityFocus = 1 << 16, + kCustomAction = 1 << 17, + kDismiss = 1 << 18, + kMoveCursorForwardByWord = 1 << 19, + kMoveCursorBackwardByWord = 1 << 20, + kSetText = 1 << 21, +}; + */ +} // namespace flutter +#endif // OHOS_ACCESSIBILITY_BRIDGE_H diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_manager.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e636097658b3fe54ef80062b79e8fd5649ce1f8 --- /dev/null +++ b/shell/platform/ohos/accessibility/ohos_accessibility_manager.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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. + */ +#include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_manager.h" +#include "flutter/fml/logging.h" + +namespace flutter { +OhosAccessibilityManager::OhosAccessibilityManager() {}; +OhosAccessibilityManager::~OhosAccessibilityManager() {}; + +void OhosAccessibilityManager::onAccessibilityStateChanged( + bool isOhosAccessibilityEnabled) {}; + +void OhosAccessibilityManager::setOhosAccessibilityEnabled(bool isEnabled) { + FML_DLOG(INFO) << "OhosAccessibilityManager::setOhosAccessibilityEnabled = " + << isEnabled; + this->isOhosAccessibilityEnabled_ = isEnabled; +} + +bool OhosAccessibilityManager::getOhosAccessibilityEnabled() { + return this->isOhosAccessibilityEnabled_; +} + +} // namespace flutter diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_manager.h b/shell/platform/ohos/accessibility/ohos_accessibility_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..1e8dd7f0cd9fd218ea2ee61854c3a95f6a442026 --- /dev/null +++ b/shell/platform/ohos/accessibility/ohos_accessibility_manager.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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. + */ +#ifndef OHOS_ACCESSIBILITY_MANAGER_H +#define OHOS_ACCESSIBILITY_MANAGER_H + +// #include "flutter/shell/platform/ohos/napi/platform_view_ohos_napi.h" + +namespace flutter { +/** + * 无障碍辅助管理类 + */ +class OhosAccessibilityManager { + public: + OhosAccessibilityManager(); + ~OhosAccessibilityManager(); + + void onAccessibilityStateChanged(bool isOhosAccessibilityEnabled); + bool getOhosAccessibilityEnabled(); + void setOhosAccessibilityEnabled(bool isEnabled); + + private: + bool isOhosAccessibilityEnabled_; +}; + +} // namespace flutter + +#endif \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets index bbaa2987bb0da14659f8debc153ff537a9bf9827..458a7f175dcb5678d78b6dae51a8ab03d7185ba0 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets @@ -17,6 +17,7 @@ import common from '@ohos.app.ability.common'; import resourceManager from '@ohos.resourceManager'; import image from '@ohos.multimedia.image'; import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; +import { ByteBuffer } from '../../../ets/util/ByteBuffer'; export const getContext: (a: number) => napiContext; @@ -109,6 +110,12 @@ export const nativeXComponentDispatchMouseWheel: (nativeShellHolderId: number, timestamp: number ) => void; + +// send updateSemantics and updateCustomAccessibilityActions from ets to c++ +export const nativeUpdateSemantics: (buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]) => void; +export const nativeUpdateCustomAccessibilityActions: (buffer: ByteBuffer, strings: string[]) => void; + + /** * Detaches flutterNapi和engine之间的关联 * 这个方法执行前提是flutterNapi已经和engine关联 @@ -130,3 +137,12 @@ export const nativeRegisterTexture: (nativeShellHolderId: number, textureId: num export const nativeEncodeUtf8: (str: string) => Uint8Array; export const nativeDecodeUtf8: (array: Uint8Array) => string; + +/** + * accessibiltyChannel中的 + */ +export const nativeSetAccessibilityFeatures: (accessibilityFeatureFlags: number, responseId: number) => void; + +export const nativeAccessibilityStateChange: (state: Boolean) => string; + +export const nativeAnnounce: (message: string) => string; \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets index cd3cd81923431aedd613734d5a7953624ec63f81..db8dd00969b9c38310d298536922dc168cc32d90 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets @@ -34,11 +34,12 @@ import SystemChannel from './systemchannels/SystemChannel'; import MouseCursorChannel from './systemchannels/MouseCursorChannel'; import RestorationChannel from './systemchannels/RestorationChannel'; import LocalizationChannel from './systemchannels/LocalizationChannel'; -import AccessibilityChannel from './systemchannels/AccessibilityChannel'; +import AccessibilityChannel, { AccessibilityMessageHandler } from './systemchannels/AccessibilityChannel'; import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin' import SettingsChannel from './systemchannels/SettingsChannel'; import PlatformViewsController from '../../plugin/platform/PlatformViewsController'; import { FlutterRenderer } from './renderer/FlutterRenderer'; +import { ByteBuffer } from '../../util/ByteBuffer'; const TAG = "FlutterEngine"; @@ -123,6 +124,7 @@ export default class FlutterEngine implements EngineLifecycleListener{ this.localeChannel = new LocalizationChannel(this.dartExecutor); this.accessibilityChannel = new AccessibilityChannel(this.dartExecutor, this.flutterNapi); + this.accessibilityChannel.setAccessibilityMessageHandler(new AccessibilityMessageHandlerImp()); this.flutterNapi.addEngineLifecycleListener(this); this.localizationPlugin = new LocalizationPlugin(context, this.localeChannel); @@ -288,4 +290,27 @@ export interface EngineLifecycleListener { onPreEngineRestart(): void; onEngineWillDestroy(): void; +} +export class AccessibilityMessageHandlerImp implements AccessibilityMessageHandler { + announce(message: string): void { + Log.d(TAG, "handler announce."); + } + onTap(nodeId: number): void { + Log.d(TAG, "handler onTap."); + } + onLongPress(nodeId: number): void { + Log.d(TAG, "handler onLongPress."); + } + onTooltip(nodeId: string): void { + Log.d(TAG, "handler onTooltip."); + } + updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void { + Log.d(TAG, "handler updateSemantics"); + } + updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void { + Log.d(TAG, "handler updateCustomAccessibilityActions"); + } + accessibilityStateChange(state: Boolean): void{ + Log.d(TAG, "handler accessibilityStateChange"); + } } \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets index 6fcf4a574fde2c3b46e070c6159b36ec3b14597b..38f3de9ebcf8414bdb9eab0ebbf85d4429c760e2 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets @@ -331,7 +331,8 @@ export default class FlutterNapi { setAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void { if (this.isAttached()) { - this.nativeSetAccessibilityFeatures(accessibilityFeatureFlags, responseId); + // this.nativeSetAccessibilityFeatures(accessibilityFeatureFlags, responseId); + flutter.nativeSetAccessibilityFeatures(accessibilityFeatureFlags, responseId); } else { Log.w( TAG, @@ -344,7 +345,8 @@ export default class FlutterNapi { dispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void { if (this.isAttached()) { - this.nativeDispatchSemanticsAction(virtualViewId, action, responseId); + // this.nativeDispatchSemanticsAction(virtualViewId, action, responseId); + // flutter. } else { Log.w( TAG, @@ -366,6 +368,37 @@ export default class FlutterNapi { } } + + // debug updateSemantics + updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void { + this.ensureRunningOnMainThread(); + if(this.accessibilityDelegate != null) { + this.accessibilityDelegate.updateSemantics(buffer, strings, stringAttributeArgs); + } + // TODO(mattcarroll): log dropped messages when in debug mode + // (https://github.com/flutter/flutter/issues/25391) + Log.d(TAG, "updateSemantics is called"); + flutter.nativeUpdateSemantics(buffer, strings, stringAttributeArgs); + } + + updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void { + this.ensureRunningOnMainThread(); + if(this.accessibilityDelegate != null) { + this.accessibilityDelegate.updateCustomAccessibilityActions(buffer, strings); + } + Log.d(TAG, "updateCustomAccessibilityActions is called"); + flutter.nativeUpdateCustomAccessibilityActions(buffer, strings); + } + + accessibilityStateChange(state: Boolean): void { + this.ensureRunningOnMainThread(); + if(this.accessibilityDelegate != null) { + this.accessibilityDelegate.accessibilityStateChange(state); + } + Log.d(TAG, "accessibilityStateChange is called"); + flutter.nativeAccessibilityStateChange(state); + } + setLocalizationPlugin(localizationPlugin: LocalizationPlugin | null): void { this.localizationPlugin = localizationPlugin; } @@ -494,4 +527,6 @@ export interface AccessibilityDelegate { updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void; updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void; + + accessibilityStateChange(state: Boolean): void; } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets index 9b2f9ee6cfdcfa5bbee616474617b936344c7e42..bb733649ccbdd22abc0078fc74c117251a3a31a4 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets @@ -22,6 +22,8 @@ import { Action } from '../../../view/AccessibilityBridge' import StandardMessageCodec from '../../../plugin/common/StandardMessageCodec'; import StringUtils from '../../../util/StringUtils'; import Any from '../../../plugin/common/Any'; +import flutter from 'libflutter.so'; +import { ByteBuffer } from '../../../util/ByteBuffer'; /** * 辅助功能channel @@ -31,12 +33,12 @@ export default class AccessibilityChannel implements MessageHandler{ private static CHANNEL_NAME = "flutter/accessibility"; private channel: BasicMessageChannel; private flutterNapi: FlutterNapi; - private handler: AccessibilityMessageHandler | null = null; + private handler: AccessibilityMessageHandler = new DefaultHandler(); private nextReplyId: number = 1; onMessage(message: object, reply: Reply): void { if (this.handler == null) { - Log.i(AccessibilityChannel.TAG, "NULL"); + Log.i(AccessibilityChannel.TAG, "handler = NULL"); reply.reply(StringUtils.stringToArrayBuffer("")); return; } @@ -50,6 +52,7 @@ export default class AccessibilityChannel implements MessageHandler{ Log.i(AccessibilityChannel.TAG, "Announce"); let announceMessage: string = data.get("message"); if (announceMessage != null) { + Log.i(AccessibilityChannel.TAG, "message is " + announceMessage); this.handler.announce(announceMessage); } break; @@ -92,16 +95,19 @@ export default class AccessibilityChannel implements MessageHandler{ onOhosAccessibilityEnabled(): void { let replyId: number = this.nextReplyId++; this.flutterNapi.setSemanticsEnabled(true, replyId); + Log.i(AccessibilityChannel.TAG, "onOhosAccessibilityEnabled = true"); } onOhosAccessibilityFeatures(accessibilityFeatureFlags: number): void { let replyId: number = this.nextReplyId++; this.flutterNapi.setAccessibilityFeatures(accessibilityFeatureFlags, replyId); + Log.i(AccessibilityChannel.TAG, "onOhosAccessibilityFeatures"); } dispatchSemanticsAction(virtualViewId: number, action: Action): void { let replyId: number = this.nextReplyId++; this.flutterNapi.dispatchSemanticsAction(virtualViewId, action, replyId); + Log.i(AccessibilityChannel.TAG, "dispatchSemanticsAction"); } setAccessibilityMessageHandler(handler: AccessibilityMessageHandler): void { @@ -112,9 +118,35 @@ export default class AccessibilityChannel implements MessageHandler{ } -interface AccessibilityMessageHandler extends AccessibilityDelegate { +export interface AccessibilityMessageHandler extends AccessibilityDelegate { announce(message: string): void; onTap(nodeId: number): void; onLongPress(nodeId: number): void; onTooltip(nodeId: string): void; +} + +export class DefaultHandler implements AccessibilityMessageHandler { + private static TAG = "AccessibilityMessageHandler"; + announce(message: string): void { + Log.i(DefaultHandler.TAG, "handler announce."); + flutter.nativeAnnounce(message); + } + onTap(nodeId: number): void { + Log.i(DefaultHandler.TAG, "handler onTap."); + } + onLongPress(nodeId: number): void { + Log.i(DefaultHandler.TAG, "handler onLongPress."); + } + onTooltip(nodeId: string): void { + Log.i(DefaultHandler.TAG, "handler onTooltip."); + } + updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void { + Log.i(DefaultHandler.TAG, "handler updateSemantics"); + } + updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void { + Log.i(DefaultHandler.TAG, "handler updateCustomAccessibilityActions"); + } + accessibilityStateChange(state: Boolean): void{ + Log.i(DefaultHandler.TAG, "handler accessibilityStateChange"); + } } \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/PlatformPlugin.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/PlatformPlugin.ets index 15c04d38b43e7e5b9fa8a06e3708b55052ba8f82..965292d31dc2d1ba7ab5e1cfafce92521607abab 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/PlatformPlugin.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/PlatformPlugin.ets @@ -288,7 +288,6 @@ export class PlatformPluginCallback implements PlatformMessageHandler { FlutterManager.getInstance().setUseFullScreen(true); } else if (mode == SystemUiMode.EDGE_TO_EDGE) { //全屏显示,在应用程序上呈现状态和导航元素 - FlutterManager.getInstance().setUseFullScreen(false); uiConfig = ['status', 'navigation']; } else { return; diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets index ea9450d4aa0f140dceeb4a7925f46383a65d0ea3..aae15ba935e29f71d8f734b5505b8236b49af2d7 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets @@ -32,7 +32,7 @@ export class AccessibilityEventsDelegate { return true; } - setAccessibilityBridge (accessibilityBridge: AccessibilityBridge): void { + setAccessibilityBridge (accessibilityBridge: AccessibilityBridge | null): void { this.accessibilityBridge = accessibilityBridge; } } \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets index 9b297318100f532b931487a508f1b49677992e6e..4ec7c08ed0e002f68d80f1e8941df6f18eac1487 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets @@ -115,11 +115,11 @@ export default class PlatformViewsController implements PlatformViewsAccessibili } attachAccessibilityBridge(accessibilityBridge: AccessibilityBridge): void { - throw new Error('Method not implemented.'); + this.accessibilityEventsDelegate.setAccessibilityBridge(accessibilityBridge); } detachAccessibilityBridge(): void { - throw new Error('Method not implemented.'); + this.accessibilityEventsDelegate.setAccessibilityBridge(null); } createForPlatformViewLayer(request: PlatformViewCreationRequest): void { diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/AccessibilityBridge.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/AccessibilityBridge.ets index 0e08f41fe9171658365b4e2c806b075807ddc423..1cfc8a801a4b03ab5f46e1336879f916f9bcba05 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/AccessibilityBridge.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/AccessibilityBridge.ets @@ -12,11 +12,67 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import AccessibilityChannel, {AccessibilityMessageHandler} from '../embedding/engine/systemchannels/AccessibilityChannel'; +import { ByteBuffer } from '../util/ByteBuffer'; +import Log from '../util/Log'; + +const TAG = "AccessibilityBridge"; + +export default class AccessibilityBridge implements AccessibilityMessageHandler { + + private accessibilityChannel: AccessibilityChannel | null = null; -export default class AccessibilityBridge { constructor(){ } + + announce(message: string): void { + throw new Error('Method not implemented.'); + // android -> rootAccessibilityView.announceForAccessibility(message); + } + + onTap(nodeId: number): void { + throw new Error('Method not implemented.'); + // android -> sendAccessibilityEvent(nodeId, AccessibilityEvent.TYPE_VIEW_CLICKED); + } + + onLongPress(nodeId: number): void { + throw new Error('Method not implemented.'); + // android -> sendAccessibilityEvent(nodeId, AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); + } + + onTooltip(nodeId: string): void { + throw new Error('Method not implemented.'); + // android -> AccessibilityEvent e = + // obtainAccessibilityEvent(ROOT_NODE_ID, AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + // e.getText().add(message); + // sendAccessibilityEvent(e); + } + + /** + * updateSemantics、updateCustomAccessibilityActions的debug流程,该过程只在native c++层实现,后续会删除 + * @param buffer + * @param strings + * @param stringAttributeArgs + */ + updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void { + Log.d(TAG, "AccessibilityBridge.ets updateSemantics is called"); + } + + updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void { + Log.d(TAG, "AccessibilityBridge.ets updateCustomAccessibilityActions is called"); + + } + + accessibilityStateChange(state: Boolean): void{ + Log.d(TAG, "AccessibilityBridge.ets accessibilityStateChange is called"); + } + + /** + * TODO lack of AccessibilityManager.AccessibilityStateChangeListener + * Listener that is notified when accessibility is turned on/off. + */ + } export enum Action { diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index 03bdbc5b0845e3347894977acf72f17f61b2a3ef..75e449666f2c0ac093a09f35987fbd9d1eb4aeb4 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -26,6 +26,7 @@ import ArrayList from '@ohos.util.ArrayList'; import { EmbeddingNodeController } from '../embedding/ohos/EmbeddingNodeController'; import PlatformView, { Params } from '../plugin/platform/PlatformView'; import { JSON } from '@kit.ArkTS'; +import { accessibility } from '@kit.AccessibilityKit'; const TAG = "FlutterViewTag"; @@ -106,6 +107,11 @@ export class FlutterView { this.mainWindow?.on('windowSizeChange', this.windowSizeChangeCallback); this.mainWindow?.on('avoidAreaChange', this.avoidAreaChangeCallback); this.mainWindow?.on('windowStatusChange', this.windowStatusChangeCallback); + + accessibility.on('accessibilityStateChange', (data: boolean) => { + Log.i(TAG, `subscribe accessibility state change, result: ${JSON.stringify(data)}`); + this.flutterEngine?.getFlutterNapi()?.accessibilityStateChange(data); + }); } private windowSizeChangeCallback = (data: window.Size) => { @@ -174,6 +180,9 @@ export class FlutterView { this.mainWindow?.off('windowSizeChange', this.windowSizeChangeCallback); this.mainWindow?.off('avoidAreaChange', this.avoidAreaChangeCallback); this.mainWindow?.off('windowStatusChange', this.windowStatusChangeCallback); + accessibility.off('accessibilityStateChange', (data: boolean) => { + Log.i(TAG, `unsubscribe accessibility state change, result: ${JSON.stringify(data)}`); + }); } catch (e) { Log.e(TAG, "mainWindow off error: " + JSON.stringify(e)); } @@ -270,8 +279,7 @@ export class FlutterView { if (this.checkFullScreen && FlutterManager.getInstance().getFullScreenListener().useFullScreen()) { // 全屏显示 this.viewportMetrics.physicalViewPaddingTop = systemAvoidArea?.topRect.height ?? 0; this.viewportMetrics.physicalViewPaddingBottom = navigationAvoidArea?.bottomRect.height ?? 0; - } else { // 非全屏显示(保持规避效果) - // 顶部状态栏和底部导航栏规避为0,无平滑过渡效果 + } else { this.viewportMetrics.physicalViewPaddingTop = 0; this.viewportMetrics.physicalViewPaddingBottom = 0; } diff --git a/shell/platform/ohos/library_loader.cpp b/shell/platform/ohos/library_loader.cpp index 9106a4ace5b5db9a1619f9fe54f9db511145f97c..e70264a03ff437c047edc55b1fcc15818b2afb89 100644 --- a/shell/platform/ohos/library_loader.cpp +++ b/shell/platform/ohos/library_loader.cpp @@ -17,8 +17,8 @@ #include "flutter/shell/platform/ohos/ohos_main.h" #include "napi/native_api.h" #include "napi_common.h" -#include "ohos_xcomponent_adapter.h" #include "ohos_logging.h" +#include "ohos_xcomponent_adapter.h" // namespace flutter { @@ -129,12 +129,22 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_FUNCTION( "nativeSetTextureBackGroundPixelMap", flutter::PlatformViewOHOSNapi::nativeSetTextureBackGroundPixelMap), + DECLARE_NAPI_FUNCTION("nativeEncodeUtf8", + flutter::PlatformViewOHOSNapi::nativeEncodeUtf8), + DECLARE_NAPI_FUNCTION("nativeDecodeUtf8", + flutter::PlatformViewOHOSNapi::nativeDecodeUtf8), + DECLARE_NAPI_FUNCTION( + "nativeUpdateSemantics", + flutter::PlatformViewOHOSNapi::nativeUpdateSemantics), + DECLARE_NAPI_FUNCTION( + "nativeUpdateCustomAccessibilityActions", + flutter::PlatformViewOHOSNapi::nativeUpdateCustomAccessibilityActions), DECLARE_NAPI_FUNCTION( - "nativeEncodeUtf8", - flutter::PlatformViewOHOSNapi::nativeEncodeUtf8), + "nativeAccessibilityStateChange", + flutter::PlatformViewOHOSNapi::nativeAccessibilityStateChange), DECLARE_NAPI_FUNCTION( - "nativeDecodeUtf8", - flutter::PlatformViewOHOSNapi::nativeDecodeUtf8), + "nativeAnnounce", + flutter::PlatformViewOHOSNapi::nativeAnnounce), }; diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 76a61090a880fc6b31f83af1ec2f737bcb99f4d5..3a442bc21e7a4edf9a9167e26a31598ec11b751d 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -25,13 +25,14 @@ #include "flutter/fml/make_copyable.h" #include "flutter/fml/platform/ohos/napi_util.h" +#include "flutter/shell/platform/ohos/ohos_logging.h" #include "flutter/shell/platform/ohos/ohos_main.h" #include "flutter/shell/platform/ohos/ohos_shell_holder.h" +#include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" #include "flutter/shell/platform/ohos/surface/ohos_native_window.h" #include "flutter/shell/platform/ohos/types.h" #include "unicode/uchar.h" -#include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" -#include "flutter/shell/platform/ohos/ohos_logging.h" +#include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" #define OHOS_SHELL_HOLDER (reinterpret_cast(shell_holder)) namespace flutter { @@ -415,9 +416,10 @@ void PlatformViewOHOSNapi::DecodeImage(int64_t imageGeneratorAddress, void* inputData, size_t dataSize) { FML_DLOG(INFO) << "start decodeImage"; - platform_task_runner_->PostTask(fml::MakeCopyable( - [imageGeneratorAddress_ = imageGeneratorAddress, - inputData_ = std::move(inputData), dataSize_ = dataSize, this]() mutable { + platform_task_runner_->PostTask( + fml::MakeCopyable([imageGeneratorAddress_ = imageGeneratorAddress, + inputData_ = std::move(inputData), + dataSize_ = dataSize, this]() mutable { napi_value callbackParam[2]; callbackParam[0] = @@ -435,7 +437,9 @@ void PlatformViewOHOSNapi::DecodeImage(int64_t imageGeneratorAddress, })); } -void PlatformViewOHOSNapi::FlutterViewOnTouchEvent(std::shared_ptr touchPacketString, int size) { +void PlatformViewOHOSNapi::FlutterViewOnTouchEvent( + std::shared_ptr touchPacketString, + int size) { if (touchPacketString == nullptr) { FML_LOG(ERROR) << "Input parameter error"; return; @@ -445,11 +449,13 @@ void PlatformViewOHOSNapi::FlutterViewOnTouchEvent(std::shared_ptr( OhosMain::Get().GetSettings(), napi_facade, platform_loop); if (shell_holder->IsValid()) { - int64_t shell_holder_value = - reinterpret_cast(shell_holder.get()); + int64_t shell_holder_value = reinterpret_cast(shell_holder.get()); FML_DLOG(INFO) << "PlatformViewOHOSNapi shell_holder:" << shell_holder_value; napi_value id; @@ -596,7 +601,8 @@ napi_value PlatformViewOHOSNapi::nativeGetPixelMap(napi_env env, /** * 从当前的flutterNapi复制一个新的实例 */ -napi_value PlatformViewOHOSNapi::nativeSpawn(napi_env env, napi_callback_info info) { +napi_value PlatformViewOHOSNapi::nativeSpawn(napi_env env, + napi_callback_info info) { napi_status ret; size_t argc = 6; napi_value args[6] = {nullptr}; @@ -636,12 +642,14 @@ napi_value PlatformViewOHOSNapi::nativeSpawn(napi_env env, napi_callback_info in LOGD(" initialRoute: %{public}s", initial_route.c_str()); std::vector entrypoint_args; - if (fml::napi::SUCCESS != fml::napi::GetArrayString(env, args[4], entrypoint_args)) { + if (fml::napi::SUCCESS != + fml::napi::GetArrayString(env, args[4], entrypoint_args)) { LOGE("nativeRunBundleAndSnapshotFromLibrary GetArrayString error"); return nullptr; } - std::shared_ptr napi_facade = std::make_shared(env); + std::shared_ptr napi_facade = + std::make_shared(env); napi_create_reference(env, args[5], 1, &(napi_facade->ref_napi_obj_)); auto spawned_shell_holder = OHOS_SHELL_HOLDER->Spawn( @@ -653,7 +661,9 @@ napi_value PlatformViewOHOSNapi::nativeSpawn(napi_env env, napi_callback_info in } napi_value shell_holder_id; - napi_create_int64(env, reinterpret_cast(spawned_shell_holder.release()), &shell_holder_id); + napi_create_int64(env, + reinterpret_cast(spawned_shell_holder.release()), + &shell_holder_id); return shell_holder_id; } @@ -1447,9 +1457,8 @@ napi_value PlatformViewOHOSNapi::nativeGetSystemLanguages( napi_value PlatformViewOHOSNapi::nativeInitNativeImage( napi_env env, - napi_callback_info info) -{ - FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeInitNativeImage"; + napi_callback_info info) { + FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeInitNativeImage"; size_t argc = 3; napi_value args[3] = {nullptr}; int64_t shell_holder; @@ -1457,17 +1466,17 @@ napi_value PlatformViewOHOSNapi::nativeInitNativeImage( NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); - ImageNative *imageNative = OH_Image_InitImageNative(env, args[2]); + ImageNative* imageNative = OH_Image_InitImageNative(env, args[2]); // std::unique_ptr uImage; - OHOS_SHELL_HOLDER->GetPlatformView()->RegisterExternalTextureByImage(textureId, imageNative); + OHOS_SHELL_HOLDER->GetPlatformView()->RegisterExternalTextureByImage( + textureId, imageNative); return nullptr; } napi_value PlatformViewOHOSNapi::nativeRegisterTexture( napi_env env, - napi_callback_info info) -{ - FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeRegisterTexture"; + napi_callback_info info) { + FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeRegisterTexture"; size_t argc = 2; napi_value args[2] = {nullptr}; int64_t shell_holder; @@ -1475,17 +1484,17 @@ napi_value PlatformViewOHOSNapi::nativeRegisterTexture( NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); - int64_t surfaceId = OHOS_SHELL_HOLDER->GetPlatformView()->RegisterExternalTexture(textureId); + int64_t surfaceId = + OHOS_SHELL_HOLDER->GetPlatformView()->RegisterExternalTexture(textureId); napi_value res; napi_create_int64(env, surfaceId, &res); return res; } napi_value PlatformViewOHOSNapi::nativeUnregisterTexture( - napi_env env, - napi_callback_info info) -{ - FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeUnregisterTexture"; + napi_env env, + napi_callback_info info) { + FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeUnregisterTexture"; size_t argc = 2; napi_value args[2] = {nullptr}; int64_t shell_holder; @@ -1498,9 +1507,8 @@ napi_value PlatformViewOHOSNapi::nativeUnregisterTexture( } napi_value PlatformViewOHOSNapi::nativeMarkTextureFrameAvailable( - napi_env env, - napi_callback_info info) -{ + napi_env env, + napi_callback_info info) { size_t argc = 2; napi_value args[2] = {nullptr}; int64_t shell_holder; @@ -1513,10 +1521,9 @@ napi_value PlatformViewOHOSNapi::nativeMarkTextureFrameAvailable( } napi_value PlatformViewOHOSNapi::nativeRegisterPixelMap( - napi_env env, - napi_callback_info info) -{ - FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeRegisterPixelMap"; + napi_env env, + napi_callback_info info) { + FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeRegisterPixelMap"; size_t argc = 3; napi_value args[3] = {nullptr}; int64_t shell_holder; @@ -1524,16 +1531,16 @@ napi_value PlatformViewOHOSNapi::nativeRegisterPixelMap( NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); - NativePixelMap *nativePixelMap = OH_PixelMap_InitNativePixelMap(env, args[2]); - OHOS_SHELL_HOLDER->GetPlatformView()->RegisterExternalTextureByPixelMap(textureId, nativePixelMap); + NativePixelMap* nativePixelMap = OH_PixelMap_InitNativePixelMap(env, args[2]); + OHOS_SHELL_HOLDER->GetPlatformView()->RegisterExternalTextureByPixelMap( + textureId, nativePixelMap); return nullptr; } napi_value PlatformViewOHOSNapi::nativeSetTextureBackGroundPixelMap( - napi_env env, - napi_callback_info info) -{ - FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeSetTextureBackGroundPixelMap"; + napi_env env, + napi_callback_info info) { + FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeSetTextureBackGroundPixelMap"; size_t argc = 3; napi_value args[3] = {nullptr}; int64_t shell_holder; @@ -1541,8 +1548,9 @@ napi_value PlatformViewOHOSNapi::nativeSetTextureBackGroundPixelMap( NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); - NativePixelMap *nativePixelMap = OH_PixelMap_InitNativePixelMap(env, args[2]); - OHOS_SHELL_HOLDER->GetPlatformView()->SetExternalTextureBackGroundPixelMap(textureId, nativePixelMap); + NativePixelMap* nativePixelMap = OH_PixelMap_InitNativePixelMap(env, args[2]); + OHOS_SHELL_HOLDER->GetPlatformView()->SetExternalTextureBackGroundPixelMap( + textureId, nativePixelMap); return nullptr; } @@ -1577,36 +1585,41 @@ void PlatformViewOHOSNapi::SetPlatformTaskRunner( */ napi_value PlatformViewOHOSNapi::nativeXComponentAttachFlutterEngine( napi_env env, - napi_callback_info info){ - napi_status ret; - size_t argc = 2; - napi_value args[2] = {nullptr}; - std::string xcomponent_id; - int64_t shell_holder; - ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); - if (ret != napi_ok) { - FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine napi_get_cb_info error:" - << ret; - return nullptr; - } + napi_callback_info info) { + napi_status ret; + size_t argc = 2; + napi_value args[2] = {nullptr}; + std::string xcomponent_id; + int64_t shell_holder; + ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + if (ret != napi_ok) { + FML_DLOG(ERROR) + << "nativeXComponentAttachFlutterEngine napi_get_cb_info error:" << ret; + return nullptr; + } - if (fml::napi::GetString(env, args[0], xcomponent_id) != 0) { - FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine xcomponent_id GetString error"; - return nullptr; - } + if (fml::napi::GetString(env, args[0], xcomponent_id) != 0) { + FML_DLOG(ERROR) + << "nativeXComponentAttachFlutterEngine xcomponent_id GetString error"; + return nullptr; + } - ret = napi_get_value_int64(env, args[1], &shell_holder); - if (ret != napi_ok) { - FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine shell_holder napi_get_value_int64 error"; - return nullptr; - } - std::string shell_holder_str = std::to_string(shell_holder); + ret = napi_get_value_int64(env, args[1], &shell_holder); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine shell_holder " + "napi_get_value_int64 error"; + return nullptr; + } + std::string shell_holder_str = std::to_string(shell_holder); - LOGD("nativeXComponentAttachFlutterEngine xcomponent_id: %{public}s, shell_holder: %{public}ld ", - xcomponent_id.c_str(), shell_holder); + LOGD( + "nativeXComponentAttachFlutterEngine xcomponent_id: %{public}s, " + "shell_holder: %{public}ld ", + xcomponent_id.c_str(), shell_holder); - XComponentAdapter::GetInstance()->AttachFlutterEngine(xcomponent_id, shell_holder_str); - return nullptr; + XComponentAdapter::GetInstance()->AttachFlutterEngine(xcomponent_id, + shell_holder_str); + return nullptr; } /** * @brief xcomponent解除flutter引擎绑定 @@ -1617,31 +1630,34 @@ napi_value PlatformViewOHOSNapi::nativeXComponentAttachFlutterEngine( */ napi_value PlatformViewOHOSNapi::nativeXComponentDetachFlutterEngine( napi_env env, - napi_callback_info info){ - napi_status ret; - size_t argc = 2; - napi_value args[2] = {nullptr}; - std::string xcomponent_id; - int64_t shell_holder; - ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); - if (ret != napi_ok) { - FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine napi_get_cb_info error:" - << ret; - return nullptr; - } - if (fml::napi::GetString(env, args[0], xcomponent_id) != 0) { - FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine xcomponent_id GetString error"; - return nullptr; - } - ret = napi_get_value_int64(env, args[1], &shell_holder); - if (ret != napi_ok) { - FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine shell_holder napi_get_value_int64 error"; - return nullptr; - } - - LOGD("nativeXComponentDetachFlutterEngine xcomponent_id: %{public}s", xcomponent_id.c_str()); - XComponentAdapter::GetInstance()->DetachFlutterEngine(xcomponent_id); + napi_callback_info info) { + napi_status ret; + size_t argc = 2; + napi_value args[2] = {nullptr}; + std::string xcomponent_id; + int64_t shell_holder; + ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + if (ret != napi_ok) { + FML_DLOG(ERROR) + << "nativeXComponentAttachFlutterEngine napi_get_cb_info error:" << ret; + return nullptr; + } + if (fml::napi::GetString(env, args[0], xcomponent_id) != 0) { + FML_DLOG(ERROR) + << "nativeXComponentAttachFlutterEngine xcomponent_id GetString error"; return nullptr; + } + ret = napi_get_value_int64(env, args[1], &shell_holder); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine shell_holder " + "napi_get_value_int64 error"; + return nullptr; + } + + LOGD("nativeXComponentDetachFlutterEngine xcomponent_id: %{public}s", + xcomponent_id.c_str()); + XComponentAdapter::GetInstance()->DetachFlutterEngine(xcomponent_id); + return nullptr; } /** @@ -1657,74 +1673,82 @@ napi_value PlatformViewOHOSNapi::nativeXComponentDetachFlutterEngine( * @param timestamp: number * @return napi_value */ -napi_value PlatformViewOHOSNapi::nativeXComponentDispatchMouseWheel(napi_env env, napi_callback_info info) -{ - napi_status ret; - size_t argc = 8; - napi_value args[8] = {nullptr}; - int64_t shellHolder; - std::string xcomponentId; - std::string eventType; - int64_t fingerId; - double globalX; - double globalY; - double offsetY; - int64_t timestamp; - ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); - if (ret != napi_ok) { - FML_DLOG(ERROR) << "nativeXComponentDispatchMouseWheel napi_get_cb_info error:" - << ret; - return nullptr; - } - ret = napi_get_value_int64(env, args[0], &shellHolder); - if (ret != napi_ok) { - LOGE("nativeXComponentDispatchMouseWheel shellHolder napi_get_value_int64 error"); - return nullptr; - } - if (fml::napi::GetString(env, args[1], xcomponentId) != 0) { - FML_DLOG(ERROR) << "nativeXComponentDispatchMouseWheel xcomponentId GetString error"; - return nullptr; - } - if (fml::napi::GetString(env, args[2], eventType) != 0) { - FML_DLOG(ERROR) << "nativeXComponentDispatchMouseWheel eventType GetString error"; - return nullptr; - } - ret = napi_get_value_int64(env, args[3], &fingerId); - if (ret != napi_ok) { - LOGE("nativeXComponentDispatchMouseWheel fingerId napi_get_value_int64 error"); - return nullptr; - } - ret = napi_get_value_double(env, args[4], &globalX); - if (ret != napi_ok) { - LOGE("nativeXComponentDispatchMouseWheel globalX napi_get_value_double error"); - return nullptr; - } - ret = napi_get_value_double(env, args[5], &globalY); - if (ret != napi_ok) { - LOGE("nativeXComponentDispatchMouseWheel globalY napi_get_value_double error"); - return nullptr; - } - ret = napi_get_value_double(env, args[6], &offsetY); - if (ret != napi_ok) { - LOGE("nativeXComponentDispatchMouseWheel offsetY napi_get_value_double error"); - return nullptr; - } - ret = napi_get_value_int64(env, args[7], ×tamp); - if (ret != napi_ok) { - LOGE("nativeXComponentDispatchMouseWheel timestamp napi_get_value_int64 error"); - return nullptr; - } - flutter::mouseWheelEvent event { - eventType, - shellHolder, - fingerId, - globalX, - globalY, - offsetY, - timestamp - }; - XComponentAdapter::GetInstance()->OnMouseWheel(xcomponentId, event); +napi_value PlatformViewOHOSNapi::nativeXComponentDispatchMouseWheel( + napi_env env, + napi_callback_info info) { + napi_status ret; + size_t argc = 8; + napi_value args[8] = {nullptr}; + int64_t shellHolder; + std::string xcomponentId; + std::string eventType; + int64_t fingerId; + double globalX; + double globalY; + double offsetY; + int64_t timestamp; + ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + if (ret != napi_ok) { + FML_DLOG(ERROR) + << "nativeXComponentDispatchMouseWheel napi_get_cb_info error:" << ret; + return nullptr; + } + ret = napi_get_value_int64(env, args[0], &shellHolder); + if (ret != napi_ok) { + LOGE( + "nativeXComponentDispatchMouseWheel shellHolder napi_get_value_int64 " + "error"); + return nullptr; + } + if (fml::napi::GetString(env, args[1], xcomponentId) != 0) { + FML_DLOG(ERROR) + << "nativeXComponentDispatchMouseWheel xcomponentId GetString error"; + return nullptr; + } + if (fml::napi::GetString(env, args[2], eventType) != 0) { + FML_DLOG(ERROR) + << "nativeXComponentDispatchMouseWheel eventType GetString error"; + return nullptr; + } + ret = napi_get_value_int64(env, args[3], &fingerId); + if (ret != napi_ok) { + LOGE( + "nativeXComponentDispatchMouseWheel fingerId napi_get_value_int64 " + "error"); + return nullptr; + } + ret = napi_get_value_double(env, args[4], &globalX); + if (ret != napi_ok) { + LOGE( + "nativeXComponentDispatchMouseWheel globalX napi_get_value_double " + "error"); return nullptr; + } + ret = napi_get_value_double(env, args[5], &globalY); + if (ret != napi_ok) { + LOGE( + "nativeXComponentDispatchMouseWheel globalY napi_get_value_double " + "error"); + return nullptr; + } + ret = napi_get_value_double(env, args[6], &offsetY); + if (ret != napi_ok) { + LOGE( + "nativeXComponentDispatchMouseWheel offsetY napi_get_value_double " + "error"); + return nullptr; + } + ret = napi_get_value_int64(env, args[7], ×tamp); + if (ret != napi_ok) { + LOGE( + "nativeXComponentDispatchMouseWheel timestamp napi_get_value_int64 " + "error"); + return nullptr; + } + flutter::mouseWheelEvent event{eventType, shellHolder, fingerId, globalX, + globalY, offsetY, timestamp}; + XComponentAdapter::GetInstance()->OnMouseWheel(xcomponentId, event); + return nullptr; } /** @@ -1733,27 +1757,29 @@ napi_value PlatformViewOHOSNapi::nativeXComponentDispatchMouseWheel(napi_env env * @param str: string * @return napi_value */ -napi_value PlatformViewOHOSNapi::nativeEncodeUtf8(napi_env env, napi_callback_info info) -{ - size_t argc = 1; - napi_value args[1] = {nullptr}; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); - - size_t length = 0; - napi_get_value_string_utf8(env, args[0], nullptr, 0, &length); - - auto null_terminated_length = length + 1; - auto char_array = std::make_unique(null_terminated_length); - napi_get_value_string_utf8(env, args[0], char_array.get(), null_terminated_length, nullptr); - - void *data; - napi_value arraybuffer; - napi_create_arraybuffer(env, length, &data, &arraybuffer); - std::memcpy(data, char_array.get(), length); - - napi_value uint8_array; - napi_create_typedarray(env, napi_uint8_array, length, arraybuffer, 0, &uint8_array); - return uint8_array; +napi_value PlatformViewOHOSNapi::nativeEncodeUtf8(napi_env env, + napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + size_t length = 0; + napi_get_value_string_utf8(env, args[0], nullptr, 0, &length); + + auto null_terminated_length = length + 1; + auto char_array = std::make_unique(null_terminated_length); + napi_get_value_string_utf8(env, args[0], char_array.get(), + null_terminated_length, nullptr); + + void* data; + napi_value arraybuffer; + napi_create_arraybuffer(env, length, &data, &arraybuffer); + std::memcpy(data, char_array.get(), length); + + napi_value uint8_array; + napi_create_typedarray(env, napi_uint8_array, length, arraybuffer, 0, + &uint8_array); + return uint8_array; } /** @@ -1762,19 +1788,90 @@ napi_value PlatformViewOHOSNapi::nativeEncodeUtf8(napi_env env, napi_callback_in * @param array: Uint8Array * @return napi_value */ -napi_value PlatformViewOHOSNapi::nativeDecodeUtf8(napi_env env, napi_callback_info info) -{ - size_t argc = 1; - napi_value args[1] = {nullptr}; - napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); - - size_t size = 0; - void *data = nullptr; - napi_get_typedarray_info(env, args[0], nullptr, &size, &data, nullptr, nullptr); - - napi_value result; - napi_create_string_utf8(env, static_cast(data), size, &result); - return result; +napi_value PlatformViewOHOSNapi::nativeDecodeUtf8(napi_env env, + napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + size_t size = 0; + void* data = nullptr; + napi_get_typedarray_info(env, args[0], nullptr, &size, &data, nullptr, + nullptr); + + napi_value result; + napi_create_string_utf8(env, static_cast(data), size, &result); + return result; +} + +napi_value PlatformViewOHOSNapi::nativeUpdateSemantics( + napi_env env, + napi_callback_info info) { + // TODO ets calls c++ + + return nullptr; +} + +napi_value PlatformViewOHOSNapi::nativeUpdateCustomAccessibilityActions( + napi_env env, + napi_callback_info info) { + // TODO ets calls c++ + + return nullptr; +} +/** + * 监听获取系统的无障碍服务是否开启 + */ +napi_value PlatformViewOHOSNapi::nativeAccessibilityStateChange( + napi_env env, + napi_callback_info info) { + napi_status ret; + size_t argc = 1; + napi_value args[1] = {nullptr}; + ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "PlatformViewOHOSNapi::nativeAccessibilityStateChange " + "napi_get_cb_info error:" + << ret; + return nullptr; + } + bool state = false; + ret = napi_get_value_bool(env, args[0], &state); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "PlatformViewOHOSNapi::nativeAccessibilityStateChange " + "napi_get_value_bool error:" + << ret; + return nullptr; + } + LOGD( + "PlatformViewOHOSNapi::nativeAccessibilityStateChange state is: " + "%{public}s", + (state ? "true" : "false")); + // 传递到无障碍管理类 + auto ohosAccessibilityManager_ = std::make_shared(); + ohosAccessibilityManager_->setOhosAccessibilityEnabled(state); + return nullptr; +} + +napi_value PlatformViewOHOSNapi::nativeAnnounce( + napi_env env, + napi_callback_info info) { + + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + size_t length = 0; + napi_get_value_string_utf8(env, args[0], nullptr, 0, &length); + + auto null_terminated_length = length + 1; + auto char_array = std::make_unique(null_terminated_length); + napi_get_value_string_utf8(env, args[0], char_array.get(), + null_terminated_length, nullptr); + LOGD("1535 PlatformViewOHOSNapi::nativeAnnounce message: %{public}s", char_array.get()); + OhosAccessibilityBridge ohosAccessibilityBridge = flutter::OhosAccessibilityBridge::GetInstance(); + ohosAccessibilityBridge.announce(char_array); + return nullptr; } } // namespace flutter \ No newline at end of file diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.h b/shell/platform/ohos/napi/platform_view_ohos_napi.h index a155048ec58f67a8b251c0c2113fdffd482df458..c5712fd93d3e8e3449f49de65c8c4e034de90c08 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.h +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.h @@ -28,6 +28,8 @@ #include "flutter/shell/common/run_configuration.h" #include "flutter/shell/platform/ohos/napi_common.h" #include "napi/native_api.h" +#include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_manager.h" + // class for all c++ to call js function namespace flutter { @@ -38,13 +40,13 @@ struct locale { }; struct mouseWheelEvent { - std::string eventType; - int64_t shellHolder; - int64_t fingerId; - double globalX; - double globalY; - double offsetY; - int64_t timestamp; + std::string eventType; + int64_t shellHolder; + int64_t fingerId; + double globalX; + double globalY; + double offsetY; + int64_t timestamp; }; class PlatformViewOHOSNapi { @@ -82,7 +84,8 @@ class PlatformViewOHOSNapi { void* inputData, size_t dataSize); - void FlutterViewOnTouchEvent(std::shared_ptr touchPacketString, int size); + void FlutterViewOnTouchEvent(std::shared_ptr touchPacketString, + int size); static napi_value nativeUpdateRefreshRate( napi_env env, @@ -155,37 +158,30 @@ class PlatformViewOHOSNapi { napi_env env, napi_callback_info info); // 应用下发系统语言设置 - static napi_value nativeInitNativeImage( - napi_env env, - napi_callback_info info); + static napi_value nativeInitNativeImage(napi_env env, + napi_callback_info info); - static napi_value nativeUnregisterTexture( - napi_env env, - napi_callback_info info); + static napi_value nativeUnregisterTexture(napi_env env, + napi_callback_info info); - static napi_value nativeMarkTextureFrameAvailable( - napi_env env, - napi_callback_info info); + static napi_value nativeMarkTextureFrameAvailable(napi_env env, + napi_callback_info info); - static napi_value nativeRegisterPixelMap( - napi_env env, - napi_callback_info info); + static napi_value nativeRegisterPixelMap(napi_env env, + napi_callback_info info); - static napi_value nativeSetTextureBackGroundPixelMap( - napi_env env, - napi_callback_info info); + static napi_value nativeSetTextureBackGroundPixelMap(napi_env env, + napi_callback_info info); - static napi_value nativeRegisterTexture( - napi_env env, - napi_callback_info info); + static napi_value nativeRegisterTexture(napi_env env, + napi_callback_info info); // Surface相关,XComponent调用 static void SurfaceCreated(int64_t shell_holder, void* window); - static void SurfaceChanged( - int64_t shell_holder, - int32_t width, - int32_t height); + static void SurfaceChanged(int64_t shell_holder, + int32_t width, + int32_t height); static void SurfaceDestroyed(int64_t shell_holder); static int64_t GetShellHolder(); @@ -195,13 +191,23 @@ class PlatformViewOHOSNapi { static napi_value nativeXComponentDetachFlutterEngine( napi_env env, napi_callback_info info); - static napi_value nativeXComponentDispatchMouseWheel( + static napi_value nativeXComponentDispatchMouseWheel(napi_env env, + napi_callback_info info); + static napi_value nativeEncodeUtf8(napi_env env, napi_callback_info info); + static napi_value nativeDecodeUtf8(napi_env env, napi_callback_info info); + + /** + * debug --> ets call c++ + */ + static napi_value nativeUpdateSemantics(napi_env env, + napi_callback_info info); + static napi_value nativeUpdateCustomAccessibilityActions( napi_env env, napi_callback_info info); - static napi_value nativeEncodeUtf8( + static napi_value nativeAccessibilityStateChange( napi_env env, napi_callback_info info); - static napi_value nativeDecodeUtf8( + static napi_value nativeAnnounce( napi_env env, napi_callback_info info); @@ -210,6 +216,7 @@ class PlatformViewOHOSNapi { napi_ref ref_napi_obj_; static std::vector system_languages; fml::RefPtr platform_task_runner_; + std::shared_ptr ohosAccessibilityManager_; }; } // namespace flutter diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index 34c6193685561fe188732da54c4ac73dbff8a5b6..1af47e8786e2f3b8ffa8a8a29de69a214f407d0e 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -22,8 +22,9 @@ #include "flutter/shell/platform/ohos/ohos_surface_software.h" #include "flutter/shell/platform/ohos/platform_message_response_ohos.h" #include "napi_common.h" -#include "ohos_logging.h" #include "ohos_external_texture_gl.h" +#include "ohos_logging.h" +#include "flutter/shell/platform/ohos/platform_view_ohos_delegate.h" #include @@ -117,9 +118,11 @@ PlatformViewOHOS::PlatformViewOHOS( PlatformViewOHOS::~PlatformViewOHOS() { FML_LOG(INFO) << "PlatformViewOHOS::~PlatformViewOHOS"; - for (std::map::iterator it = contextDatas_.begin(); it != contextDatas_.end(); ++it) { + for (std::map::iterator it = contextDatas_.begin(); + it != contextDatas_.end(); ++it) { if (it->second != nullptr) { - OhosImageFrameData* data = reinterpret_cast(it->second); + OhosImageFrameData* data = + reinterpret_cast(it->second); delete data; data = nullptr; it->second = nullptr; @@ -199,8 +202,7 @@ void PlatformViewOHOS::SetDestroyed(bool isDestroyed) { } // |PlatformView| -void PlatformViewOHOS::NotifyDestroyed() -{ +void PlatformViewOHOS::NotifyDestroyed() { SetDestroyed(true); LOGI("PlatformViewOHOS NotifyDestroyed enter"); PlatformView::NotifyDestroyed(); @@ -290,11 +292,13 @@ void PlatformViewOHOS::UpdateAssetResolverByType( delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type); } -// todo +// todo accessbility_bridges void PlatformViewOHOS::UpdateSemantics( flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) { - FML_DLOG(INFO) << "UpdateSemantics"; + FML_DLOG(INFO) << "PlatformViewOHOS::UpdateSemantics"; + // platform_view_ohos_delegate_->UpdateSemantics(update, actions); + ax_bridge_delegate_->updateSemantics(update, actions); } // |PlatformView| @@ -421,17 +425,15 @@ void PlatformViewOHOS::FireFirstFrameCallback() { napi_facade_->FlutterViewOnFirstFrame(); } -void PlatformViewOHOS::RegisterExternalTextureByImage( - int64_t texture_id, - ImageNative* image) -{ +void PlatformViewOHOS::RegisterExternalTextureByImage(int64_t texture_id, + ImageNative* image) { if (ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { auto iter = external_texture_gl_.find(texture_id); if (iter != external_texture_gl_.end()) { iter->second->DispatchImage(image); } else { std::shared_ptr ohos_external_gl = - std::make_shared(texture_id, ohos_surface_); + std::make_shared(texture_id, ohos_surface_); external_texture_gl_[texture_id] = ohos_external_gl; RegisterTexture(ohos_external_gl); ohos_external_gl->DispatchImage(image); @@ -445,14 +447,14 @@ PointerDataDispatcherMaker PlatformViewOHOS::GetDispatcherMaker() { }; } -uint64_t PlatformViewOHOS::RegisterExternalTexture(int64_t texture_id) -{ +uint64_t PlatformViewOHOS::RegisterExternalTexture(int64_t texture_id) { uint64_t surface_id = 0; int ret = -1; if (ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { std::shared_ptr ohos_external_gl = - std::make_shared(texture_id, ohos_surface_); - ohos_external_gl->nativeImage_ = OH_NativeImage_Create(texture_id, GL_TEXTURE_EXTERNAL_OES); + std::make_shared(texture_id, ohos_surface_); + ohos_external_gl->nativeImage_ = + OH_NativeImage_Create(texture_id, GL_TEXTURE_EXTERNAL_OES); if (ohos_external_gl->nativeImage_ == nullptr) { FML_DLOG(ERROR) << "Error with OH_NativeImage_Create"; return surface_id; @@ -462,12 +464,15 @@ uint64_t PlatformViewOHOS::RegisterExternalTexture(int64_t texture_id) OH_OnFrameAvailableListener listener; listener.context = contextData; listener.onFrameAvailable = &PlatformViewOHOS::OnNativeImageFrameAvailable; - ret = OH_NativeImage_SetOnFrameAvailableListener(ohos_external_gl->nativeImage_, listener); + ret = OH_NativeImage_SetOnFrameAvailableListener( + ohos_external_gl->nativeImage_, listener); if (ret != 0) { - FML_DLOG(ERROR) << "Error with OH_NativeImage_SetOnFrameAvailableListener"; + FML_DLOG(ERROR) + << "Error with OH_NativeImage_SetOnFrameAvailableListener"; return surface_id; } - ret = OH_NativeImage_GetSurfaceId(ohos_external_gl->nativeImage_, &surface_id); + ret = OH_NativeImage_GetSurfaceId(ohos_external_gl->nativeImage_, + &surface_id); ohos_external_gl->first_update_ = false; if (ret != 0) { FML_DLOG(ERROR) << "Error with OH_NativeImage_GetSurfaceId"; @@ -479,48 +484,49 @@ uint64_t PlatformViewOHOS::RegisterExternalTexture(int64_t texture_id) return surface_id; } -void PlatformViewOHOS::OnNativeImageFrameAvailable(void *data) -{ - auto frameData = reinterpret_cast(data); +void PlatformViewOHOS::OnNativeImageFrameAvailable(void* data) { + auto frameData = reinterpret_cast(data); if (frameData == nullptr || frameData->context_ == nullptr) { - FML_DLOG(ERROR) << "OnNativeImageFrameAvailable, frameData or context_ is null."; + FML_DLOG(ERROR) + << "OnNativeImageFrameAvailable, frameData or context_ is null."; return; } if (frameData->context_->GetDestroyed()) { - FML_LOG(ERROR) << "OnNativeImageFrameAvailable NotifyDstroyed, will not MarkTextureFrameAvailable"; + FML_LOG(ERROR) << "OnNativeImageFrameAvailable NotifyDstroyed, will not " + "MarkTextureFrameAvailable"; return; } - std::shared_ptr ohos_surface = frameData->context_->ohos_surface_; + std::shared_ptr ohos_surface = + frameData->context_->ohos_surface_; const TaskRunners task_runners = frameData->context_->task_runners_; if (ohos_surface) { fml::TaskRunner::RunNowOrPostTask( - task_runners.GetPlatformTaskRunner(), - [frameData]() { + task_runners.GetPlatformTaskRunner(), [frameData]() { if (frameData->context_->GetDestroyed()) { - FML_LOG(ERROR) << "OnNativeImageFrameAvailable NotifyDstroyed, will not MarkTextureFrameAvailable"; + FML_LOG(ERROR) << "OnNativeImageFrameAvailable NotifyDstroyed, " + "will not MarkTextureFrameAvailable"; return; } - frameData->context_->MarkTextureFrameAvailable(frameData->texture_id_); + frameData->context_->MarkTextureFrameAvailable( + frameData->texture_id_); }); } } -void PlatformViewOHOS::UnRegisterExternalTexture(int64_t texture_id) -{ - FML_DLOG(INFO) << "PlatformViewOHOS::UnRegisterExternalTexture, texture_id=" << texture_id; +void PlatformViewOHOS::UnRegisterExternalTexture(int64_t texture_id) { + FML_DLOG(INFO) << "PlatformViewOHOS::UnRegisterExternalTexture, texture_id=" + << texture_id; external_texture_gl_.erase(texture_id); UnregisterTexture(texture_id); std::map::iterator it = contextDatas_.find(texture_id); if (it != contextDatas_.end()) { if (it->second != nullptr) { - OhosImageFrameData* data = reinterpret_cast(it->second); + OhosImageFrameData* data = + reinterpret_cast(it->second); task_runners_.GetPlatformTaskRunner()->PostDelayedTask( - [data_ = data]() { - delete data_; - }, - fml::TimeDelta::FromSeconds(2)); + [data_ = data]() { delete data_; }, fml::TimeDelta::FromSeconds(2)); data = nullptr; it->second = nullptr; } @@ -528,8 +534,9 @@ void PlatformViewOHOS::UnRegisterExternalTexture(int64_t texture_id) } } -void PlatformViewOHOS::RegisterExternalTextureByPixelMap(int64_t texture_id, NativePixelMap* pixelMap) -{ +void PlatformViewOHOS::RegisterExternalTextureByPixelMap( + int64_t texture_id, + NativePixelMap* pixelMap) { if (ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { auto iter = external_texture_gl_.find(texture_id); if (iter != external_texture_gl_.end()) { @@ -545,8 +552,9 @@ void PlatformViewOHOS::RegisterExternalTextureByPixelMap(int64_t texture_id, Nat } } -void PlatformViewOHOS::SetExternalTextureBackGroundPixelMap(int64_t texture_id, NativePixelMap* pixelMap) -{ +void PlatformViewOHOS::SetExternalTextureBackGroundPixelMap( + int64_t texture_id, + NativePixelMap* pixelMap) { if (ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { auto iter = external_texture_gl_.find(texture_id); if (iter != external_texture_gl_.end()) { @@ -555,14 +563,14 @@ void PlatformViewOHOS::SetExternalTextureBackGroundPixelMap(int64_t texture_id, } } -void PlatformViewOHOS::OnTouchEvent(const std::shared_ptr touchPacketString, int size) -{ +void PlatformViewOHOS::OnTouchEvent( + const std::shared_ptr touchPacketString, + int size) { return napi_facade_->FlutterViewOnTouchEvent(touchPacketString, size); } -OhosImageFrameData::OhosImageFrameData( - PlatformViewOHOS* context, - int64_t texture_id) +OhosImageFrameData::OhosImageFrameData(PlatformViewOHOS* context, + int64_t texture_id) : context_(context), texture_id_(texture_id) {} OhosImageFrameData::~OhosImageFrameData() = default; diff --git a/shell/platform/ohos/platform_view_ohos.h b/shell/platform/ohos/platform_view_ohos.h index cccbc048466eca73b9c5dd5ec496d5b7d36fb6fa..56916b705c802761a5b08312dd08b4d3c64e86be 100644 --- a/shell/platform/ohos/platform_view_ohos.h +++ b/shell/platform/ohos/platform_view_ohos.h @@ -35,6 +35,8 @@ #include "flutter/shell/platform/ohos/surface/ohos_snapshot_surface_producer.h" #include "flutter/shell/platform/ohos/surface/ohos_surface.h" #include "flutter/shell/platform/ohos/vsync_waiter_ohos.h" +#include "flutter/shell/platform/ohos/platform_view_ohos_delegate.h" +#include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" namespace flutter { @@ -139,6 +141,9 @@ class PlatformViewOHOS final : public PlatformView { std::map> external_texture_gl_; std::map contextDatas_; + std::shared_ptr platform_view_ohos_delegate_; + std::shared_ptr ax_bridge_delegate_; + static bool isDestroyed_; static pthread_mutex_t mutex_; diff --git a/shell/platform/ohos/platform_view_ohos_delegate.cpp b/shell/platform/ohos/platform_view_ohos_delegate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..16527e03856a51c246dc16698b5f6103b2521bee --- /dev/null +++ b/shell/platform/ohos/platform_view_ohos_delegate.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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. + */ + +#include "flutter/shell/platform/ohos/platform_view_ohos_delegate.h" +#include + +namespace flutter { + +void putStringAttributesIntoBuffer( + const StringAttributes& attributes, + int32_t* buffer_int32, + size_t& position, + std::vector>& string_attribute_args) { + if (attributes.empty()) { + buffer_int32[position++] = -1; + return; + } + buffer_int32[position++] = attributes.size(); + for (const auto& attribute : attributes) { + buffer_int32[position++] = attribute->start; + buffer_int32[position++] = attribute->end; + buffer_int32[position++] = static_cast(attribute->type); + switch (attribute->type) { + case StringAttributeType::kSpellOut: + buffer_int32[position++] = -1; + break; + case StringAttributeType::kLocale: + buffer_int32[position++] = string_attribute_args.size(); + std::shared_ptr locale_attribute = + std::static_pointer_cast(attribute); + string_attribute_args.push_back( + {locale_attribute->locale.begin(), locale_attribute->locale.end()}); + break; + } + } +} +// interaction between java and native, encoding the semantics info to bytebuffer +PlatformViewOHOSDelegate::PlatformViewOHOSDelegate( + std::shared_ptr napi_facade) + : napi_facade_(std::move(napi_facade)) {}; + +void PlatformViewOHOSDelegate::UpdateSemantics( + const flutter::SemanticsNodeUpdates& update, + const flutter::CustomAccessibilityActionUpdates& actions) { + constexpr size_t kBytesPerNode = 47 * sizeof(int32_t); + constexpr size_t kBytesPerChild = sizeof(int32_t); + constexpr size_t kBytesPerCustomAction = sizeof(int32_t); + constexpr size_t kBytesPerAction = 4 * sizeof(int32_t); + constexpr size_t kBytesPerStringAttribute = 4 * sizeof(int32_t); + + { + size_t num_bytes = 0; + for (const auto& value : update) { + num_bytes += kBytesPerNode; + num_bytes += + value.second.childrenInTraversalOrder.size() * kBytesPerChild; + num_bytes += value.second.childrenInHitTestOrder.size() * kBytesPerChild; + num_bytes += value.second.customAccessibilityActions.size() * + kBytesPerCustomAction; + num_bytes += + value.second.labelAttributes.size() * kBytesPerStringAttribute; + num_bytes += + value.second.valueAttributes.size() * kBytesPerStringAttribute; + num_bytes += value.second.increasedValueAttributes.size() * + kBytesPerStringAttribute; + num_bytes += value.second.decreasedValueAttributes.size() * + kBytesPerStringAttribute; + num_bytes += + value.second.hintAttributes.size() * kBytesPerStringAttribute; + } + // encode the updated nodes/actions into bytebuffer/strings + std::vector buffer(num_bytes); + std::vector strings; + std::vector> string_attribute_args; + + int32_t* buffer_int32 = reinterpret_cast(&buffer[0]); + float* buffer_float32 = reinterpret_cast(&buffer[0]); + + size_t position = 0; + for (const auto& value : update) { + // make sure you update kBytesPerNode and/or kBytesPerChild above to + // match the number of values you are sending. + const flutter::SemanticsNode& node = value.second; + buffer_int32[position++] = node.id; + buffer_int32[position++] = node.flags; + buffer_int32[position++] = node.actions; + buffer_int32[position++] = node.maxValueLength; + buffer_int32[position++] = node.currentValueLength; + buffer_int32[position++] = node.textSelectionBase; + buffer_int32[position++] = node.textSelectionExtent; + buffer_int32[position++] = node.platformViewId; + buffer_int32[position++] = node.scrollChildren; + buffer_int32[position++] = node.scrollIndex; + buffer_float32[position++] = static_cast(node.scrollPosition); + buffer_float32[position++] = static_cast(node.scrollExtentMax); + buffer_float32[position++] = static_cast(node.scrollExtentMin); + if (node.label.empty()) { + buffer_int32[position++] = -1; + } else { + buffer_int32[position++] = strings.size(); + strings.push_back(node.label); + } + + putStringAttributesIntoBuffer(node.labelAttributes, buffer_int32, + position, string_attribute_args); + if (node.value.empty()) { + buffer_int32[position++] = -1; + } else { + buffer_int32[position++] = strings.size(); + strings.push_back(node.value); + } + + putStringAttributesIntoBuffer(node.valueAttributes, buffer_int32, + position, string_attribute_args); + if (node.increasedValue.empty()) { + buffer_int32[position++] = -1; + } else { + buffer_int32[position++] = strings.size(); + strings.push_back(node.increasedValue); + } + + putStringAttributesIntoBuffer(node.increasedValueAttributes, buffer_int32, + position, string_attribute_args); + if (node.decreasedValue.empty()) { + buffer_int32[position++] = -1; + } else { + buffer_int32[position++] = strings.size(); + strings.push_back(node.decreasedValue); + } + + putStringAttributesIntoBuffer(node.decreasedValueAttributes, buffer_int32, + position, string_attribute_args); + + if (node.hint.empty()) { + buffer_int32[position++] = -1; + } else { + buffer_int32[position++] = strings.size(); + strings.push_back(node.hint); + } + + putStringAttributesIntoBuffer(node.hintAttributes, buffer_int32, position, + string_attribute_args); + + if (node.tooltip.empty()) { + buffer_int32[position++] = -1; + } else { + buffer_int32[position++] = strings.size(); + strings.push_back(node.tooltip); + } + + buffer_int32[position++] = node.textDirection; + buffer_float32[position++] = node.rect.left(); + buffer_float32[position++] = node.rect.top(); + buffer_float32[position++] = node.rect.right(); + buffer_float32[position++] = node.rect.bottom(); + node.transform.getColMajor(&buffer_float32[position]); + position += 16; + + buffer_int32[position++] = node.childrenInTraversalOrder.size(); + for (int32_t child : node.childrenInTraversalOrder) { + buffer_int32[position++] = child; + } + + for (int32_t child : node.childrenInHitTestOrder) { + buffer_int32[position++] = child; + } + + buffer_int32[position++] = node.customAccessibilityActions.size(); + for (int32_t child : node.customAccessibilityActions) { + buffer_int32[position++] = child; + } + } + + // custom accessibility actions. + size_t num_action_bytes = actions.size() * kBytesPerAction; + std::vector actions_buffer(num_action_bytes); + int32_t* actions_buffer_int32 = + reinterpret_cast(&actions_buffer[0]); + + std::vector action_strings; + size_t actions_position = 0; + for (const auto& value : actions) { + // If you edit this code, make sure you update kBytesPerAction + // to match the number of values you are sending. + const flutter::CustomAccessibilityAction& action = value.second; + actions_buffer_int32[actions_position++] = action.id; + actions_buffer_int32[actions_position++] = action.overrideId; + if (action.label.empty()) { + actions_buffer_int32[actions_position++] = -1; + } else { + actions_buffer_int32[actions_position++] = action_strings.size(); + action_strings.push_back(action.label); + } + if (action.hint.empty()) { + actions_buffer_int32[actions_position++] = -1; + } else { + actions_buffer_int32[actions_position++] = action_strings.size(); + action_strings.push_back(action.hint); + } + } + + if (!actions_buffer.empty()) { + // napi_facade_->FlutterViewUpdateCustomAccessibilityActions(actions_buffer, + // action_strings); + // ax_bridge_router_->updateCustomAccessibilityActions(actions_buffer, + // action_strings); + FML_DLOG(INFO) << "PlatformViewOHOSDelegate::" + "updateCustomAccessibilityActions is called"; + } + + if (!buffer.empty()) { + // napi_facade_->FlutterViewUpdateSemantics(buffer, strings, + // string_attribute_args); + // ax_bridge_router_->updateSemantics(buffer, strings, + // string_attribute_args); + FML_DLOG(INFO) << "PlatformViewOHOSDelegate::UpdateSemantics is called"; + } + } +} + +} // namespace flutter \ No newline at end of file diff --git a/shell/platform/ohos/platform_view_ohos_delegate.h b/shell/platform/ohos/platform_view_ohos_delegate.h new file mode 100644 index 0000000000000000000000000000000000000000..97f5d826fcc7c7f5d4dfbde6cd31aacdd10b2e01 --- /dev/null +++ b/shell/platform/ohos/platform_view_ohos_delegate.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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. + */ + +#ifndef SHELL_PLATFORM_OHOS_PLATFORM_VIEW_OHOS_DELEGATE +#define SHELL_PLATFORM_OHOS_PLATFORM_VIEW_OHOS_DELEGATE + +#include +#include +#include + +#include "flutter/shell/common/platform_view.h" +#include "flutter/shell/platform/ohos/napi/platform_view_ohos_napi.h" +#include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" + +namespace flutter { + +class PlatformViewOHOSDelegate { + public: +// PlatformViewOHOSDelegate() = default; +// ~PlatformViewOHOSDelegate() = default; + + explicit PlatformViewOHOSDelegate( + std::shared_ptr napi_facade); + + void UpdateSemantics( + const flutter::SemanticsNodeUpdates& update, + const flutter::CustomAccessibilityActionUpdates& actions); + + private: + const std::shared_ptr napi_facade_; + const std::shared_ptr ax_bridge_router_; +}; +} // namespace flutter +#endif \ No newline at end of file