已合并
修复无障碍bug:开启无障碍再冷启动flutter页面导致先调用无障碍bridge类再注册无障碍服务,造成空指针闪退 #592
雾中失焦创建于 2024年12月28日
修复无障碍bug:开启无障碍再冷启动flutter页面导致先调用无障碍bridge类再注册无障碍服务,造成空指针闪退 #592
已合并
从refs/pull/592/head合入到dev
共 9 个文件变更+86-102
| @@ -83,8 +83,7 @@ namespace flutter { | |||
| 83 | flutter::SemanticsNodeUpdates update, | 83 | flutter::SemanticsNodeUpdates update, |
| 84 | flutter::CustomAccessibilityActionUpdates actions) | 84 | flutter::CustomAccessibilityActionUpdates actions) |
| 85 | { | 85 | { |
| 86 | - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); | 86 | + OhosAccessibilityBridge::GetInstance()->UpdateSemantics(update, actions); |
| 87 | - ohos_a11y_bridge->UpdateSemantics(update, actions); | ||
| 88 | } | 87 | } |
| 89 | 88 | ||
| 90 | /** | 89 | /** |
| @@ -102,8 +101,7 @@ namespace flutter { | |||
| 102 | void NativeAccessibilityChannel::AccessibilityMessageHandler::Announce( | 101 | void NativeAccessibilityChannel::AccessibilityMessageHandler::Announce( |
| 103 | std::unique_ptr<char[]>& message) | 102 | std::unique_ptr<char[]>& message) |
| 104 | { | 103 | { |
| 105 | - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); | 104 | + OhosAccessibilityBridge::GetInstance()->Announce(message); |
| 106 | - ohos_a11y_bridge->Announce(message); | ||
| 107 | } | 105 | } |
| 108 | 106 | ||
| 109 | /** | 107 | /** |
| @@ -112,8 +110,7 @@ namespace flutter { | |||
| 112 | void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTap( | 110 | void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTap( |
| 113 | int32_t nodeId) | 111 | int32_t nodeId) |
| 114 | { | 112 | { |
| 115 | - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); | 113 | + OhosAccessibilityBridge::GetInstance()->OnTap(nodeId); |
| 116 | - ohos_a11y_bridge->OnTap(nodeId); | ||
| 117 | } | 114 | } |
| 118 | 115 | ||
| 119 | /** | 116 | /** |
| @@ -122,8 +119,7 @@ namespace flutter { | |||
| 122 | void NativeAccessibilityChannel::AccessibilityMessageHandler::OnLongPress( | 119 | void NativeAccessibilityChannel::AccessibilityMessageHandler::OnLongPress( |
| 123 | int32_t nodeId) | 120 | int32_t nodeId) |
| 124 | { | 121 | { |
| 125 | - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); | 122 | + OhosAccessibilityBridge::GetInstance()->OnLongPress(nodeId); |
| 126 | - ohos_a11y_bridge->OnLongPress(nodeId); | ||
| 127 | } | 123 | } |
| 128 | 124 | ||
| 129 | /** | 125 | /** |
| @@ -132,7 +128,6 @@ namespace flutter { | |||
| 132 | void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTooltip( | 128 | void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTooltip( |
| 133 | std::unique_ptr<char[]>& message) | 129 | std::unique_ptr<char[]>& message) |
| 134 | { | 130 | { |
| 135 | - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); | 131 | + OhosAccessibilityBridge::GetInstance()->OnTooltip(message); |
| 136 | - ohos_a11y_bridge->OnTooltip(message); | ||
| 137 | } | 132 | } |
| 138 | } | 133 | } |
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "flutter/shell/platform/ohos/ohos_shell_holder.h" | 23 | #include "flutter/shell/platform/ohos/ohos_shell_holder.h" |
| 24 | #include "third_party/skia/include/core/SkMatrix.h" | 24 | #include "third_party/skia/include/core/SkMatrix.h" |
| 25 | #include "third_party/skia/include/core/SkScalar.h" | 25 | #include "third_party/skia/include/core/SkScalar.h" |
| 26 | +#include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" | ||
| 26 | 27 | ||
| 27 | namespace flutter { | 28 | namespace flutter { |
| 28 | 29 | ||
| @@ -42,6 +43,9 @@ OhosAccessibilityBridge* OhosAccessibilityBridge::GetInstance() | |||
| 42 | return bridgeInstance_.get(); | 43 | return bridgeInstance_.get(); |
| 43 | } | 44 | } |
| 44 | 45 | ||
| 46 | +OhosAccessibilityBridge::OhosAccessibilityBridge() | ||
| 47 | + : isFlutterNavigated_(false), provider_(nullptr), isAccessibilityEnabled_(false) {} | ||
| 48 | + | ||
| 45 | /** | 49 | /** |
| 46 | * 监听当前ohos平台是否开启无障碍屏幕朗读服务 | 50 | * 监听当前ohos平台是否开启无障碍屏幕朗读服务 |
| 47 | */ | 51 | */ |
| @@ -50,6 +54,7 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( | |||
| 50 | bool ohosAccessibilityEnabled) | 54 | bool ohosAccessibilityEnabled) |
| 51 | { | 55 | { |
| 52 | native_shell_holder_id_ = shellHolderId; | 56 | native_shell_holder_id_ = shellHolderId; |
| 57 | + provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; | ||
| 53 | nativeAccessibilityChannel_ = std::make_shared<NativeAccessibilityChannel>(); | 58 | nativeAccessibilityChannel_ = std::make_shared<NativeAccessibilityChannel>(); |
| 54 | accessibilityFeatures_ = std::make_shared<OhosAccessibilityFeatures>(); | 59 | accessibilityFeatures_ = std::make_shared<OhosAccessibilityFeatures>(); |
| 55 | 60 | ||
| @@ -79,16 +84,16 @@ void OhosAccessibilityBridge::UpdateSemantics( | |||
| 79 | std::vector<SemanticsNodeExtent> updatedFlutterNodes; | 84 | std::vector<SemanticsNodeExtent> updatedFlutterNodes; |
| 80 | 85 | ||
| 81 | // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) | 86 | // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) |
| 82 | - if (IS_FLUTTER_NAVIGATE) { | 87 | + if (isFlutterNavigated_) { |
| 83 | Flutter_SendAccessibilityAsyncEvent(0, | 88 | Flutter_SendAccessibilityAsyncEvent(0, |
| 84 | ArkUI_AccessibilityEventType:: | 89 | ArkUI_AccessibilityEventType:: |
| 85 | ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); | 90 | ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); |
| 86 | RequestFocusWhenPageUpdate(0); | 91 | RequestFocusWhenPageUpdate(0); |
| 87 | - IS_FLUTTER_NAVIGATE = false; | 92 | + isFlutterNavigated_ = false; |
| 88 | } | 93 | } |
| 89 | 94 | ||
| 90 | /** 获取并分析每个语义节点的更新属性 */ | 95 | /** 获取并分析每个语义节点的更新属性 */ |
| 91 | - for (auto& item : update) { | 96 | + for (const auto& item : update) { |
| 92 | // 获取当前更新的节点node | 97 | // 获取当前更新的节点node |
| 93 | const auto& node = item.second; | 98 | const auto& node = item.second; |
| 94 | 99 | ||
| @@ -269,7 +274,10 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) | |||
| 269 | { | 274 | { |
| 270 | if (OHOS_API_VERSION < 13) { return; } | 275 | if (OHOS_API_VERSION < 13) { return; } |
| 271 | CHECK_NULL_PTR(provider_, RequestFocusWhenPageUpdate); | 276 | CHECK_NULL_PTR(provider_, RequestFocusWhenPageUpdate); |
| 272 | - | 277 | + if (provider_ == nullptr) { |
| 278 | + return; | ||
| 279 | + } | ||
| 280 | + | ||
| 273 | auto OH_ArkUI_CreateAccessibilityEventInfo = | 281 | auto OH_ArkUI_CreateAccessibilityEventInfo = |
| 274 | OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); | 282 | OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); |
| 275 | CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); | 283 | CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); |
| @@ -459,24 +467,18 @@ std::pair<float, float> OhosAccessibilityBridge::GetRealScaleFactor() | |||
| 459 | } | 467 | } |
| 460 | 468 | ||
| 461 | /** | 469 | /** |
| 462 | - * flutter无障碍语义树的子节点相对坐标系转化为屏幕绝对坐标的映射算法 | 470 | + * flutter语义树中相对坐标系转化为屏幕绝对坐标的映射算法实现 |
| 463 | - * 目前暂未考虑旋转、透视场景,不影响屏幕朗读功能 | 471 | + * NOTE:目前暂未考虑旋转、透视场景,不影响屏幕朗读功能 |
| 472 | + * (SkMatrix::kMSkewX, SkMatrix::kMSkewY, SkMatrix::kMPersp0, | ||
| 473 | + * SkMatrix::kMPersp1, SkMatrix::kMPersp2) | ||
| 464 | */ | 474 | */ |
| 465 | void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( | 475 | void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( |
| 466 | SemanticsNodeExtent currNode) | 476 | SemanticsNodeExtent currNode) |
| 467 | { | 477 | { |
| 468 | // 获取当前flutter节点的相对rect | 478 | // 获取当前flutter节点的相对rect |
| 469 | - auto currLeft = static_cast<float>(currNode.rect.fLeft); | 479 | + auto [currLeft, currTop, currRight, currBottom] = currNode.rect; |
| 470 | - auto currTop = static_cast<float>(currNode.rect.fTop); | ||
| 471 | - auto currRight = static_cast<float>(currNode.rect.fRight); | ||
| 472 | - auto currBottom = static_cast<float>(currNode.rect.fBottom); | ||
| 473 | 480 | ||
| 474 | - /** | 481 | + // 获取当前flutter节点的缩放、平移、透视等矩阵坐标转换以下矩阵坐标变换参数 |
| 475 | - * 获取当前flutter节点的缩放、平移、透视等矩阵坐标转换 | ||
| 476 | - * 以下矩阵坐标变换参数(如:旋转/错切、透视)场景目前暂不考虑 | ||
| 477 | - * NOTE: SkMatrix::kMSkewX, SkMatrix::kMSkewY, | ||
| 478 | - * SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 | ||
| 479 | - */ | ||
| 480 | SkMatrix transform = currNode.transform.asM33(); | 482 | SkMatrix transform = currNode.transform.asM33(); |
| 481 | auto _kMScaleX = transform.get(SkMatrix::kMScaleX); | 483 | auto _kMScaleX = transform.get(SkMatrix::kMScaleX); |
| 482 | auto _kMTransX = transform.get(SkMatrix::kMTransX); | 484 | auto _kMTransX = transform.get(SkMatrix::kMTransX); |
| @@ -486,7 +488,7 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( | |||
| 486 | // 获取当前flutter节点的父节点的相对rect | 488 | // 获取当前flutter节点的父节点的相对rect |
| 487 | int32_t parentId = GetParentId(currNode.id); | 489 | int32_t parentId = GetParentId(currNode.id); |
| 488 | auto parentNode = GetFlutterSemanticsNode(parentId); | 490 | auto parentNode = GetFlutterSemanticsNode(parentId); |
| 489 | - if (!g_flutterSemanticsTree.count(parentId)) { | 491 | + if (g_flutterSemanticsTree.find(parentId) == g_flutterSemanticsTree.end()) { |
| 490 | LOGE("FlutterRelativeRectToScreenRect: GetFlutterSemanticsNode id=%{public}d null", parentId); | 492 | LOGE("FlutterRelativeRectToScreenRect: GetFlutterSemanticsNode id=%{public}d null", parentId); |
| 491 | } | 493 | } |
| 492 | 494 | ||
| @@ -502,41 +504,30 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( | |||
| 502 | // 获取真实缩放系数 | 504 | // 获取真实缩放系数 |
| 503 | auto [realScaleXFactor, realScaleYFactor] = GetRealScaleFactor(); | 505 | auto [realScaleXFactor, realScaleYFactor] = GetRealScaleFactor(); |
| 504 | 506 | ||
| 505 | - // 更新后的节点屏幕坐标 | 507 | + // 更新后的节点屏幕坐标,子节点的屏幕绝对坐标转换,包括offset偏移值计算、缩放系数变换 |
| 506 | - float newLeft = 0.0; | 508 | + bool isRectScaleChanged = _kMScaleX > 1 && _kMScaleY > 1; |
| 507 | - float newTop = 0.0; | 509 | + float newLeft = isRectScaleChanged ? |
| 508 | - float newRight = 0.0; | 510 | + currLeft + _kMTransX * _kMScaleX : (currLeft + _kMTransX) * realScaleXFactor + realParentLeft; |
| 509 | - float newBottom = 0.0; | 511 | + float newTop = isRectScaleChanged ? |
| 512 | + currTop + _kMTransY * _kMScaleY : (currTop + _kMTransY) * realScaleYFactor + realParentTop; | ||
| 513 | + float newRight = isRectScaleChanged ? | ||
| 514 | + currRight * _kMScaleX : newLeft + currRight * realScaleXFactor; | ||
| 515 | + float newBottom = isRectScaleChanged ? | ||
| 516 | + currBottom * _kMScaleY : newTop + currBottom * realScaleYFactor; | ||
| 510 | 517 | ||
| 511 | - if (_kMScaleX > 1 && _kMScaleY > 1) { | 518 | + // 若子节点rect超过父节点则跳过显示(单个屏幕显示不下,滑动再重新显示) |
| 512 | - // 子节点相对父节点进行变化(缩放、 平移) | 519 | + const bool isExceedScreeArea = newLeft < realParentLeft || newTop < realParentTop || |
| 513 | - newLeft = currLeft + _kMTransX * _kMScaleX; | 520 | + newRight > realParentRight || newBottom > realParentBottom || |
| 514 | - newTop = currTop + _kMTransY * _kMScaleY; | 521 | + newLeft >= newRight || newTop >= newBottom || |
| 515 | - newRight = currRight * _kMScaleX; | 522 | + newRight > rootWidth || newBottom > rootHeight; |
| 516 | - newBottom = currBottom * _kMScaleY; | 523 | + if (isExceedScreeArea) { |
| 517 | - // 更新当前flutter节点currNode的相对坐标 -> 屏幕绝对坐标 | 524 | + FML_DLOG(WARNING) << "RelativeRectToScreenRect -> childRect exceeds parentRect {Id: " |
| 518 | - SetAbsoluteScreenRect(currNode, newLeft, newTop, newRight, newBottom); | 525 | + << currNode.id << ", (" << newLeft << ", " << newTop |
| 526 | + << ", " << newRight << ", " << newBottom << ")}"; | ||
| 527 | + // 防止滑动场景下绿框坐标超出屏幕范围,进行正则化处理 | ||
| 528 | + SetAbsoluteScreenRect(currNode, rootWidth, rootHeight, 0, 0); | ||
| 519 | } else { | 529 | } else { |
| 520 | - // 子节点的屏幕绝对坐标转换,包括offset偏移值计算、缩放系数变换 | 530 | + SetAbsoluteScreenRect(currNode, newLeft, newTop, newRight, newBottom); |
| 521 | - newLeft = (currLeft + _kMTransX) * realScaleXFactor + realParentLeft; | ||
| 522 | - newTop = (currTop + _kMTransY) * realScaleYFactor + realParentTop; | ||
| 523 | - newRight = newLeft + currRight * realScaleXFactor; | ||
| 524 | - newBottom = newTop + currBottom * realScaleYFactor; | ||
| 525 | - | ||
| 526 | - // 若子节点rect超过父节点则跳过显示(单个屏幕显示不下,滑动再重新显示) | ||
| 527 | - const bool IS_OVER_SCREEN_AREA = newLeft < realParentLeft || newTop < realParentTop || | ||
| 528 | - newRight > realParentRight || newBottom > realParentBottom || | ||
| 529 | - newLeft >= newRight || newTop >= newBottom || | ||
| 530 | - newRight > rootWidth || newBottom > rootHeight; | ||
| 531 | - if (IS_OVER_SCREEN_AREA) { | ||
| 532 | - FML_DLOG(WARNING) << "RelativeRectToScreenRect -> childRect exceeds parentRect {Id: " | ||
| 533 | - << currNode.id << ", (" << newLeft << ", " << newTop | ||
| 534 | - << ", " << newRight << ", " << newBottom << ")}"; | ||
| 535 | - // 防止滑动场景下绿框坐标超出屏幕范围,进行正则化处理 | ||
| 536 | - SetAbsoluteScreenRect(currNode, rootWidth, rootHeight, 0, 0); | ||
| 537 | - } else { | ||
| 538 | - SetAbsoluteScreenRect(currNode, newLeft, newTop, newRight, newBottom); | ||
| 539 | - } | ||
| 540 | } | 531 | } |
| 541 | } | 532 | } |
| 542 | 533 | ||
| @@ -1580,7 +1571,12 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAnnounceEvent( | |||
| 1580 | std::unique_ptr<char[]>& message, | 1571 | std::unique_ptr<char[]>& message, |
| 1581 | ArkUI_AccessibilityEventType eventType) | 1572 | ArkUI_AccessibilityEventType eventType) |
| 1582 | { | 1573 | { |
| 1583 | - // 创建并设置屏幕朗读事件 | 1574 | + if (OHOS_API_VERSION < 13) { return; } |
| 1575 | + | ||
| 1576 | + CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAnnounceEvent); | ||
| 1577 | + if (provider_ == nullptr) { return; } | ||
| 1578 | + | ||
| 1579 | + // 创建并设置屏幕朗读事件 | ||
| 1584 | auto OH_ArkUI_CreateAccessibilityEventInfo = | 1580 | auto OH_ArkUI_CreateAccessibilityEventInfo = |
| 1585 | OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); | 1581 | OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); |
| 1586 | CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); | 1582 | CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); |
| @@ -1628,6 +1624,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( | |||
| 1628 | if (OHOS_API_VERSION < 13) { return; } | 1624 | if (OHOS_API_VERSION < 13) { return; } |
| 1629 | 1625 | ||
| 1630 | CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAsyncEvent); | 1626 | CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAsyncEvent); |
| 1627 | + if (provider_ == nullptr) { return; } | ||
| 1631 | 1628 | ||
| 1632 | // 创建eventInfo对象 | 1629 | // 创建eventInfo对象 |
| 1633 | auto OH_ArkUI_CreateAccessibilityEventInfo = | 1630 | auto OH_ArkUI_CreateAccessibilityEventInfo = |
| @@ -78,9 +78,9 @@ public: | |||
| 78 | OhosAccessibilityBridge(const OhosAccessibilityBridge&) = delete; | 78 | OhosAccessibilityBridge(const OhosAccessibilityBridge&) = delete; |
| 79 | OhosAccessibilityBridge& operator=(const OhosAccessibilityBridge&) = delete; | 79 | OhosAccessibilityBridge& operator=(const OhosAccessibilityBridge&) = delete; |
| 80 | 80 | ||
| 81 | - bool IS_FLUTTER_NAVIGATE = false; | 81 | + bool isFlutterNavigated_; |
| 82 | int64_t native_shell_holder_id_; | 82 | int64_t native_shell_holder_id_; |
| 83 | - ArkUI_AccessibilityProvider* provider_ = nullptr; | 83 | + ArkUI_AccessibilityProvider* provider_; |
| 84 | 84 | ||
| 85 | void OnOhosAccessibilityStateChange( | 85 | void OnOhosAccessibilityStateChange( |
| 86 | int64_t shellHolderId, | 86 | int64_t shellHolderId, |
| @@ -157,8 +157,8 @@ public: | |||
| 157 | void ClearFlutterSemanticsCaches(); | 157 | void ClearFlutterSemanticsCaches(); |
| 158 | 158 | ||
| 159 | private: | 159 | private: |
| 160 | - OhosAccessibilityBridge() = default; | 160 | + OhosAccessibilityBridge(); |
| 161 | - bool isAccessibilityEnabled_ = false; | 161 | + bool isAccessibilityEnabled_; |
| 162 | static std::unique_ptr<OhosAccessibilityBridge> bridgeInstance_; | 162 | static std::unique_ptr<OhosAccessibilityBridge> bridgeInstance_; |
| 163 | std::shared_ptr<NativeAccessibilityChannel> nativeAccessibilityChannel_; | 163 | std::shared_ptr<NativeAccessibilityChannel> nativeAccessibilityChannel_; |
| 164 | std::shared_ptr<OhosAccessibilityFeatures> accessibilityFeatures_; | 164 | std::shared_ptr<OhosAccessibilityFeatures> accessibilityFeatures_; |
| @@ -36,7 +36,6 @@ import appRecovery from '@ohos.app.ability.appRecovery'; | |||
| 36 | import FlutterManager from './FlutterManager'; | 36 | import FlutterManager from './FlutterManager'; |
| 37 | import { FlutterView } from '../../view/FlutterView'; | 37 | import { FlutterView } from '../../view/FlutterView'; |
| 38 | import ApplicationInfoLoader from '../engine/loader/ApplicationInfoLoader'; | 38 | import ApplicationInfoLoader from '../engine/loader/ApplicationInfoLoader'; |
| 39 | -import { accessibility } from '@kit.AccessibilityKit'; | ||
| 40 | import { AccessibilityManager } from '../../view/AccessibilityBridge'; | 39 | import { AccessibilityManager } from '../../view/AccessibilityBridge'; |
| 41 | 40 | ||
| 42 | const TAG = "FlutterAbility"; | 41 | const TAG = "FlutterAbility"; |
| @@ -107,13 +106,6 @@ export class FlutterAbility extends UIAbility implements Host { | |||
| 107 | if (flutterApplicationInfo.isDebugMode) { | 106 | if (flutterApplicationInfo.isDebugMode) { |
| 108 | this.delegate?.initWindow(); | 107 | this.delegate?.initWindow(); |
| 109 | } | 108 | } |
| 110 | - | ||
| 111 | - //冷启动对os是否开启无障碍服务进行查询 | ||
| 112 | - let accessibilityState: boolean = accessibility.isOpenAccessibilitySync(); | ||
| 113 | - if(accessibilityState) { | ||
| 114 | - this.delegate?.getFlutterNapi()?.accessibilityStateChange(accessibilityState); | ||
| 115 | - } | ||
| 116 | - Log.i(TAG, `accessibility isOpen state -> ${JSON.stringify(accessibilityState)}`); | ||
| 117 | } | 109 | } |
| 118 | 110 | ||
| 119 | onDestroy() { | 111 | onDestroy() { |
| @@ -56,6 +56,7 @@ export struct FlutterPage { | |||
| 56 | .onLoad((context) => { | 56 | .onLoad((context) => { |
| 57 | this.flutterView?.onSurfaceCreated() | 57 | this.flutterView?.onSurfaceCreated() |
| 58 | Log.d(TAG, "XComponent onLoad "); | 58 | Log.d(TAG, "XComponent onLoad "); |
| 59 | + this.flutterView?.onAccessibilityIsOpen() | ||
| 59 | }) | 60 | }) |
| 60 | .onDestroy(() => { | 61 | .onDestroy(() => { |
| 61 | Log.d(TAG, "XComponent onDestroy "); | 62 | Log.d(TAG, "XComponent onDestroy "); |
| @@ -135,6 +136,7 @@ export struct FlutterPage { | |||
| 135 | .onLoad((context) => { | 136 | .onLoad((context) => { |
| 136 | this.flutterView?.onSurfaceCreated() | 137 | this.flutterView?.onSurfaceCreated() |
| 137 | Log.d(TAG, "XComponent onLoad "); | 138 | Log.d(TAG, "XComponent onLoad "); |
| 139 | + this.flutterView?.onAccessibilityIsOpen() | ||
| 138 | }) | 140 | }) |
| 139 | .onDestroy(() => { | 141 | .onDestroy(() => { |
| 140 | Log.d(TAG, "XComponent onDestroy "); | 142 | Log.d(TAG, "XComponent onDestroy "); |
| @@ -492,6 +492,14 @@ export class FlutterView { | |||
| 492 | } | 492 | } |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | + onAccessibilityIsOpen() { | ||
| 496 | + let accessibilityState: boolean = accessibility.isOpenAccessibilitySync(); | ||
| 497 | + if(accessibilityState) { | ||
| 498 | + this.flutterEngine?.getFlutterNapi()?.accessibilityStateChange(accessibilityState) | ||
| 499 | + } | ||
| 500 | + Log.i(TAG, `accessibility isOpen state -> ${JSON.stringify(accessibilityState)}`); | ||
| 501 | + } | ||
| 502 | + | ||
| 495 | onAreaChange(newArea: Area | null, setFullScreen: boolean = false) { | 503 | onAreaChange(newArea: Area | null, setFullScreen: boolean = false) { |
| 496 | const originalMetrics = this.viewportMetrics.clone(); | 504 | const originalMetrics = this.viewportMetrics.clone(); |
| 497 | 505 | ||
| @@ -1872,10 +1872,8 @@ napi_value PlatformViewOHOSNapi::nativeAccessibilityStateChange( | |||
| 1872 | (state ? "true" : "false")); | 1872 | (state ? "true" : "false")); |
| 1873 | 1873 | ||
| 1874 | //send to accessibility bridge | 1874 | //send to accessibility bridge |
| 1875 | - const int32_t OHOS_API_VERSION = OH_GetSdkApiVersion(); | ||
| 1876 | if (OHOS_API_VERSION >= 13) { | 1875 | if (OHOS_API_VERSION >= 13) { |
| 1877 | - auto a11y_bridge = OhosAccessibilityBridge::GetInstance(); | 1876 | + OhosAccessibilityBridge::GetInstance()->OnOhosAccessibilityStateChange(shell_holder_id, state); |
| 1878 | - a11y_bridge->OnOhosAccessibilityStateChange(shell_holder_id, state); | ||
| 1879 | } | 1877 | } |
| 1880 | FML_DLOG(INFO) << "nativeAccessibilityStateChange: state=" << state | 1878 | FML_DLOG(INFO) << "nativeAccessibilityStateChange: state=" << state |
| 1881 | << " shell_holder_id=" << shell_holder_id; | 1879 | << " shell_holder_id=" << shell_holder_id; |
| @@ -2169,8 +2167,7 @@ napi_value PlatformViewOHOSNapi::nativeGetFlutterNavigationAction(napi_env env, | |||
| 2169 | return nullptr; | 2167 | return nullptr; |
| 2170 | } | 2168 | } |
| 2171 | 2169 | ||
| 2172 | - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); | 2170 | + OhosAccessibilityBridge::GetInstance()->isFlutterNavigated_ = isNavigate; |
| 2173 | - ohosAccessibilityBridge->IS_FLUTTER_NAVIGATE = isNavigate; | ||
| 2174 | FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeGetFlutterNavigationAction -> "<<isNavigate; | 2171 | FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeGetFlutterNavigationAction -> "<<isNavigate; |
| 2175 | return nullptr; | 2172 | return nullptr; |
| 2176 | } | 2173 | } |
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "types.h" | 18 | #include "types.h" |
| 19 | #include "ohos_logging.h" | 19 | #include "ohos_logging.h" |
| 20 | #include <functional> | 20 | #include <functional> |
| 21 | +#include "flutter/fml/logging.h" | ||
| 21 | 22 | ||
| 22 | namespace flutter { | 23 | namespace flutter { |
| 23 | 24 | ||
| @@ -247,9 +248,8 @@ int32_t FindAccessibilityNodeInfosById( | |||
| 247 | int32_t requestId, | 248 | int32_t requestId, |
| 248 | ArkUI_AccessibilityElementInfoList* elementList) | 249 | ArkUI_AccessibilityElementInfoList* elementList) |
| 249 | { | 250 | { |
| 250 | - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); | 251 | + OhosAccessibilityBridge::GetInstance()->FindAccessibilityNodeInfosById(elementId, mode, requestId, elementList); |
| 251 | - ohosAccessibilityBridge->FindAccessibilityNodeInfosById(elementId, mode, requestId, elementList); | 252 | + FML_DLOG(INFO) << "accessibilityProviderCallback_.FindAccessibilityNodeInfosById"; |
| 252 | - LOGD("accessibilityProviderCallback_.FindAccessibilityNodeInfosById"); | ||
| 253 | return 0; | 253 | return 0; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| @@ -260,8 +260,7 @@ int32_t FindAccessibilityNodeInfosByText( | |||
| 260 | int32_t requestId, | 260 | int32_t requestId, |
| 261 | ArkUI_AccessibilityElementInfoList* elementList) | 261 | ArkUI_AccessibilityElementInfoList* elementList) |
| 262 | { | 262 | { |
| 263 | - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); | 263 | + OhosAccessibilityBridge::GetInstance()->FindAccessibilityNodeInfosByText(elementId, text, requestId, elementList); |
| 264 | - ohosAccessibilityBridge->FindAccessibilityNodeInfosByText(elementId, text, requestId, elementList); | ||
| 265 | LOGD("accessibilityProviderCallback_.FindAccessibilityNodeInfosByText"); | 264 | LOGD("accessibilityProviderCallback_.FindAccessibilityNodeInfosByText"); |
| 266 | return 0; | 265 | return 0; |
| 267 | } | 266 | } |
| @@ -273,8 +272,7 @@ int32_t FindFocusedAccessibilityNode( | |||
| 273 | int32_t requestId, | 272 | int32_t requestId, |
| 274 | ArkUI_AccessibilityElementInfo* elementinfo) | 273 | ArkUI_AccessibilityElementInfo* elementinfo) |
| 275 | { | 274 | { |
| 276 | - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); | 275 | + OhosAccessibilityBridge::GetInstance()->FindFocusedAccessibilityNode(elementId, focusType, requestId, elementinfo); |
| 277 | - ohosAccessibilityBridge->FindFocusedAccessibilityNode(elementId, focusType, requestId, elementinfo); | ||
| 278 | LOGD("accessibilityProviderCallback_.FindFocusedAccessibilityNode"); | 276 | LOGD("accessibilityProviderCallback_.FindFocusedAccessibilityNode"); |
| 279 | return 0; | 277 | return 0; |
| 280 | } | 278 | } |
| @@ -286,8 +284,7 @@ int32_t FindNextFocusAccessibilityNode( | |||
| 286 | int32_t requestId, | 284 | int32_t requestId, |
| 287 | ArkUI_AccessibilityElementInfo *elementList) | 285 | ArkUI_AccessibilityElementInfo *elementList) |
| 288 | { | 286 | { |
| 289 | - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); | 287 | + OhosAccessibilityBridge::GetInstance()->FindNextFocusAccessibilityNode(elementId, direction, requestId, elementList); |
| 290 | - ohosAccessibilityBridge->FindNextFocusAccessibilityNode(elementId, direction, requestId, elementList); | ||
| 291 | LOGD("accessibilityProviderCallback_.FindNextFocusAccessibilityNode"); | 288 | LOGD("accessibilityProviderCallback_.FindNextFocusAccessibilityNode"); |
| 292 | return 0; | 289 | return 0; |
| 293 | } | 290 | } |
| @@ -299,8 +296,7 @@ int32_t ExecuteAccessibilityAction( | |||
| 299 | ArkUI_AccessibilityActionArguments* actionArguments, | 296 | ArkUI_AccessibilityActionArguments* actionArguments, |
| 300 | int32_t requestId) | 297 | int32_t requestId) |
| 301 | { | 298 | { |
| 302 | - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); | 299 | + OhosAccessibilityBridge::GetInstance()->ExecuteAccessibilityAction(elementId, action, actionArguments, requestId); |
| 303 | - ohosAccessibilityBridge->ExecuteAccessibilityAction(elementId, action, actionArguments, requestId); | ||
| 304 | LOGD("accessibilityProviderCallback_.ExecuteAccessibilityAction"); | 300 | LOGD("accessibilityProviderCallback_.ExecuteAccessibilityAction"); |
| 305 | return 0; | 301 | return 0; |
| 306 | } | 302 | } |
| @@ -318,8 +314,7 @@ int32_t GetAccessibilityNodeCursorPosition( | |||
| 318 | int32_t requestId, | 314 | int32_t requestId, |
| 319 | int32_t* index) | 315 | int32_t* index) |
| 320 | { | 316 | { |
| 321 | - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); | 317 | + OhosAccessibilityBridge::GetInstance()->GetAccessibilityNodeCursorPosition(elementId, requestId, index); |
| 322 | - ohosAccessibilityBridge->GetAccessibilityNodeCursorPosition(elementId, requestId, index); | ||
| 323 | LOGD("accessibilityProviderCallback_.GetAccessibilityNodeCursorPosition"); | 318 | LOGD("accessibilityProviderCallback_.GetAccessibilityNodeCursorPosition"); |
| 324 | return 0; | 319 | return 0; |
| 325 | } | 320 | } |
| @@ -373,29 +368,27 @@ void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nati | |||
| 373 | { | 368 | { |
| 374 | if (OH_GetSdkApiVersion() < 13) { return; } | 369 | if (OH_GetSdkApiVersion() < 13) { return; } |
| 375 | LOGD("api version: %{public}d", OH_GetSdkApiVersion()); | 370 | LOGD("api version: %{public}d", OH_GetSdkApiVersion()); |
| 371 | + | ||
| 376 | BindAccessibilityProviderCallback(); | 372 | BindAccessibilityProviderCallback(); |
| 377 | 373 | ||
| 378 | auto OH_NativeXComponent_GetNativeAccessibilityProvider = | 374 | auto OH_NativeXComponent_GetNativeAccessibilityProvider = |
| 379 | OhosAccessibilityDDL::DLLoadGetNativeA11yProvider(ArkUIAccessibilityConstant::OH_GET_A11Y_PROVIDER); | 375 | OhosAccessibilityDDL::DLLoadGetNativeA11yProvider(ArkUIAccessibilityConstant::OH_GET_A11Y_PROVIDER); |
| 380 | CHECK_DLL_NULL_PTR(OH_NativeXComponent_GetNativeAccessibilityProvider); | 376 | CHECK_DLL_NULL_PTR(OH_NativeXComponent_GetNativeAccessibilityProvider); |
| 381 | - | 377 | + ArkUI_AccessibilityProvider* a11yProvider = nullptr; |
| 382 | - ArkUI_AccessibilityProvider* accessibilityProvider = nullptr; | ||
| 383 | ARKUI_ACCESSIBILITY_CALL_CHECK( | 378 | ARKUI_ACCESSIBILITY_CALL_CHECK( |
| 384 | - OH_NativeXComponent_GetNativeAccessibilityProvider(nativeXComponent, &accessibilityProvider) | 379 | + OH_NativeXComponent_GetNativeAccessibilityProvider(nativeXComponent, &a11yProvider) |
| 385 | ); | 380 | ); |
| 386 | 381 | ||
| 387 | auto OH_ArkUI_AccessibilityProviderRegisterCallback = | 382 | auto OH_ArkUI_AccessibilityProviderRegisterCallback = |
| 388 | OhosAccessibilityDDL::DLLoadRegisterFunc(ArkUIAccessibilityConstant::ARKUI_REGISTER_CALLBACK); | 383 | OhosAccessibilityDDL::DLLoadRegisterFunc(ArkUIAccessibilityConstant::ARKUI_REGISTER_CALLBACK); |
| 389 | CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityProviderRegisterCallback); | 384 | CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityProviderRegisterCallback); |
| 385 | + CHECK_NULL_PTR(a11yProvider, RegisterArkUIAccessibilityService); | ||
| 390 | ARKUI_ACCESSIBILITY_CALL_CHECK( | 386 | ARKUI_ACCESSIBILITY_CALL_CHECK( |
| 391 | - OH_ArkUI_AccessibilityProviderRegisterCallback(accessibilityProvider, &accessibilityProviderCallback_) | 387 | + OH_ArkUI_AccessibilityProviderRegisterCallback(a11yProvider, &accessibilityProviderCallback_) |
| 392 | ); | 388 | ); |
| 393 | 389 | ||
| 394 | - //将ArkUI_AccessibilityProvider传到无障碍bridge类 | 390 | + XComponentAdapter::GetInstance()->accessibilityProvider_ = a11yProvider; |
| 395 | - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); | 391 | + FML_DLOG(INFO) << "RegisterArkUIAccessibilityService is finished"; |
| 396 | - ohosAccessibilityBridge->provider_ = accessibilityProvider; | ||
| 397 | - | ||
| 398 | - LOGI("XComponentBase::SetNativeXComponent OH_ArkUI_AccessibilityProviderRegisterCallback is succeed"); | ||
| 399 | } | 392 | } |
| 400 | 393 | ||
| 401 | void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ | 394 | void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ |
| @@ -404,7 +397,7 @@ void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ | |||
| 404 | BindXComponentCallback(); | 397 | BindXComponentCallback(); |
| 405 | OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); | 398 | OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); |
| 406 | OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent_, &mouseCallback_); | 399 | OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent_, &mouseCallback_); |
| 407 | - // 注册ArkUI无障碍服务 | 400 | + // register the OH_ArkUI accessibility callbacks |
| 408 | RegisterArkUIAccessibilityService(nativeXComponent_); | 401 | RegisterArkUIAccessibilityService(nativeXComponent_); |
| 409 | } | 402 | } |
| 410 | } | 403 | } |
| @@ -26,7 +26,6 @@ | |||
| 26 | #include "napi_common.h" | 26 | #include "napi_common.h" |
| 27 | #include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" | 27 | #include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" |
| 28 | #include "flutter/shell/platform/ohos/utils/ddl_utils.h" | 28 | #include "flutter/shell/platform/ohos/utils/ddl_utils.h" |
| 29 | - | ||
| 30 | namespace flutter { | 29 | namespace flutter { |
| 31 | 30 | ||
| 32 | class XComponentBase | 31 | class XComponentBase |
| @@ -84,6 +83,7 @@ class XComponentAdapter { | |||
| 84 | 83 | ||
| 85 | public: | 84 | public: |
| 86 | std::map<std::string, XComponentBase*> xcomponetMap_; | 85 | std::map<std::string, XComponentBase*> xcomponetMap_; |
| 86 | + ArkUI_AccessibilityProvider* accessibilityProvider_; | ||
| 87 | 87 | ||
| 88 | private: | 88 | private: |
| 89 | static XComponentAdapter mXComponentAdapter; | 89 | static XComponentAdapter mXComponentAdapter; |