From 7e664ac3d2ce78e216382d7ebadd08ae925a24f4 Mon Sep 17 00:00:00 2001 From: zjxi Date: Fri, 24 Jan 2025 11:12:20 +0800 Subject: [PATCH 1/6] =?UTF-8?q?refactor:=E4=BC=98=E5=8C=96=E5=9D=90?= =?UTF-8?q?=E6=A0=87=E5=AE=B9=E5=99=A8=E5=AD=98=E5=82=A8=E4=B8=BA=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E4=BD=93=E5=AD=97=E6=AE=B5=E5=AD=98=E5=82=A8=EF=BC=8C?= =?UTF-8?q?=E5=87=8F=E5=B0=91=E5=86=85=E5=AD=98=E5=BC=80=E9=94=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 20 +++++++++---------- .../accessibility/ohos_accessibility_bridge.h | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 16f9d4b7b6..90c7f43e9b 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -470,20 +470,21 @@ void OhosAccessibilityBridge::SetAbsoluteScreenRect(SemanticsNodeExtent& flutter float right, float bottom) { - g_screenRectMap[flutterNode.id] = AbsoluteRect{left, top, right, bottom}; + flutterNode.absoluteRect = {left, top, right, bottom}; FML_DLOG(INFO) << "SetAbsoluteScreenRect -> id=" << flutterNode.id << ", {" << left << ", " << top << ", " << right << ", "<< bottom << "> }"; } -AbsoluteRect OhosAccessibilityBridge::GetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode) +AbsoluteRect OhosAccessibilityBridge::GetAbsoluteScreenRect(const SemanticsNodeExtent& flutterNode) { - if (!g_screenRectMap.empty() && g_screenRectMap.count(flutterNode.id) > 0) { - return g_screenRectMap.at(flutterNode.id); - } else { - FML_DLOG(ERROR) << "GetAbsoluteScreenRect -> flutterNodeId=" - << flutterNode.id << " is not found !"; - return {}; - } + return flutterNode.absoluteRect; + // if (!g_screenRectMap.empty() && g_screenRectMap.count(flutterNode.id) > 0) { + // return g_screenRectMap.at(flutterNode.id); + // } else { + // FML_DLOG(ERROR) << "GetAbsoluteScreenRect -> flutterNodeId=" + // << flutterNode.id << " is not found !"; + // return {}; + // } } /** @@ -2012,7 +2013,6 @@ void OhosAccessibilityBridge::ClearFlutterSemanticsCaches() { g_flutterSemanticsTree.clear(); g_parentChildIdVec.clear(); - g_screenRectMap.clear(); Flutter_SendAccessibilityAsyncEvent( accessibilityFocusedNode.id, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUS_CLEARED); diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 673f762d37..6c73218b94 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -146,7 +146,7 @@ public: ArkUI_AccessibilityEventType eventType); void RelativeRectToScreenRect(SemanticsNodeExtent& node); - AbsoluteRect GetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode); + AbsoluteRect GetAbsoluteScreenRect(const SemanticsNodeExtent& flutterNode); void SetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode, float left, float top, @@ -174,7 +174,7 @@ private: std::unordered_map g_flutterSemanticsTree; std::vector> g_parentChildIdVec; - std::unordered_map g_screenRectMap; + // std::unordered_map g_screenRectMap; std::unordered_map g_globalTransformMap; SemanticsNodeExtent inputFocusedNode; -- Gitee From 2e5717875be5ee3dd49fc20b903f24f171585a69 Mon Sep 17 00:00:00 2001 From: zjxi Date: Fri, 24 Jan 2025 15:08:23 +0800 Subject: [PATCH 2/6] =?UTF-8?q?refactor:=E6=97=A0=E9=9A=9C=E7=A2=8D?= =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96-=E5=87=8F=E5=B0=91?= =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E9=9D=9E=E5=BF=85=E8=A6=81=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=AE=B9=E5=99=A8=E5=86=85=E5=AD=98=E5=BC=80=E5=AD=A6=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=87=8F=E5=B0=91=E5=86=97=E4=BD=99=E9=81=8D?= =?UTF-8?q?=E5=8E=86=E5=BC=80=E9=94=80=EF=BC=8C=E6=8F=90=E5=8D=87=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BD=93=E9=AA=8C=E6=B5=81=E7=95=85=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 147 ++++++------------ .../accessibility/ohos_accessibility_bridge.h | 14 +- 2 files changed, 54 insertions(+), 107 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 90c7f43e9b..68c9569a80 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -47,12 +47,10 @@ void OhosAccessibilityBridge::AccessibiltiyChangesWithXComponentId() xcomponentId_ = currXcompId; native_shell_holder_id_ = std::stoll(it->second->shellholderId_); g_flutterSemanticsTree = g_flutterSemanticsTreeXComponents[xcomponentId_]; - g_parentChildIdVec = g_parentChildIdVecXComponents[xcomponentId_]; FML_DLOG(INFO) << "AccessibiltiyChangesWithXComponentId -> xcomponentid:" << xcomponentId_; } else { xcomponentId_ = "oh_flutter_1"; g_flutterSemanticsTree = g_flutterSemanticsTreeXComponents[xcomponentId_]; - g_parentChildIdVec = g_parentChildIdVecXComponents[xcomponentId_]; FML_DLOG(INFO) << "AccessibiltiyChangesWithXComponentId -> xcomponentid:" << xcomponentId_; } } @@ -93,20 +91,6 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( } } -/** - * build the id mapping betwween parent node and its children nodes - */ -void OhosAccessibilityBridge::BuildParentChildNodeIdRelation( - const SemanticsNodeExtent& node) -{ - if (!IsNodeVisible(node)) { return; } - for (const auto& childId : node.childrenInTraversalOrder) { - auto childNode = GetFlutterSemanticsNode(childId); - if (!IsNodeVisible(childNode)) { continue; } - g_parentChildIdVec.emplace_back(std::make_pair(node.id, childId)); - } -} - /** * 从dart侧传递到c++侧的flutter无障碍语义树节点更新过程, * 路由新页面、滑动页面等操作会自动触发该语义树的更新 @@ -134,14 +118,8 @@ void OhosAccessibilityBridge::UpdateSemantics( // 构建flutter无障碍语义节点树 g_flutterSemanticsTree[nodeEx.id] = nodeEx; - // 构建flutter节点的父子id映射关系 - BuildParentChildNodeIdRelation(nodeEx); - //print semantics node and flags info for debugging - GetSemanticsNodeDebugInfo(nodeEx); - GetSemanticsFlagsDebugInfo(nodeEx); - - if (!IsNodeVisible(nodeEx)) { continue; } + // if (!IsNodeVisible(nodeEx)) { continue; } // 若当前节点为获焦 if (IsNodeFocused(nodeEx)) { @@ -154,20 +132,20 @@ void OhosAccessibilityBridge::UpdateSemantics( } } + // calculate the global tranfomr matrix and parent id for each node + ComputeGlobalTransformAndParentId(); + // 将更新后的flutter语义树和父子节点id映射缓存,保存到相应的xcomponent里面 g_flutterSemanticsTreeXComponents[xcomponentId_] = g_flutterSemanticsTree; - g_parentChildIdVecXComponents[xcomponentId_] = g_parentChildIdVec; - - // 页面内容更新事件 - Flutter_SendAccessibilityAsyncEvent(0, - ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); - LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); /* 针对更新后的节点进行事件处理 */ for (auto& nodeEx: updatedFlutterNodes) { FML_DLOG(INFO) << "*#*#* updated node.id=" << nodeEx.id; + //print semantics node and flags info for debugging + GetSemanticsNodeDebugInfo(nodeEx); + GetSemanticsFlagsDebugInfo(nodeEx); + // 当滑动节点产生滑动,并执行滑动处理 if (HasScrolled(nodeEx)) { LOGD("UpdateSemantics -> nodeId = %{public}d has scrolled", nodeEx.id); @@ -200,8 +178,6 @@ void OhosAccessibilityBridge::UpdateSemantics( ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); } } - // calculate the global tranfomr matrix for each node - ComputeGlobalTransform(); // 输出flutter语义树相关重要语义信息debug日志 GetSemanticsDebugInfo(); FML_DLOG(INFO) << "=== UpdateSemantics() is finished ==="; @@ -445,20 +421,16 @@ SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterSemanticsNode( */ int32_t OhosAccessibilityBridge::GetParentId(int64_t elementId) { - if (!g_parentChildIdVec.size()) { - FML_DLOG(WARNING) << "OhosAccessibilityBridge::GetParentId parentChildIdMap.size()=0"; - return ARKUI_ACCESSIBILITY_ROOT_PARENT_ID; - } if (elementId == -1 || elementId == 0) { return ARKUI_ACCESSIBILITY_ROOT_PARENT_ID; } - int32_t childElementId = static_cast(elementId); - for (const auto& item : g_parentChildIdVec) { - if (item.second == childElementId) { - return item.first; - } + int32_t id = static_cast(elementId); + auto node = GetFlutterSemanticsNode(id); + if (!g_flutterSemanticsTree.count(id)) { + LOGE("GetParentId: %{public}d is null", id); + return -1; } - return RET_ERROR_STATE_CODE; + return node.parentId; } /** @@ -478,37 +450,20 @@ void OhosAccessibilityBridge::SetAbsoluteScreenRect(SemanticsNodeExtent& flutter AbsoluteRect OhosAccessibilityBridge::GetAbsoluteScreenRect(const SemanticsNodeExtent& flutterNode) { return flutterNode.absoluteRect; - // if (!g_screenRectMap.empty() && g_screenRectMap.count(flutterNode.id) > 0) { - // return g_screenRectMap.at(flutterNode.id); - // } else { - // FML_DLOG(ERROR) << "GetAbsoluteScreenRect -> flutterNodeId=" - // << flutterNode.id << " is not found !"; - // return {}; - // } -} - -/** - * 获取flutter相对-绝对坐标映射的真实缩放系数 - */ -std::pair OhosAccessibilityBridge::GetRealScaleFactor() -{ - auto secondNode = GetFlutterSemanticsNode(1); - SkMatrix transform = secondNode.transform.asM33(); - auto scaleX = transform.get(SkMatrix::kMScaleX); - auto scaleY = transform.get(SkMatrix::kMScaleY); - return std::make_pair(scaleX, scaleY); } /** * calculate the global transform matrix for each node */ -void OhosAccessibilityBridge::ComputeGlobalTransform() +void OhosAccessibilityBridge::ComputeGlobalTransformAndParentId() { std::queue semanticsQue; - auto root = GetFlutterSemanticsNode(0); - semanticsQue.push(root); - g_globalTransformMap[root.id] = root.transform; + auto rootNode = GetFlutterSemanticsNode(0); + rootNode.globalTransform = rootNode.transform; + rootNode.parentId = ARKUI_ACCESSIBILITY_ROOT_PARENT_ID; + g_flutterSemanticsTree[rootNode.id] = rootNode; + semanticsQue.push(rootNode); while (!semanticsQue.empty()) { uint32_t queSize = semanticsQue.size(); @@ -518,8 +473,10 @@ void OhosAccessibilityBridge::ComputeGlobalTransform() for (const auto& childId: currNode.childrenInTraversalOrder) { auto childNode = GetFlutterSemanticsNode(childId); + childNode.parentId = currNode.id; + childNode.globalTransform = currNode.globalTransform * childNode.transform; + g_flutterSemanticsTree[childId] = childNode; semanticsQue.push(childNode); - g_globalTransformMap[childId] = g_globalTransformMap[currNode.id] * childNode.transform; } } } @@ -538,7 +495,8 @@ SkPoint OhosAccessibilityBridge::ApplyTransform( void OhosAccessibilityBridge::RelativeRectToScreenRect(SemanticsNodeExtent& node) { auto [left, top, right, bottom] = node.rect; - SkM44 globalTransform = g_globalTransformMap[node.id]; + // SkM44 globalTransform = g_globalTransformMap[node.id]; + SkM44 globalTransform = node.globalTransform; SkPoint points[4] = { SkPoint::Make(left, top), // top-left point @@ -1992,17 +1950,6 @@ void OhosAccessibilityBridge::RemoveSemanticsNode( "g_flutterSemanticsTree.szie()=0"; return; } - if (g_flutterSemanticsTree.find(nodeToBeRemoved.id) == - g_flutterSemanticsTree.end()) { - FML_DLOG(INFO) << "Attempted to remove a node that is not in the tree."; - } - int32_t nodeToBeRemovedParentId = GetParentId(nodeToBeRemoved.id); - for (auto it = g_parentChildIdVec.begin(); it != g_parentChildIdVec.end(); it++) { - if (it->first == nodeToBeRemovedParentId && - it->second == nodeToBeRemoved.id) { - g_parentChildIdVec.erase(it); - } - } } /** @@ -2012,7 +1959,6 @@ void OhosAccessibilityBridge::RemoveSemanticsNode( void OhosAccessibilityBridge::ClearFlutterSemanticsCaches() { g_flutterSemanticsTree.clear(); - g_parentChildIdVec.clear(); Flutter_SendAccessibilityAsyncEvent( accessibilityFocusedNode.id, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUS_CLEARED); @@ -2027,19 +1973,31 @@ SemanticsNodeExtent OhosAccessibilityBridge::UpdatetSemanticsNodeExtent( { SemanticsNodeExtent nodeEx = SemanticsNodeExtent(); // 获取更新前的flutter节点信息 - if (g_flutterSemanticsTree.size() > 0) { - auto prevNode = GetFlutterSemanticsNode(node.id); - nodeEx.hadPreviousConfig = true; - nodeEx.previousFlags = prevNode.flags; - nodeEx.previousActions = prevNode.actions; - nodeEx.previousTextSelectionBase = prevNode.textSelectionBase; - nodeEx.previousTextSelectionExtent = prevNode.textSelectionExtent; - nodeEx.previousScrollPosition = prevNode.scrollPosition; - nodeEx.previousScrollExtentMax = prevNode.scrollExtentMax; - nodeEx.previousScrollExtentMin = prevNode.scrollExtentMin; - nodeEx.previousValue = prevNode.value; - nodeEx.previousLabel = prevNode.label; - } + // if (g_flutterSemanticsTree.size() > 0) { + // auto prevNode = GetFlutterSemanticsNode(node.id); + // nodeEx.hadPreviousConfig = true; + // nodeEx.previousFlags = prevNode.flags; + // nodeEx.previousActions = prevNode.actions; + // nodeEx.previousTextSelectionBase = prevNode.textSelectionBase; + // nodeEx.previousTextSelectionExtent = prevNode.textSelectionExtent; + // nodeEx.previousScrollPosition = prevNode.scrollPosition; + // nodeEx.previousScrollExtentMax = prevNode.scrollExtentMax; + // nodeEx.previousScrollExtentMin = prevNode.scrollExtentMin; + // nodeEx.previousValue = prevNode.value; + // nodeEx.previousLabel = prevNode.label; + // } + + nodeEx.hadPreviousConfig = true; + nodeEx.previousFlags = nodeEx.flags; + nodeEx.previousActions = nodeEx.actions; + nodeEx.previousTextSelectionBase = nodeEx.textSelectionBase; + nodeEx.previousTextSelectionExtent = nodeEx.textSelectionExtent; + nodeEx.previousScrollPosition = nodeEx.scrollPosition; + nodeEx.previousScrollExtentMax = nodeEx.scrollExtentMax; + nodeEx.previousScrollExtentMin = nodeEx.scrollExtentMin; + nodeEx.previousValue = nodeEx.value; + nodeEx.previousLabel = nodeEx.label; + // 更新当前flutter节点信息 nodeEx.isNull = false; nodeEx.id = std::move(node.id); @@ -2083,6 +2041,7 @@ void OhosAccessibilityBridge::GetSemanticsNodeDebugInfo( FML_DLOG(INFO) << "-------------------SemanticsNode------------------"; SkMatrix _transform = node.transform.asM33(); FML_DLOG(INFO) << "node.id=" << node.id; + FML_DLOG(INFO) << "node.parentId=" << node.parentId; FML_DLOG(INFO) << "node.label=" << node.label; FML_DLOG(INFO) << "node.previousLabel=" << node.previousLabel; FML_DLOG(INFO) << "node.tooltip=" << node.tooltip; @@ -2217,10 +2176,6 @@ void OhosAccessibilityBridge::GetSemanticsDebugInfo() FML_DLOG(INFO) << "g_flutterSemanticsTree -> {" << item.first << ", " << item.second.id << "}"; } - for (const auto& item : g_parentChildIdVec) { - FML_DLOG(INFO) << "g_parentChildIdVec -> (" << item.first << ", " - << item.second << ")"; - } //打印按层次遍历排序的flutter语义树节点id数组 std::vector levelOrderTraversalTree = GetLevelOrderTraversalTree(0); for (const auto& item: levelOrderTraversalTree) { diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 6c73218b94..d57a18fec4 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -167,15 +167,9 @@ private: static std::unique_ptr bridgeInstance_; std::shared_ptr nativeAccessibilityChannel_; std::shared_ptr accessibilityFeatures_; - - std::unordered_map> g_flutterSemanticsTreeXComponents; - std::unordered_map>> g_parentChildIdVecXComponents; - std::unordered_map> g_screenRectMapXComponents; - + std::unordered_map g_flutterSemanticsTree; - std::vector> g_parentChildIdVec; - // std::unordered_map g_screenRectMap; - std::unordered_map g_globalTransformMap; + std::unordered_map> g_flutterSemanticsTreeXComponents; SemanticsNodeExtent inputFocusedNode; SemanticsNodeExtent lastInputFocusedNode; @@ -262,8 +256,7 @@ private: flutter::SemanticsAction ArkuiActionsToFlutterActions( ArkUI_Accessibility_ActionType arkui_action); - void BuildParentChildNodeIdRelation(const SemanticsNodeExtent& node); - void ComputeGlobalTransform(); + void ComputeGlobalTransformAndParentId(); void ConvertRectToGlobal(SemanticsNodeExtent& node); SkPoint ApplyTransform(SkPoint& point, const SkM44& transform); @@ -337,7 +330,6 @@ private: void RequestFocusWhenPageUpdate(int32_t requestFocusId); bool Contains(const std::string source, const std::string target); - std::pair GetRealScaleFactor(); void DoubleClickRouteToNewPage(SemanticsNodeExtent node); void GetSemanticsDebugInfo(); void AccessibiltiyChangesWithXComponentId(); -- Gitee From fbbad044b92012e019d9edb060cc9318108a99ab Mon Sep 17 00:00:00 2001 From: zjxi Date: Wed, 5 Feb 2025 20:24:32 +0800 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=E4=BC=98=E5=8C=96=E6=97=A0?= =?UTF-8?q?=E9=9A=9C=E7=A2=8D=E8=8A=82=E7=82=B9=E5=8A=A8=E4=BD=9C=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=AE=9E=E7=8E=B0=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E8=8A=82=E7=82=B9=E7=8A=B6=E6=80=81=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=86=97=E4=BD=99sort=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 240 +++++++----------- .../accessibility/ohos_accessibility_bridge.h | 36 +-- 2 files changed, 97 insertions(+), 179 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 68c9569a80..9ec00d774d 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "flutter/fml/logging.h" #include "flutter/shell/platform/ohos/ohos_logging.h" #include "flutter/shell/common/platform_view.h" @@ -100,7 +101,7 @@ void OhosAccessibilityBridge::UpdateSemantics( flutter::CustomAccessibilityActionUpdates actions) { FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics()"; - std::vector updatedFlutterNodes; + std::unordered_set updatedFlutterNodes; // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) if (isFlutterNavigated_) { @@ -112,29 +113,31 @@ void OhosAccessibilityBridge::UpdateSemantics( for (const auto& item : update) { // 获取当前更新的节点node const auto& node = item.second; - FML_DLOG(INFO) << "*#*#* node.id=" << node.id; // 更新扩展的SemanticsNode信息 auto nodeEx = UpdatetSemanticsNodeExtent(node); // 构建flutter无障碍语义节点树 g_flutterSemanticsTree[nodeEx.id] = nodeEx; - // if (!IsNodeVisible(nodeEx)) { continue; } + // print semantics node and flags info for debugging + GetSemanticsNodeDebugInfo(nodeEx); + GetSemanticsFlagsDebugInfo(nodeEx); + + if (!IsNodeVisible(nodeEx)) { continue; } - // 若当前节点为获焦 - if (IsNodeFocused(nodeEx)) { - inputFocusedNode = nodeEx; - } // 若当前节点和更新前节点信息不同,则加入更新节点数组 if (nodeEx.hadPreviousConfig) { - updatedFlutterNodes.emplace_back(nodeEx); + updatedFlutterNodes.emplace(nodeEx); FML_DLOG(INFO) << "updatedFlutterNodes -> node.id=" << nodeEx.id; } } - // calculate the global tranfomr matrix and parent id for each node + // calculate the global tranfom matrix and parent id for each node ComputeGlobalTransformAndParentId(); + Flutter_SendAccessibilityAsyncEvent( + 0, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); + // 将更新后的flutter语义树和父子节点id映射缓存,保存到相应的xcomponent里面 g_flutterSemanticsTreeXComponents[xcomponentId_] = g_flutterSemanticsTree; @@ -142,10 +145,6 @@ void OhosAccessibilityBridge::UpdateSemantics( for (auto& nodeEx: updatedFlutterNodes) { FML_DLOG(INFO) << "*#*#* updated node.id=" << nodeEx.id; - //print semantics node and flags info for debugging - GetSemanticsNodeDebugInfo(nodeEx); - GetSemanticsFlagsDebugInfo(nodeEx); - // 当滑动节点产生滑动,并执行滑动处理 if (HasScrolled(nodeEx)) { LOGD("UpdateSemantics -> nodeId = %{public}d has scrolled", nodeEx.id); @@ -170,7 +169,7 @@ void OhosAccessibilityBridge::UpdateSemantics( _elementInfo = nullptr; } - // 判断是否触发liveRegion活动区,当前节点是否活跃 nodeEx.HasFlag(FLAGS_::kIsLiveRegion) + // 判断是否触发liveRegion活动区,当前节点是否活跃 if (nodeEx.HasFlag(FLAGS_::kIsLiveRegion) && HasChangedLabel(nodeEx)) { FML_DLOG(INFO) << "liveRegion -> page content update, nodeEx.id=" << nodeEx.id; Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), @@ -178,8 +177,6 @@ void OhosAccessibilityBridge::UpdateSemantics( ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); } } - // 输出flutter语义树相关重要语义信息debug日志 - GetSemanticsDebugInfo(); FML_DLOG(INFO) << "=== UpdateSemantics() is finished ==="; } @@ -391,15 +388,7 @@ void OhosAccessibilityBridge::OnTooltip(std::unique_ptr& message) //获取根节点 SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterRootSemanticsNode() { - if (!g_flutterSemanticsTree.size()) { - LOGE("GetFlutterRootSemanticsNode: g_flutterSemanticsTree.size()=0"); - return {}; - } - if (g_flutterSemanticsTree.find(0) == g_flutterSemanticsTree.end()) { - LOGE("GetFlutterRootSemanticsNod: g_flutterSemanticsTree has no root id"); - return {}; - } - return g_flutterSemanticsTree.at(0); + return GetFlutterSemanticsNode(0); } /** @@ -408,12 +397,11 @@ SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterRootSemanticsNode() SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterSemanticsNode( int32_t id) { - if (g_flutterSemanticsTree.count(id) > 0) { - return g_flutterSemanticsTree.at(id); - } else { - LOGE("GetFlutterSemanticsNode g_flutterSemanticsTree = null"); - return {}; + auto it = g_flutterSemanticsTree.find(id); + if (it != g_flutterSemanticsTree.end()) { + return it->second; } + return {}; } /** @@ -426,7 +414,7 @@ int32_t OhosAccessibilityBridge::GetParentId(int64_t elementId) } int32_t id = static_cast(elementId); auto node = GetFlutterSemanticsNode(id); - if (!g_flutterSemanticsTree.count(id)) { + if (g_flutterSemanticsTree.find(id) == g_flutterSemanticsTree.end()) { LOGE("GetParentId: %{public}d is null", id); return -1; } @@ -525,95 +513,78 @@ void OhosAccessibilityBridge::RelativeRectToScreenRect(SemanticsNodeExtent& node */ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( ArkUI_AccessibilityElementInfo* elementInfoFromList, - std::string widget_type) + const SemanticsNodeExtent& node) { if (OHOS_API_VERSION < 13) { return; } auto OH_ArkUI_AccessibilityElementInfoSetOperationActions = OhosAccessibilityDDL::DLLoadSetElemOperActionsFunc(ArkUIAccessibilityConstant::ARKUI_SET_ACTIONS); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetOperationActions); - if (OHOSUtils::Contains(widget_type, EDIT_TEXT_WIDGET_NAME) || - OHOSUtils::Contains(widget_type, EDIT_MULTILINE_TEXT_WIDGET_NAME)) { - // set elementinfo action types - int32_t actionTypeNum = 10; - ArkUI_AccessibleAction actions[actionTypeNum]; - int32_t idx = 0; - actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; - actions[idx++].description = "获取焦点"; - actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; - actions[idx++].description = "清除焦点"; + + int32_t actionTypeNum = 30; // declare an unreachable array length + ArkUI_AccessibleAction actions[actionTypeNum]; + size_t idx = 0; // real length of array + if (node.HasAction(ACTIONS_::kTap)) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; - actions[idx++].description = "点击操作"; + actions[idx++].description = "click action"; + } + if (node.HasAction(ACTIONS_::kLongPress)) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_LONG_CLICK; - actions[idx++].description = "长按操作"; - actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY; - actions[idx++].description = "文本复制"; - actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_PASTE; - actions[idx++].description = "文本粘贴"; - actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CUT; - actions[idx++].description = "文本剪切"; - actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SELECT_TEXT; - actions[idx++].description = "文本选择"; + actions[idx++].description = "longClick action"; + } + if (node.HasAction(ACTIONS_::kSetText)) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_TEXT; - actions[idx++].description = "文本内容设置"; + actions[idx++].description = "setText action"; + } + if (node.HasAction(ACTIONS_::kSetSelection)) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_CURSOR_POSITION; - actions[idx].description = "光标位置设置"; - - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) - ); - } else if (OHOSUtils::Contains(widget_type, SCROLL_WIDGET_NAME)) { - // if node is a scrollable component - int32_t actionTypeNum = 5; - ArkUI_AccessibleAction actions[actionTypeNum]; - int32_t idx = 0; + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SELECT_TEXT; + actions[idx++].description = "setSelection action"; + } + if (node.HasAction(ACTIONS_::kCopy)) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; - actions[idx++].description = "获取焦点"; + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY; + actions[idx++].description = "copy action"; + } + if (node.HasAction(ACTIONS_::kCut)) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; - actions[idx++].description = "清除焦点"; + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CUT; + actions[idx++].description = "cut action"; + } + if (node.HasAction(ACTIONS_::kPaste)) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; - actions[idx++].description = "点击动作"; + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_PASTE; + actions[idx++].description = "paste action"; + } + if (node.HasAction(ACTIONS_::kScrollLeft) || + node.HasAction(ACTIONS_::kScrollUp) || + node.HasAction(ACTIONS_::kIncrease)) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_FORWARD; - actions[idx++].description = "向上滑动"; + actions[idx++].description = "scrollForward action"; + } + if (node.HasAction(ACTIONS_::kScrollRight) || + node.HasAction(ACTIONS_::kScrollDown) || + node.HasAction(ACTIONS_::kDecrease)) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_BACKWARD; - actions[idx].description = "向下滑动"; - - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) - ); - } else { - // set common component action types - int32_t actionTypeNum = 3; - ArkUI_AccessibleAction actions[actionTypeNum]; - int32_t idx = 0; - actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; - actions[idx++].description = "获取焦点"; + actions[idx++].description = "scrollBackward action"; + } + if (accessibilityFocusedNode.id != 0 && + accessibilityFocusedNode.id == node.id) { actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; - actions[idx++].description = "清除焦点"; + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; + actions[idx++].description = "clearFocus action"; + } else { actions[idx].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; - actions[idx].description = "点击动作"; - - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) - ); + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; + actions[idx++].description = "focus action"; } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, idx, actions) + ); } /** @@ -665,9 +636,9 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( // 设置root节点的action类型 std::string widgeType = GetNodeComponentType(flutterNode); if (elementId < 1) { - FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); + FlutterSetElementInfoOperationActions(elementInfoFromList, flutterNode); } else { - FlutterSetElementInfoOperationActions(elementInfoFromList, widgeType); + FlutterSetElementInfoOperationActions(elementInfoFromList, flutterNode); } // 设置当前节点的父节点id @@ -710,7 +681,6 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( int32_t childCount = flutterNode.childrenInTraversalOrder.size(); if (childCount > 0) { auto childrenIdsVec = flutterNode.childrenInTraversalOrder; - std::sort(childrenIdsVec.begin(), childrenIdsVec.end()); int64_t childNodeIds[childCount]; for (int32_t i = 0; i < childCount; i++) { childNodeIds[i] = static_cast(childrenIdsVec[i]); @@ -912,15 +882,11 @@ std::vector OhosAccessibilityBridge::GetLevelOrderTraversalTree(int32_t uint32_t queSize = semanticsQue.size(); for (uint32_t i=0; i(currNode.id)); - - std::sort(currNode.childrenInTraversalOrder.begin(), - currNode.childrenInTraversalOrder.end()); + for (const auto& childId: currNode.childrenInTraversalOrder) { auto childNode = GetFlutterSemanticsNode(childId); - semanticsQue.push(childNode); } } @@ -1069,8 +1035,6 @@ void OhosAccessibilityBridge::PerformClickAction( << ")" << " event: click(" << clickEventType << ")"; auto flutterTapAction = ArkuiActionsToFlutterActions(action); DispatchSemanticsAction(static_cast(elementId), flutterTapAction, {}); - // double click at button-like node for pushing page update - DoubleClickRouteToNewPage(flutterNode); } /** @@ -1163,16 +1127,6 @@ void OhosAccessibilityBridge::PerformScrollUpAction( elementId, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kIncrease, {}); } - std::string currComponetType = GetNodeComponentType(flutterNode); - if (OHOSUtils::Contains(currComponetType, SCROLL_WIDGET_NAME)) { - /** Scrolled event, sent when a scrollable component experiences a scroll event. 4096 */ - ArkUI_AccessibilityEventType scrollEventType1 = - ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SCROLLED; - Flutter_SendAccessibilityAsyncEvent(elementId, scrollEventType1); - FML_DLOG(INFO) - << "ExecuteAccessibilityAction -> action: scroll forward(" << action - << ")" << " event: scroll forward(" << scrollEventType1 << ")"; - } } /** @@ -1197,17 +1151,6 @@ void OhosAccessibilityBridge::PerformScrollDownAction( elementId, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kDecrease, {}); } - std::string currComponetType = GetNodeComponentType(flutterNode); - if (OHOSUtils::Contains(currComponetType, SCROLL_WIDGET_NAME)) { - /** Scrolled event, sent when a scrollable component experiences a - * scroll event. 4096 */ - ArkUI_AccessibilityEventType scrollEventType1 = - ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SCROLLED; - Flutter_SendAccessibilityAsyncEvent(elementId, scrollEventType1); - FML_DLOG(INFO) - << "ExecuteAccessibilityAction -> action: scroll forward(" << action - << ")" << " event: scroll forward(" << scrollEventType1 << ")"; - } } /** * perform invalid action in accessibility status @@ -1973,33 +1916,22 @@ SemanticsNodeExtent OhosAccessibilityBridge::UpdatetSemanticsNodeExtent( { SemanticsNodeExtent nodeEx = SemanticsNodeExtent(); // 获取更新前的flutter节点信息 - // if (g_flutterSemanticsTree.size() > 0) { - // auto prevNode = GetFlutterSemanticsNode(node.id); - // nodeEx.hadPreviousConfig = true; - // nodeEx.previousFlags = prevNode.flags; - // nodeEx.previousActions = prevNode.actions; - // nodeEx.previousTextSelectionBase = prevNode.textSelectionBase; - // nodeEx.previousTextSelectionExtent = prevNode.textSelectionExtent; - // nodeEx.previousScrollPosition = prevNode.scrollPosition; - // nodeEx.previousScrollExtentMax = prevNode.scrollExtentMax; - // nodeEx.previousScrollExtentMin = prevNode.scrollExtentMin; - // nodeEx.previousValue = prevNode.value; - // nodeEx.previousLabel = prevNode.label; - // } - - nodeEx.hadPreviousConfig = true; - nodeEx.previousFlags = nodeEx.flags; - nodeEx.previousActions = nodeEx.actions; - nodeEx.previousTextSelectionBase = nodeEx.textSelectionBase; - nodeEx.previousTextSelectionExtent = nodeEx.textSelectionExtent; - nodeEx.previousScrollPosition = nodeEx.scrollPosition; - nodeEx.previousScrollExtentMax = nodeEx.scrollExtentMax; - nodeEx.previousScrollExtentMin = nodeEx.scrollExtentMin; - nodeEx.previousValue = nodeEx.value; - nodeEx.previousLabel = nodeEx.label; + if (!g_flutterSemanticsTree.size()) { + auto prevNode = GetFlutterSemanticsNode(node.id); + nodeEx.hadPreviousConfig = true; + nodeEx.parentId = prevNode.parentId; + nodeEx.previousFlags = prevNode.flags; + nodeEx.previousActions = prevNode.actions; + nodeEx.previousTextSelectionBase = prevNode.textSelectionBase; + nodeEx.previousTextSelectionExtent = prevNode.textSelectionExtent; + nodeEx.previousScrollPosition = prevNode.scrollPosition; + nodeEx.previousScrollExtentMax = prevNode.scrollExtentMax; + nodeEx.previousScrollExtentMin = prevNode.scrollExtentMin; + nodeEx.previousValue = prevNode.value; + nodeEx.previousLabel = prevNode.label; + } // 更新当前flutter节点信息 - nodeEx.isNull = false; nodeEx.id = std::move(node.id); nodeEx.flags = std::move(node.flags); nodeEx.actions = std::move(node.actions); diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index d57a18fec4..f83a5e5ddf 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -53,7 +53,6 @@ struct AbsoluteRect { }; struct SemanticsNodeExtent : flutter::SemanticsNode { - bool isNull = false; SkM44 globalTransform = SkM44{}; AbsoluteRect absoluteRect = AbsoluteRect::MakeEmpty(); int32_t parentId = -1; @@ -68,14 +67,20 @@ struct SemanticsNodeExtent : flutter::SemanticsNode { double previousScrollExtentMin = std::nan(""); std::string previousValue; std::string previousLabel; - bool HasPrevAction(SemanticsAction action) const - { + bool HasPrevAction(SemanticsAction action) const { return (previousActions & this->actions) != 0; } - bool HasPrevFlag(SemanticsFlags flag) const - { + bool HasPrevFlag(SemanticsFlags flag) const { return (previousFlags & this->flags) != 0; } + bool operator==(const SemanticsNodeExtent& other) const { + return id == other.id; + } + struct Hash { + std::size_t operator()(const SemanticsNodeExtent& obj) const { + return std::hash()(obj.id); + } + }; }; /** @@ -171,8 +176,6 @@ private: std::unordered_map g_flutterSemanticsTree; std::unordered_map> g_flutterSemanticsTreeXComponents; - SemanticsNodeExtent inputFocusedNode; - SemanticsNodeExtent lastInputFocusedNode; SemanticsNodeExtent accessibilityFocusedNode; static const int32_t OHOS_API_VERSION; @@ -201,23 +204,6 @@ private: const std::string SWITCH_WIDGET_NAME = "Toggle"; const std::string SEEKBAR_WIDGET_NAME = "SeekBar"; - const std::map - ArkUI_ACTION_TYPE_MAP_ = { - {"invalid", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_INVALID}, - {"click", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK}, - {"long press", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_LONG_CLICK}, - {"focus acquisition", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS}, - {"focus clearance", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS}, - {"forward scroll", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_FORWARD}, - {"backward scroll", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_BACKWARD}, - {"copy text", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY}, - {"paste text", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_PASTE}, - {"cut text", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CUT}, - {"text selection", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SELECT_TEXT}, - {"set text", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_TEXT}, - {"text cursor position setting", ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_CURSOR_POSITION}, - }; - static const int32_t FOCUSABLE_FLAGS = static_cast(FLAGS_::kHasCheckedState) | static_cast(FLAGS_::kIsChecked) | @@ -244,7 +230,7 @@ private: int64_t elementId); void FlutterSetElementInfoOperationActions( ArkUI_AccessibilityElementInfo* elementInfoFromList, - std::string widget_type); + const SemanticsNodeExtent& node); void BuildArkUISemanticsTree( int64_t elementId, ArkUI_AccessibilityElementInfo* elementInfoFromList, -- Gitee From dbe34c1c9ba6278a7fae536a92c9b3136779f127 Mon Sep 17 00:00:00 2001 From: zjxi Date: Sat, 8 Feb 2025 12:06:28 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat:=E5=AE=9E=E7=8E=B0=E6=97=A0=E9=9A=9C?= =?UTF-8?q?=E7=A2=8DXComponent=E5=A4=9A=E5=AE=9E=E4=BE=8B=E5=9C=BA?= =?UTF-8?q?=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../native_accessibility_channel.cpp | 189 ++++++------ .../native_accessibility_channel.h | 3 +- .../ohos_accessibility_bridge.cpp | 278 +++++++++++++++++- .../accessibility/ohos_accessibility_bridge.h | 45 ++- .../accessibility/ohos_accessibility_ddl.cpp | 15 + .../accessibility/ohos_accessibility_ddl.h | 2 + .../ohos_accessibility_interface.h | 12 + .../src/main/cpp/types/libflutter/index.d.ets | 4 +- .../main/ets/embedding/engine/FlutterNapi.ets | 11 +- shell/platform/ohos/library_loader.cpp | 10 +- .../ohos/napi/platform_view_ohos_napi.cpp | 89 ++---- .../ohos/napi/platform_view_ohos_napi.h | 13 +- .../platform/ohos/ohos_xcomponent_adapter.cpp | 177 ++++++++++- shell/platform/ohos/ohos_xcomponent_adapter.h | 6 + shell/platform/ohos/platform_view_ohos.cpp | 67 ++++- shell/platform/ohos/platform_view_ohos.h | 13 + .../ohos/utils/arkui_accessibility_constant.h | 1 + 17 files changed, 727 insertions(+), 208 deletions(-) diff --git a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp index 7d571f3528..49a0773d35 100644 --- a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp +++ b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp @@ -18,116 +18,125 @@ namespace flutter { - NativeAccessibilityChannel::NativeAccessibilityChannel() {} +NativeAccessibilityChannel::NativeAccessibilityChannel() {} - NativeAccessibilityChannel::~NativeAccessibilityChannel() {} - - /** - * 通知flutter框架ohos平台无障碍屏幕朗读已开启 - */ - void NativeAccessibilityChannel::OnOhosAccessibilityEnabled(int64_t shellHolderId) - { - FML_DLOG(INFO) << "NativeAccessibilityChannel -> OnOhosAccessibilityEnabled"; +NativeAccessibilityChannel::~NativeAccessibilityChannel() {} + +/** + * 通知flutter框架ohos平台无障碍屏幕朗读已开启 + */ +void NativeAccessibilityChannel::OnOhosAccessibilityEnabled(int64_t shellHolderId) +{ + FML_DLOG(INFO) << "NativeAccessibilityChannel -> OnOhosAccessibilityEnabled, " + << "shellHolderId: " << shellHolderId; this->SetSemanticsEnabled(shellHolderId, true); - } +} - /** - * 通知flutter框架ohos平台无障碍屏幕朗读未开启 - */ - void NativeAccessibilityChannel::OnOhosAccessibilityDisabled(int64_t shellHolderId) - { - FML_DLOG(INFO) << "NativeAccessibilityChannel -> OnOhosAccessibilityDisabled"; +/** + * 通知flutter框架ohos平台无障碍屏幕朗读未开启 + */ +void NativeAccessibilityChannel::OnOhosAccessibilityDisabled(int64_t shellHolderId) +{ + FML_DLOG(INFO) << "NativeAccessibilityChannel -> OnOhosAccessibilityDisabled, " + << "shellHolderId: " << shellHolderId; this->SetSemanticsEnabled(shellHolderId, false); - } - - /** - * Native无障碍通道传递语义感知,若开启则实时更新语义树信息 - */ - void NativeAccessibilityChannel::SetSemanticsEnabled(int64_t shellHolderId, - bool enabled) - { +} + +/** + * Native无障碍通道传递语义感知,若开启则实时更新语义树信息 + */ +void NativeAccessibilityChannel::SetSemanticsEnabled(int64_t shellHolderId, + bool enabled) +{ auto ohos_shell_holder = reinterpret_cast(shellHolderId); ohos_shell_holder->GetPlatformView()->SetSemanticsEnabled(enabled); - } + FML_DLOG(INFO) << "NativeAccessibilityChannel -> SetSemanticsEnabled, " + << "shellHolderId: " << shellHolderId; +} - /** - * Native无障碍通道设置无障碍特征类型,如:无障碍导航、字体加粗等 - */ - void NativeAccessibilityChannel::SetAccessibilityFeatures(int64_t shellHolderId, - int32_t flags) - { +/** + * Native无障碍通道设置无障碍特征类型,如:无障碍导航、字体加粗等 + */ +void NativeAccessibilityChannel::SetAccessibilityFeatures(int64_t shellHolderId, + int32_t flags) +{ auto ohos_shell_holder = reinterpret_cast(shellHolderId); ohos_shell_holder->GetPlatformView()->SetAccessibilityFeatures(flags); - } + FML_DLOG(INFO) << "NativeAccessibilityChannel -> SetAccessibilityFeatures, " + << "shellHolderId: " << shellHolderId; +} - /** - * Native无障碍通道分发flutter屏幕语义动作,如:点击、滑动等 - */ - void NativeAccessibilityChannel::DispatchSemanticsAction( - int64_t shellHolderId, - int32_t id, - flutter::SemanticsAction action, - fml::MallocMapping args) - { +/** + * Native无障碍通道分发flutter屏幕语义动作,如:点击、滑动等 + */ +void NativeAccessibilityChannel::DispatchSemanticsAction( + int64_t shellHolderId, + int32_t id, + flutter::SemanticsAction action, + fml::MallocMapping args) +{ auto ohos_shell_holder = reinterpret_cast(shellHolderId); ohos_shell_holder->GetPlatformView()->PlatformView::DispatchSemanticsAction(id, action, std::move(args)); - } + FML_DLOG(INFO) << "NativeAccessibilityChannel -> DispatchSemanticsAction, " + << "shellHolderId: " << shellHolderId; +} - /** - * 更新flutter无障碍相关语义信息 - */ - void NativeAccessibilityChannel::UpdateSemantics( - flutter::SemanticsNodeUpdates update, - flutter::CustomAccessibilityActionUpdates actions) - { - OhosAccessibilityBridge::GetInstance()->UpdateSemantics(update, actions); - } +/** + * 更新flutter无障碍相关语义信息 + */ +void NativeAccessibilityChannel::UpdateSemantics( + flutter::SemanticsNodeUpdates update, + flutter::CustomAccessibilityActionUpdates actions, + std::string& xcomponentId) +{ + OhosAccessibilityBridge::GetInstance()->UpdateSemantics(update, actions, xcomponentId); +} - /** - * 设置无障碍消息处理器,通过无障碍通道发送处理dart侧传递的相关信息 - */ - void NativeAccessibilityChannel::SetAccessibilityMessageHandler( - std::shared_ptr handler) - { +/** + * 设置无障碍消息处理器,通过无障碍通道发送处理dart侧传递的相关信息 + */ +void NativeAccessibilityChannel::SetAccessibilityMessageHandler( + std::shared_ptr handler) +{ this->handler = handler; - } +} - /** - * 利用通道内部类AccessibilityMessageHandler处理主动播报事件 - */ - void NativeAccessibilityChannel::AccessibilityMessageHandler::Announce( - std::unique_ptr& message) - { - OhosAccessibilityBridge::GetInstance()->Announce(message); - } +/** + * 利用通道内部类AccessibilityMessageHandler处理主动播报事件 + */ +void NativeAccessibilityChannel::AccessibilityMessageHandler::Announce( + std::unique_ptr& message) +{ + OhosAccessibilityBridge::GetInstance()->Announce(message); +} - /** - * 利用通道内部类AccessibilityMessageHandler处理主动点击给定id组件事件 - */ - void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTap( - int32_t nodeId) - { - OhosAccessibilityBridge::GetInstance()->OnTap(nodeId); - } +/** + * 利用通道内部类AccessibilityMessageHandler处理主动点击给定id组件事件 + */ +void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTap( + int32_t nodeId) +{ + OhosAccessibilityBridge::GetInstance()->OnTap(nodeId); +} - /** - * 利用通道内部类AccessibilityMessageHandler处理主动长按给定id组件事件 - */ - void NativeAccessibilityChannel::AccessibilityMessageHandler::OnLongPress( - int32_t nodeId) - { - OhosAccessibilityBridge::GetInstance()->OnLongPress(nodeId); - } +/** + * 利用通道内部类AccessibilityMessageHandler处理主动长按给定id组件事件 + */ +void NativeAccessibilityChannel::AccessibilityMessageHandler::OnLongPress( + int32_t nodeId) +{ + OhosAccessibilityBridge::GetInstance()->OnLongPress(nodeId); +} - /** - * 利用通道内部类AccessibilityMessageHandler处理提示文字事件 - */ - void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTooltip( - std::unique_ptr& message) - { - OhosAccessibilityBridge::GetInstance()->OnTooltip(message); - } +/** + * 利用通道内部类AccessibilityMessageHandler处理提示文字事件 + */ +void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTooltip( + std::unique_ptr& message) +{ + OhosAccessibilityBridge::GetInstance()->OnTooltip(message); +} } \ No newline at end of file diff --git a/shell/platform/ohos/accessibility/native_accessibility_channel.h b/shell/platform/ohos/accessibility/native_accessibility_channel.h index 29d6e895c4..daa32ce0a8 100644 --- a/shell/platform/ohos/accessibility/native_accessibility_channel.h +++ b/shell/platform/ohos/accessibility/native_accessibility_channel.h @@ -39,7 +39,8 @@ class NativeAccessibilityChannel { fml::MallocMapping args); void UpdateSemantics(flutter::SemanticsNodeUpdates update, - flutter::CustomAccessibilityActionUpdates actions); + flutter::CustomAccessibilityActionUpdates actions, + std::string& xcomponentId); class AccessibilityMessageHandler { public: diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 9ec00d774d..ecd50cc727 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -56,6 +56,28 @@ void OhosAccessibilityBridge::AccessibiltiyChangesWithXComponentId() } } +void OhosAccessibilityBridge::GetFlutterSemanticsTreeWithInstance(const char* instanceId) +{ + auto xcompMap = XComponentAdapter::GetInstance()->xcomponetMap_; + // Splicing the prefix of xcomponetId (pure strings) and instanceId (numeric) + std::string xcomponentId = XCOMPONENT_ID_PREFIX; + xcomponentId.append(instanceId); + + auto it = xcompMap.find(xcomponentId); + if (!xcompMap.empty() && it != xcompMap.end()) { + xcomponentId_ = xcomponentId; + native_shell_holder_id_ = std::stoll(it->second->shellholderId_); + provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId); + g_flutterSemanticsTree = g_flutterSemanticsTreeXComponents[xcomponentId]; + FML_DLOG(INFO) << "GetFlutterSemanticsTreeWithInstance -> xcomponentid:" << xcomponentId; + } else { + xcomponentId_ = "oh_flutter_1"; + g_flutterSemanticsTree = g_flutterSemanticsTreeXComponents[xcomponentId_]; + FML_DLOG(INFO) << "GetFlutterSemanticsTreeWithInstance -> xcomponentid:" << xcomponentId_; + } + FML_DLOG(INFO) << "GetFlutterSemanticsTreeWithInstance -> xcomponentid:" << xcomponentId_; +} + /** * 采用局部静态变量配合call-once特性,实现线程安全的单例模式 */ @@ -69,8 +91,7 @@ OhosAccessibilityBridge* OhosAccessibilityBridge::GetInstance() } OhosAccessibilityBridge::OhosAccessibilityBridge() - : isFlutterNavigated_(false), - isAccessibilityEnabled_(false) {} + : isFlutterNavigated_(false), isAccessibilityEnabled_(false), provider_(nullptr) {} /** * 监听当前ohos平台是否开启无障碍屏幕朗读服务 @@ -85,10 +106,10 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( if (ohosAccessibilityEnabled) { isAccessibilityEnabled_ = ohosAccessibilityEnabled; - nativeAccessibilityChannel_->OnOhosAccessibilityEnabled(native_shell_holder_id_); + nativeAccessibilityChannel_->OnOhosAccessibilityEnabled(shellholderId); } else { - accessibilityFeatures_->SetAccessibleNavigation(false, native_shell_holder_id_); - nativeAccessibilityChannel_->OnOhosAccessibilityDisabled(native_shell_holder_id_); + accessibilityFeatures_->SetAccessibleNavigation(false, shellholderId); + nativeAccessibilityChannel_->OnOhosAccessibilityDisabled(shellholderId); } } @@ -98,9 +119,10 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( */ void OhosAccessibilityBridge::UpdateSemantics( flutter::SemanticsNodeUpdates update, - flutter::CustomAccessibilityActionUpdates actions) + flutter::CustomAccessibilityActionUpdates actions, + std::string& xcomponentId) { - FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics()"; + FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics(), xcomponentId: " << xcomponentId; std::unordered_set updatedFlutterNodes; // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) @@ -135,12 +157,13 @@ void OhosAccessibilityBridge::UpdateSemantics( // calculate the global tranfom matrix and parent id for each node ComputeGlobalTransformAndParentId(); + // 将更新后的flutter语义树和父子节点id映射缓存,保存到相应的xcomponent里面 + xcomponentId_ = xcomponentId; + g_flutterSemanticsTreeXComponents[xcomponentId] = g_flutterSemanticsTree; + Flutter_SendAccessibilityAsyncEvent( 0, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); - // 将更新后的flutter语义树和父子节点id映射缓存,保存到相应的xcomponent里面 - g_flutterSemanticsTreeXComponents[xcomponentId_] = g_flutterSemanticsTree; - /* 针对更新后的节点进行事件处理 */ for (auto& nodeEx: updatedFlutterNodes) { FML_DLOG(INFO) << "*#*#* updated node.id=" << nodeEx.id; @@ -280,7 +303,7 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) { if (OHOS_API_VERSION < 13) { return; } std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); - auto provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); + // auto provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); CHECK_NULL_PTR_RET_VOID(provider_, RequestFocusWhenPageUpdate); auto OH_ArkUI_CreateAccessibilityEventInfo = @@ -996,6 +1019,79 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL; } +/** + * Called to obtain element information based on a specified node with multi-instances. + * 无障碍多实例 -> FindAccessibilityNodeInfosById + */ +int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( + const char* instanceId, + int64_t elementId, + ArkUI_AccessibilitySearchMode mode, + int32_t requestId, + ArkUI_AccessibilityElementInfoList* elementList) +{ + if (OHOS_API_VERSION < 13) { return ARKUI_FAILED_CODE; } + FML_DLOG(INFO) + << "#### FindAccessibilityNodeInfosById input-params ####: elementId = " << elementId + << " mode=" << mode << " instanceId=" << instanceId; + CHECK_NULL_PTR_WITH_RET(elementList, FindAccessibilityNodeInfosById); + + // match the corresponding component instanceId to get the flutterSemanticsTree + GetFlutterSemanticsTreeWithInstance(instanceId); + + if (g_flutterSemanticsTree.size() == 0) { + FML_DLOG(INFO) + << "FindAccessibilityNodeInfosById g_flutterSemanticsTree is null"; + return ARKUI_ACCESSIBILITY_NATIVE_RESULT_FAILED; + } + + // 获取当前对应id的flutter节点,若为空则返回错误编码 + auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); + if (!g_flutterSemanticsTree.count(flutterNode.id)) { + LOGE("FindAccessibilityNodeInfosById: GetFlutterSemanticsNode id=%{public}ld is null", elementId); + } + + // 开启无障碍导航功能 + if(elementId == -1 || elementId == 0) { + accessibilityFeatures_->SetAccessibleNavigation(true, native_shell_holder_id_); + } + + // 从elementinfolist中获取elementinfo + auto OH_ArkUI_AddAndGetAccessibilityElementInfo = + OhosAccessibilityDDL::DLLoadGetElemFunc(ArkUIAccessibilityConstant::ARKUI_GET_A11Y_NODE); + CHECK_DLL_NULL_PTR(OH_ArkUI_AddAndGetAccessibilityElementInfo); + auto* elementInfoFromList = OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); + CHECK_NULL_PTR_WITH_RET(elementInfoFromList, OH_ArkUI_AddAndGetAccessibilityElementInfo); + + if (mode == ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_CURRENT) { + /** Search for current nodes. (mode = 0) */ + BuildArkUISemanticsTree(elementId, elementInfoFromList, elementList); + } else if (mode ==ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_PREDECESSORS) { + /** Search for parent nodes. (mode = 1) */ + if (IsNodeVisible(flutterNode)) { + FlutterSetElementInfoProperties(elementInfoFromList, elementId); + } + } else if (mode ==ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_SIBLINGS) { + /** Search for sibling nodes. (mode = 2) */ + if (IsNodeVisible(flutterNode)) { + FlutterSetElementInfoProperties(elementInfoFromList, elementId); + } + } else if (mode ==ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_CHILDREN) { + /** Search for child nodes at the next level. (mode = 4) */ + if (IsNodeVisible(flutterNode)) { + FlutterSetElementInfoProperties(elementInfoFromList, elementId); + } + } else if (mode ==ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_RECURSIVE_CHILDREN) { + /** Search for all child nodes. (mode = 8) */ + BuildArkUISemanticsTree(elementId, elementInfoFromList, elementList); + } else { + FlutterSetElementInfoProperties(elementInfoFromList, elementId); + } + FML_DLOG(INFO) << "--- FindAccessibilityNodeInfosById is end ---"; + + return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL; +} + /** * 解析flutter语义动作,并通过NativAccessibilityChannel分发 */ @@ -1403,6 +1499,113 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL; } +/** + * 无障碍多实例 -> ExecuteAccessibilityAction + * 执行语义动作解析,当FindAccessibilityNodeInfosById找到相应的elementinfo时才会触发该回调函数 + */ +int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( + const char* instanceId, + int64_t elementId, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments, + int32_t requestId) +{ + FML_DLOG(INFO) << "ExecuteAccessibilityAction input-params-> elementId=" + << elementId << " action=" << action << " instanceId=" << instanceId; + CHECK_NULL_PTR_WITH_RET(actionArguments, ExecuteAccessibilityAction); + + // match the corresponding component instanceId to get the flutterSemanticsTree + GetFlutterSemanticsTreeWithInstance(instanceId); + + // 获取当前elementid对应的flutter语义节点 + auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); + if (!g_flutterSemanticsTree.count(flutterNode.id)) { + LOGE("ExecuteAccessibilityAction: GetFlutterSemanticsNode id=%{public}ld is null", elementId); + } + + /** + * 将被遮挡的flutter节点显示在屏幕上 + * @NOTE: arkui无障碍缺少showOnScreen动作 + */ + PerformShowOnScreenAction(flutterNode); + + // 根据当前elementid和无障碍动作类型,发送无障碍事件 + switch (action) { + /** Response to a click. 16 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK: + PerformClickAction(elementId, action, flutterNode); + break; + + /** Response to a long click. 32 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_LONG_CLICK: + PerformLongClickAction(elementId, action, flutterNode); + break; + + /** Accessibility focus acquisition. 64 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS: + PerformGainFocusnAction(elementId, action, flutterNode); + break; + + /** Accessibility focus clearance. 128 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS: + PerformClearFocusAction(elementId, action, flutterNode); + break; + + /** Forward scroll action. 256 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_FORWARD: + PerformScrollUpAction(elementId, action, flutterNode); + break; + + /** Backward scroll action. 512 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_BACKWARD: + PerformScrollDownAction(elementId, action, flutterNode); + break; + + /** Copy action for text content. 1024 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY: + PerformClipboardAction(elementId, action); + break; + + /** Paste action for text content. 2048 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_PASTE: + PerformClipboardAction(elementId, action); + break; + + /** Cut action for text content. 4096 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CUT: + PerformClipboardAction(elementId, action); + break; + + /** Text selection action, requiring the setting of selectTextBegin, + * TextEnd, and TextInForward parameters to select a text + * segment in the text box. 8192 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SELECT_TEXT: + PerformSelectText(flutterNode, action, actionArguments); + break; + + /** Text content setting action. 16384 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_TEXT: + PerformSetText(flutterNode, action, actionArguments); + break; + + /** Cursor position setting action. 1048576 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_CURSOR_POSITION: + PerformSetCursorPosition(flutterNode, action, actionArguments); + break; + + /** Invalid action. 0 */ + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_INVALID: + PerformInvalidAction(elementId, action, flutterNode); + break; + + default: + /** custom semantics action */ + PerformCustomAction(flutterNode, action, actionArguments); + } + FML_DLOG(INFO) << "--- ExecuteAccessibilityAction is end ---"; + return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL; +} + /** * Called to obtain element information based on a specified node and text * content. @@ -1448,6 +1651,55 @@ int32_t OhosAccessibilityBridge::GetAccessibilityNodeCursorPosition( return 0; } +/** + * muliple xcomponent instance callbacks (unimplementation) + */ +int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosByText( + const char* instanceId, + int64_t elementId, + const char* text, + int32_t requestId, + ArkUI_AccessibilityElementInfoList* elementList) +{ + FML_DLOG(INFO) << "=== FindAccessibilityNodeInfosByText() ==="; + return 0; +} +int32_t OhosAccessibilityBridge::FindFocusedAccessibilityNode( + const char* instanceId, + int64_t elementId, + ArkUI_AccessibilityFocusType focusType, + int32_t requestId, + ArkUI_AccessibilityElementInfo* elementinfo) +{ + FML_DLOG(INFO) << "=== FindFocusedAccessibilityNode() ==="; + return 0; +} +int32_t OhosAccessibilityBridge::FindNextFocusAccessibilityNode( + const char* instanceId, + int64_t elementId, + ArkUI_AccessibilityFocusMoveDirection direction, + int32_t requestId, + ArkUI_AccessibilityElementInfo* elementList) { + FML_DLOG(INFO) << "=== FindNextFocusAccessibilityNode() ==="; + return 0; +} + +int32_t OhosAccessibilityBridge::ClearFocusedFocusAccessibilityNode( + const char* instanceId) +{ + FML_DLOG(INFO) << "=== ClearFocusedFocusAccessibilityNode() ==="; + return 0; +} +int32_t OhosAccessibilityBridge::GetAccessibilityNodeCursorPosition( + const char* instanceId, + int64_t elementId, + int32_t requestId, + int32_t* index) +{ + FML_DLOG(INFO) << "=== GetAccessibilityNodeCursorPosition() ==="; + return 0; +} + /** * 将arkui的action类型转化为flutter的action类型 */ @@ -1511,7 +1763,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAnnounceEvent( if (OHOS_API_VERSION < 13) { return; } AccessibiltiyChangesWithXComponentId(); std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); - auto provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); + provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); CHECK_NULL_PTR_RET_VOID(provider_, Flutter_SendAccessibilityAnnounceEvent); // 创建并设置屏幕朗读事件 @@ -1562,7 +1814,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( if (OHOS_API_VERSION < 13) { return; } AccessibiltiyChangesWithXComponentId(); std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); - auto provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); + provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); CHECK_NULL_PTR_RET_VOID(provider_, Flutter_SendAccessibilityAsyncEvent); // 创建eventInfo对象 diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index f83a5e5ddf..42c73be4c0 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -50,7 +50,6 @@ struct AbsoluteRect { float left, float top, float right, float bottom) { return AbsoluteRect{left, top, right, bottom}; } - }; struct SemanticsNodeExtent : flutter::SemanticsNode { SkM44 globalTransform = SkM44{}; @@ -99,7 +98,8 @@ public: void OnOhosAccessibilityStateChange(bool ohosAccessibilityEnabled, int64_t shellholderId); void UpdateSemantics(flutter::SemanticsNodeUpdates update, - flutter::CustomAccessibilityActionUpdates actions); + flutter::CustomAccessibilityActionUpdates actions, + std::string& xcomponentId); void DispatchSemanticsAction(int32_t id, flutter::SemanticsAction action, @@ -143,6 +143,43 @@ public: int32_t requestId, int32_t* index); + // mulitple xcomponent instances ArkUI callbacks + int32_t FindAccessibilityNodeInfosById( + const char* instance, + int64_t elementId, + ArkUI_AccessibilitySearchMode mode, + int32_t requestId, + ArkUI_AccessibilityElementInfoList* elementList); + int32_t FindAccessibilityNodeInfosByText( + const char* instance, + int64_t elementId, + const char* text, + int32_t requestId, + ArkUI_AccessibilityElementInfoList* elementList); + int32_t FindFocusedAccessibilityNode( + const char* instance, + int64_t elementId, + ArkUI_AccessibilityFocusType focusType, + int32_t requestId, + ArkUI_AccessibilityElementInfo* elementinfo); + int32_t FindNextFocusAccessibilityNode( + const char* instance, + int64_t elementId, + ArkUI_AccessibilityFocusMoveDirection direction, + int32_t requestId, + ArkUI_AccessibilityElementInfo* elementList); + int32_t ExecuteAccessibilityAction( + const char* instance, + int64_t elementId, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments, + int32_t requestId); + int32_t ClearFocusedFocusAccessibilityNode(const char* instance); + int32_t GetAccessibilityNodeCursorPosition(const char* instance, + int64_t elementId, + int32_t requestId, + int32_t* index); + void Flutter_SendAccessibilityAsyncEvent( int64_t elementId, ArkUI_AccessibilityEventType eventType); @@ -177,6 +214,7 @@ private: std::unordered_map> g_flutterSemanticsTreeXComponents; SemanticsNodeExtent accessibilityFocusedNode; + ArkUI_AccessibilityProvider* provider_; static const int32_t OHOS_API_VERSION; static const int32_t ARKUI_ACCESSIBILITY_ROOT_PARENT_ID = -2100000; @@ -204,6 +242,8 @@ private: const std::string SWITCH_WIDGET_NAME = "Toggle"; const std::string SEEKBAR_WIDGET_NAME = "SeekBar"; + const char* XCOMPONENT_ID_PREFIX = "oh_flutter_"; + static const int32_t FOCUSABLE_FLAGS = static_cast(FLAGS_::kHasCheckedState) | static_cast(FLAGS_::kIsChecked) | @@ -319,6 +359,7 @@ private: void DoubleClickRouteToNewPage(SemanticsNodeExtent node); void GetSemanticsDebugInfo(); void AccessibiltiyChangesWithXComponentId(); + void GetFlutterSemanticsTreeWithInstance(const char* instanceId); }; enum class AccessibilityAction : int32_t { diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.cpp index f4be1cadc6..507ad1589b 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.cpp @@ -34,6 +34,21 @@ RegisterFunc OhosAccessibilityDDL::DLLoadRegisterFunc(const char* symbolName) return symbol; } +RegisterWithInstanceFunc OhosAccessibilityDDL::DLLoadRegisterWithInstanceFunc(const char* symbolName) +{ + LIBHANDLE handler = LOAD_LIB(ACCESSIBILITY_LIB_NAME); + if (handler == nullptr) { + return nullptr; + } + + auto symbol = reinterpret_cast(LOAD_SYM(handler, symbolName)); + if (symbol == nullptr) { + CLOSE_LIB(handler); + return nullptr; + } + return symbol; +} + SendAsyncEventFunc OhosAccessibilityDDL::DLLoadSendAsyncEventFunc(const char* symbolName) { LIBHANDLE handler = LOAD_LIB(ACCESSIBILITY_LIB_NAME); diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h index 92f27eee15..93745b6634 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h @@ -21,6 +21,7 @@ namespace flutter { using RegisterFunc = int32_t (*)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityProviderCallbacks*); +using RegisterWithInstanceFunc = int32_t (*)(const char*, ArkUI_AccessibilityProvider*, ArkUI_AccessibilityProviderCallbacksWithInstance*); using SendAsyncEventFunc = void (*)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*)(int32_t)); using GetElemFunc = ArkUI_AccessibilityElementInfo* (*)(ArkUI_AccessibilityElementInfoList*); @@ -52,6 +53,7 @@ public: static constexpr char ACCESSIBILITY_LIB_NAME[] = "libflutter_accessibility.so"; static RegisterFunc DLLoadRegisterFunc(const char* symbolName); + static RegisterWithInstanceFunc DLLoadRegisterWithInstanceFunc(const char* symbolName); static SendAsyncEventFunc DLLoadSendAsyncEventFunc(const char* symbolName); static GetElemFunc DLLoadGetElemFunc(const char* symbolName); diff --git a/shell/platform/ohos/compatibility/ohos_accessibility_interface.h b/shell/platform/ohos/compatibility/ohos_accessibility_interface.h index 5a4ca0769d..b0178d0470 100644 --- a/shell/platform/ohos/compatibility/ohos_accessibility_interface.h +++ b/shell/platform/ohos/compatibility/ohos_accessibility_interface.h @@ -73,6 +73,18 @@ int32_t OH_NativeXComponent_GetNativeAccessibilityProvider( int32_t OH_ArkUI_AccessibilityProviderRegisterCallback( ArkUI_AccessibilityProvider* provider, ArkUI_AccessibilityProviderCallbacks* callbacks); +/** + * @brief Registers a callback with instance for this ArkUI_AccessibilityProvider instance. + * @param instanceId Indicates ID of third-party framework instance. + * @param provider Indicates the pointer to the ArkUI_AccessibilityProvider instance. + * @param callbacks Indicates the pointer to the ArkUI_AccessibilityProviderCallbacksWithInstance callback. + * @return Returns {@link ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL} if the operation is successful. + * Returns {@link ARKUI_ACCESSIBILITY_NATIVE_RESULT_BAD_PARAMETER} if a parameter is incorrect. + * @since 15 + */ +int32_t OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance(const char* instanceId, + ArkUI_AccessibilityProvider* provider, ArkUI_AccessibilityProviderCallbacksWithInstance* callbacks); + /** * @brief Sends accessibility event information. * 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 257b1e7225..e4a3cebf0a 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 @@ -181,4 +181,6 @@ export const nativeUnicodeIsRegionalIndicatorSymbol: (code: number) => number; export const nativeGetXComponentId: (id: string) => number; -export const nativeSetDVsyncSwitch: (nativeShellHolderId: number, isEnable: boolean) => void; \ No newline at end of file +export const nativeSetDVsyncSwitch: (nativeShellHolderId: number, isEnable: boolean) => void; + +export const nativeSetXComponentInfo: (platformViewOHOSAddr: number, nativeXComponentId: string, nativeShellHolderId: number) => void; \ 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 9b0104ec00..f81b75f1a1 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 @@ -46,7 +46,7 @@ export default class FlutterNapi { private static hasInit: boolean = false; //是否已实现 hasImplemented: boolean = false; - + nativeXComponentId : string | null = null; nativeShellHolderId: number | null = null; platformMessageHandler: PlatformMessageHandler | null = null; private engineLifecycleListeners = new Set(); @@ -322,6 +322,14 @@ export default class FlutterNapi { } } + /** + * Invoked by native c++ to get the xcomponent info (xcomponentid, shellholderid) + * via taking a platformViewOHOS address + */ + setXComponentInfo(platformViewOHOSAddr : number): void { + flutter.nativeSetXComponentInfo(platformViewOHOSAddr, this.nativeXComponentId!, this.nativeShellHolderId!); + } + setSemanticsEnabledWithRespId(enabled: boolean, responseId: number): void { this.ensureRunningOnMainThread(); if (this.isAttached()) { @@ -418,6 +426,7 @@ export default class FlutterNapi { * @param xcomponentId */ xComponentAttachFlutterEngine(xcomponentId: string) { + this.nativeXComponentId = xcomponentId; flutter.nativeXComponentAttachFlutterEngine(xcomponentId, this.nativeShellHolderId!); } diff --git a/shell/platform/ohos/library_loader.cpp b/shell/platform/ohos/library_loader.cpp index 51e4e24ee9..0d922772bb 100644 --- a/shell/platform/ohos/library_loader.cpp +++ b/shell/platform/ohos/library_loader.cpp @@ -19,6 +19,7 @@ #include "napi_common.h" #include "ohos_logging.h" #include "ohos_xcomponent_adapter.h" +#include "flutter/shell/platform/ohos/platform_view_ohos.h" // namespace flutter { @@ -30,6 +31,9 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_FUNCTION( "nativeImageDecodeCallback", flutter::OHOSImageGenerator::NativeImageDecodeCallback), + DECLARE_NAPI_FUNCTION( + "nativeSetXComponentInfo", + flutter::PlatformViewOHOS::NativeSetXComponentInfo), DECLARE_NAPI_FUNCTION( "nativeUpdateRefreshRate", flutter::PlatformViewOHOSNapi::nativeUpdateRefreshRate), @@ -160,15 +164,9 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_FUNCTION( "nativeAccessibilityOnTooltip", flutter::PlatformViewOHOSNapi::nativeAccessibilityOnTooltip), - DECLARE_NAPI_FUNCTION( - "nativeSetSemanticsEnabled", - flutter::PlatformViewOHOSNapi::nativeSetSemanticsEnabled), DECLARE_NAPI_FUNCTION( "nativeSetFontWeightScale", flutter::PlatformViewOHOSNapi::nativeSetFontWeightScale), - DECLARE_NAPI_FUNCTION( - "nativeGetShellHolderId", - flutter::PlatformViewOHOSNapi::nativeGetShellHolderId), DECLARE_NAPI_FUNCTION( "nativeDecodeUtf8", flutter::PlatformViewOHOSNapi::nativeDecodeUtf8), diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 51271961a8..183cc9d1a9 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -40,9 +40,9 @@ namespace flutter { napi_env PlatformViewOHOSNapi::env_; std::vector PlatformViewOHOSNapi::system_languages; -int64_t PlatformViewOHOSNapi::napi_shell_holder_id_; const int32_t PlatformViewOHOSNapi::OHOS_API_VERSION = OH_GetSdkApiVersion(); + /** * @brief send empty PlatformMessage * @note @@ -246,12 +246,6 @@ napi_value PlatformViewOHOSNapi::nativeInvokePlatformMessageResponseCallback( return nullptr; } -/* void PlatformViewOHOSNapi::FlutterViewHandlePlatformMessageResponse( - int responseId, - std::unique_ptr data) { - -} - */ PlatformViewOHOSNapi::PlatformViewOHOSNapi(napi_env env) {} void PlatformViewOHOSNapi::FlutterViewHandlePlatformMessageResponse( @@ -441,6 +435,22 @@ void PlatformViewOHOSNapi::DecodeImage(int64_t imageGeneratorAddress, })); } +void PlatformViewOHOSNapi::SetXcomponentInfo(int64_t platformViewOHOSAddr) { + FML_DLOG(INFO) << "PlatformViewOHOSNapi::SetXcomponentInfo()"; + // int64_t address = platformViewOHOSAddr; + napi_value callbackParam[1]; + napi_status status = + napi_create_int64(env_, platformViewOHOSAddr, &callbackParam[0]); + if (status != napi_ok) { + FML_DLOG(ERROR) << "napi_create_int64 SetXcomponentInfo failed "; + } + status = fml::napi::InvokeJsMethod(env_, ref_napi_obj_, "setXComponentInfo", + 1, callbackParam); + if (status != napi_ok) { + FML_DLOG(ERROR) << "InvokeJsMethod setXcomponentInfo failed "; + } +} + void PlatformViewOHOSNapi::FlutterViewOnTouchEvent( std::shared_ptr touchPacketString, int size) { @@ -1668,6 +1678,7 @@ napi_value PlatformViewOHOSNapi::nativeXComponentAttachFlutterEngine( XComponentAdapter::GetInstance()->AttachFlutterEngine(xcomponent_id, shell_holder_str); + return nullptr; } /** @@ -1977,52 +1988,6 @@ if (OHOS_API_VERSION >= 13) { return nullptr; } -napi_value PlatformViewOHOSNapi::nativeSetSemanticsEnabled(napi_env env, napi_callback_info info) { - napi_status ret; - size_t argc = 2; - napi_value args[2] = {nullptr}; - ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); - if (ret != napi_ok) { - FML_DLOG(ERROR) << "PlatformViewOHOSNapi::nativeSetSemanticsEnabled " - "napi_get_cb_info error:" - << ret; - return nullptr; - } - - int64_t shell_holder; - ret = napi_get_value_int64(env, args[0], &shell_holder); - if (ret != napi_ok) { - FML_DLOG(ERROR) << "PlatformViewOHOSNapi::nativeSetSemanticsEnabled " - "napi_get_value_int64 error:" - << ret; - return nullptr; - } - bool enabled = false; - ret = napi_get_value_bool(env, args[1], &enabled); - if (ret != napi_ok) { - FML_DLOG(ERROR) << "PlatformViewOHOSNapi::nativeSetSemanticsEnabled " - "napi_get_value_bool error:" - << ret; - return nullptr; - } - OHOS_SHELL_HOLDER->GetPlatformView()->SetSemanticsEnabled(enabled); - FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeSetSemanticsEnabled " - "OHOS_SHELL_HOLDER->GetPlatformView()->SetSemanticsEnabled= "<ClearFlutterSemanticsCaches(); - FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeSetSemanticsEnabled -> ClearFlutterSemanticsCaches()"; - } - - //给无障碍bridge传递nativeShellHolderId - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); - ohosAccessibilityBridge->native_shell_holder_id_ = shell_holder; - FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeSetSemanticsEnabled -> shell_holder:"< shell_holder:"< system_languages; fml::RefPtr platform_task_runner_; - static int64_t napi_shell_holder_id_; static const int32_t OHOS_API_VERSION; }; diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index a35325b3db..d069e68a1d 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -19,6 +19,7 @@ #include "ohos_logging.h" #include #include "flutter/fml/logging.h" +// #include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" namespace flutter { @@ -26,6 +27,8 @@ bool g_isMouseLeftActive = false; double g_scrollDistance = 0.0; double g_resizeRate = 0.8; +const int32_t OHOS_API_VERSION = OH_GetSdkApiVersion(); + XComponentAdapter XComponentAdapter::mXComponentAdapter; XComponentAdapter::XComponentAdapter(/* args */) {} @@ -66,6 +69,9 @@ bool XComponentAdapter::Export(napi_env env, napi_value exports) { std::string id(idStr); auto context = XComponentAdapter::GetInstance(); if (context) { + // give each PlatformViewOHOS::UpdateSemantics() a xcomponent id + context->xcomponentId_ = id; + LOGD("0090 -> xcomponentid: %{public}s", id.c_str()); context->SetNativeXComponent(id, nativeXComponent); return true; } @@ -307,6 +313,7 @@ int32_t ExecuteAccessibilityAction( /** Clears the focus status of the currently focused node */ int32_t ClearFocusedFocusAccessibilityNode() { + OhosAccessibilityBridge::GetInstance()->ClearFocusedFocusAccessibilityNode(); LOGD("accessibilityProviderCallback_.ClearFocusedFocusAccessibilityNode"); return 0; } @@ -322,14 +329,110 @@ int32_t GetAccessibilityNodeCursorPosition( return 0; } +/** Called when need to get element infos based on a specified node with multi-instances. */ +int32_t FindAccessibilityNodeInfosByIdWithInstance( + const char* instanceId, + int64_t elementId, + ArkUI_AccessibilitySearchMode mode, + int32_t requestId, + ArkUI_AccessibilityElementInfoList* elementList) +{ + OhosAccessibilityBridge::GetInstance()->FindAccessibilityNodeInfosById(instanceId, elementId, mode, requestId, elementList); + FML_DLOG(INFO) << "accessibilityProviderCallbackWithInstance_.FindAccessibilityNodeInfosByIdWithInstance"; + return 0; +} + +/** Performing the Action operation on a specified node with multi-instances. */ +int32_t ExecuteAccessibilityActionWithInstance( + const char* instanceId, + int64_t elementId, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments, + int32_t requestId) +{ + OhosAccessibilityBridge::GetInstance()->ExecuteAccessibilityAction(instanceId, elementId, action, actionArguments, requestId); + LOGD("accessibilityProviderCallbackWithInstance_.ExecuteAccessibilityActionWithInstance"); + return 0; +} + +/** Called when need to get element infos based on a specified node and text content. */ +int32_t FindAccessibilityNodeInfosByTextWithInstance( + const char* instanceId, + int64_t elementId, + const char* text, + int32_t requestId, + ArkUI_AccessibilityElementInfoList* elementList) +{ + OhosAccessibilityBridge::GetInstance()->FindAccessibilityNodeInfosByText(instanceId, elementId, text, requestId, elementList); + LOGD("accessibilityProviderCallback_.FindAccessibilityNodeInfosByTextWithInstance"); + return 0; +} + +/** Called when need to get the focused element info based on a specified node. */ +int32_t FindFocusedAccessibilityNodeWithInstance( + const char* instanceId, + int64_t elementId, + ArkUI_AccessibilityFocusType focusType, + int32_t requestId, + ArkUI_AccessibilityElementInfo* elementinfo) +{ + OhosAccessibilityBridge::GetInstance()->FindFocusedAccessibilityNode(instanceId, elementId, focusType, requestId, elementinfo); + LOGD("accessibilityProviderCallback_.FindFocusedAccessibilityNodeWithInstance"); + return 0; +} + +/** 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 FindNextFocusAccessibilityNodeWithInstance( + const char* instanceId, + int64_t elementId, + ArkUI_AccessibilityFocusMoveDirection direction, + int32_t requestId, + ArkUI_AccessibilityElementInfo *elementList) +{ + OhosAccessibilityBridge::GetInstance()->FindNextFocusAccessibilityNode(instanceId, elementId, direction, requestId, elementList); + LOGD("accessibilityProviderCallback_.FindNextFocusAccessibilityNodeWithInstance"); + return 0; +} + +/** Clears the focus status of the currently focused node */ +int32_t ClearFocusedFocusAccessibilityNodeWithInstance(const char* instanceId) +{ + OhosAccessibilityBridge::GetInstance()->ClearFocusedFocusAccessibilityNode(instanceId); + LOGD("accessibilityProviderCallback_.ClearFocusedFocusAccessibilityNodeWithInstance"); + return 0; +} + +/** Queries the current cursor position of a specified node. */ +int32_t GetAccessibilityNodeCursorPositionWithInstance( + const char* instanceId, + int64_t elementId, + int32_t requestId, + int32_t* index) +{ + OhosAccessibilityBridge::GetInstance()->GetAccessibilityNodeCursorPosition(instanceId, elementId, requestId, index); + LOGD("accessibilityProviderCallback_.GetAccessibilityNodeCursorPositionWithInstance"); + return 0; +} + void XComponentBase::BindAccessibilityProviderCallback() { - accessibilityProviderCallback_.findAccessibilityNodeInfosById = FindAccessibilityNodeInfosById; - accessibilityProviderCallback_.findAccessibilityNodeInfosByText = FindAccessibilityNodeInfosByText; - accessibilityProviderCallback_.findFocusedAccessibilityNode = FindFocusedAccessibilityNode; - accessibilityProviderCallback_.findNextFocusAccessibilityNode = FindNextFocusAccessibilityNode; - accessibilityProviderCallback_.executeAccessibilityAction = ExecuteAccessibilityAction; - accessibilityProviderCallback_.clearFocusedFocusAccessibilityNode = ClearFocusedFocusAccessibilityNode; - accessibilityProviderCallback_.getAccessibilityNodeCursorPosition = GetAccessibilityNodeCursorPosition; + if (OHOS_API_VERSION < 13) { return; } + if (OHOS_API_VERSION >= 13 && OHOS_API_VERSION < 15) { + accessibilityProviderCallback_.findAccessibilityNodeInfosById = FindAccessibilityNodeInfosById; + accessibilityProviderCallback_.findAccessibilityNodeInfosByText = FindAccessibilityNodeInfosByText; + accessibilityProviderCallback_.findFocusedAccessibilityNode = FindFocusedAccessibilityNode; + accessibilityProviderCallback_.findNextFocusAccessibilityNode = FindNextFocusAccessibilityNode; + accessibilityProviderCallback_.executeAccessibilityAction = ExecuteAccessibilityAction; + accessibilityProviderCallback_.clearFocusedFocusAccessibilityNode = ClearFocusedFocusAccessibilityNode; + accessibilityProviderCallback_.getAccessibilityNodeCursorPosition = GetAccessibilityNodeCursorPosition; + } else { + accessibilityProviderCallbackWithInstance_.findAccessibilityNodeInfosById = FindAccessibilityNodeInfosByIdWithInstance; + accessibilityProviderCallbackWithInstance_.executeAccessibilityAction = ExecuteAccessibilityActionWithInstance; + accessibilityProviderCallbackWithInstance_.findAccessibilityNodeInfosByText = FindAccessibilityNodeInfosByTextWithInstance; + accessibilityProviderCallbackWithInstance_.findFocusedAccessibilityNode = FindFocusedAccessibilityNodeWithInstance; + accessibilityProviderCallbackWithInstance_.findNextFocusAccessibilityNode = FindNextFocusAccessibilityNodeWithInstance; + accessibilityProviderCallbackWithInstance_.clearFocusedFocusAccessibilityNode = ClearFocusedFocusAccessibilityNodeWithInstance; + accessibilityProviderCallbackWithInstance_.getAccessibilityNodeCursorPosition = GetAccessibilityNodeCursorPositionWithInstance; + } } XComponentBase::XComponentBase(std::string id){ @@ -406,16 +509,58 @@ void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nati FML_DLOG(INFO) << "RegisterArkUIAccessibilityService is finished"; } +/** + * register accessibility service with mulitple xcomponent instances + */ +void XComponentBase::RegisterArkUIAccessibilityServiceWithInstance( + const char* instanceId, OH_NativeXComponent* nativeXComponent) +{ + BindAccessibilityProviderCallback(); + + auto OH_NativeXComponent_GetNativeAccessibilityProvider = + OhosAccessibilityDDL::DLLoadGetNativeA11yProvider(ArkUIAccessibilityConstant::OH_GET_A11Y_PROVIDER); + CHECK_DLL_NULL_PTR(OH_NativeXComponent_GetNativeAccessibilityProvider); + + ArkUI_AccessibilityProvider* a11yProvider = nullptr; + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_NativeXComponent_GetNativeAccessibilityProvider(nativeXComponent, &a11yProvider) + ); + + auto OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance = + OhosAccessibilityDDL::DLLoadRegisterWithInstanceFunc(ArkUIAccessibilityConstant::ARKUI_REGISTER_CALLBACK_MULTI_INSTANCES); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance); + CHECK_NULL_PTR(a11yProvider, RegisterArkUIAccessibilityServiceWithInstance); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance(instanceId, a11yProvider, &accessibilityProviderCallbackWithInstance_) + ); + + std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); + auto* base = XComponentAdapter::GetInstance()->xcomponetMap_[id_]; + base->accessibilityProvider_ = a11yProvider; + base->nativeXComponent_ = nativeXComponent; + + FML_DLOG(INFO) << "RegisterArkUIAccessibilityServiceWithInstance is finished"; +} + void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ - nativeXComponent_ = nativeXComponent; - if (nativeXComponent_ != nullptr) { - BindXComponentCallback(); - OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); - OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent_, &mouseCallback_); - // register the OH_ArkUI accessibility callbacks - if (OH_GetSdkApiVersion() < 13) { return; } - RegisterArkUIAccessibilityService(nativeXComponent_); - } + nativeXComponent_ = nativeXComponent; + if (nativeXComponent_ != nullptr) { + BindXComponentCallback(); + OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); + OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent_, &mouseCallback_); + // register the OH_ArkUI accessibility callbacks + if (OHOS_API_VERSION < 13) { return; } + if (OHOS_API_VERSION >= 13 && OHOS_API_VERSION < 15) { + RegisterArkUIAccessibilityService(nativeXComponent_); + } else { + std::string xcomponentId = id_; + LOGD("RegisterArkUIAccessibilityServiceWithInstance -> xcomponentId: %{public}s", xcomponentId.c_str()); + // extract the instanceId number from xcomponent id by cutting the prefix of xcomponentId; + auto instanceId = xcomponentId.substr(xcomponentIdPrefix_.size()); + LOGD("RegisterArkUIAccessibilityServiceWithInstance -> instanceId: %{public}s", instanceId.c_str()); + RegisterArkUIAccessibilityServiceWithInstance(instanceId.c_str(), nativeXComponent_); + } + } } void XComponentBase::OnSurfaceCreated(OH_NativeXComponent* component, diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.h b/shell/platform/ohos/ohos_xcomponent_adapter.h index 632e9d216d..6d8075ef23 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.h +++ b/shell/platform/ohos/ohos_xcomponent_adapter.h @@ -34,6 +34,7 @@ class XComponentBase private: void BindXComponentCallback(); void BindAccessibilityProviderCallback(); + std::string xcomponentIdPrefix_ = "oh_flutter_"; public: XComponentBase(std::string id); @@ -53,11 +54,14 @@ public: void RegisterArkUIAccessibilityService( OH_NativeXComponent* nativeXComponent); + void RegisterArkUIAccessibilityServiceWithInstance( + const char* instanceId, OH_NativeXComponent* nativeXComponent); OH_NativeXComponent_TouchEvent touchEvent_; OH_NativeXComponent_Callback callback_; OH_NativeXComponent_MouseEvent_Callback mouseCallback_; ArkUI_AccessibilityProviderCallbacks accessibilityProviderCallback_; + ArkUI_AccessibilityProviderCallbacksWithInstance accessibilityProviderCallbackWithInstance_; std::string id_; std::string shellholderId_; @@ -69,6 +73,7 @@ public: uint64_t height_; OhosTouchProcessor ohosTouchProcessor_; ArkUI_AccessibilityProvider* accessibilityProvider_; + }; class XComponentAdapter { @@ -89,6 +94,7 @@ class XComponentAdapter { std::map xcomponetMap_; std::string currentXComponentId_; std::mutex mutex_; + std::string xcomponentId_; private: static XComponentAdapter mXComponentAdapter; diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index e9944104c0..9536b85c3b 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -14,6 +14,7 @@ */ #include "flutter/shell/platform/ohos/platform_view_ohos.h" +#include #include "flutter/fml/make_copyable.h" #include "flutter/lib/ui/window/viewport_metrics.h" #include "flutter/shell/common/shell_io_manager.h" @@ -25,7 +26,8 @@ #include "ohos_external_texture_gl.h" #include "ohos_logging.h" #include "flutter/shell/platform/ohos/platform_view_ohos_delegate.h" -#include +#include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" +#include "flutter/fml/platform/ohos/napi_util.h" namespace flutter { @@ -288,8 +290,69 @@ void PlatformViewOHOS::UpdateSemantics( flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) { FML_DLOG(INFO) << "PlatformViewOHOS::UpdateSemantics()"; + + // send the addr of this class to get the non-static members + // from static member method + SetPlatformViewOHOSAddr((int64_t)this); + + auto xcompInfo = GetXComponentInfo(); + FML_DLOG(INFO) << "PlatformViewOHOS::UpdateSemantics() -> " + << "xcomponentId: " << xcompInfo.xcomponentId + << " shellholderId: " << xcompInfo.shellHolderId; + auto nativeAccessibilityChannel_ = std::make_shared(); - nativeAccessibilityChannel_->UpdateSemantics(update, actions); + nativeAccessibilityChannel_->UpdateSemantics(std::move(update), + std::move(actions), + xcompInfo.xcomponentId); +} + +XComponentInfo PlatformViewOHOS::GetXComponentInfo() { + XComponentInfo info{xcomponentId_, shellHolderId_}; + return info; +} + +void PlatformViewOHOS::SetPlatformViewOHOSAddr(int64_t platformViewOHOSAddr) { + napi_facade_->SetXcomponentInfo(platformViewOHOSAddr); +} + +napi_value PlatformViewOHOS::NativeSetXComponentInfo(napi_env env, napi_callback_info info) { + size_t argc = 3; + napi_value args[3] = {nullptr}; + napi_status status = + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + if (status != napi_ok) { + LOGE("NativeSetXComponentInfo napi_get_cb_info error"); + } + if (argc != 3) { + FML_LOG(ERROR) << "argc is error"; + } + + // unwarp object + PlatformViewOHOS* context = nullptr; + std::string xcomponentId; + int64_t shellHolderId = 0; + + status = napi_get_value_int64(env, args[0], (int64_t*)&context); + if (status != napi_ok) { + FML_LOG(ERROR) << "napi_get_value_int64 platformViewOHOSAddr error"; + } + + bool ret = fml::napi::GetString(env, args[1], xcomponentId); + if (ret != napi_ok) { + FML_LOG(ERROR) << "fml::napi::GetString xcomponentId error"; + } + + status = napi_get_value_int64(env, args[2], &shellHolderId); + if (status != napi_ok) { + FML_LOG(ERROR) << "napi_get_value_int64 shellHolderId error"; + } + + // call object native func to set xcomponent info, + // this way can assign non-static members in static menthods + context->xcomponentId_ = xcomponentId; + context->shellHolderId_ = shellHolderId; + + return nullptr; } // |PlatformView| diff --git a/shell/platform/ohos/platform_view_ohos.h b/shell/platform/ohos/platform_view_ohos.h index 031bed7522..a94c90a11a 100644 --- a/shell/platform/ohos/platform_view_ohos.h +++ b/shell/platform/ohos/platform_view_ohos.h @@ -47,6 +47,11 @@ enum class OHOS_THREAD_TYPE { OHOS_THREAD_TYPE_IO, }; +struct XComponentInfo { + std::string xcomponentId; + int64_t shellHolderId; +}; + class OhosSurfaceFactoryImpl : public OhosSurfaceFactory { public: OhosSurfaceFactoryImpl(const std::shared_ptr& context, @@ -144,6 +149,9 @@ class PlatformViewOHOS final : public PlatformView { void RunTask(OHOS_THREAD_TYPE type, const fml::closure& task); + static napi_value NativeSetXComponentInfo(napi_env env, napi_callback_info info); + XComponentInfo GetXComponentInfo(); + private: const std::shared_ptr napi_facade_; std::shared_ptr ohos_context_; @@ -159,6 +167,9 @@ class PlatformViewOHOS final : public PlatformView { std::atomic isDestroyed_; + std::string xcomponentId_; + int64_t shellHolderId_; + bool GetDestroyed(); void SetDestroyed(bool isDestroyed_); @@ -209,6 +220,8 @@ class PlatformViewOHOS final : public PlatformView { void FireFirstFrameCallback(); FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewOHOS); + + void SetPlatformViewOHOSAddr(int64_t platformViewOHOSAddr); }; } // namespace flutter diff --git a/shell/platform/ohos/utils/arkui_accessibility_constant.h b/shell/platform/ohos/utils/arkui_accessibility_constant.h index a5226aad6a..d9dbe8611b 100644 --- a/shell/platform/ohos/utils/arkui_accessibility_constant.h +++ b/shell/platform/ohos/utils/arkui_accessibility_constant.h @@ -24,6 +24,7 @@ class ArkUIAccessibilityConstant { public: static constexpr char OH_GET_A11Y_PROVIDER[] = "OH_NativeXComponent_GetNativeAccessibilityProvider"; static constexpr char ARKUI_REGISTER_CALLBACK[] = "OH_ArkUI_AccessibilityProviderRegisterCallback"; + static constexpr char ARKUI_REGISTER_CALLBACK_MULTI_INSTANCES[] = "OH_ArkUI_AccessibilityProviderRegisterCallbackWithInstance"; static constexpr char ARKUI_SEND_A11Y_EVENT[] = "OH_ArkUI_SendAccessibilityAsyncEvent"; static constexpr char ARKUI_GET_A11Y_NODE[] = "OH_ArkUI_AddAndGetAccessibilityElementInfo"; -- Gitee From ac676ff63edfb4942cbdccd653f42fc600b0e96c Mon Sep 17 00:00:00 2001 From: zjxi Date: Sat, 8 Feb 2025 16:46:32 +0800 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=E5=A2=9E=E5=8A=A0=E5=B7=B2?= =?UTF-8?q?=E5=88=A0=E9=99=A4xcomponent=E5=AE=9E=E4=BE=8B=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E7=9A=84flutter=E8=AF=AD=E4=B9=89=E6=A0=91=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E7=9A=84=E5=88=A0=E9=99=A4=EF=BC=8C=E5=AF=B9=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=96=B9=E6=B3=95=E7=9A=84=E5=8F=82=E6=95=B0=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=BB=A5=E5=87=8F=E5=B0=91=E6=8B=B7=E8=B4=9D=E5=BC=80?= =?UTF-8?q?=E9=94=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../native_accessibility_channel.cpp | 4 +- .../native_accessibility_channel.h | 2 +- .../ohos_accessibility_bridge.cpp | 188 ++++++------------ .../accessibility/ohos_accessibility_bridge.h | 126 +++--------- .../platform/ohos/ohos_xcomponent_adapter.cpp | 2 + shell/platform/ohos/platform_view_ohos.cpp | 13 +- shell/platform/ohos/platform_view_ohos.h | 5 +- 7 files changed, 111 insertions(+), 229 deletions(-) diff --git a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp index 49a0773d35..bff8473ffd 100644 --- a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp +++ b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp @@ -90,9 +90,9 @@ void NativeAccessibilityChannel::DispatchSemanticsAction( void NativeAccessibilityChannel::UpdateSemantics( flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions, - std::string& xcomponentId) + const std::string& xcomponentId) { - OhosAccessibilityBridge::GetInstance()->UpdateSemantics(update, actions, xcomponentId); + OhosAccessibilityBridge::GetInstance()->UpdateSemantics(std::move(update), std::move(actions), xcomponentId); } /** diff --git a/shell/platform/ohos/accessibility/native_accessibility_channel.h b/shell/platform/ohos/accessibility/native_accessibility_channel.h index daa32ce0a8..50f2cfedc8 100644 --- a/shell/platform/ohos/accessibility/native_accessibility_channel.h +++ b/shell/platform/ohos/accessibility/native_accessibility_channel.h @@ -40,7 +40,7 @@ class NativeAccessibilityChannel { void UpdateSemantics(flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions, - std::string& xcomponentId); + const std::string& xcomponentId); class AccessibilityMessageHandler { public: diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index ecd50cc727..fa71d1a5fb 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -120,7 +120,7 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( void OhosAccessibilityBridge::UpdateSemantics( flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions, - std::string& xcomponentId) + const std::string& xcomponentId) { FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics(), xcomponentId: " << xcomponentId; std::unordered_set updatedFlutterNodes; @@ -136,7 +136,7 @@ void OhosAccessibilityBridge::UpdateSemantics( // 获取当前更新的节点node const auto& node = item.second; // 更新扩展的SemanticsNode信息 - auto nodeEx = UpdatetSemanticsNodeExtent(node); + auto nodeEx = UpdatetSemanticsNodeExtent(std::move(node)); // 构建flutter无障碍语义节点树 g_flutterSemanticsTree[nodeEx.id] = nodeEx; @@ -1106,23 +1106,13 @@ void OhosAccessibilityBridge::DispatchSemanticsAction( std::move(args)); } -/** - * flutter按钮节点双击跳转新页面时,发送页面更新事件 - */ -void OhosAccessibilityBridge::DoubleClickRouteToNewPage(SemanticsNodeExtent node) -{ - if (node.HasFlag(FLAGS_::kIsButton)) { - RequestFocusWhenPageUpdate(0); - } -} - /** * perform click action in accessibility status */ void OhosAccessibilityBridge::PerformClickAction( int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { /** Click event, sent after the UI component responds. 1 */ auto clickEventType = ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_CLICKED; @@ -1139,7 +1129,7 @@ void OhosAccessibilityBridge::PerformClickAction( void OhosAccessibilityBridge::PerformLongClickAction( int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { /** Long click event, sent after the UI component responds. 2 */ auto longClickEventType = ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_LONG_CLICKED; @@ -1157,7 +1147,7 @@ void OhosAccessibilityBridge::PerformLongClickAction( void OhosAccessibilityBridge::PerformGainFocusnAction( int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { // 感知获焦flutter节点 accessibilityFocusedNode = flutterNode; @@ -1186,7 +1176,7 @@ void OhosAccessibilityBridge::PerformGainFocusnAction( void OhosAccessibilityBridge::PerformClearFocusAction( int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { // 解析arkui的失焦 -> flutter对应节点的失焦 auto flutterLoseFocusAction = ArkuiActionsToFlutterActions(action); @@ -1207,7 +1197,7 @@ void OhosAccessibilityBridge::PerformClearFocusAction( void OhosAccessibilityBridge::PerformScrollUpAction( int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode) + SemanticsNodeExtent& flutterNode) { // flutter scroll forward with different situations if (flutterNode.HasAction(ACTIONS_::kScrollUp)) { @@ -1231,7 +1221,7 @@ void OhosAccessibilityBridge::PerformScrollUpAction( void OhosAccessibilityBridge::PerformScrollDownAction( int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode) + SemanticsNodeExtent& flutterNode) { // flutter scroll down with different situations if (flutterNode.HasAction(ACTIONS_::kScrollDown)) { @@ -1253,7 +1243,7 @@ void OhosAccessibilityBridge::PerformScrollDownAction( */ void OhosAccessibilityBridge::PerformClipboardAction( int64_t elementId, - ArkUI_Accessibility_ActionType action) + const ArkUI_Accessibility_ActionType& action) { if (action == ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY) { FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: copy(" << action << ")"; @@ -1272,7 +1262,7 @@ void OhosAccessibilityBridge::PerformClipboardAction( void OhosAccessibilityBridge::PerformInvalidAction( int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { /** Invalid event. 0 */ ArkUI_AccessibilityEventType invalidEventType = @@ -1286,7 +1276,7 @@ void OhosAccessibilityBridge::PerformInvalidAction( * 设置输入框文本 */ void OhosAccessibilityBridge::PerformSetText( - SemanticsNodeExtent flutterNode, + SemanticsNodeExtent& flutterNode, ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments) { @@ -1313,7 +1303,7 @@ void OhosAccessibilityBridge::PerformSetText( * perform select text (from base to extent) in accessibility status */ void OhosAccessibilityBridge::PerformSelectText( - SemanticsNodeExtent flutterNode, + const SemanticsNodeExtent& flutterNode, ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments) { @@ -1376,7 +1366,7 @@ void OhosAccessibilityBridge::PerformSetCursorPosition( * perform custom action in accessibility status */ void OhosAccessibilityBridge::PerformCustomAction( - SemanticsNodeExtent flutterNode, + const SemanticsNodeExtent& flutterNode, ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments) { @@ -1388,7 +1378,8 @@ void OhosAccessibilityBridge::PerformCustomAction( /** * perform show on screen action in accessibility status */ -void OhosAccessibilityBridge::PerformShowOnScreenAction(SemanticsNodeExtent flutterNode) +void OhosAccessibilityBridge::PerformShowOnScreenAction( + const SemanticsNodeExtent& flutterNode) { if (!IsNodeShowOnScreen(flutterNode)) { DispatchSemanticsAction(flutterNode.id, ACTIONS_::kShowOnScreen, {}); @@ -1933,14 +1924,16 @@ std::string OhosAccessibilityBridge::GetNodeComponentType( /** * 判断当前节点是否为textfield文本框 */ -bool OhosAccessibilityBridge::IsTextField(SemanticsNodeExtent flutterNode) +bool OhosAccessibilityBridge::IsTextField( + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsTextField); } /** * 判断当前节点是否为滑动条slider类型 */ -bool OhosAccessibilityBridge::IsSlider(SemanticsNodeExtent flutterNode) +bool OhosAccessibilityBridge::IsSlider( + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsSlider); } @@ -1948,7 +1941,7 @@ bool OhosAccessibilityBridge::IsSlider(SemanticsNodeExtent flutterNode) * 判断当前flutter节点组件是否可点击 */ bool OhosAccessibilityBridge::IsNodeClickable( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasAction(ACTIONS_::kTap); } @@ -1956,7 +1949,7 @@ bool OhosAccessibilityBridge::IsNodeClickable( * 判断当前flutter节点组件是否可显示 */ bool OhosAccessibilityBridge::IsNodeVisible( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return !flutterNode.HasFlag(FLAGS_::kIsHidden); } @@ -1964,7 +1957,7 @@ bool OhosAccessibilityBridge::IsNodeVisible( * 判断当前flutter节点组件是否具备checkable属性 */ bool OhosAccessibilityBridge::IsNodeCheckable( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasFlag(FLAGS_::kHasCheckedState) || flutterNode.HasFlag(FLAGS_::kHasToggledState); @@ -1973,7 +1966,7 @@ bool OhosAccessibilityBridge::IsNodeCheckable( * 判断当前flutter节点组件是否checked/unchecked(checkbox、radio button) */ bool OhosAccessibilityBridge::IsNodeChecked( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsChecked) || flutterNode.HasFlag(FLAGS_::kIsToggled); @@ -1982,7 +1975,7 @@ bool OhosAccessibilityBridge::IsNodeChecked( * 判断当前flutter节点组件是否选中 */ bool OhosAccessibilityBridge::IsNodeSelected( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsSelected); } @@ -1990,7 +1983,7 @@ bool OhosAccessibilityBridge::IsNodeSelected( * 判断当前flutter节点组件是否为密码输入框 */ bool OhosAccessibilityBridge::IsNodePassword( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsTextField) && flutterNode.HasFlag(FLAGS_::kIsObscured); @@ -1999,7 +1992,7 @@ bool OhosAccessibilityBridge::IsNodePassword( * 判断当前flutter节点组件是否支持长按功能 */ bool OhosAccessibilityBridge::IsNodeHasLongPress( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasAction(ACTIONS_::kLongPress); } @@ -2007,7 +2000,7 @@ bool OhosAccessibilityBridge::IsNodeHasLongPress( * 判断当前flutter节点是否enabled */ bool OhosAccessibilityBridge::IsNodeEnabled( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return !flutterNode.HasFlag(FLAGS_::kHasEnabledState) || flutterNode.HasFlag(FLAGS_::kIsEnabled); @@ -2015,7 +2008,8 @@ bool OhosAccessibilityBridge::IsNodeEnabled( /** * 判断当前flutter节点是否在当前屏幕上显示 */ -bool OhosAccessibilityBridge::IsNodeShowOnScreen(SemanticsNodeExtent flutterNode) +bool OhosAccessibilityBridge::IsNodeShowOnScreen( + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasAction(ACTIONS_::kShowOnScreen); } @@ -2081,7 +2075,7 @@ bool OhosAccessibilityBridge::IsNodeFocused(const SemanticsNodeExtent& flutterNo * 判断是否可滑动 */ bool OhosAccessibilityBridge::IsNodeScrollable( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasAction(ACTIONS_::kScrollLeft) || flutterNode.HasAction(ACTIONS_::kScrollRight) || @@ -2092,61 +2086,11 @@ bool OhosAccessibilityBridge::IsNodeScrollable( * 判断当前节点组件是否是滑动组件,如: listview, gridview等 */ bool OhosAccessibilityBridge::IsScrollableWidget( - SemanticsNodeExtent flutterNode) + const SemanticsNodeExtent& flutterNode) { return flutterNode.HasFlag(FLAGS_::kHasImplicitScrolling); } -void OhosAccessibilityBridge::AddRouteNodes( - std::vector edges, - SemanticsNodeExtent node) -{ - if (node.HasFlag(FLAGS_::kScopesRoute)) { - edges.emplace_back(node); - } - for (auto& childNodeId : node.childrenInTraversalOrder) { - auto childNode = GetFlutterSemanticsNode(childNodeId); - AddRouteNodes(edges, childNode); - } -} - -std::string OhosAccessibilityBridge::GetRouteName(SemanticsNodeExtent node) -{ - if (node.HasFlag(FLAGS_::kNamesRoute) && !node.label.empty()) { - return node.label; - } - for (auto& childNodeId : node.childrenInTraversalOrder) { - auto childNode = GetFlutterSemanticsNode(childNodeId); - std::string newName = GetRouteName(childNode); - if (!newName.empty()) { - return newName; - } - } - return ""; -} - -void OhosAccessibilityBridge::OnWindowNameChange(SemanticsNodeExtent route) -{ - std::string routeName = GetRouteName(route); - if (routeName.empty()) { - routeName = " "; - } - Flutter_SendAccessibilityAsyncEvent( - static_cast(route.id), - ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); -} - -void OhosAccessibilityBridge::RemoveSemanticsNode( - SemanticsNodeExtent nodeToBeRemoved) -{ - if (!g_flutterSemanticsTree.size()) { - FML_DLOG(ERROR) << "OhosAccessibilityBridge::removeSemanticsNode -> " - "g_flutterSemanticsTree.szie()=0"; - return; - } -} - /** * when the system accessibility service is shut down, * clear all the flutter semantics-relevant caches like maps, vectors @@ -2184,43 +2128,43 @@ SemanticsNodeExtent OhosAccessibilityBridge::UpdatetSemanticsNodeExtent( } // 更新当前flutter节点信息 - nodeEx.id = std::move(node.id); - nodeEx.flags = std::move(node.flags); - nodeEx.actions = std::move(node.actions); - nodeEx.maxValueLength = std::move(node.maxValueLength); - nodeEx.currentValueLength = std::move(node.currentValueLength); - nodeEx.textSelectionBase = std::move(node.textSelectionBase); - nodeEx.textSelectionExtent = std::move(node.textSelectionExtent); - nodeEx.platformViewId = std::move(node.platformViewId); - nodeEx.scrollChildren = std::move(node.scrollChildren); - nodeEx.scrollIndex = std::move(node.scrollIndex); - nodeEx.scrollPosition = std::move(node.scrollPosition); - nodeEx.scrollExtentMax = std::move(node.scrollExtentMax); - nodeEx.scrollExtentMin = std::move(node.scrollExtentMin); - nodeEx.elevation = std::move(node.elevation); - nodeEx.thickness = std::move(node.thickness); - nodeEx.label = std::move(node.label); - nodeEx.labelAttributes = std::move(node.labelAttributes); - nodeEx.hint = std::move(node.hint); - nodeEx.hintAttributes = std::move(node.hintAttributes); - nodeEx.value = std::move(node.value); - nodeEx.valueAttributes = std::move(node.valueAttributes); - nodeEx.increasedValue = std::move(node.increasedValue); - nodeEx.increasedValueAttributes = std::move(node.increasedValueAttributes); - nodeEx.decreasedValue = std::move(node.decreasedValue); - nodeEx.decreasedValueAttributes = std::move(node.decreasedValueAttributes); - nodeEx.tooltip = std::move(node.tooltip); - nodeEx.textDirection = std::move(node.textDirection); - nodeEx.rect = std::move(node.rect); - nodeEx.transform = std::move(node.transform); - nodeEx.childrenInTraversalOrder = std::move(node.childrenInTraversalOrder); - nodeEx.childrenInHitTestOrder = std::move(node.childrenInHitTestOrder); - nodeEx.customAccessibilityActions = std::move(node.customAccessibilityActions); + nodeEx.id = node.id; + nodeEx.flags = node.flags; + nodeEx.actions = node.actions; + nodeEx.maxValueLength = node.maxValueLength; + nodeEx.currentValueLength = node.currentValueLength; + nodeEx.textSelectionBase = node.textSelectionBase; + nodeEx.textSelectionExtent = node.textSelectionExtent; + nodeEx.platformViewId = node.platformViewId; + nodeEx.scrollChildren = node.scrollChildren; + nodeEx.scrollIndex = node.scrollIndex; + nodeEx.scrollPosition = node.scrollPosition; + nodeEx.scrollExtentMax = node.scrollExtentMax; + nodeEx.scrollExtentMin = node.scrollExtentMin; + nodeEx.elevation = node.elevation; + nodeEx.thickness = node.thickness; + nodeEx.label = node.label; + nodeEx.labelAttributes = node.labelAttributes; + nodeEx.hint = node.hint; + nodeEx.hintAttributes = node.hintAttributes; + nodeEx.value = node.value; + nodeEx.valueAttributes = node.valueAttributes; + nodeEx.increasedValue = node.increasedValue; + nodeEx.increasedValueAttributes = node.increasedValueAttributes; + nodeEx.decreasedValue = node.decreasedValue; + nodeEx.decreasedValueAttributes = node.decreasedValueAttributes; + nodeEx.tooltip = node.tooltip; + nodeEx.textDirection = node.textDirection; + nodeEx.rect = node.rect; + nodeEx.transform = node.transform; + nodeEx.childrenInTraversalOrder = node.childrenInTraversalOrder; + nodeEx.childrenInHitTestOrder = node.childrenInHitTestOrder; + nodeEx.customAccessibilityActions = node.customAccessibilityActions; return nodeEx; } void OhosAccessibilityBridge::GetSemanticsNodeDebugInfo( - SemanticsNodeExtent node) + const SemanticsNodeExtent& node) { FML_DLOG(INFO) << "-------------------SemanticsNode------------------"; SkMatrix _transform = node.transform.asM33(); @@ -2298,7 +2242,7 @@ void OhosAccessibilityBridge::GetSemanticsNodeDebugInfo( } void OhosAccessibilityBridge::GetSemanticsFlagsDebugInfo( - SemanticsNodeExtent node) + const SemanticsNodeExtent& node) { FML_DLOG(INFO) << "----------------SemanticsFlags-------------------------"; FML_DLOG(INFO) << "node.id=" << node.id; @@ -2339,7 +2283,7 @@ void OhosAccessibilityBridge::GetSemanticsFlagsDebugInfo( } void OhosAccessibilityBridge::GetCustomActionDebugInfo( - flutter::CustomAccessibilityAction customAccessibilityAction) + const flutter::CustomAccessibilityAction& customAccessibilityAction) { FML_DLOG(INFO) << "--------------CustomAccessibilityAction------------"; FML_DLOG(INFO) << "customAccessibilityAction.id=" diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 42c73be4c0..4baa8296f0 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -95,11 +95,14 @@ public: bool isFlutterNavigated_; int64_t native_shell_holder_id_; + std::unordered_map g_flutterSemanticsTree; + std::unordered_map> g_flutterSemanticsTreeXComponents; + void OnOhosAccessibilityStateChange(bool ohosAccessibilityEnabled, int64_t shellholderId); void UpdateSemantics(flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions, - std::string& xcomponentId); + const std::string& xcomponentId); void DispatchSemanticsAction(int32_t id, flutter::SemanticsAction action, @@ -209,9 +212,6 @@ private: static std::unique_ptr bridgeInstance_; std::shared_ptr nativeAccessibilityChannel_; std::shared_ptr accessibilityFeatures_; - - std::unordered_map g_flutterSemanticsTree; - std::unordered_map> g_flutterSemanticsTreeXComponents; SemanticsNodeExtent accessibilityFocusedNode; ArkUI_AccessibilityProvider* provider_; @@ -291,129 +291,67 @@ private: bool IsNodeFocusable(const SemanticsNodeExtent& flutterNode); bool IsNodeFocused(const SemanticsNodeExtent& flutterNode); - bool IsNodeCheckable(SemanticsNodeExtent flutterNode); - bool IsNodeChecked(SemanticsNodeExtent flutterNode); - bool IsNodeSelected(SemanticsNodeExtent flutterNode); - bool IsNodeClickable(SemanticsNodeExtent flutterNode); - bool IsNodeScrollable(SemanticsNodeExtent flutterNode); - bool IsNodePassword(SemanticsNodeExtent flutterNode); - bool IsNodeVisible(SemanticsNodeExtent flutterNode); - bool IsNodeEnabled(SemanticsNodeExtent flutterNode); - bool IsNodeHasLongPress(SemanticsNodeExtent flutterNode); - bool IsNodeShowOnScreen(SemanticsNodeExtent flutterNode); - - bool IsTextField(SemanticsNodeExtent flutterNode); - bool IsSlider(SemanticsNodeExtent flutterNode); - bool IsScrollableWidget(SemanticsNodeExtent flutterNode); + bool IsNodeCheckable(const SemanticsNodeExtent& flutterNode); + bool IsNodeChecked(const SemanticsNodeExtent& flutterNode); + bool IsNodeSelected(const SemanticsNodeExtent& flutterNode); + bool IsNodeClickable(const SemanticsNodeExtent& flutterNode); + bool IsNodeScrollable(const SemanticsNodeExtent& flutterNode); + bool IsNodePassword(const SemanticsNodeExtent& flutterNode); + bool IsNodeVisible(const SemanticsNodeExtent& flutterNode); + bool IsNodeEnabled(const SemanticsNodeExtent& flutterNode); + bool IsNodeHasLongPress(const SemanticsNodeExtent& flutterNode); + bool IsNodeShowOnScreen(const SemanticsNodeExtent& flutterNode); + bool IsTextField(const SemanticsNodeExtent& flutterNode); + bool IsSlider(const SemanticsNodeExtent& flutterNode); + bool IsScrollableWidget(const SemanticsNodeExtent& flutterNode); void PerformClickAction(int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode); + const SemanticsNodeExtent& flutterNode); void PerformLongClickAction(int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode); + const SemanticsNodeExtent& flutterNode); void PerformGainFocusnAction(int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode); + const SemanticsNodeExtent& flutterNode); void PerformClearFocusAction(int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode); + const SemanticsNodeExtent& flutterNode); void PerformScrollUpAction(int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode); + SemanticsNodeExtent& flutterNode); void PerformScrollDownAction(int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode); + SemanticsNodeExtent& flutterNode); void PerformClipboardAction(int64_t elementId, - ArkUI_Accessibility_ActionType action); + const ArkUI_Accessibility_ActionType& action); void PerformInvalidAction(int64_t elementId, ArkUI_Accessibility_ActionType action, - SemanticsNodeExtent flutterNode); - void PerformSetText(SemanticsNodeExtent flutterNode, + const SemanticsNodeExtent& flutterNode); + void PerformSetText(SemanticsNodeExtent& flutterNode, ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments); - void PerformSelectText(SemanticsNodeExtent flutterNode, + void PerformSelectText(const SemanticsNodeExtent& flutterNode, ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments); void PerformSetCursorPosition(SemanticsNodeExtent flutterNode, ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments); - void PerformCustomAction(SemanticsNodeExtent flutterNode, + void PerformCustomAction(const SemanticsNodeExtent& flutterNode, ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments); - void PerformShowOnScreenAction(SemanticsNodeExtent flutterNode); - - void AddRouteNodes(std::vector edges, - SemanticsNodeExtent node); - std::string GetRouteName(SemanticsNodeExtent node); - void OnWindowNameChange(SemanticsNodeExtent route); - void RemoveSemanticsNode(SemanticsNodeExtent nodeToBeRemoved); + void PerformShowOnScreenAction(const SemanticsNodeExtent& flutterNode); - void GetSemanticsNodeDebugInfo(SemanticsNodeExtent node); - void GetSemanticsFlagsDebugInfo(SemanticsNodeExtent node); + void GetSemanticsNodeDebugInfo(const SemanticsNodeExtent& node); + void GetSemanticsFlagsDebugInfo(const SemanticsNodeExtent& node); void GetCustomActionDebugInfo( - flutter::CustomAccessibilityAction customAccessibilityAction); + const flutter::CustomAccessibilityAction& customAccessibilityAction); void RequestFocusWhenPageUpdate(int32_t requestFocusId); - bool Contains(const std::string source, const std::string target); - void DoubleClickRouteToNewPage(SemanticsNodeExtent node); void GetSemanticsDebugInfo(); void AccessibiltiyChangesWithXComponentId(); void GetFlutterSemanticsTreeWithInstance(const char* instanceId); }; -enum class AccessibilityAction : 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, -}; -enum class AccessibilityFlags : 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, -}; - } // namespace flutter #endif // OHOS_ACCESSIBILITY_BRIDGE_H diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index d069e68a1d..fa3c115e7e 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -211,6 +211,8 @@ void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window) { // 将当前要销毁的xcomponent对应的无障碍provider指针置nullptr it->second->accessibilityProvider_ = nullptr; it = XComponentAdapter::GetInstance()->xcomponetMap_.erase(it); + // delete the semantics tree of the destroyed xcomponent + OhosAccessibilityBridge::GetInstance()->g_flutterSemanticsTreeXComponents.erase(it->first); } else { ++it; } diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index 9536b85c3b..cb564d45d6 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -291,8 +291,8 @@ void PlatformViewOHOS::UpdateSemantics( flutter::CustomAccessibilityActionUpdates actions) { FML_DLOG(INFO) << "PlatformViewOHOS::UpdateSemantics()"; - // send the addr of this class to get the non-static members - // from static member method + // send the PlatformViewOHOS address aims to get the non-static members + // from static member method via cross language (c++, ets) mutual invoking SetPlatformViewOHOSAddr((int64_t)this); auto xcompInfo = GetXComponentInfo(); @@ -306,9 +306,8 @@ void PlatformViewOHOS::UpdateSemantics( xcompInfo.xcomponentId); } -XComponentInfo PlatformViewOHOS::GetXComponentInfo() { - XComponentInfo info{xcomponentId_, shellHolderId_}; - return info; +const XComponentInfo& PlatformViewOHOS::GetXComponentInfo() { + return xcompInfo_; } void PlatformViewOHOS::SetPlatformViewOHOSAddr(int64_t platformViewOHOSAddr) { @@ -349,8 +348,8 @@ napi_value PlatformViewOHOS::NativeSetXComponentInfo(napi_env env, napi_callback // call object native func to set xcomponent info, // this way can assign non-static members in static menthods - context->xcomponentId_ = xcomponentId; - context->shellHolderId_ = shellHolderId; + context->xcompInfo_.xcomponentId = xcomponentId; + context->xcompInfo_.shellHolderId = shellHolderId; return nullptr; } diff --git a/shell/platform/ohos/platform_view_ohos.h b/shell/platform/ohos/platform_view_ohos.h index a94c90a11a..0e98ddc857 100644 --- a/shell/platform/ohos/platform_view_ohos.h +++ b/shell/platform/ohos/platform_view_ohos.h @@ -150,7 +150,7 @@ class PlatformViewOHOS final : public PlatformView { void RunTask(OHOS_THREAD_TYPE type, const fml::closure& task); static napi_value NativeSetXComponentInfo(napi_env env, napi_callback_info info); - XComponentInfo GetXComponentInfo(); + const XComponentInfo& GetXComponentInfo(); private: const std::shared_ptr napi_facade_; @@ -167,8 +167,7 @@ class PlatformViewOHOS final : public PlatformView { std::atomic isDestroyed_; - std::string xcomponentId_; - int64_t shellHolderId_; + XComponentInfo xcompInfo_; bool GetDestroyed(); -- Gitee From 136a4780bbf23d5cf093d06e748443bf025814b5 Mon Sep 17 00:00:00 2001 From: zjxi Date: Sat, 8 Feb 2025 17:13:23 +0800 Subject: [PATCH 6/6] =?UTF-8?q?refactor:=E5=88=A0=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos/accessibility/ohos_accessibility_bridge.cpp | 7 +------ shell/platform/ohos/ohos_xcomponent_adapter.cpp | 4 ---- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index fa71d1a5fb..8fdcb0e073 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -303,7 +303,7 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) { if (OHOS_API_VERSION < 13) { return; } std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); - // auto provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); + auto provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); CHECK_NULL_PTR_RET_VOID(provider_, RequestFocusWhenPageUpdate); auto OH_ArkUI_CreateAccessibilityEventInfo = @@ -437,10 +437,6 @@ int32_t OhosAccessibilityBridge::GetParentId(int64_t elementId) } int32_t id = static_cast(elementId); auto node = GetFlutterSemanticsNode(id); - if (g_flutterSemanticsTree.find(id) == g_flutterSemanticsTree.end()) { - LOGE("GetParentId: %{public}d is null", id); - return -1; - } return node.parentId; } @@ -506,7 +502,6 @@ SkPoint OhosAccessibilityBridge::ApplyTransform( void OhosAccessibilityBridge::RelativeRectToScreenRect(SemanticsNodeExtent& node) { auto [left, top, right, bottom] = node.rect; - // SkM44 globalTransform = g_globalTransformMap[node.id]; SkM44 globalTransform = node.globalTransform; SkPoint points[4] = { diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index fa3c115e7e..ad51c77545 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -19,7 +19,6 @@ #include "ohos_logging.h" #include #include "flutter/fml/logging.h" -// #include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" namespace flutter { @@ -69,9 +68,6 @@ bool XComponentAdapter::Export(napi_env env, napi_value exports) { std::string id(idStr); auto context = XComponentAdapter::GetInstance(); if (context) { - // give each PlatformViewOHOS::UpdateSemantics() a xcomponent id - context->xcomponentId_ = id; - LOGD("0090 -> xcomponentid: %{public}s", id.c_str()); context->SetNativeXComponent(id, nativeXComponent); return true; } -- Gitee