From 4d1c09e6fcfb155f7809acca150d594c9737798e Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Sat, 7 Dec 2024 15:22:25 +0800 Subject: [PATCH 01/60] =?UTF-8?q?=E9=80=82=E9=85=8D2in1,=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=BC=A0=E6=A0=87=E6=A1=86=E9=80=89=E6=96=87=E5=AD=97,?= =?UTF-8?q?=E8=A7=84=E9=81=BF=E7=BB=84=E5=90=88=E9=94=AE=E7=9A=84=E5=86=B2?= =?UTF-8?q?=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- .../ets/embedding/ohos/KeyEventHandler.ets | 20 ++++++++++++++++++- shell/platform/ohos/ohos_touch_processor.cpp | 9 ++------- .../platform/ohos/ohos_xcomponent_adapter.cpp | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets index 58133fd461..df38b7093b 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets @@ -21,11 +21,17 @@ import { KeyCode } from "@kit.InputKit"; const TAG = "KeyEventHandler"; +const CONTROL_KEYS = [ + KeyCode.KEYCODE_CTRL_LEFT, KeyCode.KEYCODE_CTRL_RIGHT, + KeyCode.KEYCODE_ALT_LEFT, KeyCode.KEYCODE_ALT_RIGHT +]; + export class KeyEventHandler { private textInputPlugin?: TextInputPlugin; private charMap : HashMap = new HashMap(); private shiftMap : HashMap = new HashMap(); private isShiftMode: boolean = false; + private isControlMode: boolean = false; constructor(textInputPlugin?: TextInputPlugin) { this.textInputPlugin = textInputPlugin; @@ -147,9 +153,20 @@ export class KeyEventHandler { handleKeyEvent(event: KeyEvent) { Log.i(TAG, JSON.stringify({ "name": "handleKeyEvent", - "event": event + "event": event, })); + if (event.type == KeyType.Down) { + if (!this.isControlMode) { + this.isControlMode = CONTROL_KEYS.findIndex((it) => it == event.keyCode) >= 0; + } + } + Log.i(TAG, "isControlMode=" + this.isControlMode) if (event.type == KeyType.Up) { + if (!this.isControlMode) { + this.isControlMode = CONTROL_KEYS.findIndex((it) => it == event.keyCode) >= 0; + } else { + return; + } // 处理字符按键相关逻辑 if (this.charMap.hasKey(event.keyCode)) { this.textInputPlugin?.getEditingState().handleInsertTextEvent(this.getCharByEvent(event)) @@ -160,5 +177,6 @@ export class KeyEventHandler { } } this.isShiftMode = event.keyCode == KeyCode.KEYCODE_SHIFT_LEFT + || event.keyCode == KeyCode.KEYCODE_SHIFT_RIGHT } } diff --git a/shell/platform/ohos/ohos_touch_processor.cpp b/shell/platform/ohos/ohos_touch_processor.cpp index 32d2ed1ef8..b820d49e4a 100644 --- a/shell/platform/ohos/ohos_touch_processor.cpp +++ b/shell/platform/ohos/ohos_touch_processor.cpp @@ -179,12 +179,7 @@ void OhosTouchProcessor::HandleTouchEvent( OH_NativeXComponent_TouchPointToolType toolType; OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType); pointerData.kind = getPointerDeviceTypeForToolType(toolType); - if (pointerData.kind == PointerData::DeviceKind::kTouch) { - if (pointerData.change == PointerData::Change::kDown || - pointerData.change == PointerData::Change::kMove) { - pointerData.buttons = kPointerButtonTouchContact; - } - } + pointerData.buttons = kPointerButtonTouchContact; pointerData.pan_x = 0.0; pointerData.pan_y = 0.0; // Delta will be generated in pointer_data_packet_converter.cc. @@ -261,7 +256,7 @@ void OhosTouchProcessor::HandleMouseEvent( pointerData.pressure = 0.0; pointerData.pressure_max = 1.0; pointerData.pressure_min = 0.0; - pointerData.kind = PointerData::DeviceKind::kTouch; + pointerData.kind = PointerData::DeviceKind::kMouse; // kMouse支持鼠标框选文字 pointerData.buttons = getPointerButtonFromMouse(mouseEvent.button); // hover support if (mouseEvent.button == OH_NATIVEXCOMPONENT_NONE_BUTTON && pointerData.change == PointerData::Change::kMove) { diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index e9a0e82d03..b9294e1166 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -532,7 +532,7 @@ void XComponentBase::OnDispatchMouseWheelEvent(mouseWheelEvent event) } if (event.eventType == "actionUpdate") { OH_NativeXComponent_MouseEvent mouseEvent; - double scrollY = event.offsetY - g_scrollDistance; + double scrollY = -(event.offsetY - g_scrollDistance); g_scrollDistance = event.offsetY; // fix resize ratio mouseEvent.x = event.globalX / g_resizeRate; -- Gitee From 02bd8592ed88b55c560444847bf331db886cfdc3 Mon Sep 17 00:00:00 2001 From: liujiake Date: Tue, 10 Dec 2024 14:13:21 +0800 Subject: [PATCH 02/60] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9=E5=A4=96?= =?UTF-8?q?=E6=8E=A5=E7=BA=B9=E7=90=86Paint=E4=B8=AD()=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E7=9A=84openGL=E8=B5=84=E6=BA=90=E4=B8=BA=E7=A9=BA=E7=9A=84?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liujiake --- shell/platform/ohos/ohos_external_texture_gl.cpp | 2 +- shell/platform/ohos/platform_view_ohos.cpp | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/shell/platform/ohos/ohos_external_texture_gl.cpp b/shell/platform/ohos/ohos_external_texture_gl.cpp index f160e09469..1a5b304ad0 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.cpp +++ b/shell/platform/ohos/ohos_external_texture_gl.cpp @@ -343,7 +343,7 @@ bool OHOSExternalTextureGL::IsContextCurrent() void OHOSExternalTextureGL::Update() { FML_DLOG(INFO) << "OHOSExternalTextureGL::Update, texture_name_=" << texture_name_; - if (!IsContextCurrent() && context_) { + if (!IsContextCurrent() && context_ && display_ && draw_surface_ && read_surface_) { if (eglMakeCurrent(display_, draw_surface_, read_surface_, context_) != EGL_TRUE) { FML_LOG(WARNING) << "eglMakeCurrent in update failed"; } diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index b1aca3a69c..7c8cbfd34f 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -117,15 +117,13 @@ PlatformViewOHOS::PlatformViewOHOS( PlatformViewOHOS::~PlatformViewOHOS() { FML_LOG(INFO) << "PlatformViewOHOS::~PlatformViewOHOS"; - for (std::map>::iterator it = external_texture_gl_.begin(); - it != external_texture_gl_.end(); ++it) { - if (it->second != nullptr) { - OH_NativeImage_Destroy(&(it->second->nativeImage_)); - it->second->nativeImage_ = nullptr; + for (auto const &it : external_texture_gl_) { + if (it.second != nullptr) { + OH_NativeImage_Destroy(&(it.second->nativeImage_)); + it.second->nativeImage_ = nullptr; } } external_texture_gl_.clear(); - FML_LOG(INFO) << "PlatformViewOHOS::~PlatformViewOHOS finish"; } void PlatformViewOHOS::NotifyCreate( -- Gitee From d5a0f86d4a14ed9e0750e29d67b4a26cc6a8f792 Mon Sep 17 00:00:00 2001 From: liujiake Date: Wed, 11 Dec 2024 15:50:25 +0800 Subject: [PATCH 03/60] =?UTF-8?q?=E5=9C=A8PlatformViewOHOS=E6=9E=90?= =?UTF-8?q?=E6=9E=84=E5=87=BD=E6=95=B0=E4=B8=AD=E6=B7=BB=E5=8A=A0=E9=94=80?= =?UTF-8?q?=E6=AF=81nativeImage=E7=9A=84=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liujiake --- shell/platform/ohos/platform_view_ohos.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index 7c8cbfd34f..58b1056978 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -119,6 +119,7 @@ PlatformViewOHOS::~PlatformViewOHOS() { FML_LOG(INFO) << "PlatformViewOHOS::~PlatformViewOHOS"; for (auto const &it : external_texture_gl_) { if (it.second != nullptr) { + FML_LOG(INFO) << " nativeImage of textureId " << it.first << " will destroy"; OH_NativeImage_Destroy(&(it.second->nativeImage_)); it.second->nativeImage_ = nullptr; } -- Gitee From abd217ae692d08abf15ddf06c3fdf05b21146196 Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Thu, 12 Dec 2024 11:31:35 +0800 Subject: [PATCH 04/60] =?UTF-8?q?=E4=B8=8D=E5=A4=84=E7=90=86=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E9=94=AE=E7=9A=84keyEvent=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- .../flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets | 4 ---- 1 file changed, 4 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets index df38b7093b..0c9dadf394 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets @@ -171,10 +171,6 @@ export class KeyEventHandler { if (this.charMap.hasKey(event.keyCode)) { this.textInputPlugin?.getEditingState().handleInsertTextEvent(this.getCharByEvent(event)) } - // 处理非字符按键 - if (event.keyCode == KeyCode.KEYCODE_DEL) { - this.textInputPlugin?.getEditingState().handleDeleteEvent(false, 0) - } } this.isShiftMode = event.keyCode == KeyCode.KEYCODE_SHIFT_LEFT || event.keyCode == KeyCode.KEYCODE_SHIFT_RIGHT -- Gitee From f8233998a2a8bae420ee44b470664a8f6ef95264 Mon Sep 17 00:00:00 2001 From: chaoxizhang Date: Wed, 11 Dec 2024 18:36:12 +0800 Subject: [PATCH 05/60] Fix external texture flush task after engine destroyed will be caused SIGSEGV crash. Signed-off-by: chaoxizhang Remove unused OhosImageFrameData struct Signed-off-by: chaoxizhang --- .../ohos/ohos_external_texture_gl.cpp | 67 +++++++------------ .../platform/ohos/ohos_external_texture_gl.h | 22 +----- 2 files changed, 25 insertions(+), 64 deletions(-) diff --git a/shell/platform/ohos/ohos_external_texture_gl.cpp b/shell/platform/ohos/ohos_external_texture_gl.cpp index f160e09469..189fc2bb19 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.cpp +++ b/shell/platform/ohos/ohos_external_texture_gl.cpp @@ -104,7 +104,6 @@ OHOSExternalTextureGL::OHOSExternalTextureGL( backGroundPixelMap_ = nullptr; lastImage_ = nullptr; isEmulator_ = OhosMain::IsEmulator(); - frameData_ = nullptr; } OHOSExternalTextureGL::~OHOSExternalTextureGL() @@ -125,24 +124,37 @@ OHOSExternalTextureGL::~OHOSExternalTextureGL() lastImage_ = nullptr; } -void OnNativeImageFrameAvailable(void *data) +void OnNativeImageFrameAvailable(void *context) { - auto frameData = reinterpret_cast(data); - if (frameData == nullptr) { - FML_LOG(ERROR) << "OnNativeImageFrameAvailable, frameData is null."; + auto ohosExternalTextureGL = reinterpret_cast(context); + if (ohosExternalTextureGL == nullptr) { + FML_LOG(ERROR) << "OnNativeImageFrameAvailable, ohosExternalTextureGL is null."; return; } - frameData->OnPlatformViewMarkTextureFrameAvailable(); + + if (ohosExternalTextureGL != nullptr) { + auto wp_ohosExternalTextureGL = std::weak_ptr( + ohosExternalTextureGL->shared_from_this()); + fml::TaskRunner::RunNowOrPostTask( + ohosExternalTextureGL->task_runners_.GetPlatformTaskRunner(), + [wp_ohosExternalTextureGL]() { + if (auto sp_ohosExternalTextureGL = wp_ohosExternalTextureGL.lock()) { + PlatformView::Delegate& delegate = + sp_ohosExternalTextureGL->delegate_; + delegate.OnPlatformViewMarkTextureFrameAvailable(sp_ohosExternalTextureGL->Id()); + } + }); + } } -bool RegisterFrameAvailableListener(OH_NativeImage *nativeImage, OhosImageFrameData *frameData) +bool RegisterFrameAvailableListener(OH_NativeImage *nativeImage, void *context) { - if (frameData == nullptr) { - FML_LOG(ERROR) << "Error with RegisterFrameAvailableListener, frameData is null"; + if (context == nullptr) { + FML_LOG(ERROR) << "Error with RegisterFrameAvailableListener, context is null"; return false; } OH_OnFrameAvailableListener listener; - listener.context = frameData; + listener.context = context; listener.onFrameAvailable = OnNativeImageFrameAvailable; int64_t ret = OH_NativeImage_SetOnFrameAvailableListener(nativeImage, listener); if (ret != 0) { @@ -191,12 +203,7 @@ void OHOSExternalTextureGL::Attach() FML_LOG(ERROR) << "OHOSExternalTextureGL OH_NativeImage_AttachContext err code:" << ret; } - if (frameData_ == nullptr) { - frameData_ = new OhosImageFrameData(this, Id()); - } - if (!RegisterFrameAvailableListener(nativeImage_, (OhosImageFrameData *)frameData_)) { - delete (OhosImageFrameData *)frameData_; - frameData_ = nullptr; + if (!RegisterFrameAvailableListener(nativeImage_, this)) { return; } state_ = AttachmentState::attached; @@ -375,10 +382,6 @@ void OHOSExternalTextureGL::Detach() OH_NativeImage_Destroy(&nativeImage_); nativeImage_ = nullptr; } - if (frameData_ != nullptr) { - delete (OhosImageFrameData *)frameData_; - frameData_ = nullptr; - } if (nativeWindow_ != nullptr) { OH_NativeWindow_DestroyNativeWindow(nativeWindow_); nativeWindow_ = nullptr; @@ -770,28 +773,4 @@ void OHOSExternalTextureGL::DispatchBackGroundPixelMap(NativePixelMap* pixelMap) } } -OhosImageFrameData::OhosImageFrameData( - OHOSExternalTextureGL *ohosExternalTextureGL, - int64_t textureId) - : ohosExternalTextureGL(ohosExternalTextureGL), - textureId_(textureId) -{} - -OhosImageFrameData::~OhosImageFrameData() -{ - ohosExternalTextureGL = nullptr; - textureId_ = 0; -} - -void OhosImageFrameData::OnPlatformViewMarkTextureFrameAvailable() -{ - if (ohosExternalTextureGL != nullptr) { - fml::TaskRunner::RunNowOrPostTask( - ohosExternalTextureGL->task_runners_.GetPlatformTaskRunner(), [textureId = textureId_, this]() { - PlatformView::Delegate& dalegate = this->ohosExternalTextureGL->delegate_; - dalegate.OnPlatformViewMarkTextureFrameAvailable(textureId); - }); - } -} - } // namespace flutter \ No newline at end of file diff --git a/shell/platform/ohos/ohos_external_texture_gl.h b/shell/platform/ohos/ohos_external_texture_gl.h index 24beb3279d..5ddd50b573 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.h +++ b/shell/platform/ohos/ohos_external_texture_gl.h @@ -36,7 +36,8 @@ // maybe now unused namespace flutter { -class OHOSExternalTextureGL : public flutter::Texture { +// Represents an external texture for OHOS platform, using std::weak_ptr to avoid circular reference. +class OHOSExternalTextureGL : public flutter::Texture, public std::enable_shared_from_this { public: explicit OHOSExternalTextureGL(int64_t id, const std::shared_ptr& ohos_surface); explicit OHOSExternalTextureGL(int64_t id, const std::shared_ptr& ohos_surface, @@ -52,8 +53,6 @@ class OHOSExternalTextureGL : public flutter::Texture { OH_NativeImage *backGroundNativeImage_; - void *frameData_; - bool first_update_ = false; void Paint(PaintContext& context, @@ -145,22 +144,5 @@ class OHOSExternalTextureGL : public flutter::Texture { bool IsContextCurrent(); }; -class OhosImageFrameData { - public: - OhosImageFrameData(OHOSExternalTextureGL *ohosExternalTextureGL, int64_t textureId); - - OhosImageFrameData() = delete; - - ~OhosImageFrameData(); - - void OnPlatformViewMarkTextureFrameAvailable(); - - private: - - OHOSExternalTextureGL *ohosExternalTextureGL; - - int64_t textureId_; -}; - } // namespace flutter #endif \ No newline at end of file -- Gitee From de93413fbc249346db84080c2ba0435739982ca6 Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Sat, 14 Dec 2024 16:22:38 +0800 Subject: [PATCH 06/60] =?UTF-8?q?=E4=BF=AE=E6=94=B9ohos.py=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E6=A0=BC=E5=BC=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- attachment/scripts/ohos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attachment/scripts/ohos.py b/attachment/scripts/ohos.py index d60c405775..acf42ab53f 100644 --- a/attachment/scripts/ohos.py +++ b/attachment/scripts/ohos.py @@ -298,7 +298,7 @@ def zipFiles(buildInfo, useZip2=False, args=any): prefixInZip = os.path.join("src", "out", outputName) excludes = ["obj", "exe.unstripped", "so.unstripped"] if IS_WINDOWS: - excludes.extend([".*\.ilk", ".*\.pdb"]) + excludes.extend([r".*\.ilk", r".*\.pdb"]) zipFileDir(fileIn, fileName, prefixInZip, excludes=excludes, useZip2=useZip2) -- Gitee From 7fb6737b6339c464664e23ede83d8e855b6653c4 Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Sat, 14 Dec 2024 16:25:00 +0800 Subject: [PATCH 07/60] =?UTF-8?q?=E4=BF=AE=E6=94=B9FlutterView.ets,?= =?UTF-8?q?=E6=9C=89=E5=BC=82=E5=B8=B8=E6=97=B6=E5=8F=96=E5=80=BC=E4=B8=8D?= =?UTF-8?q?=E5=8F=98,=E9=81=BF=E5=85=8D=E7=8A=B6=E6=80=81=E6=A0=8F?= =?UTF-8?q?=E5=81=B6=E7=8E=B0=E9=AB=98=E5=BA=A6=E4=B8=BA0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- .../flutter/src/main/ets/view/FlutterView.ets | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index c8b2fd6742..5f5d50c849 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -388,16 +388,20 @@ export class FlutterView { // 根据是否全屏显示,设置标题栏高度(若全屏,则及时规避) if (this.checkFullScreen && (setFullScreen || this.mainWindow?.getWindowProperties().isLayoutFullScreen)) { // 全屏显示 - this.viewportMetrics.physicalViewPaddingTop = this.systemAvoidArea?.topRect.height ?? 0; - this.viewportMetrics.physicalViewPaddingBottom = this.navigationAvoidArea?.bottomRect.height ?? 0; + this.viewportMetrics.physicalViewPaddingTop = + this.systemAvoidArea?.topRect.height ?? this.viewportMetrics.physicalViewPaddingTop; + this.viewportMetrics.physicalViewPaddingBottom = + this.navigationAvoidArea?.bottomRect.height ?? this.viewportMetrics.physicalViewPaddingBottom; } else { // 非全屏显示(保持规避效果) // 顶部状态栏和底部导航栏规避为0,无平滑过渡效果 this.viewportMetrics.physicalViewPaddingTop = 0; this.viewportMetrics.physicalViewPaddingBottom = 0; } - this.viewportMetrics.physicalViewPaddingLeft = this.systemAvoidArea?.leftRect.width ?? 0; - this.viewportMetrics.physicalViewPaddingRight = this.systemAvoidArea?.rightRect.width ?? 0; + this.viewportMetrics.physicalViewPaddingLeft = + this.systemAvoidArea?.leftRect.width ?? this.viewportMetrics.physicalViewPaddingLeft; + this.viewportMetrics.physicalViewPaddingRight = + this.systemAvoidArea?.rightRect.width ?? this.viewportMetrics.physicalViewPaddingRight; this.onKeyboardAreaChange() this.onGestureAreaChange() @@ -410,10 +414,14 @@ export class FlutterView { private onKeyboardAreaChange() { if (this.checkKeyboard) { - this.viewportMetrics.physicalViewInsetTop = this.keyboardAvoidArea?.topRect.height ?? 0 - this.viewportMetrics.physicalViewInsetLeft = this.keyboardAvoidArea?.leftRect.width ?? 0 - this.viewportMetrics.physicalViewInsetBottom = this.keyboardAvoidArea?.bottomRect.height ?? 0 - this.viewportMetrics.physicalViewInsetRight = this.keyboardAvoidArea?.rightRect.width ?? 0 + this.viewportMetrics.physicalViewInsetTop = + this.keyboardAvoidArea?.topRect.height ?? this.viewportMetrics.physicalViewInsetTop + this.viewportMetrics.physicalViewInsetLeft = + this.keyboardAvoidArea?.leftRect.width ?? this.viewportMetrics.physicalViewInsetLeft + this.viewportMetrics.physicalViewInsetBottom = + this.keyboardAvoidArea?.bottomRect.height ?? this.viewportMetrics.physicalViewInsetBottom + this.viewportMetrics.physicalViewInsetRight = + this.keyboardAvoidArea?.rightRect.width ?? this.viewportMetrics.physicalViewInsetRight } else { this.viewportMetrics.physicalViewInsetTop = 0 this.viewportMetrics.physicalViewInsetLeft = 0 @@ -424,10 +432,14 @@ export class FlutterView { private onGestureAreaChange() { if (this.checkGesture) { - this.viewportMetrics.systemGestureInsetTop = this.gestureAvoidArea?.topRect.height ?? 0 - this.viewportMetrics.systemGestureInsetLeft = this.gestureAvoidArea?.leftRect.width ?? 0 - this.viewportMetrics.systemGestureInsetBottom = this.gestureAvoidArea?.bottomRect.height ?? 0 - this.viewportMetrics.systemGestureInsetRight = this.gestureAvoidArea?.rightRect.width ?? 0 + this.viewportMetrics.systemGestureInsetTop = + this.gestureAvoidArea?.topRect.height ?? this.viewportMetrics.systemGestureInsetTop + this.viewportMetrics.systemGestureInsetLeft = + this.gestureAvoidArea?.leftRect.width ?? this.viewportMetrics.systemGestureInsetLeft + this.viewportMetrics.systemGestureInsetBottom = + this.gestureAvoidArea?.bottomRect.height ?? this.viewportMetrics.systemGestureInsetBottom + this.viewportMetrics.systemGestureInsetRight = + this.gestureAvoidArea?.rightRect.width ?? this.viewportMetrics.systemGestureInsetRight } else { this.viewportMetrics.systemGestureInsetTop = 0 this.viewportMetrics.systemGestureInsetLeft = 0 -- Gitee From 1b7f70a2d5ea1c89c2b9988bca186f4a06042618 Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Sat, 14 Dec 2024 16:27:54 +0800 Subject: [PATCH 08/60] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20UIAbility+FlutterEnt?= =?UTF-8?q?ry=20=E5=9C=BA=E6=99=AF,=E6=8F=92=E4=BB=B6=E4=B8=AD=E4=B8=8D?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=20onAttachedToAbility=20=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- .../main/ets/embedding/ohos/FlutterAbility.ets | 2 +- .../main/ets/embedding/ohos/FlutterEntry.ets | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets index d13fd9859a..9eb08c3d5e 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets @@ -319,7 +319,7 @@ export class FlutterAbility extends UIAbility implements Host { if (this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] != undefined) { return this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as boolean; } - if (this.getCachedEngineId() != null) { + if (this.getCachedEngineId() != null && this.getCachedEngineId().length > 0) { // Prevent overwriting the existing state in a cached engine with restoration state. return false; } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterEntry.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterEntry.ets index 38f0192ea0..de27aa398f 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterEntry.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterEntry.ets @@ -152,15 +152,27 @@ export default class FlutterEntry implements Host { } shouldAttachEngineToAbility(): boolean { - return this.parameters![FlutterEntry.ARG_SHOULD_ATTACH_ENGINE_TO_ABILITY] as boolean + let param = this.parameters![FlutterEntry.ARG_SHOULD_ATTACH_ENGINE_TO_ABILITY]; + if (!param) { + return true; + } + return param as boolean } getCachedEngineId(): string { - return this.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as string + let param = this.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID]; + if (!param) { + return ""; + } + return param as string } getCachedEngineGroupId(): string | null { - return this.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_GROUP_ID] as string + let param = this.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_GROUP_ID]; + if (!param) { + return null; + } + return param as string } shouldDestroyEngineWithHost(): boolean { -- Gitee From 5217a1edfb89b238cc2561ca119806d509afda6a Mon Sep 17 00:00:00 2001 From: gxzmf <279822581@qq.com> Date: Sat, 14 Dec 2024 15:01:10 +0800 Subject: [PATCH 09/60] =?UTF-8?q?=E3=80=90feature=E3=80=91=E6=8F=90?= =?UTF-8?q?=E4=BA=A4PR=E5=90=88=E5=85=A5=E8=87=AA=E6=A3=80=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: gxzmf <279822581@qq.com> --- .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md new file mode 100644 index 0000000000..47f158371d --- /dev/null +++ b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md @@ -0,0 +1,25 @@ +**IssueNo**: + +**Description**: +(提交描述) + +**Feature or Bugfix**: +- [ ] Feature +- [ ] Bugfix + +**Binary Source**: +- [ ] No +- [ ] yes + +**预测试**: +- [ ] Pass +- [ ] Fail +- [ ] 评估不涉及 + +**合入前自检**: +- [ ] 不涉及非兼容性变更;若涉及,已通过相应评审。 +- [ ] 不涉及性能或已进行性能测试且无性能劣化。 +- [ ] 符合对应的编码规范。 +- [ ] 不涉及文档更新,或已更新了文档。 +- [ ] 针对可测试性要求,已增加必要的自测用例、合理的日志记录或Trace信息。 +- [ ] 不存在非法的文件引入,包括图片和代码等。 \ No newline at end of file -- Gitee From 85a68f4f48081aca2a9ca4f4e70fddd5149783f4 Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 2 Dec 2024 15:52:18 +0800 Subject: [PATCH 10/60] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E6=97=A0=E9=9A=9C?= =?UTF-8?q?=E7=A2=8D=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8=E7=9A=84=E5=85=A5?= =?UTF-8?q?=E5=8F=82=E6=8E=A5=E5=8F=A3=E5=90=8D=E6=89=93=E5=8D=B0=EF=BC=8C?= =?UTF-8?q?=E6=96=B9=E4=BE=BF=E5=AE=9A=E4=BD=8D=E9=94=99=E8=AF=AF=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E6=9D=A5=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 19 ++++++++++--------- .../accessibility/ohos_accessibility_ddl.h | 4 ---- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 5bda8bfaea..d33dcc7694 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -25,18 +25,19 @@ #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkScalar.h" -#define OHOS_API_VERSION 13 #define ARKUI_SUCCEED_CODE 0 #define ARKUI_FAILED_CODE -1 #define ARKUI_BAD_PARAM_CODE -2 #define ARKUI_OOM_CODE -3 -#define ARKUI_ACCESSIBILITY_CALL_CHECK(X) \ - do { \ - int32_t RET = X; \ - if (RET != ARKUI_SUCCEED_CODE) { \ - LOGE("Failed arkui a11y function call, error code:%{public}d", RET); \ - } \ - } while (false) \ +#define FUNCTION_NAME_STR(n) #n +#define ARKUI_ACCESSIBILITY_CALL_CHECK(X) \ + do { \ + int32_t RET = X; \ + if (RET != ARKUI_SUCCEED_CODE) { \ + LOGE("Failed function %{public}s call, error code:%{public}d", \ + FUNCTION_NAME_STR(X), RET); \ + } \ + } while (false) \ namespace flutter { @@ -1930,7 +1931,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( ArkUI_AccessibilityEventInfo* eventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); if (eventInfo == nullptr) { FML_DLOG(ERROR) << "Flutter_SendAccessibilityAsyncEvent " - "OH_ArkUI_CreateAccessibilityEventInfo eventInfo = null"; + "OH_ArkUI_CreateAccessibilityEventInfo eventInfo = null"; return; } diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h index c5d6c32631..96d3d38468 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h @@ -72,11 +72,7 @@ public: static SetReqFocusFunc DLLoadSetReqFocusFunc(const char* symbolName); static GetNativeA11yProvider DLLoadGetNativeA11yProvider(const char* symbolName); - - }; - } // namespace flutter - #endif \ No newline at end of file -- Gitee From 66abcece2bea7f03f63e7d304e4549ce26b4e91f Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 9 Dec 2024 21:25:47 +0800 Subject: [PATCH 11/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8Dhypium=E7=9A=84widg?= =?UTF-8?q?et+id=E7=BB=84=E4=BB=B6=E5=90=8D=E7=A7=B0=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E3=80=81scroll=E7=BB=84=E4=BB=B6=E5=AD=90=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=A4=B1=E8=B4=A5=E3=80=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=9D=90=E6=A0=87=E6=98=A0=E5=B0=84=E7=AE=97=E6=B3=95=E3=80=81?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=BE=93=E5=85=A5=E6=A1=86=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=96=87=E5=AD=97=E5=8F=98=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=83=A8=E5=88=86=E4=BA=8B=E4=BB=B6=E5=8F=91?= =?UTF-8?q?=E9=80=81=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 758 ++++++++++-------- .../accessibility/ohos_accessibility_bridge.h | 586 +++++++------- .../accessibility/ohos_accessibility_ddl.cpp | 15 + .../accessibility/ohos_accessibility_ddl.h | 2 + 4 files changed, 739 insertions(+), 622 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index d33dcc7694..d465dd9a2d 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 #include "flutter/fml/logging.h" #include "flutter/shell/platform/ohos/ohos_logging.h" @@ -29,7 +30,7 @@ #define ARKUI_FAILED_CODE -1 #define ARKUI_BAD_PARAM_CODE -2 #define ARKUI_OOM_CODE -3 -#define FUNCTION_NAME_STR(n) #n +#define FUNCTION_NAME_STR(func) #func #define ARKUI_ACCESSIBILITY_CALL_CHECK(X) \ do { \ int32_t RET = X; \ @@ -82,8 +83,16 @@ void OhosAccessibilityBridge::SetNativeShellHolderId(int64_t id) this->native_shell_holder_id_ = id; } +void OhosAccessibilityBridge::FlutterSemanticsTreeUpdateCallOnce() { + static std::once_flag flag; + std::call_once(flag, [this]() { + this->RequestFocusWhenPageUpdate(0); + LOGD("call once -> RequestFocusWhenPageUpdate(0)"); + }); +} /** - * 从dart侧传递到c++侧的flutter无障碍语义树节点更新过程 + * 从dart侧传递到c++侧的flutter无障碍语义树节点更新过程, + * 路由新页面、滑动页面等操作会自动触发该语义树的更新 */ void OhosAccessibilityBridge::updateSemantics( flutter::SemanticsNodeUpdates update, @@ -91,73 +100,117 @@ void OhosAccessibilityBridge::updateSemantics( { FML_DLOG(INFO) << ("OhosAccessibilityBridge::UpdateSemantics()"); - // 当flutter页面更新时,自动请求id=0节点组件获焦(滑动组件除外) + std::vector updatedFlutterNodes; + + // 当flutter页面路由更新时,自动请求id=0节点组件获焦(规避滑动组件更新干扰) if (IS_FLUTTER_NAVIGATE) { - RequestFocusWhenPageUpdate(); + RequestFocusWhenPageUpdate(0); IS_FLUTTER_NAVIGATE = false; } + // 页面状态更新事件 + Flutter_SendAccessibilityAsyncEvent(0, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); + LOGE("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); + /** 获取并分析每个语义节点的更新属性 */ for (auto& item : update) { // 获取当前更新的节点node - const flutter::SemanticsNode& node = item.second; + const auto& node = item.second; - // set struct SemanticsNodeExtent - auto nodeEx = SetAndGetSemanticsNodeExtent(node); + // 更新扩展的SemanticsNode信息 + auto nodeEx = UpdatetSemanticsNodeExtent(node); //print semantics node and flags info for debugging - GetSemanticsNodeDebugInfo(node); - GetSemanticsFlagsDebugInfo(node); + GetSemanticsNodeDebugInfo(nodeEx); + GetSemanticsFlagsDebugInfo(nodeEx); /** * 构建flutter无障碍语义节点树 * NOTE: 若使用g_flutterSemanticsTree.insert({node.id, node})方式 * 来添加新增的语义节点会导致已有key值自动忽略,不会更新原有key对应的value */ - g_flutterSemanticsTree[node.id] = node; - - if(!IsNodeVisible(node)) { - continue; + g_flutterSemanticsTree[nodeEx.id] = nodeEx; + + // 若当前节点为隐藏状态,则跳过 + // if (IsNodeVisible(nodeEx)) { + // continue; + // } + // 若当前节点为获焦 + if (IsNodeFocused(nodeEx)) { + inputFocusedNode = nodeEx; + } + // 若当前节点和更新前节点信息不同,则加入更新节点数组 + if (nodeEx.hadPreviousConfig) { + updatedFlutterNodes.emplace_back(nodeEx); } // 获取当前flutter节点的全部子节点数量,并构建父子节点id映射关系 - int32_t childNodeCount = node.childrenInTraversalOrder.size(); + int32_t childNodeCount = nodeEx.childrenInTraversalOrder.size(); for (int32_t i = 0; i < childNodeCount; i++) { - g_parentChildIdVec.emplace_back( - std::make_pair(node.id, node.childrenInTraversalOrder[i])); - FML_DLOG(INFO) << "UpdateSemantics parentChildIdMap -> (" << node.id - << ", " << node.childrenInTraversalOrder[i] << ")"; + g_parentChildIdVec.emplace_back(std::make_pair(nodeEx.id, nodeEx.childrenInTraversalOrder[i])); } + } - // 当滑动节点产生滑动,并执行滑动处理 - if (HasScrolled(node)) { - LOGD("UpdateSemantics -> has scrolled"); - if (OH_GetSdkApiVersion() >= 13) { - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); - if (OH_ArkUI_CreateAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_CreateAccessibilityElementInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); + for (const auto& nodeEx: updatedFlutterNodes) { + // 当滑动节点产生滑动,并执行滑动处理 + if (HasScrolled(nodeEx)) { + LOGD("UpdateSemantics -> has scrolled"); + if (OH_GetSdkApiVersion() >= 13) { + ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = + OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); + if (OH_ArkUI_CreateAccessibilityElementInfo == nullptr) { + LOGE("OH_ArkUI_CreateAccessibilityElementInfo is null, %{public}s", dlerror()); + } + ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); - FlutterNodeToElementInfoById(_elementInfo, static_cast(node.id)); - FlutterScrollExecution(node, _elementInfo); + FlutterNodeToElementInfoById(_elementInfo, static_cast(nodeEx.id)); + // flutter滑动组件滑动处理逻辑 + FlutterScrollExecution(nodeEx, _elementInfo); - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); - if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); - } - OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); - _elementInfo = nullptr; - } - } - // 判断是否触发liveRegion活动区,当前节点是否活跃 - if (node.HasFlag(FLAGS_::kIsLiveRegion)) { - FML_DLOG(INFO) << "UpdateSemantics -> LiveRegion, node.id=" << node.id; - FlutterPageUpdate(ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); - } + void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = + OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); + if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { + LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); + } + OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); + _elementInfo = nullptr; + } + // 发送滑动事件 + // Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), + // ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SCROLLED); + } + + // 判断是否触发liveRegion活动区,当前节点是否活跃 + if (nodeEx.HasFlag(FLAGS_::kIsLiveRegion) && HasChangedLabel(nodeEx)) { + FML_DLOG(INFO) << "UpdateSemantics -> page content update, nodeEx.id=" << nodeEx.id; + Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); + LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); + } + // 判断当前获焦节点和当前更新节点是否一致,若一致则选中 + // if (accessibilityFocusedNode.id == nodeEx.id && + // !nodeEx.HasPrevFlag(FLAGS_::kIsSelected) && + // nodeEx.HasFlag(FLAGS_::kIsSelected)) { + // Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), + // ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); + // LOGD("Flutter_SendAccessibilityAsyncEvent -> SELECTED"); + // } + + // 更新获焦节点 + // if (inputFocusedNode.id == nodeEx.id && (lastInputFocusedNode.id != inputFocusedNode.id)) { + // lastInputFocusedNode = inputFocusedNode; + // Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), + // ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUSED); + // LOGD("Flutter_SendAccessibilityAsyncEvent -> ACCESSIBILITY_FOCUSED"); + // } + // // 当输入框文本变化时,发送文本更新事件 + // if (inputFocusedNode.id == nodeEx.id && + // IsTextField(nodeEx) && + // nodeEx.previousValue != nodeEx.value) { + // Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), + // ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_TEXT_UPDATE); + // LOGD("Flutter_SendAccessibilityAsyncEvent -> TEXT_UPDATE"); + // } } // 遍历更新的actions,并将所有的actions的id添加进actionMap @@ -188,7 +241,7 @@ void OhosAccessibilityBridge::updateSemantics( * flutter可滑动组件的滑动逻辑处理实现 */ void OhosAccessibilityBridge::FlutterScrollExecution( - flutter::SemanticsNode node, + SemanticsNodeExtent node, ArkUI_AccessibilityElementInfo* elementInfoFromList) { if (OH_GetSdkApiVersion() >= 13) { @@ -219,6 +272,7 @@ void OhosAccessibilityBridge::FlutterScrollExecution( node.HasAction(ACTIONS_::kScrollDown)) { } else if (node.HasAction(ACTIONS_::kScrollLeft) || node.HasAction(ACTIONS_::kScrollRight)) { + LOGD("current flutterNode has scroll up/down/left/right"); } // 当可滑动组件存在滑动子节点 @@ -232,6 +286,15 @@ void OhosAccessibilityBridge::FlutterScrollExecution( } ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetItemCount(elementInfoFromList, itemCount)); + // 设置当前页面可见的当前选中滑动index + // int32_t currentItemIndex = node.scrollIndex; + // int32_t (*OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = + // OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex"); + // if (OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex == nullptr) { + // LOGE("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex is null, %{public}s", dlerror()); + // } + // ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex(elementInfoFromList, currentItemIndex)); + // 设置当前页面可见的起始滑动index int32_t startItemIndex = node.scrollIndex; int32_t (*OH_ArkUI_AccessibilityElementInfoSetStartItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = @@ -274,59 +337,10 @@ void OhosAccessibilityBridge::FlutterScrollExecution( } } -/** - * 当页面内容/状态更新事件,在页面转换、切换、调整大小时发送页面状态更新事件 - */ -void OhosAccessibilityBridge::FlutterPageUpdate( - ArkUI_AccessibilityEventType eventType) -{ - if (provider_ == nullptr) { - FML_DLOG(ERROR) << "PageStateUpdate ->" - "AccessibilityProvider = nullptr"; - return; - } - if (OH_GetSdkApiVersion() >= 13) { - ArkUI_AccessibilityEventInfo* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); - if (OH_ArkUI_CreateAccessibilityEventInfo == nullptr) { - LOGE("OH_ArkUI_CreateAccessibilityEventInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityEventInfo* pageUpdateEventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); - - int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = - OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); - if (OH_ArkUI_AccessibilityEventSetEventType == nullptr) { - LOGE("OH_ArkUI_AccessibilityEventSetEventType is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityEventSetEventType(pageUpdateEventInfo, eventType) - ); - - auto callback = [](int32_t errorCode) { - FML_DLOG(WARNING) << "PageStateUpdate callback-> errorCode =" << errorCode; - }; - - void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = - OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); - if (OH_ArkUI_SendAccessibilityAsyncEvent == nullptr) { - LOGE("OH_ArkUI_SendAccessibilityAsyncEvent is null, %{public}s", dlerror()); - } - OH_ArkUI_SendAccessibilityAsyncEvent(provider_, pageUpdateEventInfo, callback); - - void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = - OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); - if (OH_ArkUI_DestoryAccessibilityEventInfo == nullptr) { - LOGE("OH_ArkUI_DestoryAccessibilityEventInfo is null, %{public}s", dlerror()); - } - OH_ArkUI_DestoryAccessibilityEventInfo(pageUpdateEventInfo); - pageUpdateEventInfo = nullptr; - } -} - /** * 特定节点的焦点请求 (当页面更新时自动请求id=0节点获焦) */ -void OhosAccessibilityBridge::RequestFocusWhenPageUpdate() +void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) { if (provider_ == nullptr) { FML_DLOG(ERROR) << "RequestFocusWhenPageUpdate ->" @@ -360,7 +374,6 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate() ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_REQUEST_ACCESSIBILITY_FOCUS) ); - int32_t requestFocusId = 0; int32_t (*OH_ArkUI_AccessibilityEventSetRequestFocusId)(ArkUI_AccessibilityEventInfo*, int32_t) = OhosAccessibilityDDL::DLLoadSetReqFocusFunc("OH_ArkUI_AccessibilityEventSetRequestFocusId"); if (OH_ArkUI_AccessibilityEventSetRequestFocusId == nullptr) { @@ -473,7 +486,7 @@ void OhosAccessibilityBridge::Announce(std::unique_ptr& message) } //获取根节点 -flutter::SemanticsNode OhosAccessibilityBridge::GetFlutterRootSemanticsNode() +SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterRootSemanticsNode() { if (!g_flutterSemanticsTree.size()) { FML_DLOG(ERROR) @@ -491,10 +504,10 @@ flutter::SemanticsNode OhosAccessibilityBridge::GetFlutterRootSemanticsNode() /** * 根据nodeid获取或创建flutter语义节点 */ -flutter::SemanticsNode OhosAccessibilityBridge::GetFlutterSemanticsNode( +SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterSemanticsNode( int32_t id) { - flutter::SemanticsNode node; + SemanticsNodeExtent node; if (g_flutterSemanticsTree.count(id) > 0) { return g_flutterSemanticsTree.at(id); FML_DLOG(INFO) << "GetFlutterSemanticsNode get node.id=" << id; @@ -518,7 +531,7 @@ void OhosAccessibilityBridge::FlutterTreeToArkuiTree( if (OH_GetSdkApiVersion() >= 13) { // 将flutter语义节点树传递给arkui的无障碍elementinfo for (const auto& item : g_flutterSemanticsTree) { - flutter::SemanticsNode flutterNode = item.second; + SemanticsNodeExtent flutterNode = item.second; // 创建elementinfo,系统自动加入到elementinfolist ArkUI_AccessibilityElementInfo* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = @@ -580,23 +593,25 @@ void OhosAccessibilityBridge::FlutterTreeToArkuiTree( // 设置孩子节点 int32_t childCount = flutterNode.childrenInTraversalOrder.size(); - 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]); - FML_DLOG(INFO) << "FlutterTreeToArkuiTree flutterNode.id= " - << flutterNode.id << " childCount= " << childCount - << " childNodeId=" << childNodeIds[i]; - } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = - OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); - if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); + 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]); + FML_DLOG(INFO) << "FlutterTreeToArkuiTree flutterNode.id= " + << flutterNode.id << " childCount= " << childCount + << " childNodeId=" << childNodeIds[i]; + } + int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = + OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); + if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfo, childCount, childNodeIds) + ); } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfo, childCount, childNodeIds) - ); // 配置常用属性 int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = @@ -713,9 +728,8 @@ void OhosAccessibilityBridge::SetAbsoluteScreenRect(int32_t flutterNodeId, { g_screenRectMap[flutterNodeId] = std::make_pair(std::make_pair(left, top), std::make_pair(right, bottom)); - FML_DLOG(INFO) << "SetAbsoluteScreenRect -> insert { " << flutterNodeId - << ", <" << left << ", " << top << ", " << right << ", " - << bottom << "> } is succeed"; + FML_DLOG(INFO) << "SetAbsoluteScreenRect -> id=" << flutterNodeId + << ", {" << left << ", " << top << ", " << right << ", "<< bottom << "> }"; } std::pair, std::pair> @@ -730,12 +744,24 @@ OhosAccessibilityBridge::GetAbsoluteScreenRect(int32_t flutterNodeId) } } +/** + * 获取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); +} + /** * flutter无障碍语义树的子节点相对坐标系转化为屏幕绝对坐标的映射算法 * 目前暂未考虑旋转、透视场景,不影响屏幕朗读功能 */ void OhosAccessibilityBridge::ConvertChildRelativeRectToScreenRect( - flutter::SemanticsNode currNode) + SemanticsNodeExtent currNode) { // 获取当前flutter节点的相对rect auto currLeft = static_cast(currNode.rect.fLeft); @@ -743,23 +769,21 @@ void OhosAccessibilityBridge::ConvertChildRelativeRectToScreenRect( auto currRight = static_cast(currNode.rect.fRight); auto currBottom = static_cast(currNode.rect.fBottom); - // 获取当前flutter节点的缩放、平移、透视等矩阵坐标转换 + /** + * 获取当前flutter节点的缩放、平移、透视等矩阵坐标转换 + * 以下矩阵坐标变换参数(如:旋转/错切、透视)场景目前暂不考虑 + * NOTE: SkMatrix::kMSkewX, SkMatrix::kMSkewY, + * SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 + */ SkMatrix transform = currNode.transform.asM33(); auto _kMScaleX = transform.get(SkMatrix::kMScaleX); auto _kMTransX = transform.get(SkMatrix::kMTransX); auto _kMScaleY = transform.get(SkMatrix::kMScaleY); auto _kMTransY = transform.get(SkMatrix::kMTransY); - /** 以下矩阵坐标变换参数(如:旋转/错切、透视)场景目前暂不考虑 - * NOTE: SkMatrix::kMSkewX, SkMatrix::kMSkewY, - * SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 - */ // 获取当前flutter节点的父节点的相对rect int32_t parentId = GetParentId(currNode.id); auto parentNode = GetFlutterSemanticsNode(parentId); - auto parentRight = parentNode.rect.fRight; - auto parentBottom = parentNode.rect.fBottom; - // 获取当前flutter节点的父节点的绝对坐标 auto _rectPairs = GetAbsoluteScreenRect(parentNode.id); auto realParentLeft = _rectPairs.first.first; @@ -767,16 +791,19 @@ void OhosAccessibilityBridge::ConvertChildRelativeRectToScreenRect( auto realParentRight = _rectPairs.second.first; auto realParentBottom = _rectPairs.second.second; - // 获取root节点的绝对坐标, 即xcomponent屏幕长宽 + //获取root节点的绝对坐标 auto _rootRect = GetAbsoluteScreenRect(0); + auto rootWidth = _rootRect.second.first; auto rootHeight = _rootRect.second.second; - // 真实缩放系数 - float realScaleFactor = realParentRight / parentRight * 1.0; - float newLeft; - float newTop; - float newRight; - float newBottom; + // 获取真实缩放系数 + auto [realScaleXFactor, realScaleYFactor] = GetRealScaleFactor(); + + // 更新后的节点屏幕坐标 + float newLeft = 0.0; + float newTop = 0.0; + float newRight = 0.0; + float newBottom = 0.0; if (_kMScaleX > 1 && _kMScaleY > 1) { // 子节点相对父节点进行变化(缩放、 平移) @@ -787,42 +814,30 @@ void OhosAccessibilityBridge::ConvertChildRelativeRectToScreenRect( // 更新当前flutter节点currNode的相对坐标 -> 屏幕绝对坐标 SetAbsoluteScreenRect(currNode.id, newLeft, newTop, newRight, newBottom); } else { - // 若当前节点的相对坐标与父亲节点的相对坐标值相同,则直接继承坐标值 - if (currRight == parentRight && currBottom == parentBottom) { - newLeft = realParentLeft; - newTop = realParentTop; - newRight = realParentRight; - newBottom = realParentBottom; - } else { - // 子节点的屏幕绝对坐标转换,包括offset偏移值计算、缩放系数变换 - newLeft = (currLeft + _kMTransX) * realScaleFactor + realParentLeft; - newTop = (currTop + _kMTransY) * realScaleFactor + realParentTop; - newRight = (currLeft + _kMTransX + currRight) * realScaleFactor + realParentLeft; - newBottom = (currTop + _kMTransY + currBottom) * realScaleFactor + realParentTop; - } - // 若子节点rect超过父节点则跳过显示(单个屏幕显示不下,滑动再重新显示) - const bool IS_OVER_SCREEN_AREA = newLeft < realParentLeft || - newTop < realParentTop || - newRight > realParentRight || - newBottom > realParentBottom || - newLeft >= newRight || - newTop >= newBottom; - if (IS_OVER_SCREEN_AREA) { - FML_DLOG(ERROR) << "ConvertChildRelativeRectToScreenRect childRect is " - "bigger than parentRect -> { nodeId: " - << currNode.id << ", (" << newLeft << ", " << newTop - << ", " << newRight << ", " << newBottom << ")}"; - // 防止滑动场景下绿框坐标超出屏幕范围,进行正则化处理 - newTop -= rootHeight; - newBottom -= rootHeight; - SetAbsoluteScreenRect(currNode.id, newLeft, newTop, newRight, newBottom); - } else { - SetAbsoluteScreenRect(currNode.id, newLeft, newTop, newRight, newBottom); - } + // 子节点的屏幕绝对坐标转换,包括offset偏移值计算、缩放系数变换 + newLeft = (currLeft + _kMTransX) * realScaleXFactor + realParentLeft; + newTop = (currTop + _kMTransY) * realScaleYFactor + realParentTop; + newRight = newLeft + currRight * realScaleXFactor; + newBottom = newTop + currBottom * realScaleYFactor; + + // 若子节点rect超过父节点则跳过显示(单个屏幕显示不下,滑动再重新显示) + const bool IS_OVER_SCREEN_AREA = newLeft < realParentLeft || newTop < realParentTop || + newRight > realParentRight || newBottom > realParentBottom || + newLeft >= newRight || newTop >= newBottom || + newRight > rootWidth || newBottom > rootHeight; + + if (IS_OVER_SCREEN_AREA) { + FML_DLOG(ERROR) << "RelativeRectToScreenRect -> childRect exceeds parentRect {Id: " + << currNode.id << ", (" << newLeft << ", " << newTop + << ", " << newRight << ", " << newBottom << ")}"; + // 防止滑动场景下绿框坐标超出屏幕范围,进行正则化处理 + // newTop = realParentBottom; + // newBottom = realParentBottom; + SetAbsoluteScreenRect(currNode.id, rootWidth, rootHeight, 0, 0); + } else { + SetAbsoluteScreenRect(currNode.id, newLeft, newTop, newRight, newBottom); + } } - FML_DLOG(INFO) << "ConvertChildRelativeRectToScreenRect -> { nodeId: " - << currNode.id << ", (" << newLeft << ", " << newTop << ", " - << newRight << ", " << newBottom << ")}"; } /** @@ -843,7 +858,7 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( // 当elementId = -1或0时,创建root节点 if (elementId == 0 || elementId == -1) { // 获取flutter的root节点 - flutter::SemanticsNode flutterNode = GetFlutterSemanticsNode(static_cast(0)); + SemanticsNodeExtent flutterNode = GetFlutterSemanticsNode(static_cast(0)); // 设置elementinfo的屏幕坐标范围 int32_t left = static_cast(flutterNode.rect.fLeft); @@ -893,7 +908,7 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( } ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityText( - elementInfoFromList, flutterNode.label.empty() ? flutterNode.hint.c_str() : flutterNode.label.c_str()) + elementInfoFromList, flutterNode.label.empty() ? flutterNode.value.c_str() : flutterNode.label.c_str()) ); int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = @@ -916,23 +931,25 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( // 配置child节点信息 int32_t childCount = flutterNode.childrenInTraversalOrder.size(); - 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]); - FML_DLOG(INFO) - << "FlutterNodeToElementInfoById -> elementid=0 childCount=" - << childCount << " childNodeIds=" << childNodeIds[i]; - } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = - OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); - if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); + 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]); + FML_DLOG(INFO) + << "FlutterNodeToElementInfoById -> elementid=0 childCount=" + << childCount << " childNodeIds=" << childNodeIds[i]; + } + int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = + OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); + if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) + ); } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) - ); // 配置root节点常用属性 int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = @@ -1006,7 +1023,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( if (OH_ArkUI_AccessibilityElementInfoSetOperationActions == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetOperationActions is null, %{public}s", dlerror()); } - if (widget_type == "textfield") { + if (Contains(widget_type, EDIT_TEXT_WIDGET_NAME) || + Contains(widget_type, EDIT_MULTILINE_TEXT_WIDGET_NAME)) { // set elementinfo action types int32_t actionTypeNum = 10; ArkUI_AccessibleAction actions[actionTypeNum]; @@ -1054,7 +1072,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) ); - } else if (widget_type == "scrollable") { + } else if (Contains(widget_type, SCROLL_WIDGET_NAME)) { // if node is a scrollable component int32_t actionTypeNum = 5; ArkUI_AccessibleAction actions[actionTypeNum]; @@ -1114,7 +1132,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( int64_t elementId) { if (OH_GetSdkApiVersion() >= 13) { - flutter::SemanticsNode flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); + SemanticsNodeExtent flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); // set elementinfo id int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = @@ -1175,7 +1193,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( FML_DLOG(INFO) << "FlutterNodeToElementInfoById GetParentId = " << parentId; // set accessibility text for announcing - std::string text = flutterNode.label; + std::string text = flutterNode.label + flutterNode.value; int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityText == nullptr) { @@ -1209,23 +1227,25 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( // set chidren elementinfo ids int32_t childCount = flutterNode.childrenInTraversalOrder.size(); - 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]); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById -> elementid=" << elementId - << " childCount=" << childCount - << " childNodeIds=" << childNodeIds[i]; - } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = - OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); - if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); + 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]); + FML_DLOG(INFO) << "FlutterNodeToElementInfoById -> elementid=" << elementId + << " childCount=" << childCount + << " childNodeIds=" << childNodeIds[i]; + } + int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = + OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); + if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) + ); } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) - ); /** * 根据当前flutter节点的SemanticsFlags特性,配置对应的elmentinfo属性 @@ -1436,7 +1456,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( std::vector OhosAccessibilityBridge::GetLevelOrderTraversalTree(int32_t rootId) { std::vector levelOrderTraversalTree; - std::queue semanticsQue; + std::queue semanticsQue; auto root = GetFlutterSemanticsNode(rootId); semanticsQue.push(root); @@ -1604,6 +1624,10 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( // 获取当前elementid对应的flutter语义节点 auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); + // 若当前节点为非屏幕显示状态,将其显示在屏幕上 + if (!IsNodeShowOnScreen(flutterNode)) { + DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kShowOnScreen, {}); + } // 根据当前elementid和无障碍动作类型,发送无障碍事件 switch (action) { @@ -1638,6 +1662,8 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( } /** Accessibility focus acquisition. 64 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS: { + // 感知获焦flutter节点 + accessibilityFocusedNode = flutterNode; // 解析arkui的获焦 -> flutter对应节点的获焦 auto flutterGainFocusAction = ArkuiActionsToFlutterActions(action); DispatchSemanticsAction(static_cast(elementId), @@ -1648,11 +1674,11 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( Flutter_SendAccessibilityAsyncEvent(elementId, focusEventType); FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: focus(" << action << ")" << " event: focus(" << focusEventType << ")"; + if (flutterNode.HasAction(ACTIONS_::kIncrease) || flutterNode.HasAction(ACTIONS_::kDecrease)) { Flutter_SendAccessibilityAsyncEvent( - elementId, ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); + elementId, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); } break; } @@ -1691,19 +1717,17 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kIncrease, {}); - } else { } std::string currComponetType = GetNodeComponentType(flutterNode); - if (currComponetType == "ListView") { - /** 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 << ")"; + if (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 << ")"; } break; } @@ -1726,20 +1750,17 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kDecrease, {}); - } else { } std::string currComponetType = GetNodeComponentType(flutterNode); - if (currComponetType == "ListView") { - /** Scrolled event, sent when a scrollable component experiences a - * scroll event. 4096 */ - ArkUI_AccessibilityEventType scrollBackwardEventType = - ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SCROLLED; - Flutter_SendAccessibilityAsyncEvent(elementId, scrollBackwardEventType); - FML_DLOG(INFO) - << "ExecuteAccessibilityAction -> action: scroll backward(" - << action << ")" << " event: scroll backward(" - << scrollBackwardEventType << ")"; + if (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 << ")"; } break; } @@ -1943,6 +1964,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( } ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); FlutterNodeToElementInfoById(_elementInfo, elementId); + // 若为获焦事件,则设置当前elementinfo获焦 int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused"); @@ -2009,113 +2031,112 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( } /** - * 判断当前语义节点是否获焦 + * 设置输入框文本 */ -bool OhosAccessibilityBridge::IsNodeFocusable( - const flutter::SemanticsNode& node) -{ - if (node.HasFlag(FLAGS_::kScopesRoute)) { - return false; - } - if (node.HasFlag(FLAGS_::kIsFocusable)) { - return true; - } - // Always consider platform views focusable. - if (node.IsPlatformViewNode()) { - return true; - } - // Always consider actionable nodes focusable. - if (node.actions != 0) { - return true; - } - if ((node.flags & FOCUSABLE_FLAGS) != 0) { - return true; - } - if ((node.actions & ~FOCUSABLE_FLAGS) != 0) { - return true; - } - // Consider text nodes focusable. - return !node.label.empty() || !node.value.empty() || !node.hint.empty(); -} - void OhosAccessibilityBridge::PerformSetText( - flutter::SemanticsNode flutterNode, + SemanticsNodeExtent flutterNode, ArkUI_Accessibility_ActionType action, - ArkUI_AccessibilityActionArguments* actionArguments) {} + ArkUI_AccessibilityActionArguments* actionArguments) +{ + // 获取特殊动作参数 + int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = + OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); + if (OH_ArkUI_FindAccessibilityActionArgumentByKey == nullptr) { + LOGE("OH_ArkUI_FindAccessibilityActionArgumentByKey is null, %{public}s", dlerror()); + } + const char* key_setText = "setText"; + char* newValue; + char** value = &newValue; + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); + if (newValue == nullptr) { + // newValue = "888"; + LOGE("PerformSetText -> OH_ArkUI_FindAccessibilityActionArgumentByKey get null value"); + } + auto flutterSetTextAction = ArkuiActionsToFlutterActions(action); + DispatchSemanticsAction(flutterNode.id, flutterSetTextAction, {}); + flutterNode.value = newValue; + flutterNode.valueAttributes = {}; +} +/** + * 设置文本选择范畴 + */ void OhosAccessibilityBridge::PerformSelectText( - flutter::SemanticsNode flutterNode, + SemanticsNodeExtent flutterNode, ArkUI_Accessibility_ActionType action, - ArkUI_AccessibilityActionArguments* actionArguments) {} + ArkUI_AccessibilityActionArguments* actionArguments) +{ + return; +} /** * 获取当前flutter节点的组件类型,并映射为arkui组件 */ std::string OhosAccessibilityBridge::GetNodeComponentType( - const flutter::SemanticsNode& node) + const SemanticsNodeExtent& node) { if (node.HasFlag(FLAGS_::kIsButton)) { - return "Button"; + return BUTTON_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kIsTextField)) { - return "TextField"; + return EDIT_TEXT_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kIsMultiline)) { - return "TextArea"; + return EDIT_MULTILINE_TEXT_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kIsLink)) { - return "Link"; + return LINK_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kIsSlider) || node.HasAction(ACTIONS_::kIncrease) || node.HasAction(ACTIONS_::kDecrease)) { - return "Slider"; + return SLIDER_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kIsHeader)) { - return "Header"; + return HEADER_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kIsImage)) { - return "Image"; + return IMAGE_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kHasCheckedState)) { if (node.HasFlag(FLAGS_::kIsInMutuallyExclusiveGroup)) { // arkui没有RadioButton,这里透传为RadioButton - return "RadioButton"; + return RADIO_BUTTON_WIDGET_NAME; } else { - return "Checkbox"; + return CHECK_BOX_WIDGET_NAME; } } if (node.HasFlag(FLAGS_::kHasToggledState)) { - return "Switch"; + return SWITCH_WIDGET_NAME; } if (node.HasAction(ACTIONS_::kIncrease) || node.HasAction(ACTIONS_::kDecrease)) { - return "SeekBar"; + return SEEKBAR_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kHasImplicitScrolling)) { if (node.HasAction(ACTIONS_::kScrollLeft) || node.HasAction(ACTIONS_::kScrollRight)) { - return "HorizontalScrollView"; + return SCROLL_WIDGET_NAME; } else { - return "ScrollView"; + return SCROLL_WIDGET_NAME; } } if ((!node.label.empty() || !node.tooltip.empty() || !node.hint.empty())) { - return "Text"; + return TEXT_WIDGET_NAME; } - return "Widget"; + return OTHER_WIDGET_NAME; } /** * 判断当前节点是否为textfield文本框 */ -bool OhosAccessibilityBridge::IsTextField(flutter::SemanticsNode flutterNode) +bool OhosAccessibilityBridge::IsTextField(SemanticsNodeExtent flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsTextField); } /** * 判断当前节点是否为滑动条slider类型 */ -bool OhosAccessibilityBridge::IsSlider(flutter::SemanticsNode flutterNode) +bool OhosAccessibilityBridge::IsSlider(SemanticsNodeExtent flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsSlider); } @@ -2123,7 +2144,7 @@ bool OhosAccessibilityBridge::IsSlider(flutter::SemanticsNode flutterNode) * 判断当前flutter节点组件是否可点击 */ bool OhosAccessibilityBridge::IsNodeClickable( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { return flutterNode.HasAction(ACTIONS_::kTap); flutterNode.HasFlag(FLAGS_::kHasCheckedState) || @@ -2142,15 +2163,15 @@ bool OhosAccessibilityBridge::IsNodeClickable( * 判断当前flutter节点组件是否可显示 */ bool OhosAccessibilityBridge::IsNodeVisible( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { - return flutterNode.HasFlag(FLAGS_::kIsHidden) ? false : true; + return !flutterNode.HasFlag(FLAGS_::kIsHidden); } /** * 判断当前flutter节点组件是否具备checkable属性 */ bool OhosAccessibilityBridge::IsNodeCheckable( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { return flutterNode.HasFlag(FLAGS_::kHasCheckedState) || flutterNode.HasFlag(FLAGS_::kHasToggledState); @@ -2159,7 +2180,7 @@ bool OhosAccessibilityBridge::IsNodeCheckable( * 判断当前flutter节点组件是否checked/unchecked(checkbox、radio button) */ bool OhosAccessibilityBridge::IsNodeChecked( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsChecked) || flutterNode.HasFlag(FLAGS_::kIsToggled); @@ -2168,7 +2189,7 @@ bool OhosAccessibilityBridge::IsNodeChecked( * 判断当前flutter节点组件是否选中 */ bool OhosAccessibilityBridge::IsNodeSelected( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsSelected); } @@ -2176,7 +2197,7 @@ bool OhosAccessibilityBridge::IsNodeSelected( * 判断当前flutter节点组件是否为密码输入框 */ bool OhosAccessibilityBridge::IsNodePassword( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { return flutterNode.HasFlag(FLAGS_::kIsTextField) && flutterNode.HasFlag(FLAGS_::kIsObscured); @@ -2185,7 +2206,7 @@ bool OhosAccessibilityBridge::IsNodePassword( * 判断当前flutter节点组件是否支持长按功能 */ bool OhosAccessibilityBridge::IsNodeHasLongPress( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { return flutterNode.HasAction(ACTIONS_::kLongPress); } @@ -2193,24 +2214,81 @@ bool OhosAccessibilityBridge::IsNodeHasLongPress( * 判断当前flutter节点是否enabled */ bool OhosAccessibilityBridge::IsNodeEnabled( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { return !flutterNode.HasFlag(FLAGS_::kHasEnabledState) || flutterNode.HasFlag(FLAGS_::kIsEnabled); } +/** + * 判断当前flutter节点是否在当前屏幕上显示 + */ +bool OhosAccessibilityBridge::IsNodeShowOnScreen(SemanticsNodeExtent flutterNode) +{ + return flutterNode.HasAction(ACTIONS_::kShowOnScreen); +} /** * 判断当前节点是否已经滑动 */ bool OhosAccessibilityBridge::HasScrolled( - const flutter::SemanticsNode& flutterNode) + const SemanticsNodeExtent& flutterNode) +{ + return flutterNode.scrollPosition != std::nan("") && + flutterNode.previousScrollPosition != std::nan("") && + flutterNode.previousScrollPosition != flutterNode.scrollPosition; +} +/** + * 判断当前节点是否改变标签文本 + */ +bool OhosAccessibilityBridge::HasChangedLabel(const SemanticsNodeExtent& flutterNode) +{ + if (flutterNode.label.empty() && flutterNode.previousLabel.empty()) { + return false; + } + return flutterNode.label.empty() || + flutterNode.previousLabel.empty() || + flutterNode.label != flutterNode.previousLabel; +} +/** + * 判断当前语义节点是否可获焦 + */ +bool OhosAccessibilityBridge::IsNodeFocusable( + const SemanticsNodeExtent& node) +{ + if (node.HasFlag(FLAGS_::kScopesRoute)) { + return false; + } + if (node.HasFlag(FLAGS_::kIsFocusable)) { + return true; + } + // Always consider platform views focusable. + if (node.IsPlatformViewNode()) { + return true; + } + // Always consider actionable nodes focusable. + if (node.actions != 0) { + return true; + } + if ((node.flags & FOCUSABLE_FLAGS) != 0) { + return true; + } + if ((node.actions & ~FOCUSABLE_FLAGS) != 0) { + return true; + } + // Consider text nodes focusable. + return !node.label.empty() || !node.value.empty() || !node.hint.empty(); +} +/** + * 判断当前flutter节点是否获焦 + */ +bool OhosAccessibilityBridge::IsNodeFocused(const SemanticsNodeExtent& flutterNode) { - return flutterNode.scrollPosition != std::nan(""); + return flutterNode.HasFlag(FLAGS_::kIsFocused); } /** * 判断是否可滑动 */ bool OhosAccessibilityBridge::IsNodeScrollable( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { return flutterNode.HasAction(ACTIONS_::kScrollLeft) || flutterNode.HasAction(ACTIONS_::kScrollRight) || @@ -2221,14 +2299,14 @@ bool OhosAccessibilityBridge::IsNodeScrollable( * 判断当前节点组件是否是滑动组件,如: listview, gridview等 */ bool OhosAccessibilityBridge::IsScrollableWidget( - flutter::SemanticsNode flutterNode) + SemanticsNodeExtent flutterNode) { return flutterNode.HasFlag(FLAGS_::kHasImplicitScrolling); } void OhosAccessibilityBridge::AddRouteNodes( - std::vector edges, - flutter::SemanticsNode node) + std::vector edges, + SemanticsNodeExtent node) { if (node.HasFlag(FLAGS_::kScopesRoute)) { edges.emplace_back(node); @@ -2239,7 +2317,7 @@ void OhosAccessibilityBridge::AddRouteNodes( } } -std::string OhosAccessibilityBridge::GetRouteName(flutter::SemanticsNode node) +std::string OhosAccessibilityBridge::GetRouteName(SemanticsNodeExtent node) { if (node.HasFlag(FLAGS_::kNamesRoute) && !node.label.empty()) { return node.label; @@ -2254,7 +2332,7 @@ std::string OhosAccessibilityBridge::GetRouteName(flutter::SemanticsNode node) return ""; } -void OhosAccessibilityBridge::onWindowNameChange(flutter::SemanticsNode route) +void OhosAccessibilityBridge::onWindowNameChange(SemanticsNodeExtent route) { std::string routeName = GetRouteName(route); if (routeName.empty()) { @@ -2266,7 +2344,7 @@ void OhosAccessibilityBridge::onWindowNameChange(flutter::SemanticsNode route) } void OhosAccessibilityBridge::removeSemanticsNode( - flutter::SemanticsNode nodeToBeRemoved) + SemanticsNodeExtent nodeToBeRemoved) { if (!g_flutterSemanticsTree.size()) { FML_DLOG(ERROR) << "OhosAccessibilityBridge::removeSemanticsNode -> " @@ -2300,13 +2378,27 @@ void OhosAccessibilityBridge::ClearFlutterSemanticsCaches() } /** - * extent common struct SemanticsNode to - * derived struct SemanticsNodeExtent + * 更新扩展版flutter语义节点 */ -SemanticsNodeExtent OhosAccessibilityBridge::SetAndGetSemanticsNodeExtent( +SemanticsNodeExtent OhosAccessibilityBridge::UpdatetSemanticsNodeExtent( flutter::SemanticsNode node) { 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; + } + // 更新当前flutter节点信息 nodeEx.id = std::move(node.id); nodeEx.flags = std::move(node.flags); nodeEx.actions = std::move(node.actions); @@ -2334,87 +2426,93 @@ SemanticsNodeExtent OhosAccessibilityBridge::SetAndGetSemanticsNodeExtent( 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.customAccessibilityActions = std::move(node.customAccessibilityActions); return nodeEx; } void OhosAccessibilityBridge::GetSemanticsNodeDebugInfo( - flutter::SemanticsNode node) + SemanticsNodeExtent node) { FML_DLOG(INFO) << "-------------------SemanticsNode------------------"; SkMatrix _transform = node.transform.asM33(); FML_DLOG(INFO) << "node.id=" << node.id; FML_DLOG(INFO) << "node.label=" << node.label; + FML_DLOG(INFO) << "node.previousLabel=" << node.previousLabel; FML_DLOG(INFO) << "node.tooltip=" << node.tooltip; FML_DLOG(INFO) << "node.hint=" << node.hint; FML_DLOG(INFO) << "node.flags=" << node.flags; + FML_DLOG(INFO) << "node.previousFlags=" << node.previousFlags; FML_DLOG(INFO) << "node.actions=" << node.actions; + FML_DLOG(INFO) << "node.previousActions=" << node.previousActions; + FML_DLOG(INFO) << "node.value=" << node.value; + FML_DLOG(INFO) << "node.previousValue=" << node.previousValue; FML_DLOG(INFO) << "node.rect= {" << node.rect.fLeft << ", " << node.rect.fTop - << ", " << node.rect.fRight << ", " << node.rect.fBottom - << "}"; + << ", " << node.rect.fRight << ", " << node.rect.fBottom + << "}"; FML_DLOG(INFO) << "node.transform -> kMScaleX=" - << _transform.get(SkMatrix::kMScaleX); + << _transform.get(SkMatrix::kMScaleX); FML_DLOG(INFO) << "node.transform -> kMSkewX=" - << _transform.get(SkMatrix::kMSkewX); + << _transform.get(SkMatrix::kMSkewX); FML_DLOG(INFO) << "node.transform -> kMTransX=" - << _transform.get(SkMatrix::kMTransX); + << _transform.get(SkMatrix::kMTransX); FML_DLOG(INFO) << "node.transform -> kMSkewY=" - << _transform.get(SkMatrix::kMSkewY); + << _transform.get(SkMatrix::kMSkewY); FML_DLOG(INFO) << "node.transform -> kMScaleY=" - << _transform.get(SkMatrix::kMScaleY); + << _transform.get(SkMatrix::kMScaleY); FML_DLOG(INFO) << "node.transform -> kMTransY=" - << _transform.get(SkMatrix::kMTransY); + << _transform.get(SkMatrix::kMTransY); FML_DLOG(INFO) << "node.transform -> kMPersp0=" - << _transform.get(SkMatrix::kMPersp0); + << _transform.get(SkMatrix::kMPersp0); FML_DLOG(INFO) << "node.transform -> kMPersp1=" - << _transform.get(SkMatrix::kMPersp1); + << _transform.get(SkMatrix::kMPersp1); FML_DLOG(INFO) << "node.transform -> kMPersp2=" - << _transform.get(SkMatrix::kMPersp2); + << _transform.get(SkMatrix::kMPersp2); FML_DLOG(INFO) << "node.maxValueLength=" << node.maxValueLength; FML_DLOG(INFO) << "node.currentValueLength=" << node.currentValueLength; FML_DLOG(INFO) << "node.textSelectionBase=" << node.textSelectionBase; + FML_DLOG(INFO) << "node.previousTextSelectionBase=" << node.previousTextSelectionBase; FML_DLOG(INFO) << "node.textSelectionExtent=" << node.textSelectionExtent; - FML_DLOG(INFO) << "node.textSelectionBase=" << node.textSelectionBase; + FML_DLOG(INFO) << "node.previousTextSelectionExtent=" << node.previousTextSelectionExtent; FML_DLOG(INFO) << "node.platformViewId=" << node.platformViewId; FML_DLOG(INFO) << "node.scrollChildren=" << node.scrollChildren; FML_DLOG(INFO) << "node.scrollIndex=" << node.scrollIndex; FML_DLOG(INFO) << "node.scrollPosition=" << node.scrollPosition; + FML_DLOG(INFO) << "node.previousScrollPosition=" << node.previousScrollPosition; FML_DLOG(INFO) << "node.scrollIndex=" << node.scrollIndex; - FML_DLOG(INFO) << "node.scrollPosition=" << node.scrollPosition; FML_DLOG(INFO) << "node.scrollExtentMax=" << node.scrollExtentMax; + FML_DLOG(INFO) << "node.previousScrollExtentMax=" << node.previousScrollExtentMax; FML_DLOG(INFO) << "node.scrollExtentMin=" << node.scrollExtentMin; + FML_DLOG(INFO) << "node.previousScrollExtentMin=" << node.previousScrollExtentMin; FML_DLOG(INFO) << "node.elevation=" << node.elevation; FML_DLOG(INFO) << "node.thickness=" << node.thickness; FML_DLOG(INFO) << "node.textDirection=" << node.textDirection; FML_DLOG(INFO) << "node.childrenInTraversalOrder.size()=" - << node.childrenInTraversalOrder.size(); + << node.childrenInTraversalOrder.size(); for (uint32_t i = 0; i < node.childrenInTraversalOrder.size(); i++) { FML_DLOG(INFO) << "node.childrenInTraversalOrder[" << i - << "]=" << node.childrenInTraversalOrder[i]; + << "]=" << node.childrenInTraversalOrder[i]; } FML_DLOG(INFO) << "node.childrenInHitTestOrder.size()=" - << node.childrenInHitTestOrder.size(); + << node.childrenInHitTestOrder.size(); for (uint32_t i = 0; i < node.childrenInHitTestOrder.size(); i++) { FML_DLOG(INFO) << "node.childrenInHitTestOrder[" << i - << "]=" << node.childrenInHitTestOrder[i]; + << "]=" << node.childrenInHitTestOrder[i]; } FML_DLOG(INFO) << "node.customAccessibilityActions.size()=" - << node.customAccessibilityActions.size(); + << node.customAccessibilityActions.size(); for (uint32_t i = 0; i < node.customAccessibilityActions.size(); i++) { FML_DLOG(INFO) << "node.customAccessibilityActions[" << i - << "]=" << node.customAccessibilityActions[i]; + << "]=" << node.customAccessibilityActions[i]; } FML_DLOG(INFO) << "------------------SemanticsNode-----------------"; } void OhosAccessibilityBridge::GetSemanticsFlagsDebugInfo( - flutter::SemanticsNode node) + SemanticsNodeExtent node) { FML_DLOG(INFO) << "----------------SemanticsFlags-------------------------"; FML_DLOG(INFO) << "node.id=" << node.id; diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 5f03fdc839..5240f33a75 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -32,310 +32,312 @@ typedef flutter::SemanticsFlags FLAGS_; typedef flutter::SemanticsAction ACTIONS_; struct AbsoluteRect { - float left; - float top; - float right; - float bottom; - - static constexpr AbsoluteRect MakeEmpty() { - return AbsoluteRect{0.0, 0.0, 0.0, 0.0}; - } + float left; + float top; + float right; + float bottom; + static constexpr AbsoluteRect MakeEmpty() { + return AbsoluteRect{0.0, 0.0, 0.0, 0.0}; + } }; - struct SemanticsNodeExtent : flutter::SemanticsNode { - int32_t parentId = -1; - AbsoluteRect abRect = AbsoluteRect::MakeEmpty(); - int32_t previousFlags; - int32_t previousActions; - int32_t previousTextSelectionBase; - int32_t previousTextSelectionExtent; - float previousScrollPosition; - float previousScrollExtentMax; - float previousScrollExtentMin; - std::string previousValue; - std::string previousLabel; + AbsoluteRect absoluteRect = AbsoluteRect::MakeEmpty(); + int32_t parentId = -1; + bool hadPreviousConfig = false; + int32_t previousNodeId = -1; + int32_t previousFlags = 0; + int32_t previousActions = 0; + int32_t previousTextSelectionBase = -1; + int32_t previousTextSelectionExtent = -1; + double previousScrollPosition = std::nan(""); + double previousScrollExtentMax = std::nan(""); + double previousScrollExtentMin = std::nan(""); + std::string previousValue; + std::string previousLabel; + bool HasPrevAction(SemanticsAction action) const { + return (previousActions & this->actions) != 0; + } + bool HasPrevFlag(SemanticsFlags flag) const { + return (previousFlags & this->flags) != 0; + } }; /** - * flutter和ohos的无障碍服务桥接 + * 桥接flutter无障碍功能和ohos无障碍系统服务 */ class OhosAccessibilityBridge { - public: - static OhosAccessibilityBridge* GetInstance(); - static void DestroyInstance(); - OhosAccessibilityBridge(const OhosAccessibilityBridge&) = delete; - OhosAccessibilityBridge& operator=(const OhosAccessibilityBridge&) = delete; - - bool IS_FLUTTER_NAVIGATE = false; - int64_t native_shell_holder_id_; - ArkUI_AccessibilityProvider* provider_; - - void OnOhosAccessibilityStateChange( - int64_t shellHolderId, - bool ohosAccessibilityEnabled); - - void SetNativeShellHolderId(int64_t id); - - void updateSemantics(flutter::SemanticsNodeUpdates update, - flutter::CustomAccessibilityActionUpdates actions); - - void DispatchSemanticsAction(int32_t id, - flutter::SemanticsAction action, - fml::MallocMapping args); - - void Announce(std::unique_ptr& message); - - flutter::SemanticsNode GetFlutterSemanticsNode(int32_t id); - - int32_t FindAccessibilityNodeInfosById( - int64_t elementId, - ArkUI_AccessibilitySearchMode mode, - int32_t requestId, - ArkUI_AccessibilityElementInfoList* elementList); - int32_t FindAccessibilityNodeInfosByText( - int64_t elementId, - const char* text, - int32_t requestId, - ArkUI_AccessibilityElementInfoList* elementList); - int32_t FindFocusedAccessibilityNode( - int64_t elementId, - ArkUI_AccessibilityFocusType focusType, - int32_t requestId, - ArkUI_AccessibilityElementInfo* elementinfo); - int32_t FindNextFocusAccessibilityNode( - int64_t elementId, - ArkUI_AccessibilityFocusMoveDirection direction, - int32_t requestId, - ArkUI_AccessibilityElementInfo* elementList); - int32_t ExecuteAccessibilityAction( - int64_t elementId, - ArkUI_Accessibility_ActionType action, - ArkUI_AccessibilityActionArguments* actionArguments, - int32_t requestId); - int32_t ClearFocusedFocusAccessibilityNode(); - int32_t GetAccessibilityNodeCursorPosition(int64_t elementId, - int32_t requestId, - int32_t* index); - - void Flutter_SendAccessibilityAsyncEvent( - int64_t elementId, - ArkUI_AccessibilityEventType eventType); - void FlutterNodeToElementInfoById( - ArkUI_AccessibilityElementInfo* elementInfoFromList, - int64_t elementId); - int32_t GetParentId(int64_t elementId); - - void ConvertChildRelativeRectToScreenRect(flutter::SemanticsNode node); - std::pair, std::pair> - GetAbsoluteScreenRect(int32_t flutterNodeId); - void SetAbsoluteScreenRect(int32_t flutterNodeId, - float left, - float top, - float right, - float bottom); - - SemanticsNodeExtent SetAndGetSemanticsNodeExtent(flutter::SemanticsNode node); - - void FlutterScrollExecution( - flutter::SemanticsNode node, - ArkUI_AccessibilityElementInfo* elementInfoFromList); - - void ClearFlutterSemanticsCaches(); - - private: - OhosAccessibilityBridge(); - static OhosAccessibilityBridge* bridgeInstance; - std::shared_ptr nativeAccessibilityChannel_; - std::shared_ptr accessibilityFeatures_; - - // arkui的root节点的父节点id - static const int32_t ARKUI_ACCESSIBILITY_ROOT_PARENT_ID = -2100000; - static const int32_t RET_ERROR_STATE_CODE = -999; - static const int32_t ROOT_NODE_ID = 0; - constexpr static const double SCROLL_EXTENT_FOR_INFINITY = 100000.0; - constexpr static const double SCROLL_POSITION_CAP_FOR_INFINITY = 70000.0; - - flutter::SemanticsNode inputFocusedNode; - flutter::SemanticsNode lastInputFocusedNode; - flutter::SemanticsNode accessibilityFocusedNode; - - std::vector> g_parentChildIdVec; - std::map g_flutterSemanticsTree; - std::unordered_map< - int32_t, - std::pair, std::pair>> - g_screenRectMap; - std::unordered_map g_actions_mp; - std::vector g_flutterNavigationVec; - - 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) | - static_cast(FLAGS_::kIsSelected) | - static_cast(FLAGS_::kIsTextField) | - static_cast(FLAGS_::kIsFocused) | - static_cast(FLAGS_::kHasEnabledState) | - static_cast(FLAGS_::kIsEnabled) | - static_cast(FLAGS_::kIsInMutuallyExclusiveGroup) | - static_cast(FLAGS_::kHasToggledState) | - static_cast(FLAGS_::kIsToggled) | - static_cast(FLAGS_::kHasToggledState) | - static_cast(FLAGS_::kIsFocusable) | - static_cast(FLAGS_::kIsSlider); - - static const int32_t SCROLLABLE_ACTIONS = - static_cast(ACTIONS_::kScrollUp) | - static_cast(ACTIONS_::kScrollDown) | - static_cast(ACTIONS_::kScrollLeft) | - static_cast(ACTIONS_::kScrollRight); - - void FlutterSetElementInfoProperties( - ArkUI_AccessibilityElementInfo* elementInfoFromList, - int64_t elementId); - void FlutterSetElementInfoOperationActions( - ArkUI_AccessibilityElementInfo* elementInfoFromList, - std::string widget_type); - void FlutterTreeToArkuiTree( - ArkUI_AccessibilityElementInfoList* elementInfoList); - void BuildArkUISemanticsTree( - int64_t elementId, - ArkUI_AccessibilityElementInfo* elementInfoFromList, - ArkUI_AccessibilityElementInfoList* elementList); - - std::vector GetLevelOrderTraversalTree(int32_t rootId); - flutter::SemanticsNode GetFlutterRootSemanticsNode(); - std::string GetNodeComponentType(const flutter::SemanticsNode& node); - flutter::SemanticsAction ArkuiActionsToFlutterActions( - ArkUI_Accessibility_ActionType arkui_action); - - bool HasScrolled(const flutter::SemanticsNode& flutterNode); - - bool IsNodeFocusable(const flutter::SemanticsNode& flutterNode); - bool IsNodeCheckable(flutter::SemanticsNode flutterNode); - bool IsNodeChecked(flutter::SemanticsNode flutterNode); - bool IsNodeSelected(flutter::SemanticsNode flutterNode); - bool IsNodeClickable(flutter::SemanticsNode flutterNode); - bool IsNodeScrollable(flutter::SemanticsNode flutterNode); - bool IsNodePassword(flutter::SemanticsNode flutterNode); - bool IsNodeVisible(flutter::SemanticsNode flutterNode); - bool IsNodeEnabled(flutter::SemanticsNode flutterNode); - bool IsNodeHasLongPress(flutter::SemanticsNode flutterNode); - - bool IsTextField(flutter::SemanticsNode flutterNode); - bool IsSlider(flutter::SemanticsNode flutterNode); - bool IsScrollableWidget(flutter::SemanticsNode flutterNode); - void PerformSetText(flutter::SemanticsNode flutterNode, - ArkUI_Accessibility_ActionType action, - ArkUI_AccessibilityActionArguments* actionArguments); - void PerformSelectText(flutter::SemanticsNode flutterNode, - ArkUI_Accessibility_ActionType action, - ArkUI_AccessibilityActionArguments* actionArguments); - - void AddRouteNodes(std::vector edges, - flutter::SemanticsNode node); - std::string GetRouteName(flutter::SemanticsNode node); - void onWindowNameChange(flutter::SemanticsNode route); - void removeSemanticsNode(flutter::SemanticsNode nodeToBeRemoved); - - void GetSemanticsNodeDebugInfo(flutter::SemanticsNode node); - void GetSemanticsFlagsDebugInfo(flutter::SemanticsNode node); - void GetCustomActionDebugInfo( - flutter::CustomAccessibilityAction customAccessibilityAction); - - void FlutterPageUpdate(ArkUI_AccessibilityEventType eventType); - void RequestFocusWhenPageUpdate(); - - bool Contains(const std::string source, const std::string target); +public: + static OhosAccessibilityBridge* GetInstance(); + static void DestroyInstance(); + OhosAccessibilityBridge(const OhosAccessibilityBridge&) = delete; + OhosAccessibilityBridge& operator=(const OhosAccessibilityBridge&) = delete; + + bool IS_FLUTTER_NAVIGATE = false; + int64_t native_shell_holder_id_; + ArkUI_AccessibilityProvider* provider_; + + void OnOhosAccessibilityStateChange( + int64_t shellHolderId, + bool ohosAccessibilityEnabled); + + void SetNativeShellHolderId(int64_t id); + + void updateSemantics(flutter::SemanticsNodeUpdates update, + flutter::CustomAccessibilityActionUpdates actions); + + void DispatchSemanticsAction(int32_t id, + flutter::SemanticsAction action, + fml::MallocMapping args); + + void Announce(std::unique_ptr& message); + + SemanticsNodeExtent GetFlutterSemanticsNode(int32_t id); + + int32_t FindAccessibilityNodeInfosById( + int64_t elementId, + ArkUI_AccessibilitySearchMode mode, + int32_t requestId, + ArkUI_AccessibilityElementInfoList* elementList); + int32_t FindAccessibilityNodeInfosByText( + int64_t elementId, + const char* text, + int32_t requestId, + ArkUI_AccessibilityElementInfoList* elementList); + int32_t FindFocusedAccessibilityNode( + int64_t elementId, + ArkUI_AccessibilityFocusType focusType, + int32_t requestId, + ArkUI_AccessibilityElementInfo* elementinfo); + int32_t FindNextFocusAccessibilityNode( + int64_t elementId, + ArkUI_AccessibilityFocusMoveDirection direction, + int32_t requestId, + ArkUI_AccessibilityElementInfo* elementList); + int32_t ExecuteAccessibilityAction( + int64_t elementId, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments, + int32_t requestId); + int32_t ClearFocusedFocusAccessibilityNode(); + int32_t GetAccessibilityNodeCursorPosition(int64_t elementId, + int32_t requestId, + int32_t* index); + + void Flutter_SendAccessibilityAsyncEvent( + int64_t elementId, + ArkUI_AccessibilityEventType eventType); + void FlutterNodeToElementInfoById( + ArkUI_AccessibilityElementInfo* elementInfoFromList, + int64_t elementId); + int32_t GetParentId(int64_t elementId); + + void ConvertChildRelativeRectToScreenRect(SemanticsNodeExtent node); + std::pair, std::pair> + GetAbsoluteScreenRect(int32_t flutterNodeId); + void SetAbsoluteScreenRect(int32_t flutterNodeId, + float left, + float top, + float right, + float bottom); + + SemanticsNodeExtent UpdatetSemanticsNodeExtent(flutter::SemanticsNode node); + + void FlutterScrollExecution( + SemanticsNodeExtent node, + ArkUI_AccessibilityElementInfo* elementInfoFromList); + + void ClearFlutterSemanticsCaches(); + +private: + OhosAccessibilityBridge(); + static OhosAccessibilityBridge* bridgeInstance; + std::shared_ptr nativeAccessibilityChannel_; + std::shared_ptr accessibilityFeatures_; + + std::vector> g_parentChildIdVec; + std::map g_flutterSemanticsTree; + std::unordered_map, std::pair>> g_screenRectMap; + std::unordered_map g_actions_mp; + std::vector g_flutterNavigationVec; + + SemanticsNodeExtent inputFocusedNode; + SemanticsNodeExtent lastInputFocusedNode; + SemanticsNodeExtent accessibilityFocusedNode; + + // arkui的root节点的父节点id + static const int32_t ARKUI_ACCESSIBILITY_ROOT_PARENT_ID = -2100000; + static const int32_t RET_ERROR_STATE_CODE = -999; + static const int32_t ROOT_NODE_ID = 0; + constexpr static const double SCROLL_EXTENT_FOR_INFINITY = 100000.0; + constexpr static const double SCROLL_POSITION_CAP_FOR_INFINITY = 70000.0; + + const std::string OTHER_WIDGET_NAME = "View"; + const std::string TEXT_WIDGET_NAME = "Text"; + const std::string EDIT_TEXT_WIDGET_NAME = "TextInput"; + const std::string EDIT_MULTILINE_TEXT_WIDGET_NAME = "TextArea"; + const std::string IMAGE_WIDGET_NAME = "Image"; + const std::string SCROLL_WIDGET_NAME = "Scroll"; + const std::string BUTTON_WIDGET_NAME = "Button"; + const std::string LINK_WIDGET_NAME = "Link"; + const std::string SLIDER_WIDGET_NAME = "Slider"; + const std::string HEADER_WIDGET_NAME = "Header"; + const std::string RADIO_BUTTON_WIDGET_NAME = "Radio"; + const std::string CHECK_BOX_WIDGET_NAME = "Checkbox"; + 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) | + static_cast(FLAGS_::kIsSelected) | + static_cast(FLAGS_::kIsTextField) | + static_cast(FLAGS_::kIsFocused) | + static_cast(FLAGS_::kHasEnabledState) | + static_cast(FLAGS_::kIsEnabled) | + static_cast(FLAGS_::kIsInMutuallyExclusiveGroup) | + static_cast(FLAGS_::kHasToggledState) | + static_cast(FLAGS_::kIsToggled) | + static_cast(FLAGS_::kHasToggledState) | + static_cast(FLAGS_::kIsFocusable) | + static_cast(FLAGS_::kIsSlider); + + static const int32_t SCROLLABLE_ACTIONS = + static_cast(ACTIONS_::kScrollUp) | + static_cast(ACTIONS_::kScrollDown) | + static_cast(ACTIONS_::kScrollLeft) | + static_cast(ACTIONS_::kScrollRight); + + void FlutterSetElementInfoProperties( + ArkUI_AccessibilityElementInfo* elementInfoFromList, + int64_t elementId); + void FlutterSetElementInfoOperationActions( + ArkUI_AccessibilityElementInfo* elementInfoFromList, + std::string widget_type); + void FlutterTreeToArkuiTree( + ArkUI_AccessibilityElementInfoList* elementInfoList); + void BuildArkUISemanticsTree( + int64_t elementId, + ArkUI_AccessibilityElementInfo* elementInfoFromList, + ArkUI_AccessibilityElementInfoList* elementList); + + std::vector GetLevelOrderTraversalTree(int32_t rootId); + SemanticsNodeExtent GetFlutterRootSemanticsNode(); + std::string GetNodeComponentType(const SemanticsNodeExtent& node); + flutter::SemanticsAction ArkuiActionsToFlutterActions( + ArkUI_Accessibility_ActionType arkui_action); + + bool HasScrolled(const SemanticsNodeExtent& flutterNode); + bool HasChangedLabel(const SemanticsNodeExtent& flutterNode); + + 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); + void PerformSetText(SemanticsNodeExtent flutterNode, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments); + void PerformSelectText(SemanticsNodeExtent flutterNode, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments); + + void AddRouteNodes(std::vector edges, + SemanticsNodeExtent node); + std::string GetRouteName(SemanticsNodeExtent node); + void onWindowNameChange(SemanticsNodeExtent route); + void removeSemanticsNode(SemanticsNodeExtent nodeToBeRemoved); + + void GetSemanticsNodeDebugInfo(SemanticsNodeExtent node); + void GetSemanticsFlagsDebugInfo(SemanticsNodeExtent node); + void GetCustomActionDebugInfo( + flutter::CustomAccessibilityAction customAccessibilityAction); + + void RequestFocusWhenPageUpdate(int32_t requestFocusId); + bool Contains(const std::string source, const std::string target); + std::pair GetRealScaleFactor(); + void FlutterSemanticsTreeUpdateCallOnce(); }; 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, + 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, + 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 diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.cpp index 39ea57e8a9..f4be1cadc6 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.cpp @@ -284,4 +284,19 @@ GetNativeA11yProvider OhosAccessibilityDDL::DLLoadGetNativeA11yProvider(const ch } return symbol; } + +GetFindActionArgs OhosAccessibilityDDL::DLLoadGetFindActionArgs(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; +} } \ No newline at end of file diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h index 96d3d38468..92f27eee15 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_ddl.h @@ -42,6 +42,7 @@ using SetEventElemFunc = int32_t (*)(ArkUI_AccessibilityEventInfo*, ArkUI_Access using SetReqFocusFunc = int32_t (*)(ArkUI_AccessibilityEventInfo*, int32_t); using GetNativeA11yProvider = int32_t (*)(OH_NativeXComponent*, ArkUI_AccessibilityProvider**); +using GetFindActionArgs = int32_t (*)(ArkUI_AccessibilityActionArguments*, const char*, char**); class OhosAccessibilityDDL { public: @@ -72,6 +73,7 @@ public: static SetReqFocusFunc DLLoadSetReqFocusFunc(const char* symbolName); static GetNativeA11yProvider DLLoadGetNativeA11yProvider(const char* symbolName); + static GetFindActionArgs DLLoadGetFindActionArgs(const char* symbolName); }; } // namespace flutter -- Gitee From 3ce41168acb76547306c52d6c76a96c27340143a Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 10 Dec 2024 21:07:46 +0800 Subject: [PATCH 12/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E9=9D=9E=E6=BB=91?= =?UTF-8?q?=E5=8A=A8=E9=A6=96=E9=A1=B5=E7=9A=84=E6=BB=91=E5=8A=A8=E5=AD=90?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=97=A0=E6=B3=95=E5=9C=A8uitest=E4=B8=8A?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=EF=BC=8C=E4=BC=98=E5=8C=96=E9=83=A8=E5=88=86?= =?UTF-8?q?=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_bridge.cpp | 206 +++++++----------- .../accessibility/ohos_accessibility_bridge.h | 13 +- 2 files changed, 90 insertions(+), 129 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index d465dd9a2d..35d4c5ba1d 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -131,10 +131,6 @@ void OhosAccessibilityBridge::updateSemantics( */ g_flutterSemanticsTree[nodeEx.id] = nodeEx; - // 若当前节点为隐藏状态,则跳过 - // if (IsNodeVisible(nodeEx)) { - // continue; - // } // 若当前节点为获焦 if (IsNodeFocused(nodeEx)) { inputFocusedNode = nodeEx; @@ -187,30 +183,6 @@ void OhosAccessibilityBridge::updateSemantics( ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); } - // 判断当前获焦节点和当前更新节点是否一致,若一致则选中 - // if (accessibilityFocusedNode.id == nodeEx.id && - // !nodeEx.HasPrevFlag(FLAGS_::kIsSelected) && - // nodeEx.HasFlag(FLAGS_::kIsSelected)) { - // Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), - // ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); - // LOGD("Flutter_SendAccessibilityAsyncEvent -> SELECTED"); - // } - - // 更新获焦节点 - // if (inputFocusedNode.id == nodeEx.id && (lastInputFocusedNode.id != inputFocusedNode.id)) { - // lastInputFocusedNode = inputFocusedNode; - // Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), - // ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUSED); - // LOGD("Flutter_SendAccessibilityAsyncEvent -> ACCESSIBILITY_FOCUSED"); - // } - // // 当输入框文本变化时,发送文本更新事件 - // if (inputFocusedNode.id == nodeEx.id && - // IsTextField(nodeEx) && - // nodeEx.previousValue != nodeEx.value) { - // Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), - // ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_TEXT_UPDATE); - // LOGD("Flutter_SendAccessibilityAsyncEvent -> TEXT_UPDATE"); - // } } // 遍历更新的actions,并将所有的actions的id添加进actionMap @@ -489,13 +461,11 @@ void OhosAccessibilityBridge::Announce(std::unique_ptr& message) SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterRootSemanticsNode() { if (!g_flutterSemanticsTree.size()) { - FML_DLOG(ERROR) - << "GetFlutterRootSemanticsNode -> g_flutterSemanticsTree.size()=0"; + LOGE("GetFlutterRootSemanticsNode: g_flutterSemanticsTree.size()=0"); return {}; } if (g_flutterSemanticsTree.find(0) == g_flutterSemanticsTree.end()) { - FML_DLOG(ERROR) << "GetFlutterRootSemanticsNode -> g_flutterSemanticsTree " - "has no keys = 0"; + LOGE("GetFlutterRootSemanticsNod: g_flutterSemanticsTree has no root id"); return {}; } return g_flutterSemanticsTree.at(0); @@ -507,12 +477,10 @@ SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterRootSemanticsNode() SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterSemanticsNode( int32_t id) { - SemanticsNodeExtent node; if (g_flutterSemanticsTree.count(id) > 0) { return g_flutterSemanticsTree.at(id); - FML_DLOG(INFO) << "GetFlutterSemanticsNode get node.id=" << id; } else { - FML_DLOG(ERROR) << "GetFlutterSemanticsNode g_flutterSemanticsTree = null" << id; + LOGE("GetFlutterSemanticsNode g_flutterSemanticsTree = null"); return {}; } } @@ -720,26 +688,24 @@ int32_t OhosAccessibilityBridge::GetParentId(int64_t elementId) /** * 设置并获取xcomponet上渲染的组件的屏幕绝对坐标rect */ -void OhosAccessibilityBridge::SetAbsoluteScreenRect(int32_t flutterNodeId, +void OhosAccessibilityBridge::SetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode, float left, float top, float right, float bottom) { - g_screenRectMap[flutterNodeId] = - std::make_pair(std::make_pair(left, top), std::make_pair(right, bottom)); - FML_DLOG(INFO) << "SetAbsoluteScreenRect -> id=" << flutterNodeId + g_screenRectMap[flutterNode.id] = AbsoluteRect{left, top, right, bottom}; + FML_DLOG(INFO) << "SetAbsoluteScreenRect -> id=" << flutterNode.id << ", {" << left << ", " << top << ", " << right << ", "<< bottom << "> }"; } -std::pair, std::pair> -OhosAccessibilityBridge::GetAbsoluteScreenRect(int32_t flutterNodeId) +AbsoluteRect OhosAccessibilityBridge::GetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode) { - if (!g_screenRectMap.empty() && g_screenRectMap.count(flutterNodeId) > 0) { - return g_screenRectMap.at(flutterNodeId); + if (!g_screenRectMap.empty() && g_screenRectMap.count(flutterNode.id) > 0) { + return g_screenRectMap.at(flutterNode.id); } else { FML_DLOG(ERROR) << "GetAbsoluteScreenRect -> flutterNodeId=" - << flutterNodeId << " is not found !"; + << flutterNode.id << " is not found !"; return {}; } } @@ -760,7 +726,7 @@ std::pair OhosAccessibilityBridge::GetRealScaleFactor() * flutter无障碍语义树的子节点相对坐标系转化为屏幕绝对坐标的映射算法 * 目前暂未考虑旋转、透视场景,不影响屏幕朗读功能 */ -void OhosAccessibilityBridge::ConvertChildRelativeRectToScreenRect( +void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( SemanticsNodeExtent currNode) { // 获取当前flutter节点的相对rect @@ -784,17 +750,18 @@ void OhosAccessibilityBridge::ConvertChildRelativeRectToScreenRect( // 获取当前flutter节点的父节点的相对rect int32_t parentId = GetParentId(currNode.id); auto parentNode = GetFlutterSemanticsNode(parentId); + if (!g_flutterSemanticsTree.count(parentId)) { + LOGE("FlutterRelativeRectToScreenRect: GetFlutterSemanticsNode id=%{public}d null", parentId); + } + // 获取当前flutter节点的父节点的绝对坐标 - auto _rectPairs = GetAbsoluteScreenRect(parentNode.id); - auto realParentLeft = _rectPairs.first.first; - auto realParentTop = _rectPairs.first.second; - auto realParentRight = _rectPairs.second.first; - auto realParentBottom = _rectPairs.second.second; + auto [realParentLeft, realParentTop, realParentRight, realParentBottom] = GetAbsoluteScreenRect(parentNode); //获取root节点的绝对坐标 - auto _rootRect = GetAbsoluteScreenRect(0); - auto rootWidth = _rootRect.second.first; - auto rootHeight = _rootRect.second.second; + auto rootNode = GetFlutterSemanticsNode(0); + auto _rootRect = GetAbsoluteScreenRect(rootNode); + auto rootWidth = _rootRect.right; + auto rootHeight = _rootRect.bottom; // 获取真实缩放系数 auto [realScaleXFactor, realScaleYFactor] = GetRealScaleFactor(); @@ -812,7 +779,7 @@ void OhosAccessibilityBridge::ConvertChildRelativeRectToScreenRect( newRight = currRight * _kMScaleX; newBottom = currBottom * _kMScaleY; // 更新当前flutter节点currNode的相对坐标 -> 屏幕绝对坐标 - SetAbsoluteScreenRect(currNode.id, newLeft, newTop, newRight, newBottom); + SetAbsoluteScreenRect(currNode, newLeft, newTop, newRight, newBottom); } else { // 子节点的屏幕绝对坐标转换,包括offset偏移值计算、缩放系数变换 newLeft = (currLeft + _kMTransX) * realScaleXFactor + realParentLeft; @@ -831,11 +798,9 @@ void OhosAccessibilityBridge::ConvertChildRelativeRectToScreenRect( << currNode.id << ", (" << newLeft << ", " << newTop << ", " << newRight << ", " << newBottom << ")}"; // 防止滑动场景下绿框坐标超出屏幕范围,进行正则化处理 - // newTop = realParentBottom; - // newBottom = realParentBottom; - SetAbsoluteScreenRect(currNode.id, rootWidth, rootHeight, 0, 0); + SetAbsoluteScreenRect(currNode, rootWidth, rootHeight, 0, 0); } else { - SetAbsoluteScreenRect(currNode.id, newLeft, newTop, newRight, newBottom); + SetAbsoluteScreenRect(currNode, newLeft, newTop, newRight, newBottom); } } } @@ -859,6 +824,9 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( if (elementId == 0 || elementId == -1) { // 获取flutter的root节点 SemanticsNodeExtent flutterNode = GetFlutterSemanticsNode(static_cast(0)); + if (flutterNode.isNull) { + LOGE("FlutterNodeToElementInfoById: GetFlutterSemanticsNode id=%{public}ld null", elementId); + } // 设置elementinfo的屏幕坐标范围 int32_t left = static_cast(flutterNode.rect.fLeft); @@ -876,11 +844,10 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( ); // 设置root节点的屏幕绝对坐标rect - SetAbsoluteScreenRect(0, left, top, right, bottom); + SetAbsoluteScreenRect(flutterNode, left, top, right, bottom); - // 设置elementinfo的action类型 - std::string widget_type = "root"; - FlutterSetElementInfoOperationActions(elementInfoFromList, widget_type); + // 设置root节点的action类型 + FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); // 根据flutternode信息配置对应的elementinfo int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = @@ -1133,6 +1100,9 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( { if (OH_GetSdkApiVersion() >= 13) { SemanticsNodeExtent flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); + if (flutterNode.isNull) { + LOGE("FlutterSetElementInfoProperties: GetFlutterSemanticsNode id=%{public}ld null", elementId); + } // set elementinfo id int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = @@ -1144,15 +1114,11 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, flutterNode.id) ); - // convert relative rect to absolute rect - ConvertChildRelativeRectToScreenRect(flutterNode); - auto rectPairs = GetAbsoluteScreenRect(flutterNode.id); - // set screen rect in xcomponent - int32_t left = rectPairs.first.first; - int32_t top = rectPairs.first.second; - int32_t right = rectPairs.second.first; - int32_t bottom = rectPairs.second.second; - ArkUI_AccessibleRect rect = {left, top, right, bottom}; + // 相对-绝对坐标映射 + FlutterRelativeRectToScreenRect(flutterNode); + auto [left, top, right, bottom] = GetAbsoluteScreenRect(flutterNode); + ArkUI_AccessibleRect rect = {static_cast(left), static_cast(top), + static_cast(right), static_cast(bottom)}; int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); if (OH_ArkUI_AccessibilityElementInfoSetScreenRect == nullptr) { @@ -1168,19 +1134,17 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( // 配置arkui的elementinfo可操作动作属性 if (IsTextField(flutterNode)) { // 若当前flutter节点为文本输入框组件 - std::string widget_type = "textfield"; - FlutterSetElementInfoOperationActions(elementInfoFromList, widget_type); + std::string widgeType = flutterNode.HasFlag(FLAGS_::kIsMultiline) ? EDIT_MULTILINE_TEXT_WIDGET_NAME : EDIT_TEXT_WIDGET_NAME; + FlutterSetElementInfoOperationActions(elementInfoFromList, widgeType); } else if (IsScrollableWidget(flutterNode) || IsNodeScrollable(flutterNode)) { // 若当前flutter节点为可滑动组件类型 - std::string widget_type = "scrollable"; - FlutterSetElementInfoOperationActions(elementInfoFromList, widget_type); + FlutterSetElementInfoOperationActions(elementInfoFromList, SCROLL_WIDGET_NAME); } else { // 若当前flutter节点为通用组件 - std::string widget_type = "common"; - FlutterSetElementInfoOperationActions(elementInfoFromList, widget_type); + FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); } - // set current elementinfo parent id + // 设置当前节点的父节点id int32_t parentId = GetParentId(elementId); int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); @@ -1192,7 +1156,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( ); FML_DLOG(INFO) << "FlutterNodeToElementInfoById GetParentId = " << parentId; - // set accessibility text for announcing + // 设置可朗读文本 std::string text = flutterNode.label + flutterNode.value; int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); @@ -1202,10 +1166,9 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityText(elementInfoFromList, text.c_str()) ); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById SetAccessibilityText = " - << text; + FML_DLOG(INFO) << "FlutterNodeToElementInfoById SetAccessibilityText = " << text; - //set contents (same as AccessibilityText) + // 设置无障碍content文本 int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); if (OH_ArkUI_AccessibilityElementInfoSetContents == nullptr) { @@ -1214,7 +1177,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetContents(elementInfoFromList, text.c_str()) ); - + // 设置hint提示文本 std::string hint = flutterNode.hint; int32_t (*OH_ArkUI_AccessibilityElementInfoSetHintText)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetHintText"); @@ -1225,7 +1188,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( OH_ArkUI_AccessibilityElementInfoSetHintText(elementInfoFromList, hint.c_str()) ); - // set chidren elementinfo ids + // 设置当前节点的全部孩子节点 int32_t childCount = flutterNode.childrenInTraversalOrder.size(); if (childCount > 0) { auto childrenIdsVec = flutterNode.childrenInTraversalOrder; @@ -1497,18 +1460,19 @@ void OhosAccessibilityBridge::BuildArkUISemanticsTree( for (int64_t i = 1; i < elementInfoCount; i++) { int64_t levelOrderId = levelOrderTreeVec[i]; auto newNode = GetFlutterSemanticsNode(levelOrderId); + if (g_flutterSemanticsTree.count(newNode.id)) { + LOGE("BuildArkUISemanticsTree: GetFlutterSemanticsNode id=%{public}ld null", levelOrderId); + } //当节点为隐藏状态时,自动规避 - if (IsNodeVisible(newNode)) { - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = - OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); - if (OH_ArkUI_AddAndGetAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_AddAndGetAccessibilityElementInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityElementInfo* newElementInfo = - OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); - //配置当前子节点信息 - FlutterNodeToElementInfoById(newElementInfo, levelOrderId); + ArkUI_AccessibilityElementInfo* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = + OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); + if (OH_ArkUI_AddAndGetAccessibilityElementInfo == nullptr) { + LOGE("OH_ArkUI_AddAndGetAccessibilityElementInfo is null, %{public}s", dlerror()); } + ArkUI_AccessibilityElementInfo* newElementInfo = + OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); + //配置当前子节点信息 + FlutterNodeToElementInfoById(newElementInfo, levelOrderId); } } } @@ -1537,6 +1501,13 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( FML_DLOG(INFO) << "FindAccessibilityNodeInfosById elementList 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_); @@ -1556,9 +1527,6 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( return ARKUI_ACCESSIBILITY_NATIVE_RESULT_FAILED; } - // 过滤非当前屏幕显示的语义节点创建、配置,防止溢出屏幕坐标绘制bug以及优化性能开销 - auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); - if (mode == ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_CURRENT) { /** Search for current nodes. (mode = 0) */ BuildArkUISemanticsTree(elementId, elementInfoFromList, elementList); @@ -1624,6 +1592,10 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( // 获取当前elementid对应的flutter语义节点 auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); + if (!g_flutterSemanticsTree.count(flutterNode.id)) { + LOGE("ExecuteAccessibilityAction: GetFlutterSemanticsNode id=%{public}ld is null", elementId); + } + // 若当前节点为非屏幕显示状态,将其显示在屏幕上 if (!IsNodeShowOnScreen(flutterNode)) { DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kShowOnScreen, {}); @@ -2039,22 +2011,22 @@ void OhosAccessibilityBridge::PerformSetText( ArkUI_AccessibilityActionArguments* actionArguments) { // 获取特殊动作参数 - int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = - OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); - if (OH_ArkUI_FindAccessibilityActionArgumentByKey == nullptr) { - LOGE("OH_ArkUI_FindAccessibilityActionArgumentByKey is null, %{public}s", dlerror()); - } - const char* key_setText = "setText"; - char* newValue; - char** value = &newValue; - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); - if (newValue == nullptr) { - // newValue = "888"; - LOGE("PerformSetText -> OH_ArkUI_FindAccessibilityActionArgumentByKey get null value"); - } + // int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = + // OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); + // if (OH_ArkUI_FindAccessibilityActionArgumentByKey == nullptr) { + // LOGE("OH_ArkUI_FindAccessibilityActionArgumentByKey is null, %{public}s", dlerror()); + // } + // const char* key_setText = "setText"; + // char* newValue = "debug"; + // char** value = &newValue; + // ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); + // if (newValue == nullptr) { + // // newValue = "888"; + // LOGE("PerformSetText -> OH_ArkUI_FindAccessibilityActionArgumentByKey get null value"); + // } auto flutterSetTextAction = ArkuiActionsToFlutterActions(action); DispatchSemanticsAction(flutterNode.id, flutterSetTextAction, {}); - flutterNode.value = newValue; + flutterNode.value = "debug"; flutterNode.valueAttributes = {}; } @@ -2147,17 +2119,6 @@ bool OhosAccessibilityBridge::IsNodeClickable( SemanticsNodeExtent flutterNode) { return flutterNode.HasAction(ACTIONS_::kTap); - flutterNode.HasFlag(FLAGS_::kHasCheckedState) || - flutterNode.HasFlag(FLAGS_::kIsButton) || - flutterNode.HasFlag(FLAGS_::kIsTextField) || - flutterNode.HasFlag(FLAGS_::kIsImage) || - flutterNode.HasFlag(FLAGS_::kIsLiveRegion) || - flutterNode.HasFlag(FLAGS_::kIsMultiline) || - flutterNode.HasFlag(FLAGS_::kIsLink) || - flutterNode.HasFlag(FLAGS_::kIsSlider) || - flutterNode.HasFlag(FLAGS_::kIsKeyboardKey) || - flutterNode.HasFlag(FLAGS_::kHasToggledState) || - flutterNode.HasFlag(FLAGS_::kHasImplicitScrolling); } /** * 判断当前flutter节点组件是否可显示 @@ -2399,6 +2360,7 @@ SemanticsNodeExtent OhosAccessibilityBridge::UpdatetSemanticsNodeExtent( 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 5240f33a75..8342130bff 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -41,6 +41,7 @@ struct AbsoluteRect { } }; struct SemanticsNodeExtent : flutter::SemanticsNode { + bool isNull = false; AbsoluteRect absoluteRect = AbsoluteRect::MakeEmpty(); int32_t parentId = -1; bool hadPreviousConfig = false; @@ -131,10 +132,9 @@ public: int64_t elementId); int32_t GetParentId(int64_t elementId); - void ConvertChildRelativeRectToScreenRect(SemanticsNodeExtent node); - std::pair, std::pair> - GetAbsoluteScreenRect(int32_t flutterNodeId); - void SetAbsoluteScreenRect(int32_t flutterNodeId, + void FlutterRelativeRectToScreenRect(SemanticsNodeExtent node); + AbsoluteRect GetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode); + void SetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode, float left, float top, float right, @@ -156,8 +156,7 @@ private: std::vector> g_parentChildIdVec; std::map g_flutterSemanticsTree; - std::unordered_map, std::pair>> g_screenRectMap; + std::unordered_map g_screenRectMap; std::unordered_map g_actions_mp; std::vector g_flutterNavigationVec; @@ -167,7 +166,7 @@ private: // arkui的root节点的父节点id static const int32_t ARKUI_ACCESSIBILITY_ROOT_PARENT_ID = -2100000; - static const int32_t RET_ERROR_STATE_CODE = -999; + static const int32_t RET_ERROR_STATE_CODE = -1; static const int32_t ROOT_NODE_ID = 0; constexpr static const double SCROLL_EXTENT_FOR_INFINITY = 100000.0; constexpr static const double SCROLL_POSITION_CAP_FOR_INFINITY = 70000.0; -- Gitee From d460c9dc0056e36d33a8ef7e79aac7509d0bb3db Mon Sep 17 00:00:00 2001 From: zjxi Date: Wed, 11 Dec 2024 15:37:54 +0800 Subject: [PATCH 13/60] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96=E6=97=A0=E9=9A=9C?= =?UTF-8?q?=E7=A2=8D=E9=83=A8=E5=88=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 70 +++++++------------ .../accessibility/ohos_accessibility_bridge.h | 2 + 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 35d4c5ba1d..2b9f261cd9 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -83,13 +83,6 @@ void OhosAccessibilityBridge::SetNativeShellHolderId(int64_t id) this->native_shell_holder_id_ = id; } -void OhosAccessibilityBridge::FlutterSemanticsTreeUpdateCallOnce() { - static std::once_flag flag; - std::call_once(flag, [this]() { - this->RequestFocusWhenPageUpdate(0); - LOGD("call once -> RequestFocusWhenPageUpdate(0)"); - }); -} /** * 从dart侧传递到c++侧的flutter无障碍语义树节点更新过程, * 路由新页面、滑动页面等操作会自动触发该语义树的更新 @@ -108,9 +101,9 @@ void OhosAccessibilityBridge::updateSemantics( IS_FLUTTER_NAVIGATE = false; } - // 页面状态更新事件 + // 页面内容更新事件 Flutter_SendAccessibilityAsyncEvent(0, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); - LOGE("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); + LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); /** 获取并分析每个语义节点的更新属性 */ for (auto& item : update) { @@ -147,6 +140,7 @@ void OhosAccessibilityBridge::updateSemantics( } } + /* 针对更新后的节点进行事件处理 */ for (const auto& nodeEx: updatedFlutterNodes) { // 当滑动节点产生滑动,并执行滑动处理 if (HasScrolled(nodeEx)) { @@ -171,11 +165,8 @@ void OhosAccessibilityBridge::updateSemantics( OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); _elementInfo = nullptr; } - // 发送滑动事件 - // Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), - // ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SCROLLED); } - + // 判断是否触发liveRegion活动区,当前节点是否活跃 if (nodeEx.HasFlag(FLAGS_::kIsLiveRegion) && HasChangedLabel(nodeEx)) { FML_DLOG(INFO) << "UpdateSemantics -> page content update, nodeEx.id=" << nodeEx.id; @@ -185,28 +176,9 @@ void OhosAccessibilityBridge::updateSemantics( } } - // 遍历更新的actions,并将所有的actions的id添加进actionMap - for (const auto& item : actions) { - const flutter::CustomAccessibilityAction action = item.second; - GetCustomActionDebugInfo(action); - g_actions_mp[action.id] = action; - } - // 打印flutter语义树的不同节点的属性信息 - for (const auto& item : g_flutterSemanticsTree) { - 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) { - FML_DLOG(INFO) << "LevelOrderTraversalTree: { " << item << " }"; - } - - FML_DLOG(INFO) << "=== UpdateSemantics is end ==="; + // 输出flutter语义树相关重要语义信息debug日志 + GetSemanticsDebugInfo(); + FML_DLOG(INFO) << "=== UpdateSemantics() is finished ==="; } /** @@ -258,15 +230,6 @@ void OhosAccessibilityBridge::FlutterScrollExecution( } ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetItemCount(elementInfoFromList, itemCount)); - // 设置当前页面可见的当前选中滑动index - // int32_t currentItemIndex = node.scrollIndex; - // int32_t (*OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = - // OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex"); - // if (OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex == nullptr) { - // LOGE("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex is null, %{public}s", dlerror()); - // } - // ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex(elementInfoFromList, currentItemIndex)); - // 设置当前页面可见的起始滑动index int32_t startItemIndex = node.scrollIndex; int32_t (*OH_ArkUI_AccessibilityElementInfoSetStartItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = @@ -2528,4 +2491,23 @@ void OhosAccessibilityBridge::GetSemanticsFlagsDebugInfo( << customAccessibilityAction.hint; FML_DLOG(INFO) << "------------CustomAccessibilityAction--------------"; } + +void OhosAccessibilityBridge::GetSemanticsDebugInfo() +{ + // 打印flutter语义树的不同节点的属性信息 + for (const auto& item : g_flutterSemanticsTree) { + 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) { + FML_DLOG(INFO) << "LevelOrderTraversalTree: { " << item << " }"; + } +} + } // namespace flutter diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 8342130bff..445093c0c9 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -284,6 +284,8 @@ private: bool Contains(const std::string source, const std::string target); std::pair GetRealScaleFactor(); void FlutterSemanticsTreeUpdateCallOnce(); + + void GetSemanticsDebugInfo(); }; enum class AccessibilityAction : int32_t { -- Gitee From 347c97a09db10c9af62166525cd435f63cb949e6 Mon Sep 17 00:00:00 2001 From: zjxi Date: Fri, 13 Dec 2024 16:20:26 +0800 Subject: [PATCH 14/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E5=AD=97=E9=87=8D?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E6=94=AF=E6=8C=81=E5=A4=9A=E7=B2=92=E5=BA=A6?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- attachment/repos/skia.patch | 1526 +++++++++++++++++++++++++++++++---- 1 file changed, 1377 insertions(+), 149 deletions(-) diff --git a/attachment/repos/skia.patch b/attachment/repos/skia.patch index adad9f220a..d85176705f 100644 --- a/attachment/repos/skia.patch +++ b/attachment/repos/skia.patch @@ -1,5 +1,5 @@ diff --git a/BUILD.gn b/BUILD.gn -index ebbd898ec9..015bb75414 100644 +index ebbd898ec9..2d4257e8d7 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -26,16 +26,21 @@ import("gn/ios.gni") @@ -142,22 +142,16 @@ index ebbd898ec9..015bb75414 100644 ] if (!skia_enable_winuwp) { -@@ -1566,6 +1619,14 @@ skia_component("skia") { - } +@@ -1559,7 +1612,7 @@ skia_component("skia") { + ] } -+ if (is_ohos) { -+ sources += [ "src/ports/SkDebug_ohos.cpp" ] -+ if (skia_use_egl) { -+ libs += [ "GLESv2" ] -+ } -+ libs += [ "hilog_ndk.z" ] -+ } -+ - if (is_mac) { - public += [ "include/ports/SkCFObject.h" ] - sources += [ -@@ -1962,7 +2023,7 @@ if (skia_enable_tools) { +- if (is_linux || is_wasm) { ++ if (is_linux || is_wasm || is_ohos) { + sources += [ "src/ports/SkDebug_stdio.cpp" ] + if (skia_use_egl) { + libs += [ "GLESv2" ] +@@ -1962,7 +2015,7 @@ if (skia_enable_tools) { if (is_android || skia_use_egl) { sources += [ "tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp" ] libs += [ "EGL" ] @@ -166,7 +160,7 @@ index ebbd898ec9..015bb75414 100644 sources += [ "tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp" ] libs += [ "GLU", -@@ -2281,7 +2342,7 @@ if (skia_enable_tools) { +@@ -2281,7 +2334,7 @@ if (skia_enable_tools) { ] } @@ -175,7 +169,7 @@ index ebbd898ec9..015bb75414 100644 if (skia_enable_skottie) { test_app("skottie_tool") { deps = [ "modules/skottie:tool" ] -@@ -2777,7 +2838,7 @@ if (skia_enable_tools) { +@@ -2777,7 +2830,7 @@ if (skia_enable_tools) { "tools/sk_app/android/surface_glue_android.h", ] libs += [ "android" ] @@ -184,7 +178,7 @@ index ebbd898ec9..015bb75414 100644 sources += [ "tools/SkGetExecutablePath_linux.cpp", "tools/sk_app/unix/RasterWindowContext_unix.cpp", -@@ -2830,7 +2891,7 @@ if (skia_enable_tools) { +@@ -2830,7 +2883,7 @@ if (skia_enable_tools) { sources += [ "tools/sk_app/GLWindowContext.h" ] if (is_android) { sources += [ "tools/sk_app/android/GLWindowContext_android.cpp" ] @@ -193,7 +187,7 @@ index ebbd898ec9..015bb75414 100644 sources += [ "tools/sk_app/unix/GLWindowContext_unix.cpp" ] } else if (is_win) { sources += [ "tools/sk_app/win/GLWindowContext_win.cpp" ] -@@ -2855,7 +2916,7 @@ if (skia_enable_tools) { +@@ -2855,7 +2908,7 @@ if (skia_enable_tools) { sources += [ "tools/sk_app/VulkanWindowContext.h" ] if (is_android) { sources += [ "tools/sk_app/android/VulkanWindowContext_android.cpp" ] @@ -202,7 +196,7 @@ index ebbd898ec9..015bb75414 100644 sources += [ "tools/sk_app/unix/VulkanWindowContext_unix.cpp" ] libs += [ "X11-xcb" ] } else if (is_win) { -@@ -2887,7 +2948,7 @@ if (skia_enable_tools) { +@@ -2887,7 +2940,7 @@ if (skia_enable_tools) { if (skia_use_dawn) { sources += [ "tools/sk_app/DawnWindowContext.cpp" ] sources += [ "tools/sk_app/DawnWindowContext.h" ] @@ -211,7 +205,7 @@ index ebbd898ec9..015bb75414 100644 if (dawn_enable_vulkan) { sources += [ "tools/sk_app/unix/DawnVulkanWindowContext_unix.cpp" ] defines = [ "VK_USE_PLATFORM_XCB_KHR" ] -@@ -2931,7 +2992,7 @@ if (skia_enable_tools) { +@@ -2931,7 +2984,7 @@ if (skia_enable_tools) { } } @@ -220,7 +214,7 @@ index ebbd898ec9..015bb75414 100644 test_app("fiddle_examples") { sources = [ "tools/fiddle/all_examples.cpp", -@@ -3088,7 +3149,7 @@ if (skia_enable_tools) { +@@ -3088,7 +3141,7 @@ if (skia_enable_tools) { } } @@ -333,21 +327,6 @@ index b43526fe1f..fb34289da7 100644 ldflags = [ "-rdynamic", "-Wl,-rpath,\$ORIGIN", -diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp -index bdcf607d04..2e92ed05f3 100644 ---- a/src/core/SkRRect.cpp -+++ b/src/core/SkRRect.cpp -@@ -231,8 +231,8 @@ bool SkRRect::scaleRadii() { - double scale = 1.0; - - // The sides of the rectangle may be larger than a float. -- double width = (double)fRect.fRight - (double)fRect.fLeft; -- double height = (double)fRect.fBottom - (double)fRect.fTop; -+ double width = (double)(fRect.fRight - fRect.fLeft); -+ double height = (double)(fRect.fBottom - fRect.fTop); - scale = compute_min_scale(fRadii[0].fX, fRadii[1].fX, width, scale); - scale = compute_min_scale(fRadii[1].fY, fRadii[2].fY, height, scale); - scale = compute_min_scale(fRadii[2].fX, fRadii[3].fX, width, scale); diff --git a/src/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.cpp b/src/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.cpp index 78225b4610..c2105852b1 100644 --- a/src/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.cpp @@ -1091,57 +1070,19 @@ index 0000000000..eb318dc3a3 +#endif + +#endif /* __gl2platform_h_ */ -diff --git a/src/ports/SkDebug_ohos.cpp b/src/ports/SkDebug_ohos.cpp -new file mode 100644 -index 0000000000..0e5e0829b6 ---- /dev/null -+++ b/src/ports/SkDebug_ohos.cpp -@@ -0,0 +1,32 @@ -+// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "include/core/SkTypes.h" -+ -+#include -+#include -+ -+ -+#ifdef HILOG_LOG_DOMAIN -+ #undef HILOG_LOG_DOMAIN -+#endif -+ -+#ifdef HILOG_LOG_TAG -+ #undef HILOG_LOG_DOMAIN -+#endif -+ -+ -+#define HILOG_LOG_DOMAIN 0x0000 -+#define HILOG_LOG_TAG "Skia" -+ -+void SkDebugf(const char format[], ...) { -+ char outStr[1024] = { 0 }; -+ va_list args; -+ va_start(args, format); -+ (void)vsnprintf(outStr,sizeof(outStr), format, args); -+ va_end(args); -+ -+ (void)OH_LOG_Print(LOG_APP, LOG_INFO, HILOG_LOG_DOMAIN,\ -+ HILOG_LOG_TAG, "%{public}s", outStr); -+} diff --git a/src/ports/skia_ohos/FontConfig_ohos.cpp b/src/ports/skia_ohos/FontConfig_ohos.cpp new file mode 100644 -index 0000000000..2dfc1348c1 +index 0000000000..c502ed853e --- /dev/null +++ b/src/ports/skia_ohos/FontConfig_ohos.cpp -@@ -0,0 +1,1312 @@ +@@ -0,0 +1,1308 @@ +// Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "FontConfig_ohos.h" + -+#include ++#include +#include +#include +#include @@ -1197,10 +1138,6 @@ index 0000000000..2dfc1348c1 + */ +int FontConfig_OHOS::getFamilyCount() const +{ -+#if ENABLE_DEBUG -+ dumpGeneric(); -+ dumpFallback(); -+#endif + return genericFamilySet.size(); +} + @@ -1553,7 +1490,7 @@ index 0000000000..2dfc1348c1 + */ +void FontConfig_OHOS::dumpFont(const FontInfo& font) const +{ -+ SkDEBUGF("name=%s, family=%s, weight=%d, width=%d, slant=%d, index=%d", ++ LOGI("name=%s, family=%s, weight=%d, width=%d, slant=%d, index=%d", + font.fname.c_str(), font.familyName.c_str(), font.style.weight(), font.style.width(), font.style.slant(), + font.index); + int count = font.axisSet.axis.size(); @@ -1565,7 +1502,7 @@ index 0000000000..2dfc1348c1 + str.append(","); + } + } -+ SkDEBUGF("axis={%s}\n", str.c_str()); ++ LOGI("axis={%s}\n", str.c_str()); + } +} + @@ -1573,9 +1510,9 @@ index 0000000000..2dfc1348c1 + */ +void FontConfig_OHOS::dumpGeneric() const +{ -+ SkDEBUGF("\n"); ++ LOGI("\n"); + for (unsigned int i = 0; i < genericFamilySet.size(); i++) { -+ SkDEBUGF("[%d] familyName : %s - %d\n", i, genericFamilySet[i]->familyName.c_str(), ++ LOGI("[%d] familyName : %s - %d\n", i, genericFamilySet[i]->familyName.c_str(), + static_cast(genericFamilySet[i]->typefaceSet->size())); + for (int j = 0; j < genericFamilySet[i]->typefaceSet->size(); j++) { + if ((*(genericFamilySet[i]->typefaceSet))[j].get()) { @@ -1583,10 +1520,10 @@ index 0000000000..2dfc1348c1 + if (font) { + dumpFont(*font); + } else { -+ SkDEBUGF("font [%d] is null\n", j); ++ LOGE("font [%d] is null\n", j); + } + } else { -+ SkDEBUGF("typefeace [%d] is null\n", j); ++ LOGE("typefeace [%d] is null\n", j); + } + } + } @@ -1596,21 +1533,21 @@ index 0000000000..2dfc1348c1 + */ +void FontConfig_OHOS::dumpFallback() const +{ -+ SkDEBUGF("\n"); ++ LOGI("\n"); + int count = 0; + fallbackForMap.foreach([this, &count](const SkString& key, + const FallbackSetPos& setIndex) { -+ SkDEBUGF("[%d] family : %s - %d\n", count++, key.c_str(), setIndex.count); ++ LOGI("[%d] family : %s - %d\n", count++, key.c_str(), setIndex.count); + for (unsigned int i = setIndex.index; i < setIndex.index + setIndex.count; i++) { + const TypefaceSet& tpSet = *(fallbackSet[i]->typefaceSet.get()); -+ SkDEBUGF("[%s] - %d\n", fallbackSet[i]->familyName.c_str(), static_cast(tpSet.size())); ++ LOGI("[%s] - %d\n", fallbackSet[i]->familyName.c_str(), static_cast(tpSet.size())); + + for (unsigned int j = 0; j < tpSet.size(); j++) { + const FontInfo* font = tpSet[j]->getFontInfo(); + if (font) { + this->dumpFont(*font); + } else { -+ SkDEBUGF("font [%d] is null\n", j); ++ LOGE("font [%d] is null\n", j); + } + } + } @@ -1659,7 +1596,7 @@ index 0000000000..2dfc1348c1 + return logErrInfo(ERROR_CONFIG_MISSING_TAG, "alias"); + } + // "adjust", "variation" - optional -+ const char* tags[] = {"alias", "adjust", "variations", "index"}; ++ const char* tags[] = {"alias", "adjust", "font-variations", "index"}; + std::vector aliasSet; + std::vector adjustSet; + std::vector variationSet; @@ -1824,7 +1761,7 @@ index 0000000000..2dfc1348c1 + bool hasIndex = false; + bool hasVariations = false; + for (unsigned int i = 0; i < members.size(); i++) { -+ if (members[i] == "variations") { ++ if (members[i] == "font-variations") { + hasVariations = true; + } else if (members[i] == "index") { + hasIndex = true; @@ -1842,7 +1779,7 @@ index 0000000000..2dfc1348c1 + SkString lang = SkString(key); + SkString familyName = SkString(root[key].asCString()); + if (hasVariations) { -+ key = "variations"; ++ key = "font-variations"; + if (root[key].isArray()) { + const Json::Value& varArr = root[key]; + std::vector variationSet; @@ -1850,7 +1787,7 @@ index 0000000000..2dfc1348c1 + if (varArr[i].isObject()) { + parseVariation(varArr[i], variationSet); + } else { -+ SkString text = SkString("variations#"); ++ SkString text = SkString("font-variations#"); + text.appendU32(i + 1); + (void) logErrInfo(ERROR_CONFIG_INVALID_VALUE_TYPE, text.c_str(), + Json::objectValue, varArr[i].type()); @@ -1881,7 +1818,7 @@ index 0000000000..2dfc1348c1 + return NO_ERROR; +} + -+/*! To parse an item of 'variations' attribute ++/*! To parse an item of 'font-variations' attribute + * \param root the root node of an item in 'variations' list + * \param[out] variationSet the value of VariationInfo is written to and returned to the caller + * \return NO_ERROR successful @@ -1960,7 +1897,7 @@ index 0000000000..2dfc1348c1 + if (root.size() != keyCount) { + text.appendf("%s#0", key); + errSet.emplace_back(ret, text.c_str()); -+ SkDEBUGF("%s : '%s' size should be 2, but here it's %d\n", errToString(ret), key, root.size()); ++ LOGE("%s : '%s' size should be 2, but here it's %d\n", errToString(ret), key, root.size()); + return ret; + } else if (!root[0].isString()) { + text.appendf("%s#1", key); @@ -2106,7 +2043,7 @@ index 0000000000..2dfc1348c1 + } else { + err = ERROR_FONT_INVALID_STREAM; + } -+ SkDEBUGF("%s : %s\n", errToString(err), fname); ++ LOGE("%s : %s\n", errToString(err), fname); + char* fnameCopy = strdup(fname); + errSet.emplace_back(err, basename(fnameCopy)); + free(fnameCopy); @@ -2358,7 +2295,7 @@ index 0000000000..2dfc1348c1 +{ + errSet.emplace_back(err, key); + if (err != ERROR_CONFIG_INVALID_VALUE_TYPE) { -+ SkDEBUGF("%s : %s\n", errToString(err), key); ++ LOGE("%s : %s\n", errToString(err), key); + } else { + const char* types[] = { + "null", @@ -2373,10 +2310,10 @@ index 0000000000..2dfc1348c1 + int size = sizeof(types) / sizeof(char*); + if ((expected >= 0 && expected < size) && + (actual >= 0 && actual < size)) { -+ SkDEBUGF("%s : '%s' should be '%s', but here it's '%s'\n", ++ LOGE("%s : '%s' should be '%s', but here it's '%s'\n", + errToString(err), key, types[expected], types[actual]); + } else { -+ SkDEBUGF("%s : %s\n", errToString(err), key); ++ LOGE("%s : %s\n", errToString(err), key); + } + } + return err; @@ -2449,10 +2386,10 @@ index 0000000000..2dfc1348c1 +} diff --git a/src/ports/skia_ohos/FontConfig_ohos.h b/src/ports/skia_ohos/FontConfig_ohos.h new file mode 100644 -index 0000000000..edd2c51495 +index 0000000000..d23dc47c44 --- /dev/null +++ b/src/ports/skia_ohos/FontConfig_ohos.h -@@ -0,0 +1,217 @@ +@@ -0,0 +1,234 @@ +// Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -2473,6 +2410,23 @@ index 0000000000..edd2c51495 +#include "FontInfo_ohos.h" +#include "SkTypeface_ohos.h" + ++#ifdef ENABLE_DEBUG ++ ++#define LOGE(fmt, args...) \ ++ printf("E %s:%d %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args) ++#define LOGI(fmt, args...) \ ++ printf("I %s:%d - " fmt, __FUNCTION__, __LINE__, ##args) ++#define LOGW(fmt, args...) \ ++ printf("W %s:%d %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args) ++ ++#else ++ ++#define LOGE SkDEBUGF ++#define LOGI SkDEBUGF ++#define LOGW SkDEBUGF ++ ++#endif ++ +struct FontInfo; +struct FallbackInfo; +struct GenericFamily; @@ -2821,9 +2775,15 @@ index 0000000000..0b851ae3fa +}; + +#endif /* FONTINFO_OHOS_H */ +diff --git a/src/ports/skia_ohos/HmSymbolConfig_ohos.cpp b/src/ports/skia_ohos/HmSymbolConfig_ohos.cpp +new file mode 100644 +index 0000000000..e69de29bb2 +diff --git a/src/ports/skia_ohos/HmSymbolConfig_ohos.h b/src/ports/skia_ohos/HmSymbolConfig_ohos.h +new file mode 100644 +index 0000000000..e69de29bb2 diff --git a/src/ports/skia_ohos/SkFontMgr_ohos.cpp b/src/ports/skia_ohos/SkFontMgr_ohos.cpp new file mode 100644 -index 0000000000..a18757d5d5 +index 0000000000..029d105ebc --- /dev/null +++ b/src/ports/skia_ohos/SkFontMgr_ohos.cpp @@ -0,0 +1,437 @@ @@ -2964,7 +2924,7 @@ index 0000000000..a18757d5d5 + } + } + if (item == nullptr) { -+ SkDEBUGF("%s : '%s' must be a fallback key in the config file\n", ++ LOGE("%s : '%s' must be a fallback key in the config file\n", + FontConfig_OHOS::errToString(ERROR_FAMILY_NOT_FOUND), defaultFamily.c_str()); + return nullptr; + } @@ -3182,7 +3142,7 @@ index 0000000000..a18757d5d5 + + std::unique_ptr stream = SkStreamAsset::MakeFromFile(path); + if (stream == nullptr) { -+ SkDEBUGF("%s : %s\n", FontConfig_OHOS::errToString(ERROR_FONT_NOT_EXIST), path); ++ LOGE("%s : %s\n", FontConfig_OHOS::errToString(ERROR_FONT_NOT_EXIST), path); + return nullptr; + } + SkFontArguments args; @@ -3209,7 +3169,7 @@ index 0000000000..a18757d5d5 + if (typeface) { + return sk_sp(typeface); + } -+ SkDEBUGF("%s\n", FontConfig_OHOS::errToString(ERROR_NO_AVAILABLE_FAMILY)); ++ LOGE("%s\n", FontConfig_OHOS::errToString(ERROR_NO_AVAILABLE_FAMILY)); + return nullptr; +} + @@ -3233,14 +3193,14 @@ index 0000000000..a18757d5d5 + if (axisCount == 0) { + if (!fontScanner.scanFont(stream.get(), ttcIndex, &fontInfo.familyName, &fontInfo.style, + &fontInfo.isFixedWidth, nullptr)) { -+ SkDEBUGF("%s\n", FontConfig_OHOS::errToString(ERROR_FONT_INVALID_STREAM)); ++ LOGE("%s\n", FontConfig_OHOS::errToString(ERROR_FONT_INVALID_STREAM)); + return nullptr; + } + } else { + AxisDefinitions axisDef; + if (!fontScanner.scanFont(stream.get(), ttcIndex, &fontInfo.familyName, &fontInfo.style, + &fontInfo.isFixedWidth, &axisDef)) { -+ SkDEBUGF("%s\n", FontConfig_OHOS::errToString(ERROR_FONT_INVALID_STREAM)); ++ LOGE("%s\n", FontConfig_OHOS::errToString(ERROR_FONT_INVALID_STREAM)); + return nullptr; + } + if (axisDef.size() > 0) { @@ -3507,10 +3467,10 @@ index 0000000000..b9fb40cf1e +#endif /* SKFONTSTYLESET_OHOS_H */ diff --git a/src/ports/skia_ohos/SkTypeface_ohos.cpp b/src/ports/skia_ohos/SkTypeface_ohos.cpp new file mode 100644 -index 0000000000..05d3d56d1b +index 0000000000..3141944c32 --- /dev/null +++ b/src/ports/skia_ohos/SkTypeface_ohos.cpp -@@ -0,0 +1,165 @@ +@@ -0,0 +1,139 @@ +// Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -3521,29 +3481,6 @@ index 0000000000..05d3d56d1b +#include "SkFontHost_FreeType_common.h" +#include "SkTArray.h" + -+#if ENABLE_DEBUG -+/*! To print out the font information -+ * \param font the font object to be printed -+ */ -+void DumpFont(const FontInfo& font) const -+{ -+ SkDEBUGF("name=%s, family=%s, weight=%d, width=%d, slant=%d, index=%d", -+ font.fname.c_str(), font.familyName.c_str(), font.style.weight(), font.style.width(), font.style.slant(), -+ font.index); -+ int count = font.axisSet.axis.size(); -+ if (count > 0) { -+ SkString str; -+ for (unsigned int i = 0; i < count; i++) { -+ str.appendU32(SkFixedFloorToInt(font.axisSet.axis[i])); -+ if (i < count - 1) { -+ str.append(","); -+ } -+ } -+ SkDEBUGF("axis={%s}\n", str.c_str()); -+ } -+} -+#endif -+ +/*! Constructor + * \param familyName the specified family name for the typeface + * \param info the font information for the typeface @@ -3600,9 +3537,6 @@ index 0000000000..05d3d56d1b + if (fontInfo->stream.get() == nullptr) { + return nullptr; + } -+#if ENABLE_DEBUG -+ DumpFont(*fontInfo); -+#endif + return std::make_unique(fontInfo->stream->duplicate(), fontInfo->index, 0, + fontInfo->axisSet.axis.data(), fontInfo->axisSet.axis.size(), nullptr, 0); +} @@ -3718,10 +3652,10 @@ index 0000000000..f80e920de0 +#endif /* SKTYPEFACE_OHOS_H */ diff --git a/src/ports/skia_ohos/config/fontconfig.json b/src/ports/skia_ohos/config/fontconfig.json new file mode 100644 -index 0000000000..ec225a188e +index 0000000000..2c5458bc6b --- /dev/null +++ b/src/ports/skia_ohos/config/fontconfig.json -@@ -0,0 +1,76 @@ +@@ -0,0 +1,1373 @@ +{ + "fontdir": ["/system/fonts/"], + "generic": [ @@ -3757,6 +3691,26 @@ index 0000000000..ec225a188e + { + "weight": 200, "to": 900 + } ++ ], ++ "font-variations": [ ++ { ++ "weight": 100, "wght": 100 ++ }, ++ { ++ "weight": 300, "wght": 247 ++ }, ++ { ++ "weight": 400, "wght": 400 ++ }, ++ { ++ "weight": 500, "wght": 500 ++ }, ++ { ++ "weight": 700, "wght": 706 ++ }, ++ { ++ "weight": 900, "wght": 844 ++ } + ] + }, + { @@ -3765,6 +3719,26 @@ index 0000000000..ec225a188e + { + "HarmonyOS-Sans-Condensed": 0 + } ++ ], ++ "font-variations": [ ++ { ++ "weight": 100, "wght": 100 ++ }, ++ { ++ "weight": 300, "wght": 247 ++ }, ++ { ++ "weight": 400, "wght": 400 ++ }, ++ { ++ "weight": 500, "wght": 500 ++ }, ++ { ++ "weight": 700, "wght": 706 ++ }, ++ { ++ "weight": 900, "wght": 844 ++ } + ] + }, + { @@ -3774,27 +3748,1284 @@ index 0000000000..ec225a188e + "HarmonyOS-Sans-Digit": 0 + } + ] ++ }, ++ { ++ "family": "Noto Serif", ++ "alias": [ ++ { ++ "serif": 0 ++ } ++ ] ++ }, ++ { ++ "family": "Noto Sans Mono", ++ "alias": [ ++ { ++ "monospace": 400 ++ } ++ ] + } + ], + "fallback": [ + { + "": [ + { -+ "zh-Hans": "HarmonyOS Sans SC" ++ "und-Zsye": "HMOS Color Emoji" + }, + { -+ "zh-Hant": "HarmonyOS Sans TC" ++ "": "Noto Sans" + }, + { ++ "font-variations": [ ++ { ++ "weight": 100, "wght": 100 ++ }, ++ { ++ "weight": 300, "wght": 247 ++ }, ++ { ++ "weight": 400, "wght": 400 ++ }, ++ { ++ "weight": 500, "wght": 500 ++ }, ++ { ++ "weight": 700, "wght": 706 ++ }, ++ { ++ "weight": 900, "wght": 844 ++ } ++ ], + "und-Arab": "HarmonyOS Sans Naskh Arabic UI" + }, + { -+ "ja": "Noto Sans JP" ++ "und-Ethi": "Noto Sans Ethiopic" + }, + { -+ "ko": "Noto Sans KR" -+ } -+ ] ++ "und-Hebr": "Noto Sans Hebrew" ++ }, ++ { ++ "und-Thai": "Noto Sans Thai" ++ }, ++ { ++ "und-Armn": "Noto Sans Armenian" ++ }, ++ { ++ "und-Geor,und-Geok": "Noto Sans Georgian" ++ }, ++ { ++ "und-Deva": "Noto Sans Devanagari" ++ }, ++ { ++ "und-Gujr": "Noto Sans Gujarati" ++ }, ++ { ++ "und-Guru": "Noto Sans Gurmukhi" ++ }, ++ { ++ "und-Taml": "Noto Sans Tamil" ++ }, ++ { ++ "und-Mlym": "Noto Sans Malayalam" ++ }, ++ { ++ "und-Beng": "Noto Sans Bengali" ++ }, ++ { ++ "und-Telu": "Noto Sans Telugu" ++ }, ++ { ++ "und-Knda": "Noto Sans Kannada" ++ }, ++ { ++ "und-Orya": "Noto Sans Oriya" ++ }, ++ { ++ "und-Sinh": "Noto Sans Sinhala" ++ }, ++ { ++ "und-Khmr": "Noto Sans Khmer" ++ }, ++ { ++ "und-Laoo": "Noto Sans Lao" ++ }, ++ { ++ "und-Mymr": "Noto Sans Myanmar" ++ }, ++ { ++ "und-Thaa": "Noto Sans Thaana" ++ }, ++ { ++ "und-Cham": "Noto Sans Cham" ++ }, ++ { ++ "und-Ahom": "Noto Serif Ahom" ++ }, ++ { ++ "und-Adlm": "Noto Sans Adlam" ++ }, ++ { ++ "und-Avst": "Noto Sans Avestan" ++ }, ++ { ++ "und-Bali": "Noto Sans Balinese" ++ }, ++ { ++ "und-Bamu": "Noto Sans Bamum" ++ }, ++ { ++ "und-Batk": "Noto Sans Batak" ++ }, ++ { ++ "und-Brah": "Noto Sans Brahmi" ++ }, ++ { ++ "und-Bugi": "Noto Sans Buginese" ++ }, ++ { ++ "und-Buhd": "Noto Sans Buhid" ++ }, ++ { ++ "und-Cans": "Noto Sans Canadian Aboriginal" ++ }, ++ { ++ "und-Cari": "Noto Sans Carian" ++ }, ++ { ++ "und-Cakm": "Noto Sans Chakma" ++ }, ++ { ++ "und-Cher": "Noto Sans Cherokee" ++ }, ++ { ++ "und-Copt": "Noto Sans Coptic" ++ }, ++ { ++ "und-Xsux": "Noto Sans Cuneiform" ++ }, ++ { ++ "und-Cprt": "Noto Sans Cypriot" ++ }, ++ { ++ "und-Dsrt": "Noto Sans Deseret" ++ }, ++ { ++ "und-Egyp": "Noto Sans Egyptian Hieroglyphs" ++ }, ++ { ++ "und-Elba": "Noto Sans Elbasan" ++ }, ++ { ++ "und-Glag": "Noto Sans Glagolitic" ++ }, ++ { ++ "und-Goth": "Noto Sans Gothic" ++ }, ++ { ++ "und-Hano": "Noto Sans Hanunoo" ++ }, ++ { ++ "und-Armi": "Noto Sans Imperial Aramaic" ++ }, ++ { ++ "und-Phli": "Noto Sans Inscriptional Pahlavi" ++ }, ++ { ++ "und-Prti": "Noto Sans Inscriptional Parthian" ++ }, ++ { ++ "und-Java": "Noto Sans Javanese" ++ }, ++ { ++ "und-Kthi": "Noto Sans Kaithi" ++ }, ++ { ++ "und-Kali": "Noto Sans Kayah Li" ++ }, ++ { ++ "und-Khar": "Noto Sans Kharoshthi" ++ }, ++ { ++ "und-Lepc": "Noto Sans Lepcha" ++ }, ++ { ++ "und-Limb": "Noto Sans Limbu" ++ }, ++ { ++ "und-Linb": "Noto Sans Linear B" ++ }, ++ { ++ "und-Lisu": "Noto Sans Lisu" ++ }, ++ { ++ "und-Lyci": "Noto Sans Lycian" ++ }, ++ { ++ "und-Lydi": "Noto Sans Lydian" ++ }, ++ { ++ "und-Mand": "Noto Sans Mandaic" ++ }, ++ { ++ "und-Mtei": "Noto Sans Meetei Mayek" ++ }, ++ { ++ "und-Talu": "Noto Sans New Tai Lue" ++ }, ++ { ++ "und-Nkoo": "Noto Sans NKo" ++ }, ++ { ++ "und-Ogam": "Noto Sans Ogham" ++ }, ++ { ++ "und-Olck": "Noto Sans Ol Chiki" ++ }, ++ { ++ "und-Ital": "Noto Sans Old Italic" ++ }, ++ { ++ "und-Xpeo": "Noto Sans Old Persian" ++ }, ++ { ++ "und-Sarb": "Noto Sans Old South Arabian" ++ }, ++ { ++ "und-Orkh": "Noto Sans Old Turkic" ++ }, ++ { ++ "und-Osge": "Noto Sans Osage" ++ }, ++ { ++ "und-Osma": "Noto Sans Osmanya" ++ }, ++ { ++ "und-Phnx": "Noto Sans Phoenician" ++ }, ++ { ++ "und-Rjng": "Noto Sans Rejang" ++ }, ++ { ++ "und-Runr": "Noto Sans Runic" ++ }, ++ { ++ "und-Samr": "Noto Sans Samaritan" ++ }, ++ { ++ "und-Saur": "Noto Sans Saurashtra" ++ }, ++ { ++ "und-Shaw": "Noto Sans Shavian" ++ }, ++ { ++ "und-Sund": "Noto Sans Sundanese" ++ }, ++ { ++ "und-Sylo": "Noto Sans Syloti Nagri" ++ }, ++ { ++ "und-Syrn": "Noto Sans Syriac Eastern" ++ }, ++ { ++ "und-Syrj": "Noto Sans Syriac Western" ++ }, ++ { ++ "und-Tglg": "Noto Sans Tagalog" ++ }, ++ { ++ "und-Tagb": "Noto Sans Tagbanwa" ++ }, ++ { ++ "und-Lana": "Noto Sans Tai Tham" ++ }, ++ { ++ "und-Tavt": "Noto Sans Tai Viet" ++ }, ++ { ++ "und-Tibt": "Noto Serif Tibetan" ++ }, ++ { ++ "und-Tfng": "Noto Sans Tifinagh" ++ }, ++ { ++ "und-Ugar": "Noto Sans Ugaritic" ++ }, ++ { ++ "und-Vaii": "Noto Sans Vai" ++ }, ++ { ++ "font-variations": [ ++ { ++ "weight": 100, "wght": 100 ++ }, ++ { ++ "weight": 300, "wght": 247 ++ }, ++ { ++ "weight": 400, "wght": 400 ++ }, ++ { ++ "weight": 500, "wght": 500 ++ }, ++ { ++ "weight": 600, "wght": 603 ++ }, ++ { ++ "weight": 700, "wght": 706 ++ }, ++ { ++ "weight": 900, "wght": 844 ++ } ++ ], ++ "zh-Hans": "HarmonyOS Sans SC" ++ }, ++ { ++ "font-variations": [ ++ { ++ "weight": 100, "wght": 100 ++ }, ++ { ++ "weight": 300, "wght": 247 ++ }, ++ { ++ "weight": 400, "wght": 400 ++ }, ++ { ++ "weight": 500, "wght": 500 ++ }, ++ { ++ "weight": 700, "wght": 706 ++ }, ++ { ++ "weight": 900, "wght": 844 ++ } ++ ], ++ "zh-Hant": "HarmonyOS Sans TC" ++ }, ++ { ++ "ja": "Noto Sans CJK JP" ++ }, ++ { ++ "ko": "Noto Sans CJK JP" ++ }, ++ { ++ "und-Zsye": "HMOS Color Emoji Flags" ++ }, ++ { ++ "und-Zsym": "Noto Sans Symbols" ++ }, ++ { ++ "und-Zsym": "Noto Sans Symbols 2" ++ }, ++ { ++ "und-Tale": "Noto Sans Tai Le" ++ }, ++ { ++ "und-Yiii": "Noto Sans Yi" ++ }, ++ { ++ "und-Mong": "Noto Sans Mongolian" ++ }, ++ { ++ "und-Phag": "Noto Sans Phags-Pa" ++ }, ++ { ++ "und-Hluw": "Noto Sans Anatolian Hieroglyphs" ++ }, ++ { ++ "und-Bass": "Noto Sans Bassa Vah" ++ }, ++ { ++ "und-Bhks": "Noto Sans Bhaiksuki" ++ }, ++ { ++ "und-Hatr": "Noto Sans Hatran" ++ }, ++ { ++ "und-Lina": "Noto Sans Linear A" ++ }, ++ { ++ "und-Mani": "Noto Sans Manichaean" ++ }, ++ { ++ "und-Marc": "Noto Sans Marchen" ++ }, ++ { ++ "und-Merc": "Noto Sans Meroitic" ++ }, ++ { ++ "und-Plrd": "Noto Sans Miao" ++ }, ++ { ++ "und-Mroo": "Noto Sans Mro" ++ }, ++ { ++ "und-Mult": "Noto Sans Multani" ++ }, ++ { ++ "und-Nbat": "Noto Sans Nabataean" ++ }, ++ { ++ "und-Newa": "Noto Sans Newa" ++ }, ++ { ++ "und-Narb": "Noto Sans Old North Arabian" ++ }, ++ { ++ "und-Perm": "Noto Sans Old Permic" ++ }, ++ { ++ "und-Hmng": "Noto Sans Pahawh Hmong" ++ }, ++ { ++ "und-Palm": "Noto Sans Palmyrene" ++ }, ++ { ++ "und-Pauc": "Noto Sans Pau Cin Hau" ++ }, ++ { ++ "und-Shrd": "Noto Sans Sharada" ++ }, ++ { ++ "und-Sora": "Noto Sans Sora Sompeng" ++ }, ++ { ++ "und-Gong": "Noto Sans Gunjala Gondi" ++ }, ++ { ++ "und-Rohg": "Noto Sans Hanifi Rohingya" ++ }, ++ { ++ "und-Khoj": "Noto Sans Khojki" ++ }, ++ { ++ "und-Gonm": "Noto Sans Masaram Gondi" ++ }, ++ { ++ "und-Wcho": "Noto Sans Wancho" ++ }, ++ { ++ "und-Wara": "Noto Sans Warang Citi" ++ }, ++ { ++ "und-Gran": "Noto Sans Grantha" ++ }, ++ { ++ "und-Modi": "Noto Sans Modi" ++ }, ++ { ++ "und-Dogr": "Noto Serif Dogra" ++ }, ++ { ++ "und-Medf": "Noto Sans Medefaidrin" ++ }, ++ { ++ "und-Soyo": "Noto Sans Soyombo" ++ }, ++ { ++ "und-Takr": "Noto Sans Takri" ++ }, ++ { ++ "und-Yezi": "Noto Serif Yezidi" ++ }, ++ { ++ "und-Zsym": "HM Symbol" ++ }, ++ { ++ "und-Math": "Noto Sans Math" ++ } ++ ] ++ } ++ ], ++ "font_file_map" : [ ++ { ++ "DejaVuMathTeXGyre-Regular": "DejaVuMathTeXGyre.ttf" ++ }, ++ { ++ "FTSymbol": "FTSymbol.ttf" ++ }, ++ { ++ "FTToken": "FTToken.ttf" ++ }, ++ { ++ "FTToken2": "FTToken2.ttf" ++ }, ++ { ++ "FTToken3": "FTToken3.ttf" ++ }, ++ { ++ "FTTokens": "FTTokens.ttf" ++ }, ++ { ++ "方正仿宋-简": "FZFangS-SC.ttf" ++ }, ++ { ++ "FZFangS-SC": "FZFangS-SC.ttf" ++ }, ++ { ++ "方正仿宋-繁": "FZFangS-TC.ttf" ++ }, ++ { ++ "FZFangS-TC": "FZFangS-TC.ttf" ++ }, ++ { ++ "FZHeiT-SC Bold": "FZHeiT-SC-Bold.ttf" ++ }, ++ { ++ "FZHeiT-SC Light": "FZHeiT-SC-Light.ttf" ++ }, ++ { ++ "FZHeiT-SC": "FZHeiT-SC-Regular.ttf" ++ }, ++ { ++ "FZHeiT-TC Bold": "FZHeiT-TC-Bold.ttf" ++ }, ++ { ++ "方正黑體-繁 Bold": "FZHeiT-TC-Bold.ttf" ++ }, ++ { ++ "FZHeiT-TC Light": "FZHeiT-TC-Light.ttf" ++ }, ++ { ++ "方正黑體-繁 Light": "FZHeiT-TC-Light.ttf" ++ }, ++ { ++ "FZHeiT-TC": "FZHeiT-TC-Regular.ttf" ++ }, ++ { ++ "方正黑體-繁": "FZHeiT-TC-Regular.ttf" ++ }, ++ { ++ "方正楷体-简": "FZKaiT-SC.ttf" ++ }, ++ { ++ "FZKaiT-SC": "FZKaiT-SC.ttf" ++ }, ++ { ++ "方正楷體-繁": "FZKaiT-TC.ttf" ++ }, ++ { ++ "FZKaiT-TC": "FZKaiT-TC.ttf" ++ }, ++ { ++ "方正隶体-简": "FZLiT-SC.ttf" ++ }, ++ { ++ "FZLiT-SC": "FZLiT-SC.ttf" ++ }, ++ { ++ "方正隸變-繁": "FZLiB-TC.ttf" ++ }, ++ { ++ "FZLiB-TC": "FZLiB-TC.ttf" ++ }, ++ { ++ "方正隶书-简": "FZLiS-SC.ttf" ++ }, ++ { ++ "FZLiS-SC": "FZLiS-SC.ttf" ++ }, ++ { ++ "方正隸書-繁": "FZLiS-TC.ttf" ++ }, ++ { ++ "FZLiS-TC": "FZLiS-TC.ttf" ++ }, ++ { ++ "方正喵呜-简": "FZMiaoW-SC.ttf" ++ }, ++ { ++ "FZMiaoW-SC": "FZMiaoW-SC.ttf" ++ }, ++ { ++ "方正喵體-繁": "FZMiaoT-TC.ttf" ++ }, ++ { ++ "FZMiaoT-TC": "FZMiaoT-TC.ttf" ++ }, ++ { ++ "方正手书-简": "FZShouS-SC.ttf" ++ }, ++ { ++ "FZShouS-SC": "FZShouS-SC.ttf" ++ }, ++ { ++ "方正手書-繁": "FZShouS-TC.ttf" ++ }, ++ { ++ "FZShouS-TC": "FZShouS-TC.ttf" ++ }, ++ { ++ "方正书宋-简": "FZShuS-SC.ttf" ++ }, ++ { ++ "FZShuS-SC": "FZShuS-SC.ttf" ++ }, ++ { ++ "方正書宋-繁": "FZShuS-TC.ttf" ++ }, ++ { ++ "FZShuS-TC": "FZShuS-TC.ttf" ++ }, ++ { ++ "方正小标宋-简": "FZXiaoBS-SC.ttf" ++ }, ++ { ++ "FZXiaoBS-SC": "FZXiaoBS-SC.ttf" ++ }, ++ { ++ "方正小標宋-繁": "FZXiaoBS-TC.ttf" ++ }, ++ { ++ "FZXiaoBS-TC": "FZXiaoBS-TC.ttf" ++ }, ++ { ++ "方正行楷-简": "FZXingK-SC.ttf" ++ }, ++ { ++ "FZXingK-SC": "FZXingK-SC.ttf" ++ }, ++ { ++ "方正行楷-繁": "FZXingK-TC.ttf" ++ }, ++ { ++ "FZXingK-TC": "FZXingK-TC.ttf" ++ }, ++ { ++ "FZYuanT-SC Bold": "FZYuanT-SC-Bold.ttf" ++ }, ++ { ++ "FZYuanT-SC Light": "FZYuanT-SC-Light.ttf" ++ }, ++ { ++ "FZYuanT-SC": "FZYuanT-SC-Regular.ttf" ++ }, ++ { ++ "FZYuanT-TC Bold": "FZYuanT-TC-Bold.ttf" ++ }, ++ { ++ "方正圓體-繁 Bold": "FZYuanT-TC-Bold.ttf" ++ }, ++ { ++ "FZYuanT-TC Light": "FZYuanT-TC-Light.ttf" ++ }, ++ { ++ "方正圓體-繁 Light": "FZYuanT-TC-Light.ttf" ++ }, ++ { ++ "FZYuanT-TC": "FZYuanT-TC-Regular.ttf" ++ }, ++ { ++ "方正圓體-繁": "FZYuanT-TC-Regular.ttf" ++ }, ++ { ++ "HMOS Color Emoji": "HMOSColorEmojiCompat.ttf" ++ }, ++ { ++ "HMOS Color Emoji Flags": "HMOSColorEmojiFlags.ttf" ++ }, ++ { ++ "HM Symbol Regular": "HMSymbolVF.ttf" ++ }, ++ { ++ "HarmonyOS Sans": "HarmonyOS_Sans.ttf" ++ }, ++ { ++ "HarmonyOS Sans Condensed": "HarmonyOS_Sans_Condensed.ttf" ++ }, ++ { ++ "HarmonyOS Sans Condensed Italic": "HarmonyOS_Sans_Condensed_Italic.ttf" ++ }, ++ { ++ "HarmonyOS Sans Digit": "HarmonyOS_Sans_Digit.ttf" ++ }, ++ { ++ "HarmonyOS Sans Digit": "HarmonyOS_Sans_Digit_Medium.ttf" ++ }, ++ { ++ "HarmonyOS Sans Italic": "HarmonyOS_Sans_Italic.ttf" ++ }, ++ { ++ "HarmonyOS Sans Naskh Arabic": "HarmonyOS_Sans_Naskh_Arabic.ttf" ++ }, ++ { ++ "HarmonyOS Sans Naskh Arabic UI": "HarmonyOS_Sans_Naskh_Arabic_UI.ttf" ++ }, ++ { ++ "HarmonyOS Sans SC": "HarmonyOS_Sans_SC.ttf" ++ }, ++ { ++ "HarmonyOS Sans TC": "HarmonyOS_Sans_TC.ttf" ++ }, ++ { ++ "Noto Sans Adlam Regular": "NotoSansAdlam[wght].ttf" ++ }, ++ { ++ "Noto Sans Anatolian Hieroglyphs Regular": "NotoSansAnatolianHieroglyphs-Regular.ttf" ++ }, ++ { ++ "Noto Sans Armenian Regular": "NotoSansArmenian[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Avestan Regular": "NotoSansAvestan-Regular.ttf" ++ }, ++ { ++ "Noto Sans Balinese Regular": "NotoSansBalinese[wght].ttf" ++ }, ++ { ++ "Noto Sans Bamum Regular": "NotoSansBamum[wght].ttf" ++ }, ++ { ++ "Noto Sans Bassa Vah Regular": "NotoSansBassaVah[wght].ttf" ++ }, ++ { ++ "Noto Sans Batak Regular": "NotoSansBatak-Regular.ttf" ++ }, ++ { ++ "Noto Sans Bengali UI Bold": "NotoSansBengaliUI-Bold.ttf" ++ }, ++ { ++ "Noto Sans Bengali UI Medium": "NotoSansBengaliUI-Medium.ttf" ++ }, ++ { ++ "Noto Sans Bengali UI Regular": "NotoSansBengaliUI-Regular.ttf" ++ }, ++ { ++ "Noto Sans Bengali UI SemiBold": "NotoSansBengaliUI-SemiBold.ttf" ++ }, ++ { ++ "Noto Sans Bengali Regular": "NotoSansBengali[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Bhaiksuki Regular": "NotoSansBhaiksuki-Regular.ttf" ++ }, ++ { ++ "Noto Sans Brahmi Regular": "NotoSansBrahmi-Regular.ttf" ++ }, ++ { ++ "Noto Sans Buginese Regular": "NotoSansBuginese-Regular.ttf" ++ }, ++ { ++ "Noto Sans Buhid Regular": "NotoSansBuhid-Regular.ttf" ++ }, ++ { ++ "Noto Sans CJK JP": "NotoSansCJK-Regular.ttc" ++ }, ++ { ++ "Noto Sans Canadian Aboriginal Regular": "NotoSansCanadianAboriginal[wght].ttf" ++ }, ++ { ++ "Noto Sans Carian Regular": "NotoSansCarian-Regular.ttf" ++ }, ++ { ++ "Noto Sans Chakma Regular": "NotoSansChakma-Regular.ttf" ++ }, ++ { ++ "Noto Sans Cham Regular": "NotoSansCham[wght].ttf" ++ }, ++ { ++ "Noto Sans Cherokee Regular": "NotoSansCherokee[wght].ttf" ++ }, ++ { ++ "Noto Sans Coptic Regular": "NotoSansCoptic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Cuneiform Regular": "NotoSansCuneiform-Regular.ttf" ++ }, ++ { ++ "Noto Sans Cypriot Regular": "NotoSansCypriot-Regular.ttf" ++ }, ++ { ++ "Noto Sans Deseret Regular": "NotoSansDeseret-Regular.ttf" ++ }, ++ { ++ "Noto Sans Devanagari UI Bold": "NotoSansDevanagariUI-Bold.ttf" ++ }, ++ { ++ "Noto Sans Devanagari UI Medium": "NotoSansDevanagariUI-Medium.ttf" ++ }, ++ { ++ "Noto Sans Devanagari UI Regular": "NotoSansDevanagariUI-Regular.ttf" ++ }, ++ { ++ "Noto Sans Devanagari UI SemiBold": "NotoSansDevanagariUI-SemiBold.ttf" ++ }, ++ { ++ "Noto Sans Devanagari Regular": "NotoSansDevanagari[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Egyptian Hieroglyphs Regular": "NotoSansEgyptianHieroglyphs-Regular.ttf" ++ }, ++ { ++ "Noto Sans Elbasan Regular": "NotoSansElbasan-Regular.ttf" ++ }, ++ { ++ "Noto Sans Ethiopic Regular": "NotoSansEthiopic[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Georgian Regular": "NotoSansGeorgian[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Glagolitic Regular": "NotoSansGlagolitic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Gothic Regular": "NotoSansGothic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Grantha Regular": "NotoSansGrantha-Regular.ttf" ++ }, ++ { ++ "Noto Sans Gujarati UI Bold": "NotoSansGujaratiUI-Bold.ttf" ++ }, ++ { ++ "Noto Sans Gujarati UI Regular": "NotoSansGujaratiUI-Regular.ttf" ++ }, ++ { ++ "Noto Sans Gujarati Regular": "NotoSansGujarati[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Gunjala Gondi Regular": "NotoSansGunjalaGondi[wght].ttf" ++ }, ++ { ++ "Noto Sans Gurmukhi UI Bold": "NotoSansGurmukhiUI-Bold.ttf" ++ }, ++ { ++ "Noto Sans Gurmukhi UI Medium": "NotoSansGurmukhiUI-Medium.ttf" ++ }, ++ { ++ "Noto Sans Gurmukhi UI Regular": "NotoSansGurmukhiUI-Regular.ttf" ++ }, ++ { ++ "Noto Sans Gurmukhi UI SemiBold": "NotoSansGurmukhiUI-SemiBold.ttf" ++ }, ++ { ++ "Noto Sans Gurmukhi Regular": "NotoSansGurmukhi[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Hanifi Rohingya Regular": "NotoSansHanifiRohingya[wght].ttf" ++ }, ++ { ++ "Noto Sans Hanunoo Regular": "NotoSansHanunoo-Regular.ttf" ++ }, ++ { ++ "Noto Sans Hatran Regular": "NotoSansHatran-Regular.ttf" ++ }, ++ { ++ "Noto Sans Hebrew Regular": "NotoSansHebrew[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Imperial Aramaic Regular": "NotoSansImperialAramaic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Inscriptional Pahlavi Regular": "NotoSansInscriptionalPahlavi-Regular.ttf" ++ }, ++ { ++ "Noto Sans Inscriptional Parthian Regular": "NotoSansInscriptionalParthian-Regular.ttf" ++ }, ++ { ++ "Noto Sans Javanese Regular": "NotoSansJavanese[wght].ttf" ++ }, ++ { ++ "Noto Sans Kaithi Regular": "NotoSansKaithi-Regular.ttf" ++ }, ++ { ++ "Noto Sans Kannada UI Bold": "NotoSansKannadaUI-Bold.ttf" ++ }, ++ { ++ "Noto Sans Kannada UI Medium": "NotoSansKannadaUI-Medium.ttf" ++ }, ++ { ++ "Noto Sans Kannada UI Regular": "NotoSansKannadaUI-Regular.ttf" ++ }, ++ { ++ "Noto Sans Kannada UI SemiBold": "NotoSansKannadaUI-SemiBold.ttf" ++ }, ++ { ++ "Noto Sans Kannada Regular": "NotoSansKannada[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Kayah Li Regular": "NotoSansKayahLi[wght].ttf" ++ }, ++ { ++ "Noto Sans Kharoshthi Regular": "NotoSansKharoshthi-Regular.ttf" ++ }, ++ { ++ "Noto Sans Khmer Regular": "NotoSansKhmer[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Khojki Regular": "NotoSansKhojki-Regular.ttf" ++ }, ++ { ++ "Noto Sans Lao Regular": "NotoSansLao[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Lepcha Regular": "NotoSansLepcha-Regular.ttf" ++ }, ++ { ++ "Noto Sans Limbu Regular": "NotoSansLimbu-Regular.ttf" ++ }, ++ { ++ "Noto Sans Linear A Regular": "NotoSansLinearA-Regular.ttf" ++ }, ++ { ++ "Noto Sans Linear B Regular": "NotoSansLinearB-Regular.ttf" ++ }, ++ { ++ "Noto Sans Lisu Regular": "NotoSansLisu[wght].ttf" ++ }, ++ { ++ "Noto Sans Lycian Regular": "NotoSansLycian-Regular.ttf" ++ }, ++ { ++ "Noto Sans Lydian Regular": "NotoSansLydian-Regular.ttf" ++ }, ++ { ++ "Noto Sans Malayalam UI Bold": "NotoSansMalayalamUI-Bold.ttf" ++ }, ++ { ++ "Noto Sans Malayalam UI Medium": "NotoSansMalayalamUI-Medium.ttf" ++ }, ++ { ++ "Noto Sans Malayalam UI Regular": "NotoSansMalayalamUI-Regular.ttf" ++ }, ++ { ++ "Noto Sans Malayalam UI SemiBold": "NotoSansMalayalamUI-SemiBold.ttf" ++ }, ++ { ++ "Noto Sans Malayalam Regular": "NotoSansMalayalam[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Mandaic Regular": "NotoSansMandaic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Manichaean Regular": "NotoSansManichaean-Regular.ttf" ++ }, ++ { ++ "Noto Sans Marchen Regular": "NotoSansMarchen-Regular.ttf" ++ }, ++ { ++ "Noto Sans Masaram Gondi Regular": "NotoSansMasaramGondi-Regular.ttf" ++ }, ++ { ++ "Noto Sans Medefaidrin Regular": "NotoSansMedefaidrin[wght].ttf" ++ }, ++ { ++ "Noto Sans Meetei Mayek Regular": "NotoSansMeeteiMayek[wght].ttf" ++ }, ++ { ++ "Noto Sans Meroitic Regular": "NotoSansMeroitic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Miao Regular": "NotoSansMiao-Regular.ttf" ++ }, ++ { ++ "Noto Sans Modi Regular": "NotoSansModi-Regular.ttf" ++ }, ++ { ++ "Noto Sans Mongolian Regular": "NotoSansMongolian-Regular.ttf" ++ }, ++ { ++ "Noto Sans Mono Regular": "NotoSansMono[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Mro Regular": "NotoSansMro-Regular.ttf" ++ }, ++ { ++ "Noto Sans Multani Regular": "NotoSansMultani-Regular.ttf" ++ }, ++ { ++ "Noto Sans Myanmar Regular": "NotoSansMyanmar[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans NKo Regular": "NotoSansNKo-Regular.ttf" ++ }, ++ { ++ "Noto Sans Nabataean Regular": "NotoSansNabataean-Regular.ttf" ++ }, ++ { ++ "Noto Sans New Tai Lue Regular": "NotoSansNewTaiLue[wght].ttf" ++ }, ++ { ++ "Noto Sans Newa Regular": "NotoSansNewa-Regular.ttf" ++ }, ++ { ++ "Noto Sans Ogham Regular": "NotoSansOgham-Regular.ttf" ++ }, ++ { ++ "Noto Sans Ol Chiki Regular": "NotoSansOlChiki[wght].ttf" ++ }, ++ { ++ "Noto Sans Old Italic Regular": "NotoSansOldItalic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Old North Arabian Regular": "NotoSansOldNorthArabian-Regular.ttf" ++ }, ++ { ++ "Noto Sans Old Permic Regular": "NotoSansOldPermic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Old Persian Regular": "NotoSansOldPersian-Regular.ttf" ++ }, ++ { ++ "Noto Sans Old South Arabian Regular": "NotoSansOldSouthArabian-Regular.ttf" ++ }, ++ { ++ "Noto Sans Old Turkic Regular": "NotoSansOldTurkic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Oriya Regular": "NotoSansOriya[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Osage Regular": "NotoSansOsage-Regular.ttf" ++ }, ++ { ++ "Noto Sans Osmanya Regular": "NotoSansOsmanya-Regular.ttf" ++ }, ++ { ++ "Noto Sans Pahawh Hmong Regular": "NotoSansPahawhHmong-Regular.ttf" ++ }, ++ { ++ "Noto Sans Palmyrene Regular": "NotoSansPalmyrene-Regular.ttf" ++ }, ++ { ++ "Noto Sans Pau Cin Hau Regular": "NotoSansPauCinHau-Regular.ttf" ++ }, ++ { ++ "Noto Sans Phags-Pa Regular": "NotoSansPhags-Pa-Regular.ttf" ++ }, ++ { ++ "Noto Sans Phoenician Regular": "NotoSansPhoenician-Regular.ttf" ++ }, ++ { ++ "Noto Sans Rejang Regular": "NotoSansRejang-Regular.ttf" ++ }, ++ { ++ "Noto Sans Runic Regular": "NotoSansRunic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Samaritan Regular": "NotoSansSamaritan-Regular.ttf" ++ }, ++ { ++ "Noto Sans Saurashtra Regular": "NotoSansSaurashtra-Regular.ttf" ++ }, ++ { ++ "Noto Sans Sharada Regular": "NotoSansSharada-Regular.ttf" ++ }, ++ { ++ "Noto Sans Shavian Regular": "NotoSansShavian-Regular.ttf" ++ }, ++ { ++ "Noto Sans Sinhala UI Bold": "NotoSansSinhalaUI-Bold.ttf" ++ }, ++ { ++ "Noto Sans Sinhala UI Medium": "NotoSansSinhalaUI-Medium.ttf" ++ }, ++ { ++ "Noto Sans Sinhala UI Regular": "NotoSansSinhalaUI-Regular.ttf" ++ }, ++ { ++ "Noto Sans Sinhala UI SemiBold": "NotoSansSinhalaUI-SemiBold.ttf" ++ }, ++ { ++ "Noto Sans Sinhala Regular": "NotoSansSinhala[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Sora Sompeng Regular": "NotoSansSoraSompeng[wght].ttf" ++ }, ++ { ++ "Noto Sans Soyombo Regular": "NotoSansSoyombo-Regular.ttf" ++ }, ++ { ++ "Noto Sans Sundanese Regular": "NotoSansSundanese[wght].ttf" ++ }, ++ { ++ "Noto Sans Syloti Nagri Regular": "NotoSansSylotiNagri-Regular.ttf" ++ }, ++ { ++ "Noto Sans Symbols Regular": "NotoSansSymbols-Regular.ttf" ++ }, ++ { ++ "Noto Sans Symbols 2 Regular": "NotoSansSymbols2-Regular.ttf" ++ }, ++ { ++ "Noto Sans Syriac Eastern Regular": "NotoSansSyriacEastern[wght].ttf" ++ }, ++ { ++ "Noto Sans Syriac Western Regular": "NotoSansSyriacWestern[wght].ttf" ++ }, ++ { ++ "Noto Sans Tagalog Regular": "NotoSansTagalog-Regular.ttf" ++ }, ++ { ++ "Noto Sans Tagbanwa Regular": "NotoSansTagbanwa-Regular.ttf" ++ }, ++ { ++ "Noto Sans Tai Le Regular": "NotoSansTaiLe-Regular.ttf" ++ }, ++ { ++ "Noto Sans Tai Tham Regular": "NotoSansTaiTham[wght].ttf" ++ }, ++ { ++ "Noto Sans Tai Viet Regular": "NotoSansTaiViet-Regular.ttf" ++ }, ++ { ++ "Noto Sans Takri Regular": "NotoSansTakri-Regular.ttf" ++ }, ++ { ++ "Noto Sans Tamil UI Bold": "NotoSansTamilUI-Bold.ttf" ++ }, ++ { ++ "Noto Sans Tamil UI Medium": "NotoSansTamilUI-Medium.ttf" ++ }, ++ { ++ "Noto Sans Tamil UI Regular": "NotoSansTamilUI-Regular.ttf" ++ }, ++ { ++ "Noto Sans Tamil UI SemiBold": "NotoSansTamilUI-SemiBold.ttf" ++ }, ++ { ++ "Noto Sans Tamil Regular": "NotoSansTamil[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Telugu UI Bold": "NotoSansTeluguUI-Bold.ttf" ++ }, ++ { ++ "Noto Sans Telugu UI Medium": "NotoSansTeluguUI-Medium.ttf" ++ }, ++ { ++ "Noto Sans Telugu UI Regular": "NotoSansTeluguUI-Regular.ttf" ++ }, ++ { ++ "Noto Sans Telugu UI SemiBold": "NotoSansTeluguUI-SemiBold.ttf" ++ }, ++ { ++ "Noto Sans Telugu Regular": "NotoSansTelugu[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Thaana Regular": "NotoSansThaana[wght].ttf" ++ }, ++ { ++ "Noto Sans Thai Regular": "NotoSansThai[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Tifinagh Regular": "NotoSansTifinagh-Regular.ttf" ++ }, ++ { ++ "Noto Sans Ugaritic Regular": "NotoSansUgaritic-Regular.ttf" ++ }, ++ { ++ "Noto Sans Vai Regular": "NotoSansVai-Regular.ttf" ++ }, ++ { ++ "Noto Sans Wancho Regular": "NotoSansWancho-Regular.ttf" ++ }, ++ { ++ "Noto Sans Warang Citi Regular": "NotoSansWarangCiti-Regular.ttf" ++ }, ++ { ++ "Noto Sans Yi Regular": "NotoSansYi-Regular.ttf" ++ }, ++ { ++ "Noto Sans Regular": "NotoSans[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Ahom Regular": "NotoSerifAhom-Regular.ttf" ++ }, ++ { ++ "Noto Serif Armenian Regular": "NotoSerifArmenian[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Bengali Regular": "NotoSerifBengali[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif CJK JP": "NotoSerifCJK-Regular.ttc" ++ }, ++ { ++ "Noto Serif Devanagari Regular": "NotoSerifDevanagari[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Dogra Regular": "NotoSerifDogra-Regular.ttf" ++ }, ++ { ++ "Noto Serif Ethiopic Regular": "NotoSerifEthiopic[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Georgian Regular": "NotoSerifGeorgian[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Gujarati Regular": "NotoSerifGujarati[wght].ttf" ++ }, ++ { ++ "Noto Serif Gurmukhi Regular": "NotoSerifGurmukhi[wght].ttf" ++ }, ++ { ++ "Noto Serif Hebrew Regular": "NotoSerifHebrew[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Kannada Regular": "NotoSerifKannada[wght].ttf" ++ }, ++ { ++ "Noto Serif Khmer Regular": "NotoSerifKhmer[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Lao Regular": "NotoSerifLao[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Malayalam Regular": "NotoSerifMalayalam[wght].ttf" ++ }, ++ { ++ "Noto Serif Myanmar Regular": "NotoSerifMyanmar[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Sinhala Regular": "NotoSerifSinhala[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Tamil Regular": "NotoSerifTamil[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Telugu Regular": "NotoSerifTelugu[wght].ttf" ++ }, ++ { ++ "Noto Serif Thai Regular": "NotoSerifThai[wdth,wght].ttf" ++ }, ++ { ++ "Noto Serif Tibetan Regular": "NotoSerifTibetan[wght].ttf" ++ }, ++ { ++ "Noto Serif Yezidi Regular": "NotoSerifYezidi[wght].ttf" ++ }, ++ { ++ "Noto Serif Regular": "NotoSerif[wdth,wght].ttf" ++ }, ++ { ++ "Noto Sans Regular": "Roboto-Regular.ttf" ++ }, ++ { ++ "Noto Sans Math Regular": "NotoSansMath-Regular.ttf" ++ }, ++ { ++ "FangS-SC": "FangS-SC.ttf" ++ }, ++ { ++ "仿宋-简": "FangS-SC.ttf" ++ }, ++ { ++ "FT Thymes Regular": "FTThymes-Regular.ttf" ++ }, ++ { ++ "HeiT-SC": "HeiT-SC-Regular.ttf" ++ }, ++ { ++ "ShuS-SC ": "ShuS-SC.ttf" ++ }, ++ { ++ "书宋-简": "ShuS-SC.ttf" ++ }, ++ { ++ "KaiT-SC": "KaiT-SC.ttf" ++ }, ++ { ++ "楷体-简": "KaiT-SC.ttf" + } + ] +} @@ -3812,6 +5043,3 @@ index fca2f34ded..65955a7041 100644 OutputStream* rawOut = fOut; StringStream body; fOut = &body; --- -2.25.1 - -- Gitee From 62e5e71a67055edc6404289d829d8afea18bddcb Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 16 Dec 2024 10:34:47 +0800 Subject: [PATCH 15/60] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96=E5=9D=90=E6=A0=87?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E7=AE=97=E6=B3=95=E3=80=81=E7=84=A6=E7=82=B9?= =?UTF-8?q?=E7=BB=BF=E6=A1=86=E8=B7=9F=E9=9A=8F=E5=8F=8C=E6=8C=87=E6=BB=91?= =?UTF-8?q?=E5=8A=A8=E3=80=81=E4=BF=AE=E5=A4=8D=E5=A4=9A=E7=B2=92=E5=BA=A6?= =?UTF-8?q?=E5=AD=97=E9=87=8D=E6=98=BE=E7=A4=BA=E3=80=81=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E9=83=A8=E5=88=86=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 --- shell/platform/ohos/BUILD.gn | 6 +- .../ohos_accessibility_bridge.cpp | 522 +++++++++++------- .../accessibility/ohos_accessibility_bridge.h | 39 +- shell/platform/ohos/utils/ohos_utils.cpp | 23 + shell/platform/ohos/utils/ohos_utils.h | 31 ++ 5 files changed, 418 insertions(+), 203 deletions(-) create mode 100644 shell/platform/ohos/utils/ohos_utils.cpp create mode 100644 shell/platform/ohos/utils/ohos_utils.h diff --git a/shell/platform/ohos/BUILD.gn b/shell/platform/ohos/BUILD.gn index 84548cee19..982c45eab5 100644 --- a/shell/platform/ohos/BUILD.gn +++ b/shell/platform/ohos/BUILD.gn @@ -90,7 +90,8 @@ source_set("flutter_ohos_sources") { "./accessibility/ohos_accessibility_manager.h", "./accessibility/native_accessibility_channel.h", "./accessibility/ohos_accessibility_ddl.h", - "./utils/ddl_utils.h" + "./utils/ddl_utils.h", + "./utils/ohos_utils.h" ] #configs += [ "//flutter/shell/platform/ohos/config:gtk" ] @@ -126,7 +127,8 @@ source_set("flutter_ohos_sources") { "./accessibility/ohos_accessibility_features.cpp", "./accessibility/ohos_accessibility_manager.cpp", "./accessibility/native_accessibility_channel.cpp", - "./accessibility/ohos_accessibility_ddl.cpp" + "./accessibility/ohos_accessibility_ddl.cpp", + "./utils/ohos_utils.cpp" ] # Set flag to stop headers being directly included (library users should not do this) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 2b9f261cd9..d250610dac 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -15,6 +15,7 @@ #include "ohos_accessibility_bridge.h" #include #include +#include #include #include #include @@ -91,20 +92,17 @@ void OhosAccessibilityBridge::updateSemantics( flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) { - FML_DLOG(INFO) << ("OhosAccessibilityBridge::UpdateSemantics()"); - + FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics()"; + isFlutterSemanticsTreeUpdated = true; std::vector updatedFlutterNodes; - // 当flutter页面路由更新时,自动请求id=0节点组件获焦(规避滑动组件更新干扰) + // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) if (IS_FLUTTER_NAVIGATE) { + Flutter_SendAccessibilityAsyncEvent(0, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); RequestFocusWhenPageUpdate(0); IS_FLUTTER_NAVIGATE = false; } - // 页面内容更新事件 - Flutter_SendAccessibilityAsyncEvent(0, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); - LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); - /** 获取并分析每个语义节点的更新属性 */ for (auto& item : update) { // 获取当前更新的节点node @@ -140,6 +138,10 @@ void OhosAccessibilityBridge::updateSemantics( } } + // 页面内容更新事件 + Flutter_SendAccessibilityAsyncEvent(0, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); + LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); + /* 针对更新后的节点进行事件处理 */ for (const auto& nodeEx: updatedFlutterNodes) { // 当滑动节点产生滑动,并执行滑动处理 @@ -157,6 +159,11 @@ void OhosAccessibilityBridge::updateSemantics( // flutter滑动组件滑动处理逻辑 FlutterScrollExecution(nodeEx, _elementInfo); + // 屏幕朗读状态下双指滑动,获焦节点绿框实时跟随节点滑动 + Flutter_SendAccessibilityAsyncEvent( + static_cast(accessibilityFocusedNode.id), + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_FOCUS_NODE_UPDATE); + void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { @@ -239,6 +246,15 @@ void OhosAccessibilityBridge::FlutterScrollExecution( } ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetStartItemIndex(elementInfoFromList, startItemIndex)); + // 设置当前获焦节点的当前index + int32_t currItemIndex = accessibilityFocusedNode.id; + int32_t (*OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex"); + if (OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex(elementInfoFromList, currItemIndex)); + // 计算当前滑动位置页面的可见子滑动节点数量 int visibleChildren = 0; // handle hidden children at the beginning and end of the list. @@ -633,7 +649,7 @@ void OhosAccessibilityBridge::FlutterTreeToArkuiTree( int32_t OhosAccessibilityBridge::GetParentId(int64_t elementId) { if (!g_parentChildIdVec.size()) { - FML_DLOG(INFO) << "OhosAccessibilityBridge::GetParentId parentChildIdMap.size()=0"; + FML_DLOG(WARNING) << "OhosAccessibilityBridge::GetParentId parentChildIdMap.size()=0"; return ARKUI_ACCESSIBILITY_ROOT_PARENT_ID; } if (elementId == -1) { @@ -755,11 +771,10 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( newRight > realParentRight || newBottom > realParentBottom || newLeft >= newRight || newTop >= newBottom || newRight > rootWidth || newBottom > rootHeight; - if (IS_OVER_SCREEN_AREA) { - FML_DLOG(ERROR) << "RelativeRectToScreenRect -> childRect exceeds parentRect {Id: " - << currNode.id << ", (" << newLeft << ", " << newTop - << ", " << newRight << ", " << newBottom << ")}"; + FML_DLOG(WARNING) << "RelativeRectToScreenRect -> childRect exceeds parentRect {Id: " + << currNode.id << ", (" << newLeft << ", " << newTop + << ", " << newRight << ", " << newBottom << ")}"; // 防止滑动场景下绿框坐标超出屏幕范围,进行正则化处理 SetAbsoluteScreenRect(currNode, rootWidth, rootHeight, 0, 0); } else { @@ -998,7 +1013,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( actions[9].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_CURSOR_POSITION; actions[9].description = "光标位置设置"; - + ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) ); @@ -1533,6 +1548,282 @@ void OhosAccessibilityBridge::DispatchSemanticsAction( fml::MallocMapping()); } +/** + * flutter按钮节点双击跳转新页面时,发送页面更新事件 + */ +void OhosAccessibilityBridge::DoubleClickRouteToNewPage(SemanticsNodeExtent node) +{ + if (isFlutterSemanticsTreeUpdated && node.HasFlag(FLAGS_::kIsButton)) { + RequestFocusWhenPageUpdate(0); + // isFlutterSemanticsTreeUpdated = false; + } +} + +/** + * perform click action in accessibility status + */ +void OhosAccessibilityBridge::PerformClickAction( + int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode) +{ + /** Click event, sent after the UI component responds. 1 */ + auto clickEventType = ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_CLICKED; + Flutter_SendAccessibilityAsyncEvent(elementId, clickEventType); + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: click(" << action + << ")" << " event: click(" << clickEventType << ")"; + auto flutterTapAction = ArkuiActionsToFlutterActions(action); + DispatchSemanticsAction(static_cast(elementId), flutterTapAction, {}); + // double click at button-like node for pushing page update + DoubleClickRouteToNewPage(flutterNode); +} + +/** + * perform long-press action in accessibility status + */ +void OhosAccessibilityBridge::PerformLongClickAction( + int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode) +{ + /** Long click event, sent after the UI component responds. 2 */ + auto longClickEventType = ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_LONG_CLICKED; + Flutter_SendAccessibilityAsyncEvent(elementId, longClickEventType); + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: longclick(" + << action << ")" << " event: longclick(" + << longClickEventType << ")"; + auto flutterLongPressAction = ArkuiActionsToFlutterActions(action); + DispatchSemanticsAction(static_cast(elementId), flutterLongPressAction, {}); +} + +/** + * perform focus acquisition in accessibility status + */ +void OhosAccessibilityBridge::PerformGainFocusnAction( + int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode) +{ + // 感知获焦flutter节点 + accessibilityFocusedNode = flutterNode; + // 解析arkui的获焦 -> flutter对应节点的获焦 + auto flutterGainFocusAction = ArkuiActionsToFlutterActions(action); + DispatchSemanticsAction(static_cast(elementId), + flutterGainFocusAction, {}); + // Accessibility focus event, sent after the UI component responds. 32768 + auto focusEventType = ArkUI_AccessibilityEventType:: + ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUSED; + Flutter_SendAccessibilityAsyncEvent(elementId, focusEventType); + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: focus(" << action + << ")" << " event: focus(" << focusEventType << ")"; + + if (flutterNode.HasAction(ACTIONS_::kIncrease) || + flutterNode.HasAction(ACTIONS_::kDecrease)) { + Flutter_SendAccessibilityAsyncEvent( + elementId, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); + } +} + +/** + * perform focus clearance in accessibility status + */ +void OhosAccessibilityBridge::PerformClearFocusAction( + int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode) +{ + // 解析arkui的失焦 -> flutter对应节点的失焦 + auto flutterLoseFocusAction = ArkuiActionsToFlutterActions(action); + DispatchSemanticsAction(static_cast(elementId), flutterLoseFocusAction, {}); + /** Accessibility focus cleared event, sent after the UI component + * responds. 65536 */ + auto clearFocusEventType = ArkUI_AccessibilityEventType:: + ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUS_CLEARED; + Flutter_SendAccessibilityAsyncEvent(elementId, clearFocusEventType); + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: clearfocus(" + << action << ")" << " event: clearfocus(" + << clearFocusEventType << ")"; +} + +/** + * perform scroll forward in accessibility status + */ +void OhosAccessibilityBridge::PerformScrollUpAction( + int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode) +{ + // flutter scroll forward with different situations + if (flutterNode.HasAction(ACTIONS_::kScrollUp)) { + auto flutterScrollUpAction = ArkuiActionsToFlutterActions(action); + DispatchSemanticsAction(static_cast(elementId), flutterScrollUpAction, {}); + } else if (flutterNode.HasAction(ACTIONS_::kScrollLeft)) { + DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kScrollLeft, {}); + } else if (flutterNode.HasAction(ACTIONS_::kIncrease)) { + flutterNode.value = flutterNode.increasedValue; + flutterNode.valueAttributes = flutterNode.increasedValueAttributes; + + Flutter_SendAccessibilityAsyncEvent( + elementId, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); + DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kIncrease, {}); + } + std::string currComponetType = GetNodeComponentType(flutterNode); + if (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 scroll backward in accessibility status + */ +void OhosAccessibilityBridge::PerformScrollDownAction( + int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode) +{ + // flutter scroll down with different situations + if (flutterNode.HasAction(ACTIONS_::kScrollDown)) { + auto flutterScrollDownAction = ArkuiActionsToFlutterActions(action); + DispatchSemanticsAction(static_cast(elementId), flutterScrollDownAction, {}); + } else if (flutterNode.HasAction(ACTIONS_::kScrollRight)) { + DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kScrollRight, {}); + } else if (flutterNode.HasAction(ACTIONS_::kDecrease)) { + flutterNode.value = flutterNode.decreasedValue; + flutterNode.valueAttributes = flutterNode.decreasedValueAttributes; + + Flutter_SendAccessibilityAsyncEvent( + elementId, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); + DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kDecrease, {}); + } + std::string currComponetType = GetNodeComponentType(flutterNode); + if (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 + */ +void OhosAccessibilityBridge::PerformClipboardAction( + int64_t elementId, + ArkUI_Accessibility_ActionType action) +{ + if (action == ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY) { + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: copy(" << action << ")"; + DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kCopy, {}); + } else if (action == ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_PASTE) { + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: paste(" << action << ")"; + DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kPaste, {}); + } else { + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: cut(" << action << ")"; + DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kCut, {}); + } +} +/** + * perform invalid action in accessibility status + */ +void OhosAccessibilityBridge::PerformInvalidAction( + int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode) +{ + /** Invalid event. 0 */ + ArkUI_AccessibilityEventType invalidEventType = + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_INVALID; + Flutter_SendAccessibilityAsyncEvent(elementId, invalidEventType); + FML_DLOG(ERROR) << "ExecuteAccessibilityAction -> action: invalid(" + << action << ")" << " event: innvalid(" + << invalidEventType << ")"; +} +/** + * 设置输入框文本 + */ +void OhosAccessibilityBridge::PerformSetText( + SemanticsNodeExtent flutterNode, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments) +{ + if (OH_GetSdkApiVersion() >= 13) { + int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = + OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); + if (OH_ArkUI_FindAccessibilityActionArgumentByKey == nullptr) { + LOGE("OH_ArkUI_FindAccessibilityActionArgumentByKey is null, %{public}s", dlerror()); + } + const char* key_setText = "setText"; + const char* valueStr = flutterNode.value.c_str(); + char* newValue = strdup(valueStr); + char** value = &newValue; + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); + if (newValue == nullptr) { + LOGE("PerformSetText -> OH_ArkUI_FindAccessibilityActionArgumentByKey get null value"); + } + auto flutterSetTextAction = ArkuiActionsToFlutterActions(action); + DispatchSemanticsAction(flutterNode.id, flutterSetTextAction, fml::MallocMapping::Copy(newValue, strlen(newValue))); + flutterNode.value = newValue; + flutterNode.valueAttributes = {}; + LOGI("ExecuteAccessibilityAction -> action: set text(%{public}d), newText=%{public}s", action, newValue); + } +} + +/** + * perform cursor position setting in accessibility status + */ +void OhosAccessibilityBridge::PerformSelectText( + SemanticsNodeExtent flutterNode, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments) +{ + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: select text(" << action << ")"; + return; +} + +/** + * perform cursor position setting in accessibility status + */ +void OhosAccessibilityBridge::PerformSetCursorPosition( + SemanticsNodeExtent flutterNode, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments) +{ + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: set cursor position (" << action << ")"; + return; +} + +/** + * perform custom action in accessibility status + */ +void OhosAccessibilityBridge::PerformCustomAction( + SemanticsNodeExtent flutterNode, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments) +{ + FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: custom action (" << action << ")"; + DispatchSemanticsAction(flutterNode.id, ACTIONS_::kCustomAction, {}); + return; +} + +/** + * perform show on screen action in accessibility status + */ +void OhosAccessibilityBridge::PerformShowOnScreenAction(SemanticsNodeExtent flutterNode) +{ + if (!IsNodeShowOnScreen(flutterNode)) { + DispatchSemanticsAction(flutterNode.id, ACTIONS_::kShowOnScreen, {}); + } +} + /** * 执行语义动作解析,当FindAccessibilityNodeInfosById找到相应的elementinfo时才会触发该回调函数 */ @@ -1543,9 +1834,9 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( int32_t requestId) { FML_DLOG(INFO) << "ExecuteAccessibilityAction input-params-> elementId=" - << elementId << " action=" << action - << " requestId=" << requestId - << " *actionArguments=" << actionArguments; + << elementId << " action=" << action + << " requestId=" << requestId + << " *actionArguments=" << actionArguments; if (actionArguments == nullptr) { FML_DLOG(ERROR) << "OhosAccessibilityBridge::ExecuteAccessibilityAction " @@ -1559,205 +1850,84 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( LOGE("ExecuteAccessibilityAction: GetFlutterSemanticsNode id=%{public}ld is null", elementId); } - // 若当前节点为非屏幕显示状态,将其显示在屏幕上 - if (!IsNodeShowOnScreen(flutterNode)) { - DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kShowOnScreen, {}); - } + /** + * 将被遮挡的flutter节点显示在屏幕上 + * @NOTE: arkui无障碍缺少showOnScreen动作 + */ + PerformShowOnScreenAction(flutterNode); // 根据当前elementid和无障碍动作类型,发送无障碍事件 switch (action) { /** Response to a click. 16 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK: { - /** Click event, sent after the UI component responds. 1 */ - auto clickEventType = ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_CLICKED; - Flutter_SendAccessibilityAsyncEvent(elementId, clickEventType); - FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: click(" << action - << ")" << " event: click(" << clickEventType << ")"; - // 解析arkui的屏幕点击 -> flutter对应节点的屏幕点击 - auto flutterTapAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(static_cast(elementId), flutterTapAction, - {}); + PerformClickAction(elementId, action, flutterNode); break; } /** Response to a long click. 32 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_LONG_CLICK: { - /** Long click event, sent after the UI component responds. 2 */ - auto longClickEventType = ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_LONG_CLICKED; - Flutter_SendAccessibilityAsyncEvent(elementId, longClickEventType); - FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: longclick(" - << action << ")" << " event: longclick(" - << longClickEventType << ")"; - // 解析arkui的屏幕动作 -> flutter对应节点的屏幕动作 - auto flutterLongPressAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(static_cast(elementId), - flutterLongPressAction, {}); + PerformLongClickAction(elementId, action, flutterNode); break; } /** Accessibility focus acquisition. 64 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS: { - // 感知获焦flutter节点 - accessibilityFocusedNode = flutterNode; - // 解析arkui的获焦 -> flutter对应节点的获焦 - auto flutterGainFocusAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(static_cast(elementId), - flutterGainFocusAction, {}); - // Accessibility focus event, sent after the UI component responds. 32768 - auto focusEventType = ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUSED; - Flutter_SendAccessibilityAsyncEvent(elementId, focusEventType); - FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: focus(" << action - << ")" << " event: focus(" << focusEventType << ")"; - - if (flutterNode.HasAction(ACTIONS_::kIncrease) || - flutterNode.HasAction(ACTIONS_::kDecrease)) { - Flutter_SendAccessibilityAsyncEvent( - elementId, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); - } + PerformGainFocusnAction(elementId, action, flutterNode); break; } /** Accessibility focus clearance. 128 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS: { - // 解析arkui的失焦 -> flutter对应节点的失焦 - auto flutterLoseFocusAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(static_cast(elementId), - flutterLoseFocusAction, {}); - /** Accessibility focus cleared event, sent after the UI component - * responds. 65536 */ - auto clearFocusEventType = ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUS_CLEARED; - Flutter_SendAccessibilityAsyncEvent(elementId, clearFocusEventType); - FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: clearfocus(" - << action << ")" << " event: clearfocus(" - << clearFocusEventType << ")"; + PerformClearFocusAction(elementId, action, flutterNode); break; } /** Forward scroll action. 256 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_FORWARD: { - // flutter scroll forward with different situations - if (flutterNode.HasAction(ACTIONS_::kScrollUp)) { - auto flutterScrollUpAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(static_cast(elementId), - flutterScrollUpAction, {}); - } else if (flutterNode.HasAction(ACTIONS_::kScrollLeft)) { - DispatchSemanticsAction(static_cast(elementId), - ACTIONS_::kScrollLeft, {}); - } else if (flutterNode.HasAction(ACTIONS_::kIncrease)) { - flutterNode.value = flutterNode.increasedValue; - flutterNode.valueAttributes = flutterNode.increasedValueAttributes; - - Flutter_SendAccessibilityAsyncEvent( - elementId, ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); - DispatchSemanticsAction(static_cast(elementId), - ACTIONS_::kIncrease, {}); - } - std::string currComponetType = GetNodeComponentType(flutterNode); - if (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 << ")"; - } + PerformScrollUpAction(elementId, action, flutterNode); break; } /** Backward scroll action. 512 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_BACKWARD: { - // flutter scroll down with different situations - if (flutterNode.HasAction(ACTIONS_::kScrollDown)) { - auto flutterScrollDownAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(static_cast(elementId), - flutterScrollDownAction, {}); - } else if (flutterNode.HasAction(ACTIONS_::kScrollRight)) { - DispatchSemanticsAction(static_cast(elementId), - ACTIONS_::kScrollRight, {}); - } else if (flutterNode.HasAction(ACTIONS_::kDecrease)) { - flutterNode.value = flutterNode.decreasedValue; - flutterNode.valueAttributes = flutterNode.decreasedValueAttributes; - - Flutter_SendAccessibilityAsyncEvent( - elementId, ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); - DispatchSemanticsAction(static_cast(elementId), - ACTIONS_::kDecrease, {}); - } - std::string currComponetType = GetNodeComponentType(flutterNode); - if (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 << ")"; - } + PerformScrollDownAction(elementId, action, flutterNode); break; } /** Copy action for text content. 1024 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY: { - FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: copy(" << action - << ")"; - DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kCopy, {}); + PerformClipboardAction(elementId, action); break; } /** Paste action for text content. 2048 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_PASTE: { - FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: paste(" << action - << ")"; - DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kPaste, {}); + PerformClipboardAction(elementId, action); break; } /** Cut action for text content. 4096 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CUT: { - FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: cut(" << action << ")"; - DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kCut, {}); + 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: { - FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: select text(" - << action << ")"; - // 输入框文本选择操作 PerformSelectText(flutterNode, action, actionArguments); break; } /** Text content setting action. 16384 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_TEXT: { - FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: set text(" - << action << ")"; - // 输入框设置文本 PerformSetText(flutterNode, action, actionArguments); break; } /** Cursor position setting action. 1048576 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_CURSOR_POSITION: { - FML_DLOG(INFO) - << "ExecuteAccessibilityAction -> action: set cursor position(" - << action << ")"; + PerformSetCursorPosition(flutterNode, action, actionArguments); break; } /** Invalid action. 0 */ case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_INVALID: { - /** Invalid event. 0 */ - ArkUI_AccessibilityEventType invalidEventType = - ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_INVALID; - Flutter_SendAccessibilityAsyncEvent(elementId, invalidEventType); - FML_DLOG(ERROR) << "ExecuteAccessibilityAction -> action: invalid(" - << action << ")" << " event: innvalid(" - << invalidEventType << ")"; + PerformInvalidAction(elementId, action, flutterNode); break; } default: { /** custom semantics action */ + PerformCustomAction(flutterNode, action, actionArguments); } } FML_DLOG(INFO) << "--- ExecuteAccessibilityAction is end ---"; @@ -1848,9 +2018,6 @@ flutter::SemanticsAction OhosAccessibilityBridge::ArkuiActionsToFlutterActions( ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS: return ACTIONS_::kDidLoseAccessibilityFocus; - // Text selection action, requiring the setting of selectTextBegin, - // TextEnd, and TextInForward parameters to select a text - // segment in the text box. */ case ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SELECT_TEXT: return ACTIONS_::kSetSelection; @@ -1860,7 +2027,7 @@ flutter::SemanticsAction OhosAccessibilityBridge::ArkuiActionsToFlutterActions( return ACTIONS_::kSetText; default: - // might not match to the valid action in arkui + // might not match to the valid action in arkui return ACTIONS_::kCustomAction; } } @@ -1965,45 +2132,6 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( return; } -/** - * 设置输入框文本 - */ -void OhosAccessibilityBridge::PerformSetText( - SemanticsNodeExtent flutterNode, - ArkUI_Accessibility_ActionType action, - ArkUI_AccessibilityActionArguments* actionArguments) -{ - // 获取特殊动作参数 - // int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = - // OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); - // if (OH_ArkUI_FindAccessibilityActionArgumentByKey == nullptr) { - // LOGE("OH_ArkUI_FindAccessibilityActionArgumentByKey is null, %{public}s", dlerror()); - // } - // const char* key_setText = "setText"; - // char* newValue = "debug"; - // char** value = &newValue; - // ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); - // if (newValue == nullptr) { - // // newValue = "888"; - // LOGE("PerformSetText -> OH_ArkUI_FindAccessibilityActionArgumentByKey get null value"); - // } - auto flutterSetTextAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(flutterNode.id, flutterSetTextAction, {}); - flutterNode.value = "debug"; - flutterNode.valueAttributes = {}; -} - -/** - * 设置文本选择范畴 - */ -void OhosAccessibilityBridge::PerformSelectText( - SemanticsNodeExtent flutterNode, - ArkUI_Accessibility_ActionType action, - ArkUI_AccessibilityActionArguments* actionArguments) -{ - return; -} - /** * 获取当前flutter节点的组件类型,并映射为arkui组件 */ diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 445093c0c9..08d196aee1 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -160,6 +160,7 @@ private: std::unordered_map g_actions_mp; std::vector g_flutterNavigationVec; + bool isFlutterSemanticsTreeUpdated = false; SemanticsNodeExtent inputFocusedNode; SemanticsNodeExtent lastInputFocusedNode; SemanticsNodeExtent accessibilityFocusedNode; @@ -262,12 +263,43 @@ private: bool IsTextField(SemanticsNodeExtent flutterNode); bool IsSlider(SemanticsNodeExtent flutterNode); bool IsScrollableWidget(SemanticsNodeExtent flutterNode); + + void PerformClickAction(int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode); + void PerformLongClickAction(int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode); + void PerformGainFocusnAction(int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode); + void PerformClearFocusAction(int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode); + void PerformScrollUpAction(int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode); + void PerformScrollDownAction(int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode); + void PerformClipboardAction(int64_t elementId, + ArkUI_Accessibility_ActionType action); + void PerformInvalidAction(int64_t elementId, + ArkUI_Accessibility_ActionType action, + SemanticsNodeExtent flutterNode); void PerformSetText(SemanticsNodeExtent flutterNode, ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments); void PerformSelectText(SemanticsNodeExtent flutterNode, - ArkUI_Accessibility_ActionType action, - ArkUI_AccessibilityActionArguments* actionArguments); + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments); + void PerformSetCursorPosition(SemanticsNodeExtent flutterNode, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments); + void PerformCustomAction(SemanticsNodeExtent flutterNode, + ArkUI_Accessibility_ActionType action, + ArkUI_AccessibilityActionArguments* actionArguments); + void PerformShowOnScreenAction(SemanticsNodeExtent flutterNode); void AddRouteNodes(std::vector edges, SemanticsNodeExtent node); @@ -283,8 +315,7 @@ private: void RequestFocusWhenPageUpdate(int32_t requestFocusId); bool Contains(const std::string source, const std::string target); std::pair GetRealScaleFactor(); - void FlutterSemanticsTreeUpdateCallOnce(); - + void DoubleClickRouteToNewPage(SemanticsNodeExtent node); void GetSemanticsDebugInfo(); }; diff --git a/shell/platform/ohos/utils/ohos_utils.cpp b/shell/platform/ohos/utils/ohos_utils.cpp new file mode 100644 index 0000000000..d56f8f579e --- /dev/null +++ b/shell/platform/ohos/utils/ohos_utils.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "ohos_utils.h" + +namespace flutter { + +OHOSUtils::OHOSUtils() {}; +OHOSUtils::~OHOSUtils() {}; + + +} \ No newline at end of file diff --git a/shell/platform/ohos/utils/ohos_utils.h b/shell/platform/ohos/utils/ohos_utils.h new file mode 100644 index 0000000000..938cb07906 --- /dev/null +++ b/shell/platform/ohos/utils/ohos_utils.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_UTILS_H +#define OHOS_UTILS_H + +namespace flutter { + +class OHOSUtils { +public: + OHOSUtils(); + ~OHOSUtils(); + +}; + +} + + +#endif -- Gitee From 36640ed21311a555cd5465887c9a75627d7db256 Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 16 Dec 2024 15:02:46 +0800 Subject: [PATCH 16/60] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=97=A8=E7=A6=81?= =?UTF-8?q?=E9=9D=99=E6=80=81=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../native_accessibility_channel.cpp | 2 +- .../ohos_accessibility_bridge.cpp | 562 ++++++------------ .../accessibility/ohos_accessibility_bridge.h | 31 +- shell/platform/ohos/utils/ohos_utils.cpp | 9 +- shell/platform/ohos/utils/ohos_utils.h | 4 +- 5 files changed, 214 insertions(+), 394 deletions(-) diff --git a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp index 1d3e8a7a3a..d8ba25cb99 100644 --- a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp +++ b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp @@ -84,7 +84,7 @@ namespace flutter { flutter::CustomAccessibilityActionUpdates actions) { auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); - ohos_a11y_bridge->updateSemantics(update, actions); + ohos_a11y_bridge->UpdateSemantics(update, actions); } /** diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index d250610dac..8fd91391fd 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -14,8 +14,7 @@ */ #include "ohos_accessibility_bridge.h" #include -#include -#include +#include #include #include #include @@ -31,15 +30,14 @@ #define ARKUI_FAILED_CODE -1 #define ARKUI_BAD_PARAM_CODE -2 #define ARKUI_OOM_CODE -3 -#define FUNCTION_NAME_STR(func) #func -#define ARKUI_ACCESSIBILITY_CALL_CHECK(X) \ - do { \ - int32_t RET = X; \ - if (RET != ARKUI_SUCCEED_CODE) { \ - LOGE("Failed function %{public}s call, error code:%{public}d", \ - FUNCTION_NAME_STR(X), RET); \ - } \ - } while (false) \ +#define ARKUI_ACCESSIBILITY_CALL_CHECK(X) \ + do { \ + int32_t RET = X; \ + if (RET != ARKUI_SUCCEED_CODE) { \ + LOGE("Failed function %{public}s call, error code:%{public}d", \ + #X, RET); \ + } \ + } while (false) \ namespace flutter { @@ -88,7 +86,7 @@ void OhosAccessibilityBridge::SetNativeShellHolderId(int64_t id) * 从dart侧传递到c++侧的flutter无障碍语义树节点更新过程, * 路由新页面、滑动页面等操作会自动触发该语义树的更新 */ -void OhosAccessibilityBridge::updateSemantics( +void OhosAccessibilityBridge::UpdateSemantics( flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) { @@ -139,7 +137,9 @@ void OhosAccessibilityBridge::updateSemantics( } // 页面内容更新事件 - Flutter_SendAccessibilityAsyncEvent(0, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); + Flutter_SendAccessibilityAsyncEvent(0, + ArkUI_AccessibilityEventType:: + ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); /* 针对更新后的节点进行事件处理 */ @@ -164,7 +164,7 @@ void OhosAccessibilityBridge::updateSemantics( static_cast(accessibilityFocusedNode.id), ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_FOCUS_NODE_UPDATE); - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = + void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); @@ -178,7 +178,8 @@ void OhosAccessibilityBridge::updateSemantics( if (nodeEx.HasFlag(FLAGS_::kIsLiveRegion) && HasChangedLabel(nodeEx)) { FML_DLOG(INFO) << "UpdateSemantics -> page content update, nodeEx.id=" << nodeEx.id; Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), - ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); + ArkUI_AccessibilityEventType:: + ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); } } @@ -363,7 +364,7 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) OH_ArkUI_DestoryAccessibilityEventInfo(reqFocusEventInfo); reqFocusEventInfo = nullptr; - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = + void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); @@ -464,185 +465,6 @@ SemanticsNodeExtent OhosAccessibilityBridge::GetFlutterSemanticsNode( } } -/** - * flutter的语义节点初始化配置给arkui创建的elementInfos - */ -void OhosAccessibilityBridge::FlutterTreeToArkuiTree( - ArkUI_AccessibilityElementInfoList* elementInfoList) -{ - if (g_flutterSemanticsTree.size() == 0) { - FML_DLOG(ERROR) << "OhosAccessibilityBridge::FlutterTreeToArkuiTree " - "g_flutterSemanticsTree.size() = 0"; - return; - } - if (OH_GetSdkApiVersion() >= 13) { - // 将flutter语义节点树传递给arkui的无障碍elementinfo - for (const auto& item : g_flutterSemanticsTree) { - SemanticsNodeExtent flutterNode = item.second; - - // 创建elementinfo,系统自动加入到elementinfolist - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = - OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); - if (OH_ArkUI_AddAndGetAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_AddAndGetAccessibilityElementInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityElementInfo* elementInfo = - OH_ArkUI_AddAndGetAccessibilityElementInfo(elementInfoList); - if (elementInfo == nullptr) { - FML_DLOG(INFO) << "OhosAccessibilityBridge::FlutterTreeToArkuiTree " - "elementInfo is null"; - return; - } - // 设置elementinfo的屏幕坐标范围 - int32_t left = static_cast(flutterNode.rect.fLeft); - int32_t top = static_cast(flutterNode.rect.fTop); - int32_t right = static_cast(flutterNode.rect.fRight); - int32_t bottom = static_cast(flutterNode.rect.fBottom); - ArkUI_AccessibleRect rect = {left, top, right, bottom}; - - int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = - OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); - if (OH_ArkUI_AccessibilityElementInfoSetScreenRect == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetScreenRect is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfo, &rect) - ); - - // 设置elementinfo的action类型 - std::string widget_type = GetNodeComponentType(flutterNode); - FlutterSetElementInfoOperationActions(elementInfo, widget_type); - - // 设置elementid - int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); - if (OH_ArkUI_AccessibilityElementInfoSetElementId == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetElementId is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfo, flutterNode.id) - ); - - // 设置父节点id - int32_t parentId = GetParentId(flutterNode.id); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); - if (OH_ArkUI_AccessibilityElementInfoSetParentId == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetParentId is null, %{public}s", dlerror()); - } - if (flutterNode.id == 0) { - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfo, ARKUI_ACCESSIBILITY_ROOT_PARENT_ID) - ); - } else { - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfo, parentId)); - } - - // 设置孩子节点 - 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]); - FML_DLOG(INFO) << "FlutterTreeToArkuiTree flutterNode.id= " - << flutterNode.id << " childCount= " << childCount - << " childNodeId=" << childNodeIds[i]; - } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = - OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); - if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfo, childCount, childNodeIds) - ); - } - - // 配置常用属性 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEnabled"); - if (OH_ArkUI_AccessibilityElementInfoSetEnabled == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetEnabled is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfo, true)); - - int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetClickable"); - if (OH_ArkUI_AccessibilityElementInfoSetClickable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetClickable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfo, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetCheckable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetCheckable"); - if (OH_ArkUI_AccessibilityElementInfoSetCheckable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetCheckable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetCheckable(elementInfo, true)); - - int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetFocusable"); - if (OH_ArkUI_AccessibilityElementInfoSetFocusable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetFocusable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfo, true)); - - int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetVisible"); - if (OH_ArkUI_AccessibilityElementInfoSetVisible == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetVisible is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfo, true)); - - // 设置组件类型 - std::string componentTypeName = GetNodeComponentType(flutterNode); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); - if (OH_ArkUI_AccessibilityElementInfoSetComponentType == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetComponentType is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfo, componentTypeName.c_str()) - ); - - std::string contents = componentTypeName + "_content"; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); - if (OH_ArkUI_AccessibilityElementInfoSetContents == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetContents is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetContents(elementInfo, contents.c_str()) - ); - - // 设置无障碍相关属性 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityText == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityText(elementInfo, flutterNode.label.c_str()) - ); - - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfo, "yes")); - - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfo, false)); - } - } -} - /** * 获取当前elementid的父节点id */ @@ -797,162 +619,153 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( } FML_DLOG(INFO) << "FlutterNodeToElementInfoById elementId = " << elementId; - if (OH_GetSdkApiVersion() >= 13) { - // 当elementId = -1或0时,创建root节点 - if (elementId == 0 || elementId == -1) { - // 获取flutter的root节点 - SemanticsNodeExtent flutterNode = GetFlutterSemanticsNode(static_cast(0)); - if (flutterNode.isNull) { - LOGE("FlutterNodeToElementInfoById: GetFlutterSemanticsNode id=%{public}ld null", elementId); - } + // 当elementId = -1或0时,创建root节点 + if (elementId == 0 || elementId == -1) { + // 获取flutter的root节点 + SemanticsNodeExtent flutterNode = GetFlutterSemanticsNode(static_cast(0)); + if (flutterNode.isNull) { + LOGE("FlutterNodeToElementInfoById: GetFlutterSemanticsNode id=%{public}ld null", elementId); + } - // 设置elementinfo的屏幕坐标范围 - int32_t left = static_cast(flutterNode.rect.fLeft); - int32_t top = static_cast(flutterNode.rect.fTop); - int32_t right = static_cast(flutterNode.rect.fRight); - int32_t bottom = static_cast(flutterNode.rect.fBottom); - ArkUI_AccessibleRect rect = {left, top, right, bottom}; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = - OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); - if (OH_ArkUI_AccessibilityElementInfoSetScreenRect == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetScreenRect is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect) - ); + // 设置elementinfo的屏幕坐标范围 + int32_t left = static_cast(flutterNode.rect.fLeft); + int32_t top = static_cast(flutterNode.rect.fTop); + int32_t right = static_cast(flutterNode.rect.fRight); + int32_t bottom = static_cast(flutterNode.rect.fBottom); + ArkUI_AccessibleRect rect = {left, top, right, bottom}; + int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = + OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); + if (OH_ArkUI_AccessibilityElementInfoSetScreenRect == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetScreenRect is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect) + ); - // 设置root节点的屏幕绝对坐标rect - SetAbsoluteScreenRect(flutterNode, left, top, right, bottom); + // 设置root节点的屏幕绝对坐标rect + SetAbsoluteScreenRect(flutterNode, left, top, right, bottom); - // 设置root节点的action类型 - FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); + // 设置root节点的action类型 + FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); - // 根据flutternode信息配置对应的elementinfo - int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); - if (OH_ArkUI_AccessibilityElementInfoSetElementId == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetElementId is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, 0)); + // 根据flutternode信息配置对应的elementinfo + int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); + if (OH_ArkUI_AccessibilityElementInfoSetElementId == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetElementId is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, 0)); - // NOTE: arkui无障碍子系统强制设置root的父节点id = -2100000 (严禁更改) - int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); - if (OH_ArkUI_AccessibilityElementInfoSetParentId == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetParentId is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, ARKUI_ACCESSIBILITY_ROOT_PARENT_ID) - ); + // NOTE: arkui无障碍子系统强制设置root的父节点id = -2100000 (严禁更改) + int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); + if (OH_ArkUI_AccessibilityElementInfoSetParentId == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetParentId is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, ARKUI_ACCESSIBILITY_ROOT_PARENT_ID) + ); - // 设置无障碍播报文本 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityText == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityText( - elementInfoFromList, flutterNode.label.empty() ? flutterNode.value.c_str() : flutterNode.label.c_str()) - ); + // 设置无障碍播报文本 + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); + if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityText == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetAccessibilityText( + elementInfoFromList, flutterNode.label.empty() ? + flutterNode.value.c_str() : flutterNode.label.c_str()) + ); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes") - ); + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"); + if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes") + ); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfoFromList, false) - ); + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"); + if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfoFromList, false) + ); - // 配置child节点信息 - 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]); - FML_DLOG(INFO) - << "FlutterNodeToElementInfoById -> elementid=0 childCount=" - << childCount << " childNodeIds=" << childNodeIds[i]; - } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = - OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); - if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) - ); + // 配置child节点信息 + 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]); + FML_DLOG(INFO) + << "FlutterNodeToElementInfoById -> elementid=0 childCount=" + << childCount << " childNodeIds=" << childNodeIds[i]; } - - // 配置root节点常用属性 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEnabled"); - if (OH_ArkUI_AccessibilityElementInfoSetEnabled == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetEnabled is null, %{public}s", dlerror()); + int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = + OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); + if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfoFromList, true)); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) + ); + } + + // 配置root节点常用属性 + int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEnabled"); + if (OH_ArkUI_AccessibilityElementInfoSetEnabled == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetEnabled is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetClickable"); - if (OH_ArkUI_AccessibilityElementInfoSetClickable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetClickable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfoFromList, true)); + int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetClickable"); + if (OH_ArkUI_AccessibilityElementInfoSetClickable == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetClickable is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetFocusable"); - if (OH_ArkUI_AccessibilityElementInfoSetFocusable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetFocusable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfoFromList, true)); + int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetFocusable"); + if (OH_ArkUI_AccessibilityElementInfoSetFocusable == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetFocusable is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetVisible"); - if (OH_ArkUI_AccessibilityElementInfoSetVisible == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetVisible is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfoFromList, true)); + int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetVisible"); + if (OH_ArkUI_AccessibilityElementInfoSetVisible == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetVisible is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); - if (OH_ArkUI_AccessibilityElementInfoSetComponentType == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetComponentType is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, "root")); + int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); + if (OH_ArkUI_AccessibilityElementInfoSetComponentType == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetComponentType is null, %{public}s", dlerror()); + } + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, "root")); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); - if (OH_ArkUI_AccessibilityElementInfoSetContents == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetContents is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetContents(elementInfoFromList, flutterNode.label.c_str())); - } else { - //当elementId >= 1时,根据flutter节点信息配置elementinfo无障碍属性 - FlutterSetElementInfoProperties(elementInfoFromList, elementId); + int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); + if (OH_ArkUI_AccessibilityElementInfoSetContents == nullptr) { + LOGE("OH_ArkUI_AccessibilityElementInfoSetContents is null, %{public}s", dlerror()); } + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetContents(elementInfoFromList, flutterNode.label.c_str())); + } else { + //当elementId >= 1时,根据flutter节点信息配置elementinfo无障碍属性 + FlutterSetElementInfoProperties(elementInfoFromList, elementId); } - FML_DLOG(INFO) << "=== OhosAccessibilityBridge::FlutterNodeToElementInfoById is end ==="; -} -/** - * 判断源字符串是否包含目标字符串 - */ -bool OhosAccessibilityBridge::Contains(const std::string source, - const std::string target) -{ - return source.find(target) != std::string::npos; + FML_DLOG(INFO) << "=== OhosAccessibilityBridge::FlutterNodeToElementInfoById is end ==="; } /** @@ -968,8 +781,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( if (OH_ArkUI_AccessibilityElementInfoSetOperationActions == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetOperationActions is null, %{public}s", dlerror()); } - if (Contains(widget_type, EDIT_TEXT_WIDGET_NAME) || - Contains(widget_type, EDIT_MULTILINE_TEXT_WIDGET_NAME)) { + 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]; @@ -1017,7 +830,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) ); - } else if (Contains(widget_type, SCROLL_WIDGET_NAME)) { + } else if (OHOSUtils::Contains(widget_type, SCROLL_WIDGET_NAME)) { // if node is a scrollable component int32_t actionTypeNum = 5; ArkUI_AccessibleAction actions[actionTypeNum]; @@ -1095,7 +908,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( // 相对-绝对坐标映射 FlutterRelativeRectToScreenRect(flutterNode); auto [left, top, right, bottom] = GetAbsoluteScreenRect(flutterNode); - ArkUI_AccessibleRect rect = {static_cast(left), static_cast(top), + ArkUI_AccessibleRect rect = {static_cast(left), static_cast(top), static_cast(right), static_cast(bottom)}; int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); @@ -1436,21 +1249,20 @@ void OhosAccessibilityBridge::BuildArkUISemanticsTree( int64_t elementInfoCount = levelOrderTreeVec.size(); //创建并配置节点id >= 1的全部节点 for (int64_t i = 1; i < elementInfoCount; i++) { - int64_t levelOrderId = levelOrderTreeVec[i]; - auto newNode = GetFlutterSemanticsNode(levelOrderId); - if (g_flutterSemanticsTree.count(newNode.id)) { - LOGE("BuildArkUISemanticsTree: GetFlutterSemanticsNode id=%{public}ld null", levelOrderId); - } - //当节点为隐藏状态时,自动规避 - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = - OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); - if (OH_ArkUI_AddAndGetAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_AddAndGetAccessibilityElementInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityElementInfo* newElementInfo = - OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); - //配置当前子节点信息 - FlutterNodeToElementInfoById(newElementInfo, levelOrderId); + int64_t levelOrderId = levelOrderTreeVec[i]; + auto newNode = GetFlutterSemanticsNode(levelOrderId); + if (g_flutterSemanticsTree.count(newNode.id)) { + LOGE("BuildArkUISemanticsTree: GetFlutterSemanticsNode id=%{public}ld null", levelOrderId); + } + //当节点为隐藏状态时,自动规避 + auto* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = + OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); + if (OH_ArkUI_AddAndGetAccessibilityElementInfo == nullptr) { + LOGE("OH_ArkUI_AddAndGetAccessibilityElementInfo is null, %{public}s", dlerror()); + } + auto* newElementInfo = OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); + //配置当前子节点信息 + FlutterNodeToElementInfoById(newElementInfo, levelOrderId); } } } @@ -1493,13 +1305,12 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( if (OH_GetSdkApiVersion() >= 13) { // 从elementinfolist中获取elementinfo - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = + auto* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); if (OH_ArkUI_AddAndGetAccessibilityElementInfo == nullptr) { LOGE("OH_ArkUI_AddAndGetAccessibilityElementInfo is null, %{public}s", dlerror()); } - ArkUI_AccessibilityElementInfo* elementInfoFromList = - OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); + auto* elementInfoFromList = OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); if (elementInfoFromList == nullptr) { FML_DLOG(INFO) << "FindAccessibilityNodeInfosById elementInfoFromList is null"; return ARKUI_ACCESSIBILITY_NATIVE_RESULT_FAILED; @@ -1543,9 +1354,9 @@ void OhosAccessibilityBridge::DispatchSemanticsAction( fml::MallocMapping args) { nativeAccessibilityChannel_->DispatchSemanticsAction(native_shell_holder_id_, - id, - action, - fml::MallocMapping()); + id, + action, + fml::MallocMapping()); } /** @@ -1555,7 +1366,6 @@ void OhosAccessibilityBridge::DoubleClickRouteToNewPage(SemanticsNodeExtent node { if (isFlutterSemanticsTreeUpdated && node.HasFlag(FLAGS_::kIsButton)) { RequestFocusWhenPageUpdate(0); - // isFlutterSemanticsTreeUpdated = false; } } @@ -1600,7 +1410,7 @@ void OhosAccessibilityBridge::PerformLongClickAction( * perform focus acquisition in accessibility status */ void OhosAccessibilityBridge::PerformGainFocusnAction( - int64_t elementId, + int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode) { @@ -1620,7 +1430,8 @@ void OhosAccessibilityBridge::PerformGainFocusnAction( if (flutterNode.HasAction(ACTIONS_::kIncrease) || flutterNode.HasAction(ACTIONS_::kDecrease)) { Flutter_SendAccessibilityAsyncEvent( - elementId, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); + elementId, ArkUI_AccessibilityEventType:: + ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_SELECTED); } } @@ -1649,7 +1460,7 @@ void OhosAccessibilityBridge::PerformClearFocusAction( * perform scroll forward in accessibility status */ void OhosAccessibilityBridge::PerformScrollUpAction( - int64_t elementId, + int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode) { @@ -1668,14 +1479,14 @@ void OhosAccessibilityBridge::PerformScrollUpAction( DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kIncrease, {}); } std::string currComponetType = GetNodeComponentType(flutterNode); - if (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 << ")"; + 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 << ")"; } } @@ -1702,7 +1513,7 @@ void OhosAccessibilityBridge::PerformScrollDownAction( DispatchSemanticsAction(static_cast(elementId), ACTIONS_::kDecrease, {}); } std::string currComponetType = GetNodeComponentType(flutterNode); - if (Contains(currComponetType, SCROLL_WIDGET_NAME)) { + if (OHOSUtils::Contains(currComponetType, SCROLL_WIDGET_NAME)) { /** Scrolled event, sent when a scrollable component experiences a * scroll event. 4096 */ ArkUI_AccessibilityEventType scrollEventType1 = @@ -1756,7 +1567,7 @@ void OhosAccessibilityBridge::PerformSetText( ArkUI_AccessibilityActionArguments* actionArguments) { if (OH_GetSdkApiVersion() >= 13) { - int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = + int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); if (OH_ArkUI_FindAccessibilityActionArgumentByKey == nullptr) { LOGE("OH_ArkUI_FindAccessibilityActionArgumentByKey is null, %{public}s", dlerror()); @@ -2111,7 +1922,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( OH_ArkUI_SendAccessibilityAsyncEvent(provider_, eventInfo, callback); // 7.销毁新创建的elementinfo, eventinfo - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = + void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); @@ -2384,7 +2195,7 @@ std::string OhosAccessibilityBridge::GetRouteName(SemanticsNodeExtent node) return ""; } -void OhosAccessibilityBridge::onWindowNameChange(SemanticsNodeExtent route) +void OhosAccessibilityBridge::OnWindowNameChange(SemanticsNodeExtent route) { std::string routeName = GetRouteName(route); if (routeName.empty()) { @@ -2392,10 +2203,11 @@ void OhosAccessibilityBridge::onWindowNameChange(SemanticsNodeExtent route) } Flutter_SendAccessibilityAsyncEvent( static_cast(route.id), - ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); + ArkUI_AccessibilityEventType:: + ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); } -void OhosAccessibilityBridge::removeSemanticsNode( +void OhosAccessibilityBridge::RemoveSemanticsNode( SemanticsNodeExtent nodeToBeRemoved) { if (!g_flutterSemanticsTree.size()) { diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 08d196aee1..e8c78b71ca 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -26,6 +26,7 @@ #include "native_accessibility_channel.h" #include "ohos_accessibility_features.h" #include "ohos_accessibility_ddl.h" +#include "flutter/shell/platform/ohos/utils/ohos_utils.h" namespace flutter { typedef flutter::SemanticsFlags FLAGS_; @@ -83,7 +84,7 @@ public: void SetNativeShellHolderId(int64_t id); - void updateSemantics(flutter::SemanticsNodeUpdates update, + void UpdateSemantics(flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions); void DispatchSemanticsAction(int32_t id, @@ -231,8 +232,6 @@ private: void FlutterSetElementInfoOperationActions( ArkUI_AccessibilityElementInfo* elementInfoFromList, std::string widget_type); - void FlutterTreeToArkuiTree( - ArkUI_AccessibilityElementInfoList* elementInfoList); void BuildArkUISemanticsTree( int64_t elementId, ArkUI_AccessibilityElementInfo* elementInfoFromList, @@ -264,27 +263,27 @@ private: bool IsSlider(SemanticsNodeExtent flutterNode); bool IsScrollableWidget(SemanticsNodeExtent flutterNode); - void PerformClickAction(int64_t elementId, - ArkUI_Accessibility_ActionType action, + void PerformClickAction(int64_t elementId, + ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode); - void PerformLongClickAction(int64_t elementId, - ArkUI_Accessibility_ActionType action, + void PerformLongClickAction(int64_t elementId, + ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode); - void PerformGainFocusnAction(int64_t elementId, + void PerformGainFocusnAction(int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode); - void PerformClearFocusAction(int64_t elementId, + void PerformClearFocusAction(int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode); - void PerformScrollUpAction(int64_t elementId, + void PerformScrollUpAction(int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode); - void PerformScrollDownAction(int64_t elementId, + void PerformScrollDownAction(int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode); - void PerformClipboardAction(int64_t elementId, + void PerformClipboardAction(int64_t elementId, ArkUI_Accessibility_ActionType action); - void PerformInvalidAction(int64_t elementId, + void PerformInvalidAction(int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode); void PerformSetText(SemanticsNodeExtent flutterNode, @@ -302,10 +301,10 @@ private: void PerformShowOnScreenAction(SemanticsNodeExtent flutterNode); void AddRouteNodes(std::vector edges, - SemanticsNodeExtent node); + SemanticsNodeExtent node); std::string GetRouteName(SemanticsNodeExtent node); - void onWindowNameChange(SemanticsNodeExtent route); - void removeSemanticsNode(SemanticsNodeExtent nodeToBeRemoved); + void OnWindowNameChange(SemanticsNodeExtent route); + void RemoveSemanticsNode(SemanticsNodeExtent nodeToBeRemoved); void GetSemanticsNodeDebugInfo(SemanticsNodeExtent node); void GetSemanticsFlagsDebugInfo(SemanticsNodeExtent node); diff --git a/shell/platform/ohos/utils/ohos_utils.cpp b/shell/platform/ohos/utils/ohos_utils.cpp index d56f8f579e..fd4b68f7e6 100644 --- a/shell/platform/ohos/utils/ohos_utils.cpp +++ b/shell/platform/ohos/utils/ohos_utils.cpp @@ -13,11 +13,18 @@ * limitations under the License. */ #include "ohos_utils.h" - namespace flutter { OHOSUtils::OHOSUtils() {}; OHOSUtils::~OHOSUtils() {}; +/** + * 判断源字符串是否包含目标字符串 + */ +bool OHOSUtils::Contains(const std::string source, + const std::string target) +{ + return source.find(target) != std::string::npos; +} } \ No newline at end of file diff --git a/shell/platform/ohos/utils/ohos_utils.h b/shell/platform/ohos/utils/ohos_utils.h index 938cb07906..802d6f306a 100644 --- a/shell/platform/ohos/utils/ohos_utils.h +++ b/shell/platform/ohos/utils/ohos_utils.h @@ -15,6 +15,7 @@ #ifndef OHOS_UTILS_H #define OHOS_UTILS_H +#include namespace flutter { @@ -22,7 +23,8 @@ class OHOSUtils { public: OHOSUtils(); ~OHOSUtils(); - + + static bool Contains(const std::string source, const std::string target); }; } -- Gitee From d8b31045afbfb622b63d8ef32ca8377b99e587b3 Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 16 Dec 2024 16:55:06 +0800 Subject: [PATCH 17/60] =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=AE=8C=E5=96=84=E9=9D=99=E6=80=81?= =?UTF-8?q?=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 215 +++++++++--------- .../accessibility/ohos_accessibility_bridge.h | 8 +- .../flutter_embedding/build-profile.json5 | 16 +- .../ohos/napi/platform_view_ohos_napi.cpp | 14 +- .../ohos/napi/platform_view_ohos_napi.h | 1 + shell/platform/ohos/utils/ohos_utils.cpp | 2 +- shell/platform/ohos/utils/ohos_utils.h | 4 +- 7 files changed, 145 insertions(+), 115 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 8fd91391fd..1224d30d56 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -41,6 +41,8 @@ namespace flutter { +const int32_t OhosAccessibilityBridge::OHOS_API_VERSION = OH_GetSdkApiVersion(); + OhosAccessibilityBridge* OhosAccessibilityBridge::bridgeInstance = nullptr; OhosAccessibilityBridge* OhosAccessibilityBridge::GetInstance() @@ -96,44 +98,46 @@ void OhosAccessibilityBridge::UpdateSemantics( // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) if (IS_FLUTTER_NAVIGATE) { - Flutter_SendAccessibilityAsyncEvent(0, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); + Flutter_SendAccessibilityAsyncEvent(0, + ArkUI_AccessibilityEventType:: + ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); RequestFocusWhenPageUpdate(0); IS_FLUTTER_NAVIGATE = false; } /** 获取并分析每个语义节点的更新属性 */ for (auto& item : update) { - // 获取当前更新的节点node - const auto& node = item.second; - - // 更新扩展的SemanticsNode信息 - auto nodeEx = UpdatetSemanticsNodeExtent(node); - - //print semantics node and flags info for debugging - GetSemanticsNodeDebugInfo(nodeEx); - GetSemanticsFlagsDebugInfo(nodeEx); - - /** - * 构建flutter无障碍语义节点树 - * NOTE: 若使用g_flutterSemanticsTree.insert({node.id, node})方式 - * 来添加新增的语义节点会导致已有key值自动忽略,不会更新原有key对应的value - */ - g_flutterSemanticsTree[nodeEx.id] = nodeEx; - - // 若当前节点为获焦 - if (IsNodeFocused(nodeEx)) { - inputFocusedNode = nodeEx; - } - // 若当前节点和更新前节点信息不同,则加入更新节点数组 - if (nodeEx.hadPreviousConfig) { - updatedFlutterNodes.emplace_back(nodeEx); - } + // 获取当前更新的节点node + const auto& node = item.second; - // 获取当前flutter节点的全部子节点数量,并构建父子节点id映射关系 - int32_t childNodeCount = nodeEx.childrenInTraversalOrder.size(); - for (int32_t i = 0; i < childNodeCount; i++) { - g_parentChildIdVec.emplace_back(std::make_pair(nodeEx.id, nodeEx.childrenInTraversalOrder[i])); - } + // 更新扩展的SemanticsNode信息 + auto nodeEx = UpdatetSemanticsNodeExtent(node); + + //print semantics node and flags info for debugging + GetSemanticsNodeDebugInfo(nodeEx); + GetSemanticsFlagsDebugInfo(nodeEx); + + /** + * 构建flutter无障碍语义节点树 + * NOTE: 若使用g_flutterSemanticsTree.insert({node.id, node})方式 + * 来添加新增的语义节点会导致已有key值自动忽略,不会更新原有key对应的value + */ + g_flutterSemanticsTree[nodeEx.id] = nodeEx; + + // 若当前节点为获焦 + if (IsNodeFocused(nodeEx)) { + inputFocusedNode = nodeEx; + } + // 若当前节点和更新前节点信息不同,则加入更新节点数组 + if (nodeEx.hadPreviousConfig) { + updatedFlutterNodes.emplace_back(nodeEx); + } + + // 获取当前flutter节点的全部子节点数量,并构建父子节点id映射关系 + int32_t childNodeCount = nodeEx.childrenInTraversalOrder.size(); + for (int32_t i = 0; i < childNodeCount; i++) { + g_parentChildIdVec.emplace_back(std::make_pair(nodeEx.id, nodeEx.childrenInTraversalOrder[i])); + } } // 页面内容更新事件 @@ -147,31 +151,29 @@ void OhosAccessibilityBridge::UpdateSemantics( // 当滑动节点产生滑动,并执行滑动处理 if (HasScrolled(nodeEx)) { LOGD("UpdateSemantics -> has scrolled"); - if (OH_GetSdkApiVersion() >= 13) { - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); - if (OH_ArkUI_CreateAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_CreateAccessibilityElementInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); + ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = + OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); + if (OH_ArkUI_CreateAccessibilityElementInfo == nullptr) { + LOGE("OH_ArkUI_CreateAccessibilityElementInfo is null, %{public}s", dlerror()); + } + ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); - FlutterNodeToElementInfoById(_elementInfo, static_cast(nodeEx.id)); - // flutter滑动组件滑动处理逻辑 - FlutterScrollExecution(nodeEx, _elementInfo); + FlutterNodeToElementInfoById(_elementInfo, static_cast(nodeEx.id)); + // flutter滑动组件滑动处理逻辑 + FlutterScrollExecution(nodeEx, _elementInfo); - // 屏幕朗读状态下双指滑动,获焦节点绿框实时跟随节点滑动 - Flutter_SendAccessibilityAsyncEvent( - static_cast(accessibilityFocusedNode.id), - ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_FOCUS_NODE_UPDATE); + // 屏幕朗读状态下双指滑动,获焦节点绿框实时跟随节点滑动 + Flutter_SendAccessibilityAsyncEvent( + static_cast(accessibilityFocusedNode.id), + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_FOCUS_NODE_UPDATE); - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); - if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); - } - OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); - _elementInfo = nullptr; + void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = + OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); + if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { + LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); } + OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); + _elementInfo = nullptr; } // 判断是否触发liveRegion活动区,当前节点是否活跃 @@ -196,7 +198,7 @@ void OhosAccessibilityBridge::FlutterScrollExecution( SemanticsNodeExtent node, ArkUI_AccessibilityElementInfo* elementInfoFromList) { - if (OH_GetSdkApiVersion() >= 13) { + if (OHOS_API_VERSION >= 13) { double nodePosition = node.scrollPosition; double nodeScrollExtentMax = node.scrollExtentMax; double nodeScrollExtentMin = node.scrollExtentMin; @@ -236,7 +238,8 @@ void OhosAccessibilityBridge::FlutterScrollExecution( if (OH_ArkUI_AccessibilityElementInfoSetItemCount == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetItemCount is null, %{public}s", dlerror()); } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetItemCount(elementInfoFromList, itemCount)); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetItemCount(elementInfoFromList, itemCount)); // 设置当前页面可见的起始滑动index int32_t startItemIndex = node.scrollIndex; @@ -245,7 +248,8 @@ void OhosAccessibilityBridge::FlutterScrollExecution( if (OH_ArkUI_AccessibilityElementInfoSetStartItemIndex == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetStartItemIndex is null, %{public}s", dlerror()); } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetStartItemIndex(elementInfoFromList, startItemIndex)); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetStartItemIndex(elementInfoFromList, startItemIndex)); // 设置当前获焦节点的当前index int32_t currItemIndex = accessibilityFocusedNode.id; @@ -254,7 +258,8 @@ void OhosAccessibilityBridge::FlutterScrollExecution( if (OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex is null, %{public}s", dlerror()); } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex(elementInfoFromList, currItemIndex)); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex(elementInfoFromList, currItemIndex)); // 计算当前滑动位置页面的可见子滑动节点数量 int visibleChildren = 0; @@ -299,7 +304,7 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) "AccessibilityProvider = nullptr"; return; } - if (OH_GetSdkApiVersion() >= 13) { + if (OHOS_API_VERSION >= 13) { ArkUI_AccessibilityEventInfo* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); if (OH_ArkUI_CreateAccessibilityEventInfo == nullptr) { @@ -384,7 +389,7 @@ void OhosAccessibilityBridge::Announce(std::unique_ptr& message) "AccessibilityProvider = nullptr"; return; } - if (OH_GetSdkApiVersion() >= 13) { + if (OHOS_API_VERSION >= 13) { // 创建并设置屏幕朗读事件 ArkUI_AccessibilityEventInfo* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); @@ -536,7 +541,7 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( auto currRight = static_cast(currNode.rect.fRight); auto currBottom = static_cast(currNode.rect.fBottom); - /** + /** * 获取当前flutter节点的缩放、平移、透视等矩阵坐标转换 * 以下矩阵坐标变换参数(如:旋转/错切、透视)场景目前暂不考虑 * NOTE: SkMatrix::kMSkewX, SkMatrix::kMSkewY, @@ -552,7 +557,7 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( int32_t parentId = GetParentId(currNode.id); auto parentNode = GetFlutterSemanticsNode(parentId); if (!g_flutterSemanticsTree.count(parentId)) { - LOGE("FlutterRelativeRectToScreenRect: GetFlutterSemanticsNode id=%{public}d null", parentId); + LOGE("FlutterRelativeRectToScreenRect: GetFlutterSemanticsNode id=%{public}d null", parentId); } // 获取当前flutter节点的父节点的绝对坐标 @@ -560,9 +565,9 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( //获取root节点的绝对坐标 auto rootNode = GetFlutterSemanticsNode(0); - auto _rootRect = GetAbsoluteScreenRect(rootNode); - auto rootWidth = _rootRect.right; - auto rootHeight = _rootRect.bottom; + auto rootRect = GetAbsoluteScreenRect(rootNode); + auto rootWidth = rootRect.right; + auto rootHeight = rootRect.bottom; // 获取真实缩放系数 auto [realScaleXFactor, realScaleYFactor] = GetRealScaleFactor(); @@ -649,7 +654,7 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); // 根据flutternode信息配置对应的elementinfo - int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); if (OH_ArkUI_AccessibilityElementInfoSetElementId == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetElementId is null, %{public}s", dlerror()); @@ -657,7 +662,7 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, 0)); // NOTE: arkui无障碍子系统强制设置root的父节点id = -2100000 (严禁更改) - int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); if (OH_ArkUI_AccessibilityElementInfoSetParentId == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetParentId is null, %{public}s", dlerror()); @@ -667,18 +672,18 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( ); // 设置无障碍播报文本 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityText == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText is null, %{public}s", dlerror()); } ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityText( - elementInfoFromList, flutterNode.label.empty() ? + elementInfoFromList, flutterNode.label.empty() ? flutterNode.value.c_str() : flutterNode.label.c_str()) ); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"); if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel is null, %{public}s", dlerror()); @@ -687,7 +692,7 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes") ); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"); if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup is null, %{public}s", dlerror()); @@ -719,42 +724,42 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( } // 配置root节点常用属性 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEnabled"); if (OH_ArkUI_AccessibilityElementInfoSetEnabled == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetEnabled is null, %{public}s", dlerror()); } ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetClickable"); if (OH_ArkUI_AccessibilityElementInfoSetClickable == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetClickable is null, %{public}s", dlerror()); } ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetFocusable"); if (OH_ArkUI_AccessibilityElementInfoSetFocusable == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetFocusable is null, %{public}s", dlerror()); } ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetVisible"); if (OH_ArkUI_AccessibilityElementInfoSetVisible == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetVisible is null, %{public}s", dlerror()); } ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); if (OH_ArkUI_AccessibilityElementInfoSetComponentType == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetComponentType is null, %{public}s", dlerror()); } ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, "root")); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); if (OH_ArkUI_AccessibilityElementInfoSetContents == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetContents is null, %{public}s", dlerror()); @@ -775,7 +780,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( ArkUI_AccessibilityElementInfo* elementInfoFromList, std::string widget_type) { - if (OH_GetSdkApiVersion() >= 13) { + if (OHOS_API_VERSION >= 13) { int32_t (*OH_ArkUI_AccessibilityElementInfoSetOperationActions)(ArkUI_AccessibilityElementInfo*, int32_t, ArkUI_AccessibleAction*) = OhosAccessibilityDDL::DLLoadSetElemOperActionsFunc("OH_ArkUI_AccessibilityElementInfoSetOperationActions"); if (OH_ArkUI_AccessibilityElementInfoSetOperationActions == nullptr) { @@ -889,14 +894,14 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( ArkUI_AccessibilityElementInfo* elementInfoFromList, int64_t elementId) { - if (OH_GetSdkApiVersion() >= 13) { + if (OHOS_API_VERSION >= 13) { SemanticsNodeExtent flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); if (flutterNode.isNull) { LOGE("FlutterSetElementInfoProperties: GetFlutterSemanticsNode id=%{public}ld null", elementId); } // set elementinfo id - int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); if (OH_ArkUI_AccessibilityElementInfoSetElementId == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetElementId is null, %{public}s", dlerror()); @@ -925,7 +930,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( // 配置arkui的elementinfo可操作动作属性 if (IsTextField(flutterNode)) { // 若当前flutter节点为文本输入框组件 - std::string widgeType = flutterNode.HasFlag(FLAGS_::kIsMultiline) ? EDIT_MULTILINE_TEXT_WIDGET_NAME : EDIT_TEXT_WIDGET_NAME; + std::string widgeType = flutterNode.HasFlag(FLAGS_::kIsMultiline) ? + EDIT_MULTILINE_TEXT_WIDGET_NAME : EDIT_TEXT_WIDGET_NAME; FlutterSetElementInfoOperationActions(elementInfoFromList, widgeType); } else if (IsScrollableWidget(flutterNode) || IsNodeScrollable(flutterNode)) { // 若当前flutter节点为可滑动组件类型 @@ -991,7 +997,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( << " childCount=" << childCount << " childNodeIds=" << childNodeIds[i]; } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); @@ -1157,7 +1163,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( FML_DLOG(INFO) << "FlutterNodeToElementInfoById componentTypeName = " << componentTypeName; // flutter节点对应elementinfo所属的组件类型(如:root, button,text等) - int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); if (OH_ArkUI_AccessibilityElementInfoSetComponentType == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetComponentType is null, %{public}s", dlerror()); @@ -1241,7 +1247,7 @@ void OhosAccessibilityBridge::BuildArkUISemanticsTree( ArkUI_AccessibilityElementInfo* elementInfoFromList, ArkUI_AccessibilityElementInfoList* elementList) { - if (OH_GetSdkApiVersion() >= 13) { + if (OHOS_API_VERSION >= 13) { //配置root节点信息 FlutterNodeToElementInfoById(elementInfoFromList, elementId); //获取flutter无障碍语义树的节点总数 @@ -1303,7 +1309,7 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( accessibilityFeatures_->SetAccessibleNavigation(true, native_shell_holder_id_); } - if (OH_GetSdkApiVersion() >= 13) { + if (OHOS_API_VERSION >= 13) { // 从elementinfolist中获取elementinfo auto* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); @@ -1373,7 +1379,7 @@ void OhosAccessibilityBridge::DoubleClickRouteToNewPage(SemanticsNodeExtent node * perform click action in accessibility status */ void OhosAccessibilityBridge::PerformClickAction( - int64_t elementId, + int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode) { @@ -1392,7 +1398,7 @@ void OhosAccessibilityBridge::PerformClickAction( * perform long-press action in accessibility status */ void OhosAccessibilityBridge::PerformLongClickAction( - int64_t elementId, + int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode) { @@ -1439,7 +1445,7 @@ void OhosAccessibilityBridge::PerformGainFocusnAction( * perform focus clearance in accessibility status */ void OhosAccessibilityBridge::PerformClearFocusAction( - int64_t elementId, + int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode) { @@ -1528,7 +1534,7 @@ void OhosAccessibilityBridge::PerformScrollDownAction( * perform invalid action in accessibility status */ void OhosAccessibilityBridge::PerformClipboardAction( - int64_t elementId, + int64_t elementId, ArkUI_Accessibility_ActionType action) { if (action == ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY) { @@ -1546,7 +1552,7 @@ void OhosAccessibilityBridge::PerformClipboardAction( * perform invalid action in accessibility status */ void OhosAccessibilityBridge::PerformInvalidAction( - int64_t elementId, + int64_t elementId, ArkUI_Accessibility_ActionType action, SemanticsNodeExtent flutterNode) { @@ -1566,22 +1572,25 @@ void OhosAccessibilityBridge::PerformSetText( ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments) { - if (OH_GetSdkApiVersion() >= 13) { + if (OHOS_API_VERSION >= 13) { int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); if (OH_ArkUI_FindAccessibilityActionArgumentByKey == nullptr) { - LOGE("OH_ArkUI_FindAccessibilityActionArgumentByKey is null, %{public}s", dlerror()); + LOGE("OH_ArkUI_FindAccessibilityActionArgumentByKey is null, %{public}s", dlerror()); } const char* key_setText = "setText"; const char* valueStr = flutterNode.value.c_str(); char* newValue = strdup(valueStr); char** value = &newValue; - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); if (newValue == nullptr) { LOGE("PerformSetText -> OH_ArkUI_FindAccessibilityActionArgumentByKey get null value"); } auto flutterSetTextAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(flutterNode.id, flutterSetTextAction, fml::MallocMapping::Copy(newValue, strlen(newValue))); + DispatchSemanticsAction(flutterNode.id, + flutterSetTextAction, + fml::MallocMapping::Copy(newValue, strlen(newValue))); flutterNode.value = newValue; flutterNode.valueAttributes = {}; LOGI("ExecuteAccessibilityAction -> action: set text(%{public}d), newText=%{public}s", action, newValue); @@ -1855,7 +1864,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( "AccessibilityProvider = nullptr"; return; } - if (OH_GetSdkApiVersion() >= 13) { + if (OHOS_API_VERSION >= 13) { // 1.创建eventInfo对象 ArkUI_AccessibilityEventInfo* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); @@ -1870,7 +1879,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( } // 2.创建的elementinfo并根据对应id的flutternode进行属性初始化 - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = + ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); if (OH_ArkUI_CreateAccessibilityElementInfo == nullptr) { LOGE("OH_ArkUI_CreateAccessibilityElementInfo is null, %{public}s", dlerror()); @@ -1879,7 +1888,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( FlutterNodeToElementInfoById(_elementInfo, elementId); // 若为获焦事件,则设置当前elementinfo获焦 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused)(ArkUI_AccessibilityElementInfo*, bool) = + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused"); if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused == nullptr) { LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused is null, %{public}s", dlerror()); @@ -1891,7 +1900,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( } // 3.设置发送事件,如配置获焦、失焦、点击、滑动事件 - int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = + int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); if (OH_ArkUI_AccessibilityEventSetEventType == nullptr) { LOGE("OH_ArkUI_AccessibilityEventSetEventType is null, %{public}s", dlerror()); @@ -1899,7 +1908,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetEventType(eventInfo, eventType)); // 4.将eventinfo事件和当前elementinfo进行绑定 - int32_t (*OH_ArkUI_AccessibilityEventSetElementInfo)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityElementInfo*) = + int32_t (*OH_ArkUI_AccessibilityEventSetElementInfo)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityElementInfo*) = OhosAccessibilityDDL::DLLoadSetEventElemFunc("OH_ArkUI_AccessibilityEventSetElementInfo"); if (OH_ArkUI_AccessibilityEventSetElementInfo == nullptr) { LOGE("OH_ArkUI_AccessibilityEventSetElementInfo is null, %{public}s", dlerror()); @@ -1914,7 +1923,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( }; // 6.发送event到OH侧 - void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = + void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); if (OH_ArkUI_SendAccessibilityAsyncEvent == nullptr) { LOGE("OH_ArkUI_SendAccessibilityAsyncEvent is null, %{public}s", dlerror()); @@ -1930,7 +1939,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); _elementInfo = nullptr; - void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = + void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); if (OH_ArkUI_DestoryAccessibilityEventInfo == nullptr) { LOGE("OH_ArkUI_DestoryAccessibilityEventInfo is null, %{public}s", dlerror()); @@ -1969,7 +1978,7 @@ std::string OhosAccessibilityBridge::GetNodeComponentType( return HEADER_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kIsImage)) { - return IMAGE_WIDGET_NAME; + return IMAGE_WIDGET_NAME; } if (node.HasFlag(FLAGS_::kHasCheckedState)) { if (node.HasFlag(FLAGS_::kIsInMutuallyExclusiveGroup)) { @@ -2087,7 +2096,7 @@ bool OhosAccessibilityBridge::IsNodeEnabled( */ bool OhosAccessibilityBridge::IsNodeShowOnScreen(SemanticsNodeExtent flutterNode) { - return flutterNode.HasAction(ACTIONS_::kShowOnScreen); + return flutterNode.HasAction(ACTIONS_::kShowOnScreen); } /** * 判断当前节点是否已经滑动 @@ -2107,7 +2116,7 @@ bool OhosAccessibilityBridge::HasChangedLabel(const SemanticsNodeExtent& flutter if (flutterNode.label.empty() && flutterNode.previousLabel.empty()) { return false; } - return flutterNode.label.empty() || + return flutterNode.label.empty() || flutterNode.previousLabel.empty() || flutterNode.label != flutterNode.previousLabel; } @@ -2223,7 +2232,7 @@ void OhosAccessibilityBridge::RemoveSemanticsNode( for (auto it = g_parentChildIdVec.begin(); it != g_parentChildIdVec.end(); it++) { if (it->first == nodeToBeRemovedParentId && it->second == nodeToBeRemoved.id) { - g_parentChildIdVec.erase(it); + g_parentChildIdVec.erase(it); } } } diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index e8c78b71ca..39d14c80eb 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -56,10 +56,12 @@ 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; } }; @@ -166,7 +168,7 @@ private: SemanticsNodeExtent lastInputFocusedNode; SemanticsNodeExtent accessibilityFocusedNode; - // arkui的root节点的父节点id + static const int32_t OHOS_API_VERSION; static const int32_t ARKUI_ACCESSIBILITY_ROOT_PARENT_ID = -2100000; static const int32_t RET_ERROR_STATE_CODE = -1; static const int32_t ROOT_NODE_ID = 0; diff --git a/shell/platform/ohos/flutter_embedding/build-profile.json5 b/shell/platform/ohos/flutter_embedding/build-profile.json5 index c4150bb5a3..5e149a729c 100755 --- a/shell/platform/ohos/flutter_embedding/build-profile.json5 +++ b/shell/platform/ohos/flutter_embedding/build-profile.json5 @@ -15,7 +15,21 @@ { "app": { - "signingConfigs": [], + "signingConfigs": [ + { + "name": "default", + "type": "HarmonyOS", + "material": { + "certpath": "/Users/zijunxi/.ohos/config/default_flutter_embedding_rLTIk1jnFi1EHzVwrHLRwd24RS6fY4RPUwPq20ZOPzE=.cer", + "storePassword": "0000001B08FA11B2A4DAA98102847DAFB98304F1AC13B13A6B8F79579BEAF52F6A1D5D4DB74E2647047F9B", + "keyAlias": "debugKey", + "keyPassword": "0000001BF3FB1B423C45C8C2E02B8384FCD4271C32DC52C9B957E68D247C420B785F45D26558EB30EBD53D", + "profile": "/Users/zijunxi/.ohos/config/default_flutter_embedding_rLTIk1jnFi1EHzVwrHLRwd24RS6fY4RPUwPq20ZOPzE=.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "/Users/zijunxi/.ohos/config/default_flutter_embedding_rLTIk1jnFi1EHzVwrHLRwd24RS6fY4RPUwPq20ZOPzE=.p12" + } + } + ], "products": [ { "name": "default", diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index ef196b0b6c..431ff15b31 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -1871,8 +1871,11 @@ napi_value PlatformViewOHOSNapi::nativeAccessibilityStateChange( (state ? "true" : "false")); //send to accessibility bridge - auto a11y_bridge = OhosAccessibilityBridge::GetInstance(); - a11y_bridge->OnOhosAccessibilityStateChange(shell_holder_id, state); + const int32_t OHOS_API_VERSION = OH_GetSdkApiVersion(); + if (OHOS_API_VERSION >= 13) { + auto a11y_bridge = OhosAccessibilityBridge::GetInstance(); + a11y_bridge->OnOhosAccessibilityStateChange(shell_holder_id, state); + } FML_DLOG(INFO) << "nativeAccessibilityStateChange: state=" << state << " shell_holder_id=" << shell_holder_id; return nullptr; @@ -1893,8 +1896,11 @@ napi_value PlatformViewOHOSNapi::nativeAnnounce( napi_get_value_string_utf8(env, args[0], char_array.get(), null_terminated_length, nullptr); LOGD("PlatformViewOHOSNapi::nativeAnnounce message: %{public}s", char_array.get()); - auto handler = std::make_shared(); - handler->Announce(char_array); + const int32_t OHOS_API_VERSION = OH_GetSdkApiVersion(); + if (OHOS_API_VERSION >= 13) { + auto handler = std::make_shared(); + handler->Announce(char_array); + } return nullptr; } diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.h b/shell/platform/ohos/napi/platform_view_ohos_napi.h index 34be921e97..b246ad75c0 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.h +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.h @@ -16,6 +16,7 @@ #ifndef PLATFORM_VIEW_OHOS_NAPI_H #define PLATFORM_VIEW_OHOS_NAPI_H #include +#include #include "flutter/assets/directory_asset_bundle.h" #include "flutter/common/settings.h" #include "flutter/fml/file.h" diff --git a/shell/platform/ohos/utils/ohos_utils.cpp b/shell/platform/ohos/utils/ohos_utils.cpp index fd4b68f7e6..23813a7528 100644 --- a/shell/platform/ohos/utils/ohos_utils.cpp +++ b/shell/platform/ohos/utils/ohos_utils.cpp @@ -22,7 +22,7 @@ OHOSUtils::~OHOSUtils() {}; * 判断源字符串是否包含目标字符串 */ bool OHOSUtils::Contains(const std::string source, - const std::string target) + const std::string target) { return source.find(target) != std::string::npos; } diff --git a/shell/platform/ohos/utils/ohos_utils.h b/shell/platform/ohos/utils/ohos_utils.h index 802d6f306a..f76e79bef3 100644 --- a/shell/platform/ohos/utils/ohos_utils.h +++ b/shell/platform/ohos/utils/ohos_utils.h @@ -28,6 +28,4 @@ public: }; } - - -#endif +#endif -- Gitee From 106c56ff79f2daa13130257ac89e238bfe47c861 Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 16 Dec 2024 17:57:24 +0800 Subject: [PATCH 18/60] =?UTF-8?q?=E5=88=A0=E9=99=A4=E7=AD=BE=E5=90=8D?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos/flutter_embedding/build-profile.json5 | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/build-profile.json5 b/shell/platform/ohos/flutter_embedding/build-profile.json5 index 5e149a729c..c4150bb5a3 100755 --- a/shell/platform/ohos/flutter_embedding/build-profile.json5 +++ b/shell/platform/ohos/flutter_embedding/build-profile.json5 @@ -15,21 +15,7 @@ { "app": { - "signingConfigs": [ - { - "name": "default", - "type": "HarmonyOS", - "material": { - "certpath": "/Users/zijunxi/.ohos/config/default_flutter_embedding_rLTIk1jnFi1EHzVwrHLRwd24RS6fY4RPUwPq20ZOPzE=.cer", - "storePassword": "0000001B08FA11B2A4DAA98102847DAFB98304F1AC13B13A6B8F79579BEAF52F6A1D5D4DB74E2647047F9B", - "keyAlias": "debugKey", - "keyPassword": "0000001BF3FB1B423C45C8C2E02B8384FCD4271C32DC52C9B957E68D247C420B785F45D26558EB30EBD53D", - "profile": "/Users/zijunxi/.ohos/config/default_flutter_embedding_rLTIk1jnFi1EHzVwrHLRwd24RS6fY4RPUwPq20ZOPzE=.p7b", - "signAlg": "SHA256withECDSA", - "storeFile": "/Users/zijunxi/.ohos/config/default_flutter_embedding_rLTIk1jnFi1EHzVwrHLRwd24RS6fY4RPUwPq20ZOPzE=.p12" - } - } - ], + "signingConfigs": [], "products": [ { "name": "default", -- Gitee From 0334924ef01b14aff09dabefc880897d658eb90e Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 16 Dec 2024 19:17:25 +0800 Subject: [PATCH 19/60] =?UTF-8?q?=E5=A2=9E=E5=8A=A0unittests=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=9A=84build.gn=E7=9A=84deviceinfo=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E5=BA=93=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- shell/platform/ohos/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/ohos/BUILD.gn b/shell/platform/ohos/BUILD.gn index 982c45eab5..7dd1671fa5 100644 --- a/shell/platform/ohos/BUILD.gn +++ b/shell/platform/ohos/BUILD.gn @@ -249,6 +249,7 @@ executable("flutter_ohos_unittests") { ldflags += ["-lnative_window"] ldflags += ["-lnative_vsync"] ldflags += ["-limage_ndk.z"] + ldflags += ["-ldeviceinfo_ndk.z"] ldflags += ["-lrawfile.z"] ldflags += ["-lnative_image"] ldflags += ["-lpixelmap_ndk.z"] -- Gitee From d4ef7a6c2968550bfef40ecccedd3dc83600ac18 Mon Sep 17 00:00:00 2001 From: laoguanyao <806103474@qq.com> Date: Mon, 16 Dec 2024 19:21:05 +0800 Subject: [PATCH 20/60] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=90=88=E7=90=86=E6=80=A7=EF=BC=8C=E5=88=A0=E9=99=A4=E6=98=93?= =?UTF-8?q?=E5=87=BA=E9=97=AE=E9=A2=98=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: laoguanyao <806103474@qq.com> --- .../ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets | 4 +--- .../flutter/src/main/ets/plugin/editing/TextInputPlugin.ets | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets index df56710974..1f3c735b0e 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets @@ -35,7 +35,6 @@ import FlutterNapi from '../engine/FlutterNapi'; import { FlutterView } from '../../view/FlutterView'; import FlutterManager from './FlutterManager'; import Any from '../../plugin/common/Any'; -import inputMethod from '@ohos.inputMethod'; const TAG = "FlutterAbilityDelegate"; const PLUGINS_RESTORATION_BUNDLE_KEY = "plugins"; @@ -56,7 +55,6 @@ class FlutterAbilityAndEntryDelegate implements ExclusiveAppComponent private engineGroup?: FlutterEngineGroup; private isHost:boolean = false; private flutterView?: FlutterView; - private inputMethodController: inputMethod.InputMethodController = inputMethod.getController(); constructor(host?: Host) { this.host = host; @@ -99,7 +97,7 @@ class FlutterAbilityAndEntryDelegate implements ExclusiveAppComponent this.flutterEngine?.getNavigationChannel()?.popRoute(); this.flutterEngine?.getPlatformViewsController()?.setBackNodeControllers(); } else { - this.inputMethodController.detach(); + this.flutterEngine?.getTextInputChannel()?.textInputMethodHandler?.hide(); } }); } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets index 5f3a67c362..50be54c4b0 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets @@ -324,9 +324,6 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { private sendKeyboardStatusCallback = (state: inputMethod.KeyboardStatus) => { this.keyboardStatus = state; - if (state == inputMethod.KeyboardStatus.HIDE) { - this.plugin.textInputChannel.onConnectionClosed(this.inputTarget.id); - } } private selectByRangeCallback = (range: inputMethod.Range) => { -- Gitee From f49b777a67bbd275b6100b17ba0276e71d3b4be0 Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 16 Dec 2024 20:32:44 +0800 Subject: [PATCH 21/60] =?UTF-8?q?=E5=9B=9E=E9=80=80skia.patch=E7=89=88?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E5=B9=B6=E5=A2=9E=E9=87=8F=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=AD=97=E9=87=8D=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- attachment/repos/skia.patch | 200 ++++++++++++++++++++++++------------ 1 file changed, 133 insertions(+), 67 deletions(-) diff --git a/attachment/repos/skia.patch b/attachment/repos/skia.patch index d85176705f..d4edec37a9 100644 --- a/attachment/repos/skia.patch +++ b/attachment/repos/skia.patch @@ -1,5 +1,5 @@ diff --git a/BUILD.gn b/BUILD.gn -index ebbd898ec9..2d4257e8d7 100644 +index ebbd898ec9..015bb75414 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -26,16 +26,21 @@ import("gn/ios.gni") @@ -7,7 +7,7 @@ index ebbd898ec9..2d4257e8d7 100644 # Skia public API, generally provided by :skia. config("skia_public") { - include_dirs = [ "." ] -+ include_dirs = [ ".", ++ include_dirs = [ ".", + "//third_part/khronos/", ] defines = [] @@ -142,16 +142,22 @@ index ebbd898ec9..2d4257e8d7 100644 ] if (!skia_enable_winuwp) { -@@ -1559,7 +1612,7 @@ skia_component("skia") { - ] +@@ -1566,6 +1619,14 @@ skia_component("skia") { + } } -- if (is_linux || is_wasm) { -+ if (is_linux || is_wasm || is_ohos) { - sources += [ "src/ports/SkDebug_stdio.cpp" ] - if (skia_use_egl) { - libs += [ "GLESv2" ] -@@ -1962,7 +2015,7 @@ if (skia_enable_tools) { ++ if (is_ohos) { ++ sources += [ "src/ports/SkDebug_ohos.cpp" ] ++ if (skia_use_egl) { ++ libs += [ "GLESv2" ] ++ } ++ libs += [ "hilog_ndk.z" ] ++ } ++ + if (is_mac) { + public += [ "include/ports/SkCFObject.h" ] + sources += [ +@@ -1962,7 +2023,7 @@ if (skia_enable_tools) { if (is_android || skia_use_egl) { sources += [ "tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp" ] libs += [ "EGL" ] @@ -160,7 +166,7 @@ index ebbd898ec9..2d4257e8d7 100644 sources += [ "tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp" ] libs += [ "GLU", -@@ -2281,7 +2334,7 @@ if (skia_enable_tools) { +@@ -2281,7 +2342,7 @@ if (skia_enable_tools) { ] } @@ -169,7 +175,7 @@ index ebbd898ec9..2d4257e8d7 100644 if (skia_enable_skottie) { test_app("skottie_tool") { deps = [ "modules/skottie:tool" ] -@@ -2777,7 +2830,7 @@ if (skia_enable_tools) { +@@ -2777,7 +2838,7 @@ if (skia_enable_tools) { "tools/sk_app/android/surface_glue_android.h", ] libs += [ "android" ] @@ -178,7 +184,7 @@ index ebbd898ec9..2d4257e8d7 100644 sources += [ "tools/SkGetExecutablePath_linux.cpp", "tools/sk_app/unix/RasterWindowContext_unix.cpp", -@@ -2830,7 +2883,7 @@ if (skia_enable_tools) { +@@ -2830,7 +2891,7 @@ if (skia_enable_tools) { sources += [ "tools/sk_app/GLWindowContext.h" ] if (is_android) { sources += [ "tools/sk_app/android/GLWindowContext_android.cpp" ] @@ -187,7 +193,7 @@ index ebbd898ec9..2d4257e8d7 100644 sources += [ "tools/sk_app/unix/GLWindowContext_unix.cpp" ] } else if (is_win) { sources += [ "tools/sk_app/win/GLWindowContext_win.cpp" ] -@@ -2855,7 +2908,7 @@ if (skia_enable_tools) { +@@ -2855,7 +2916,7 @@ if (skia_enable_tools) { sources += [ "tools/sk_app/VulkanWindowContext.h" ] if (is_android) { sources += [ "tools/sk_app/android/VulkanWindowContext_android.cpp" ] @@ -196,7 +202,7 @@ index ebbd898ec9..2d4257e8d7 100644 sources += [ "tools/sk_app/unix/VulkanWindowContext_unix.cpp" ] libs += [ "X11-xcb" ] } else if (is_win) { -@@ -2887,7 +2940,7 @@ if (skia_enable_tools) { +@@ -2887,7 +2948,7 @@ if (skia_enable_tools) { if (skia_use_dawn) { sources += [ "tools/sk_app/DawnWindowContext.cpp" ] sources += [ "tools/sk_app/DawnWindowContext.h" ] @@ -205,7 +211,7 @@ index ebbd898ec9..2d4257e8d7 100644 if (dawn_enable_vulkan) { sources += [ "tools/sk_app/unix/DawnVulkanWindowContext_unix.cpp" ] defines = [ "VK_USE_PLATFORM_XCB_KHR" ] -@@ -2931,7 +2984,7 @@ if (skia_enable_tools) { +@@ -2931,7 +2992,7 @@ if (skia_enable_tools) { } } @@ -214,7 +220,7 @@ index ebbd898ec9..2d4257e8d7 100644 test_app("fiddle_examples") { sources = [ "tools/fiddle/all_examples.cpp", -@@ -3088,7 +3141,7 @@ if (skia_enable_tools) { +@@ -3088,7 +3149,7 @@ if (skia_enable_tools) { } } @@ -327,6 +333,21 @@ index b43526fe1f..fb34289da7 100644 ldflags = [ "-rdynamic", "-Wl,-rpath,\$ORIGIN", +diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp +index bdcf607d04..2e92ed05f3 100644 +--- a/src/core/SkRRect.cpp ++++ b/src/core/SkRRect.cpp +@@ -231,8 +231,8 @@ bool SkRRect::scaleRadii() { + double scale = 1.0; + + // The sides of the rectangle may be larger than a float. +- double width = (double)fRect.fRight - (double)fRect.fLeft; +- double height = (double)fRect.fBottom - (double)fRect.fTop; ++ double width = (double)(fRect.fRight - fRect.fLeft); ++ double height = (double)(fRect.fBottom - fRect.fTop); + scale = compute_min_scale(fRadii[0].fX, fRadii[1].fX, width, scale); + scale = compute_min_scale(fRadii[1].fY, fRadii[2].fY, height, scale); + scale = compute_min_scale(fRadii[2].fX, fRadii[3].fX, width, scale); diff --git a/src/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.cpp b/src/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.cpp index 78225b4610..c2105852b1 100644 --- a/src/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.cpp @@ -1070,12 +1091,50 @@ index 0000000000..eb318dc3a3 +#endif + +#endif /* __gl2platform_h_ */ +diff --git a/src/ports/SkDebug_ohos.cpp b/src/ports/SkDebug_ohos.cpp +new file mode 100644 +index 0000000000..0e5e0829b6 +--- /dev/null ++++ b/src/ports/SkDebug_ohos.cpp +@@ -0,0 +1,32 @@ ++// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#include "include/core/SkTypes.h" ++ ++#include ++#include ++ ++ ++#ifdef HILOG_LOG_DOMAIN ++ #undef HILOG_LOG_DOMAIN ++#endif ++ ++#ifdef HILOG_LOG_TAG ++ #undef HILOG_LOG_DOMAIN ++#endif ++ ++ ++#define HILOG_LOG_DOMAIN 0x0000 ++#define HILOG_LOG_TAG "Skia" ++ ++void SkDebugf(const char format[], ...) { ++ char outStr[1024] = { 0 }; ++ va_list args; ++ va_start(args, format); ++ (void)vsnprintf(outStr,sizeof(outStr), format, args); ++ va_end(args); ++ ++ (void)OH_LOG_Print(LOG_APP, LOG_INFO, HILOG_LOG_DOMAIN,\ ++ HILOG_LOG_TAG, "%{public}s", outStr); ++} diff --git a/src/ports/skia_ohos/FontConfig_ohos.cpp b/src/ports/skia_ohos/FontConfig_ohos.cpp new file mode 100644 -index 0000000000..c502ed853e +index 0000000000..ea5c8ecf84 --- /dev/null +++ b/src/ports/skia_ohos/FontConfig_ohos.cpp -@@ -0,0 +1,1308 @@ +@@ -0,0 +1,1312 @@ +// Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -1138,6 +1197,10 @@ index 0000000000..c502ed853e + */ +int FontConfig_OHOS::getFamilyCount() const +{ ++#if ENABLE_DEBUG ++ dumpGeneric(); ++ dumpFallback(); ++#endif + return genericFamilySet.size(); +} + @@ -1490,7 +1553,7 @@ index 0000000000..c502ed853e + */ +void FontConfig_OHOS::dumpFont(const FontInfo& font) const +{ -+ LOGI("name=%s, family=%s, weight=%d, width=%d, slant=%d, index=%d", ++ SkDEBUGF("name=%s, family=%s, weight=%d, width=%d, slant=%d, index=%d", + font.fname.c_str(), font.familyName.c_str(), font.style.weight(), font.style.width(), font.style.slant(), + font.index); + int count = font.axisSet.axis.size(); @@ -1502,7 +1565,7 @@ index 0000000000..c502ed853e + str.append(","); + } + } -+ LOGI("axis={%s}\n", str.c_str()); ++ SkDEBUGF("axis={%s}\n", str.c_str()); + } +} + @@ -1510,9 +1573,9 @@ index 0000000000..c502ed853e + */ +void FontConfig_OHOS::dumpGeneric() const +{ -+ LOGI("\n"); ++ SkDEBUGF("\n"); + for (unsigned int i = 0; i < genericFamilySet.size(); i++) { -+ LOGI("[%d] familyName : %s - %d\n", i, genericFamilySet[i]->familyName.c_str(), ++ SkDEBUGF("[%d] familyName : %s - %d\n", i, genericFamilySet[i]->familyName.c_str(), + static_cast(genericFamilySet[i]->typefaceSet->size())); + for (int j = 0; j < genericFamilySet[i]->typefaceSet->size(); j++) { + if ((*(genericFamilySet[i]->typefaceSet))[j].get()) { @@ -1520,10 +1583,10 @@ index 0000000000..c502ed853e + if (font) { + dumpFont(*font); + } else { -+ LOGE("font [%d] is null\n", j); ++ SkDEBUGF("font [%d] is null\n", j); + } + } else { -+ LOGE("typefeace [%d] is null\n", j); ++ SkDEBUGF("typefeace [%d] is null\n", j); + } + } + } @@ -1533,21 +1596,21 @@ index 0000000000..c502ed853e + */ +void FontConfig_OHOS::dumpFallback() const +{ -+ LOGI("\n"); ++ SkDEBUGF("\n"); + int count = 0; + fallbackForMap.foreach([this, &count](const SkString& key, + const FallbackSetPos& setIndex) { -+ LOGI("[%d] family : %s - %d\n", count++, key.c_str(), setIndex.count); ++ SkDEBUGF("[%d] family : %s - %d\n", count++, key.c_str(), setIndex.count); + for (unsigned int i = setIndex.index; i < setIndex.index + setIndex.count; i++) { + const TypefaceSet& tpSet = *(fallbackSet[i]->typefaceSet.get()); -+ LOGI("[%s] - %d\n", fallbackSet[i]->familyName.c_str(), static_cast(tpSet.size())); ++ SkDEBUGF("[%s] - %d\n", fallbackSet[i]->familyName.c_str(), static_cast(tpSet.size())); + + for (unsigned int j = 0; j < tpSet.size(); j++) { + const FontInfo* font = tpSet[j]->getFontInfo(); + if (font) { + this->dumpFont(*font); + } else { -+ LOGE("font [%d] is null\n", j); ++ SkDEBUGF("font [%d] is null\n", j); + } + } + } @@ -1897,7 +1960,7 @@ index 0000000000..c502ed853e + if (root.size() != keyCount) { + text.appendf("%s#0", key); + errSet.emplace_back(ret, text.c_str()); -+ LOGE("%s : '%s' size should be 2, but here it's %d\n", errToString(ret), key, root.size()); ++ SkDEBUGF("%s : '%s' size should be 2, but here it's %d\n", errToString(ret), key, root.size()); + return ret; + } else if (!root[0].isString()) { + text.appendf("%s#1", key); @@ -2043,7 +2106,7 @@ index 0000000000..c502ed853e + } else { + err = ERROR_FONT_INVALID_STREAM; + } -+ LOGE("%s : %s\n", errToString(err), fname); ++ SkDEBUGF("%s : %s\n", errToString(err), fname); + char* fnameCopy = strdup(fname); + errSet.emplace_back(err, basename(fnameCopy)); + free(fnameCopy); @@ -2295,7 +2358,7 @@ index 0000000000..c502ed853e +{ + errSet.emplace_back(err, key); + if (err != ERROR_CONFIG_INVALID_VALUE_TYPE) { -+ LOGE("%s : %s\n", errToString(err), key); ++ SkDEBUGF("%s : %s\n", errToString(err), key); + } else { + const char* types[] = { + "null", @@ -2310,10 +2373,10 @@ index 0000000000..c502ed853e + int size = sizeof(types) / sizeof(char*); + if ((expected >= 0 && expected < size) && + (actual >= 0 && actual < size)) { -+ LOGE("%s : '%s' should be '%s', but here it's '%s'\n", ++ SkDEBUGF("%s : '%s' should be '%s', but here it's '%s'\n", + errToString(err), key, types[expected], types[actual]); + } else { -+ LOGE("%s : %s\n", errToString(err), key); ++ SkDEBUGF("%s : %s\n", errToString(err), key); + } + } + return err; @@ -2386,10 +2449,10 @@ index 0000000000..c502ed853e +} diff --git a/src/ports/skia_ohos/FontConfig_ohos.h b/src/ports/skia_ohos/FontConfig_ohos.h new file mode 100644 -index 0000000000..d23dc47c44 +index 0000000000..edd2c51495 --- /dev/null +++ b/src/ports/skia_ohos/FontConfig_ohos.h -@@ -0,0 +1,234 @@ +@@ -0,0 +1,217 @@ +// Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -2410,23 +2473,6 @@ index 0000000000..d23dc47c44 +#include "FontInfo_ohos.h" +#include "SkTypeface_ohos.h" + -+#ifdef ENABLE_DEBUG -+ -+#define LOGE(fmt, args...) \ -+ printf("E %s:%d %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args) -+#define LOGI(fmt, args...) \ -+ printf("I %s:%d - " fmt, __FUNCTION__, __LINE__, ##args) -+#define LOGW(fmt, args...) \ -+ printf("W %s:%d %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args) -+ -+#else -+ -+#define LOGE SkDEBUGF -+#define LOGI SkDEBUGF -+#define LOGW SkDEBUGF -+ -+#endif -+ +struct FontInfo; +struct FallbackInfo; +struct GenericFamily; @@ -2775,15 +2821,9 @@ index 0000000000..0b851ae3fa +}; + +#endif /* FONTINFO_OHOS_H */ -diff --git a/src/ports/skia_ohos/HmSymbolConfig_ohos.cpp b/src/ports/skia_ohos/HmSymbolConfig_ohos.cpp -new file mode 100644 -index 0000000000..e69de29bb2 -diff --git a/src/ports/skia_ohos/HmSymbolConfig_ohos.h b/src/ports/skia_ohos/HmSymbolConfig_ohos.h -new file mode 100644 -index 0000000000..e69de29bb2 diff --git a/src/ports/skia_ohos/SkFontMgr_ohos.cpp b/src/ports/skia_ohos/SkFontMgr_ohos.cpp new file mode 100644 -index 0000000000..029d105ebc +index 0000000000..a18757d5d5 --- /dev/null +++ b/src/ports/skia_ohos/SkFontMgr_ohos.cpp @@ -0,0 +1,437 @@ @@ -2924,7 +2964,7 @@ index 0000000000..029d105ebc + } + } + if (item == nullptr) { -+ LOGE("%s : '%s' must be a fallback key in the config file\n", ++ SkDEBUGF("%s : '%s' must be a fallback key in the config file\n", + FontConfig_OHOS::errToString(ERROR_FAMILY_NOT_FOUND), defaultFamily.c_str()); + return nullptr; + } @@ -3142,7 +3182,7 @@ index 0000000000..029d105ebc + + std::unique_ptr stream = SkStreamAsset::MakeFromFile(path); + if (stream == nullptr) { -+ LOGE("%s : %s\n", FontConfig_OHOS::errToString(ERROR_FONT_NOT_EXIST), path); ++ SkDEBUGF("%s : %s\n", FontConfig_OHOS::errToString(ERROR_FONT_NOT_EXIST), path); + return nullptr; + } + SkFontArguments args; @@ -3169,7 +3209,7 @@ index 0000000000..029d105ebc + if (typeface) { + return sk_sp(typeface); + } -+ LOGE("%s\n", FontConfig_OHOS::errToString(ERROR_NO_AVAILABLE_FAMILY)); ++ SkDEBUGF("%s\n", FontConfig_OHOS::errToString(ERROR_NO_AVAILABLE_FAMILY)); + return nullptr; +} + @@ -3193,14 +3233,14 @@ index 0000000000..029d105ebc + if (axisCount == 0) { + if (!fontScanner.scanFont(stream.get(), ttcIndex, &fontInfo.familyName, &fontInfo.style, + &fontInfo.isFixedWidth, nullptr)) { -+ LOGE("%s\n", FontConfig_OHOS::errToString(ERROR_FONT_INVALID_STREAM)); ++ SkDEBUGF("%s\n", FontConfig_OHOS::errToString(ERROR_FONT_INVALID_STREAM)); + return nullptr; + } + } else { + AxisDefinitions axisDef; + if (!fontScanner.scanFont(stream.get(), ttcIndex, &fontInfo.familyName, &fontInfo.style, + &fontInfo.isFixedWidth, &axisDef)) { -+ LOGE("%s\n", FontConfig_OHOS::errToString(ERROR_FONT_INVALID_STREAM)); ++ SkDEBUGF("%s\n", FontConfig_OHOS::errToString(ERROR_FONT_INVALID_STREAM)); + return nullptr; + } + if (axisDef.size() > 0) { @@ -3467,10 +3507,10 @@ index 0000000000..b9fb40cf1e +#endif /* SKFONTSTYLESET_OHOS_H */ diff --git a/src/ports/skia_ohos/SkTypeface_ohos.cpp b/src/ports/skia_ohos/SkTypeface_ohos.cpp new file mode 100644 -index 0000000000..3141944c32 +index 0000000000..05d3d56d1b --- /dev/null +++ b/src/ports/skia_ohos/SkTypeface_ohos.cpp -@@ -0,0 +1,139 @@ +@@ -0,0 +1,165 @@ +// Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -3481,6 +3521,29 @@ index 0000000000..3141944c32 +#include "SkFontHost_FreeType_common.h" +#include "SkTArray.h" + ++#if ENABLE_DEBUG ++/*! To print out the font information ++ * \param font the font object to be printed ++ */ ++void DumpFont(const FontInfo& font) const ++{ ++ SkDEBUGF("name=%s, family=%s, weight=%d, width=%d, slant=%d, index=%d", ++ font.fname.c_str(), font.familyName.c_str(), font.style.weight(), font.style.width(), font.style.slant(), ++ font.index); ++ int count = font.axisSet.axis.size(); ++ if (count > 0) { ++ SkString str; ++ for (unsigned int i = 0; i < count; i++) { ++ str.appendU32(SkFixedFloorToInt(font.axisSet.axis[i])); ++ if (i < count - 1) { ++ str.append(","); ++ } ++ } ++ SkDEBUGF("axis={%s}\n", str.c_str()); ++ } ++} ++#endif ++ +/*! Constructor + * \param familyName the specified family name for the typeface + * \param info the font information for the typeface @@ -3537,6 +3600,9 @@ index 0000000000..3141944c32 + if (fontInfo->stream.get() == nullptr) { + return nullptr; + } ++#if ENABLE_DEBUG ++ DumpFont(*fontInfo); ++#endif + return std::make_unique(fontInfo->stream->duplicate(), fontInfo->index, 0, + fontInfo->axisSet.axis.data(), fontInfo->axisSet.axis.size(), nullptr, 0); +} -- Gitee From 9505ac3f917bf13d81178a68f7ffb96e7c069cf6 Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 17 Dec 2024 15:04:34 +0800 Subject: [PATCH 22/60] =?UTF-8?q?refactor:=E5=B0=81=E8=A3=85=E5=AE=8F?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=88=A4=E6=96=AD=E7=A9=BA=E6=8C=87=E9=92=88?= =?UTF-8?q?=EF=BC=8C=E5=87=8F=E5=B0=91=E5=86=97=E4=BD=99=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=87=8F=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=BB=A3=E7=A0=81=E5=8F=AF?= =?UTF-8?q?=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 1523 ++++++++--------- shell/platform/ohos/utils/ddl_utils.h | 1 + 2 files changed, 692 insertions(+), 832 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 1224d30d56..ba0882e42c 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -30,14 +30,40 @@ #define ARKUI_FAILED_CODE -1 #define ARKUI_BAD_PARAM_CODE -2 #define ARKUI_OOM_CODE -3 -#define ARKUI_ACCESSIBILITY_CALL_CHECK(X) \ - do { \ - int32_t RET = X; \ - if (RET != ARKUI_SUCCEED_CODE) { \ - LOGE("Failed function %{public}s call, error code:%{public}d", \ - #X, RET); \ - } \ - } while (false) \ + +#define ARKUI_ACCESSIBILITY_CALL_CHECK(X) \ + do { \ + int32_t RET = X; \ + if (RET != ARKUI_SUCCEED_CODE) { \ + LOGE("Failed function %{public}s call, error code:%{public}d",\ + #X, RET); \ + } \ + } while (false) \ + +#define CHECK_DLL_NULL_PTR(func) \ + do { \ + if (func == nullptr) { \ + LOGE("Error: Function %{public}s is nullptr, %{public}s", \ + #func, LOAD_ERROR()); \ + } \ + } while (false) \ + +#define CHECK_NULL_PTR(PARAM, FUNC) \ + do { \ + if (PARAM == nullptr) { \ + LOGE("Error: %{public}s -> %{public}s is nullptr", \ + #FUNC, #PARAM); \ + } \ + } while (false) \ + +#define CHECK_NULL_PTR_WITH_RET(PARAM, FUNC) \ + do { \ + if (PARAM == nullptr) { \ + LOGE("Error: %{public}s -> %{public}s is nullptr", \ + #FUNC, #PARAM); \ + return ARKUI_FAILED_CODE; \ + } \ + } while (false) \ namespace flutter { @@ -151,12 +177,10 @@ void OhosAccessibilityBridge::UpdateSemantics( // 当滑动节点产生滑动,并执行滑动处理 if (HasScrolled(nodeEx)) { LOGD("UpdateSemantics -> has scrolled"); - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = + auto* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); - if (OH_ArkUI_CreateAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_CreateAccessibilityElementInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); + CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); + auto* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); FlutterNodeToElementInfoById(_elementInfo, static_cast(nodeEx.id)); // flutter滑动组件滑动处理逻辑 @@ -169,9 +193,7 @@ void OhosAccessibilityBridge::UpdateSemantics( void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); - if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityElementInfo); OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); _elementInfo = nullptr; } @@ -198,248 +220,204 @@ void OhosAccessibilityBridge::FlutterScrollExecution( SemanticsNodeExtent node, ArkUI_AccessibilityElementInfo* elementInfoFromList) { - if (OHOS_API_VERSION >= 13) { - double nodePosition = node.scrollPosition; - double nodeScrollExtentMax = node.scrollExtentMax; - double nodeScrollExtentMin = node.scrollExtentMin; - double infinity = std::numeric_limits::infinity(); - - // 设置flutter可滑动的最大范围值 - if (nodeScrollExtentMax == infinity) { - nodeScrollExtentMax = SCROLL_EXTENT_FOR_INFINITY; - if (nodePosition > SCROLL_POSITION_CAP_FOR_INFINITY) { - nodePosition = SCROLL_POSITION_CAP_FOR_INFINITY; - } - } - if (nodeScrollExtentMin == infinity) { - nodeScrollExtentMax += SCROLL_EXTENT_FOR_INFINITY; - if (nodePosition < -SCROLL_POSITION_CAP_FOR_INFINITY) { - nodePosition = -SCROLL_POSITION_CAP_FOR_INFINITY; - } - nodePosition += SCROLL_EXTENT_FOR_INFINITY; - } else { - nodeScrollExtentMax -= node.scrollExtentMin; - nodePosition -= node.scrollExtentMin; - } + if (OHOS_API_VERSION < 13) { return; } + double nodePosition = node.scrollPosition; + double nodeScrollExtentMax = node.scrollExtentMax; + double nodeScrollExtentMin = node.scrollExtentMin; + double infinity = std::numeric_limits::infinity(); - if (node.HasAction(ACTIONS_::kScrollUp) || - node.HasAction(ACTIONS_::kScrollDown)) { - } else if (node.HasAction(ACTIONS_::kScrollLeft) || - node.HasAction(ACTIONS_::kScrollRight)) { - LOGD("current flutterNode has scroll up/down/left/right"); + // 设置flutter可滑动的最大范围值 + if (nodeScrollExtentMax == infinity) { + nodeScrollExtentMax = SCROLL_EXTENT_FOR_INFINITY; + if (nodePosition > SCROLL_POSITION_CAP_FOR_INFINITY) { + nodePosition = SCROLL_POSITION_CAP_FOR_INFINITY; } - - // 当可滑动组件存在滑动子节点 - if (node.scrollChildren > 0) { - // 配置当前滑动组件的子节点总数 - int32_t itemCount = node.scrollChildren; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetItemCount)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetItemCount"); - if (OH_ArkUI_AccessibilityElementInfoSetItemCount == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetItemCount is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetItemCount(elementInfoFromList, itemCount)); - - // 设置当前页面可见的起始滑动index - int32_t startItemIndex = node.scrollIndex; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetStartItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetStartItemIndex"); - if (OH_ArkUI_AccessibilityElementInfoSetStartItemIndex == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetStartItemIndex is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetStartItemIndex(elementInfoFromList, startItemIndex)); - - // 设置当前获焦节点的当前index - int32_t currItemIndex = accessibilityFocusedNode.id; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex"); - if (OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex(elementInfoFromList, currItemIndex)); - - // 计算当前滑动位置页面的可见子滑动节点数量 - int visibleChildren = 0; - // handle hidden children at the beginning and end of the list. - for (const auto& childId : node.childrenInHitTestOrder) { - auto childNode = GetFlutterSemanticsNode(childId); - if (!childNode.HasFlag(FLAGS_::kIsHidden)) { - visibleChildren += 1; - } - } - // 当可见滑动子节点数量超过滑动组件总子节点数量 - if (node.scrollIndex + visibleChildren > node.scrollChildren) { - FML_DLOG(WARNING) - << "FlutterScrollExecution -> Scroll index is out of bounds"; - } - // 当滑动击中子节点数量为0 - if (!node.childrenInHitTestOrder.size()) { - FML_DLOG(WARNING) << "FlutterScrollExecution -> Had scrollChildren but no " - "childrenInHitTestOrder"; - } - // 设置当前页面可见的末尾滑动index - int32_t endItemIndex = node.scrollIndex + visibleChildren - 1; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEndItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetEndItemIndex"); - if (OH_ArkUI_AccessibilityElementInfoSetEndItemIndex == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetEndItemIndex is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetEndItemIndex(elementInfoFromList, endItemIndex) - ); + } + if (nodeScrollExtentMin == infinity) { + nodeScrollExtentMax += SCROLL_EXTENT_FOR_INFINITY; + if (nodePosition < -SCROLL_POSITION_CAP_FOR_INFINITY) { + nodePosition = -SCROLL_POSITION_CAP_FOR_INFINITY; } + nodePosition += SCROLL_EXTENT_FOR_INFINITY; + } else { + nodeScrollExtentMax -= node.scrollExtentMin; + nodePosition -= node.scrollExtentMin; } -} -/** - * 特定节点的焦点请求 (当页面更新时自动请求id=0节点获焦) - */ -void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) -{ - if (provider_ == nullptr) { - FML_DLOG(ERROR) << "RequestFocusWhenPageUpdate ->" - "AccessibilityProvider = nullptr"; - return; + if (node.HasAction(ACTIONS_::kScrollUp) || + node.HasAction(ACTIONS_::kScrollDown)) { + } else if (node.HasAction(ACTIONS_::kScrollLeft) || + node.HasAction(ACTIONS_::kScrollRight)) { + LOGD("current flutterNode has scroll up/down/left/right"); } - if (OHOS_API_VERSION >= 13) { - ArkUI_AccessibilityEventInfo* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); - if (OH_ArkUI_CreateAccessibilityEventInfo == nullptr) { - LOGE("OH_ArkUI_CreateAccessibilityEventInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityEventInfo* reqFocusEventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); - - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); - if (OH_ArkUI_CreateAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_CreateAccessibilityElementInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityElementInfo* elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); - int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = - OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); - if (OH_ArkUI_AccessibilityEventSetEventType == nullptr) { - LOGE("OH_ArkUI_AccessibilityEventSetEventType is null, %{public}s", dlerror()); - } + // 当可滑动组件存在滑动子节点 + if (node.scrollChildren > 0) { + // 配置当前滑动组件的子节点总数 + int32_t itemCount = node.scrollChildren; + int32_t (*OH_ArkUI_AccessibilityElementInfoSetItemCount)(ArkUI_AccessibilityElementInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetItemCount"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetItemCount); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityEventSetEventType( - reqFocusEventInfo, - ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_REQUEST_ACCESSIBILITY_FOCUS) - ); + OH_ArkUI_AccessibilityElementInfoSetItemCount(elementInfoFromList, itemCount)); - int32_t (*OH_ArkUI_AccessibilityEventSetRequestFocusId)(ArkUI_AccessibilityEventInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetReqFocusFunc("OH_ArkUI_AccessibilityEventSetRequestFocusId"); - if (OH_ArkUI_AccessibilityEventSetRequestFocusId == nullptr) { - LOGE("OH_ArkUI_AccessibilityEventSetRequestFocusId is null, %{public}s", dlerror()); - } + // 设置当前页面可见的起始滑动index + int32_t startItemIndex = node.scrollIndex; + int32_t (*OH_ArkUI_AccessibilityElementInfoSetStartItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetStartItemIndex"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetStartItemIndex); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityEventSetRequestFocusId(reqFocusEventInfo, - requestFocusId) - ); + OH_ArkUI_AccessibilityElementInfoSetStartItemIndex(elementInfoFromList, startItemIndex)); - int32_t (*OH_ArkUI_AccessibilityEventSetElementInfo)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadSetEventElemFunc("OH_ArkUI_AccessibilityEventSetElementInfo"); - if (OH_ArkUI_AccessibilityEventSetElementInfo == nullptr) { - LOGE("OH_ArkUI_AccessibilityEventSetElementInfo is null, %{public}s", dlerror()); + // 设置当前获焦节点的当前index + int32_t currItemIndex = accessibilityFocusedNode.id; + int32_t (*OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex(elementInfoFromList, currItemIndex)); + + // 计算当前滑动位置页面的可见子滑动节点数量 + int visibleChildren = 0; + // handle hidden children at the beginning and end of the list. + for (const auto& childId : node.childrenInHitTestOrder) { + auto childNode = GetFlutterSemanticsNode(childId); + if (!childNode.HasFlag(FLAGS_::kIsHidden)) { + visibleChildren += 1; + } } + // 当可见滑动子节点数量超过滑动组件总子节点数量 + if (node.scrollIndex + visibleChildren > node.scrollChildren) { + FML_DLOG(WARNING) + << "FlutterScrollExecution -> Scroll index is out of bounds"; + } + // 当滑动击中子节点数量为0 + if (!node.childrenInHitTestOrder.size()) { + FML_DLOG(WARNING) << "FlutterScrollExecution -> Had scrollChildren but no " + "childrenInHitTestOrder"; + } + // 设置当前页面可见的末尾滑动index + int32_t endItemIndex = node.scrollIndex + visibleChildren - 1; + int32_t (*OH_ArkUI_AccessibilityElementInfoSetEndItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetEndItemIndex"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetEndItemIndex); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityEventSetElementInfo(reqFocusEventInfo, elementInfo) + OH_ArkUI_AccessibilityElementInfoSetEndItemIndex(elementInfoFromList, endItemIndex) ); - - auto callback = [](int32_t errorCode) { - FML_DLOG(WARNING) << "PageStateUpdate callback-> errorCode =" << errorCode; - }; - - void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = - OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); - if (OH_ArkUI_SendAccessibilityAsyncEvent == nullptr) { - LOGE("OH_ArkUI_SendAccessibilityAsyncEvent is null, %{public}s", dlerror()); - } - OH_ArkUI_SendAccessibilityAsyncEvent(provider_, reqFocusEventInfo, callback); - - void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = - OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); - if (OH_ArkUI_DestoryAccessibilityEventInfo == nullptr) { - LOGE("OH_ArkUI_DestoryAccessibilityEventInfo is null, %{public}s", dlerror()); - } - OH_ArkUI_DestoryAccessibilityEventInfo(reqFocusEventInfo); - reqFocusEventInfo = nullptr; - - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); - if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); - } - OH_ArkUI_DestoryAccessibilityElementInfo(elementInfo); - elementInfo = nullptr; } } +/** + * 特定节点的焦点请求 (当页面更新时自动请求id=0节点获焦) + */ +void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) +{ + if (OHOS_API_VERSION < 13) { return; } + CHECK_NULL_PTR(provider_, RequestFocusWhenPageUpdate); + + auto* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = + OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); + auto* reqFocusEventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); + + auto* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = + OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); + auto* elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); + + int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = + OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetEventType); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityEventSetEventType( + reqFocusEventInfo, + ArkUI_AccessibilityEventType:: + ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_REQUEST_ACCESSIBILITY_FOCUS) + ); + + int32_t (*OH_ArkUI_AccessibilityEventSetRequestFocusId)(ArkUI_AccessibilityEventInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetReqFocusFunc("OH_ArkUI_AccessibilityEventSetRequestFocusId"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetRequestFocusId); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityEventSetRequestFocusId(reqFocusEventInfo, requestFocusId) + ); + + int32_t (*OH_ArkUI_AccessibilityEventSetElementInfo)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityElementInfo*) = + OhosAccessibilityDDL::DLLoadSetEventElemFunc("OH_ArkUI_AccessibilityEventSetElementInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetElementInfo); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityEventSetElementInfo(reqFocusEventInfo, elementInfo) + ); + + auto callback = [](int32_t errorCode) { + FML_DLOG(WARNING) << "PageStateUpdate callback-> errorCode =" << errorCode; + }; + + void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = + OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); + CHECK_DLL_NULL_PTR(OH_ArkUI_SendAccessibilityAsyncEvent); + OH_ArkUI_SendAccessibilityAsyncEvent(provider_, reqFocusEventInfo, callback); + + void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = + OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityEventInfo); + OH_ArkUI_DestoryAccessibilityEventInfo(reqFocusEventInfo); + reqFocusEventInfo = nullptr; + + void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = + OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityElementInfo); + OH_ArkUI_DestoryAccessibilityElementInfo(elementInfo); + elementInfo = nullptr; +} + /** * 主动播报特定文本 */ void OhosAccessibilityBridge::Announce(std::unique_ptr& message) { - if (provider_ == nullptr) { - FML_DLOG(ERROR) << "announce ->" - "AccessibilityProvider = nullptr"; - return; - } - if (OHOS_API_VERSION >= 13) { - // 创建并设置屏幕朗读事件 - ArkUI_AccessibilityEventInfo* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); - if (OH_ArkUI_CreateAccessibilityEventInfo == nullptr) { - LOGE("OH_ArkUI_CreateAccessibilityEventInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityEventInfo* announceEventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); - - - int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = - OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); - if (OH_ArkUI_AccessibilityEventSetEventType == nullptr) { - LOGE("OH_ArkUI_AccessibilityEventSetEventType is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityEventSetEventType( - announceEventInfo, - ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ANNOUNCE_FOR_ACCESSIBILITY) - ); - - int32_t (*OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility)(ArkUI_AccessibilityEventInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetEventStringFunc("OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility"); - if (OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility == nullptr) { - LOGE("OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility( - announceEventInfo, message.get()) - ); - FML_DLOG(INFO) << ("announce -> message: ") << (message.get()); - - auto callback = [](int32_t errorCode) { - FML_DLOG(WARNING) << "announce callback-> errorCode =" << errorCode; - }; - - void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = - OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); - if (OH_ArkUI_SendAccessibilityAsyncEvent == nullptr) { - LOGE("OH_ArkUI_SendAccessibilityAsyncEvent is null, %{public}s", dlerror()); - } - OH_ArkUI_SendAccessibilityAsyncEvent(provider_, announceEventInfo, callback); - - void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = - OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); - if (OH_ArkUI_DestoryAccessibilityEventInfo == nullptr) { - LOGE("OH_ArkUI_DestoryAccessibilityEventInfo is null, %{public}s", dlerror()); - } - OH_ArkUI_DestoryAccessibilityEventInfo(announceEventInfo); - announceEventInfo = nullptr; - } + if (OHOS_API_VERSION < 13) { return; } + CHECK_NULL_PTR(provider_, Announce); + + // 创建并设置屏幕朗读事件 + auto* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = + OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); + auto* announceEventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); + + + int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = + OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetEventType); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityEventSetEventType( + announceEventInfo, + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ANNOUNCE_FOR_ACCESSIBILITY) + ); + + int32_t (*OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility)(ArkUI_AccessibilityEventInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetEventStringFunc("OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility( + announceEventInfo, message.get()) + ); + FML_DLOG(INFO) << ("announce -> message: ") << (message.get()); + + auto callback = [](int32_t errorCode) { + FML_DLOG(WARNING) << "announce callback-> errorCode =" << errorCode; + }; + + void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = + OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); + CHECK_DLL_NULL_PTR(OH_ArkUI_SendAccessibilityAsyncEvent); + OH_ArkUI_SendAccessibilityAsyncEvent(provider_, announceEventInfo, callback); + + void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = + OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityEventInfo); + OH_ArkUI_DestoryAccessibilityEventInfo(announceEventInfo); + announceEventInfo = nullptr; } //获取根节点 @@ -617,11 +595,7 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( ArkUI_AccessibilityElementInfo* elementInfoFromList, int64_t elementId) { - if (elementInfoFromList == nullptr) { - FML_DLOG(INFO) << "OhosAccessibilityBridge::FlutterNodeToElementInfoById " - "elementInfoFromList is null"; - return; - } + CHECK_NULL_PTR(elementInfoFromList, FlutterNodeToElementInfoById); FML_DLOG(INFO) << "FlutterNodeToElementInfoById elementId = " << elementId; // 当elementId = -1或0时,创建root节点 @@ -640,9 +614,7 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( ArkUI_AccessibleRect rect = {left, top, right, bottom}; int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); - if (OH_ArkUI_AccessibilityElementInfoSetScreenRect == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetScreenRect is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetScreenRect); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect) ); @@ -656,17 +628,13 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( // 根据flutternode信息配置对应的elementinfo int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); - if (OH_ArkUI_AccessibilityElementInfoSetElementId == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetElementId is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetElementId); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, 0)); // NOTE: arkui无障碍子系统强制设置root的父节点id = -2100000 (严禁更改) int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); - if (OH_ArkUI_AccessibilityElementInfoSetParentId == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetParentId is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetParentId); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, ARKUI_ACCESSIBILITY_ROOT_PARENT_ID) ); @@ -674,9 +642,7 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( // 设置无障碍播报文本 int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityText == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityText); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityText( elementInfoFromList, flutterNode.label.empty() ? @@ -685,18 +651,14 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes") ); int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfoFromList, false) ); @@ -715,9 +677,7 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( } int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); - if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetChildNodeIds); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) ); @@ -726,44 +686,32 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( // 配置root节点常用属性 int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEnabled"); - if (OH_ArkUI_AccessibilityElementInfoSetEnabled == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetEnabled is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetEnabled); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfoFromList, true)); int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetClickable"); - if (OH_ArkUI_AccessibilityElementInfoSetClickable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetClickable is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetClickable); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfoFromList, true)); int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetFocusable"); - if (OH_ArkUI_AccessibilityElementInfoSetFocusable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetFocusable is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetFocusable); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfoFromList, true)); int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetVisible"); - if (OH_ArkUI_AccessibilityElementInfoSetVisible == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetVisible is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetVisible); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfoFromList, true)); int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); - if (OH_ArkUI_AccessibilityElementInfoSetComponentType == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetComponentType is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetComponentType); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, "root")); int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); - if (OH_ArkUI_AccessibilityElementInfoSetContents == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetContents is null, %{public}s", dlerror()); - } + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetContents); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetContents(elementInfoFromList, flutterNode.label.c_str())); } else { //当elementId >= 1时,根据flutter节点信息配置elementinfo无障碍属性 @@ -780,110 +728,107 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( ArkUI_AccessibilityElementInfo* elementInfoFromList, std::string widget_type) { - if (OHOS_API_VERSION >= 13) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetOperationActions)(ArkUI_AccessibilityElementInfo*, int32_t, ArkUI_AccessibleAction*) = - OhosAccessibilityDDL::DLLoadSetElemOperActionsFunc("OH_ArkUI_AccessibilityElementInfoSetOperationActions"); - if (OH_ArkUI_AccessibilityElementInfoSetOperationActions == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetOperationActions is null, %{public}s", dlerror()); - } - 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]; + if (OHOS_API_VERSION < 13) { return; } + int32_t (*OH_ArkUI_AccessibilityElementInfoSetOperationActions)(ArkUI_AccessibilityElementInfo*, int32_t, ArkUI_AccessibleAction*) = + OhosAccessibilityDDL::DLLoadSetElemOperActionsFunc("OH_ArkUI_AccessibilityElementInfoSetOperationActions"); + 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]; - actions[0].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; - actions[0].description = "获取焦点"; + actions[0].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; + actions[0].description = "获取焦点"; - actions[1].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; - actions[1].description = "清除焦点"; + actions[1].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; + actions[1].description = "清除焦点"; - actions[2].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; - actions[2].description = "点击操作"; + actions[2].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; + actions[2].description = "点击操作"; - actions[3].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_LONG_CLICK; - actions[3].description = "长按操作"; + actions[3].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_LONG_CLICK; + actions[3].description = "长按操作"; - actions[4].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY; - actions[4].description = "文本复制"; + actions[4].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY; + actions[4].description = "文本复制"; - actions[5].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_PASTE; - actions[5].description = "文本粘贴"; + actions[5].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_PASTE; + actions[5].description = "文本粘贴"; - actions[6].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CUT; - actions[6].description = "文本剪切"; + actions[6].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CUT; + actions[6].description = "文本剪切"; - actions[7].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SELECT_TEXT; - actions[7].description = "文本选择"; + actions[7].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SELECT_TEXT; + actions[7].description = "文本选择"; - actions[8].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_TEXT; - actions[8].description = "文本内容设置"; + actions[8].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_TEXT; + actions[8].description = "文本内容设置"; - actions[9].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_CURSOR_POSITION; - actions[9].description = "光标位置设置"; + actions[9].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_CURSOR_POSITION; + actions[9].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]; + 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]; - actions[0].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; - actions[0].description = "获取焦点"; + actions[0].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; + actions[0].description = "获取焦点"; - actions[1].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; - actions[1].description = "清除焦点"; + actions[1].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; + actions[1].description = "清除焦点"; - actions[2].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; - actions[2].description = "点击动作"; + actions[2].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; + actions[2].description = "点击动作"; - actions[3].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_FORWARD; - actions[3].description = "向上滑动"; + actions[3].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_FORWARD; + actions[3].description = "向上滑动"; - actions[4].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_BACKWARD; - actions[4].description = "向下滑动"; + actions[4].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_BACKWARD; + actions[4].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]; + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) + ); + } else { + // set common component action types + int32_t actionTypeNum = 3; + ArkUI_AccessibleAction actions[actionTypeNum]; - actions[0].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; - actions[0].description = "获取焦点"; + actions[0].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; + actions[0].description = "获取焦点"; - actions[1].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; - actions[1].description = "清除焦点"; + actions[1].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; + actions[1].description = "清除焦点"; - actions[2].actionType = ArkUI_Accessibility_ActionType:: - ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; - actions[2].description = "点击动作"; + actions[2].actionType = ArkUI_Accessibility_ActionType:: + ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; + actions[2].description = "点击动作"; - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) - ); - } + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) + ); } } @@ -894,318 +839,275 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( ArkUI_AccessibilityElementInfo* elementInfoFromList, int64_t elementId) { - if (OHOS_API_VERSION >= 13) { - SemanticsNodeExtent flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); - if (flutterNode.isNull) { - LOGE("FlutterSetElementInfoProperties: GetFlutterSemanticsNode id=%{public}ld null", elementId); - } + if (OHOS_API_VERSION < 13) { return; } + auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); + if (!g_flutterSemanticsTree.count(flutterNode.id)) { + LOGE("FlutterSetElementInfoProperties: GetFlutterSemanticsNode id=%{public}ld null", elementId); + } + + // set elementinfo id + int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetElementId); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, flutterNode.id) + ); + + // 相对-绝对坐标映射 + FlutterRelativeRectToScreenRect(flutterNode); + auto [left, top, right, bottom] = GetAbsoluteScreenRect(flutterNode); + ArkUI_AccessibleRect rect = {static_cast(left), static_cast(top), + static_cast(right), static_cast(bottom)}; + int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = + OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetScreenRect); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect) + ); + FML_DLOG(INFO) << "FlutterNodeToElementInfoById -> node.id= " + << flutterNode.id << " SceenRect = (" << left << ", " << top + << ", " << right << ", " << bottom << ")"; + + // 配置arkui的elementinfo可操作动作属性 + if (IsTextField(flutterNode)) { + // 若当前flutter节点为文本输入框组件 + std::string widgeType = flutterNode.HasFlag(FLAGS_::kIsMultiline) ? + EDIT_MULTILINE_TEXT_WIDGET_NAME : EDIT_TEXT_WIDGET_NAME; + FlutterSetElementInfoOperationActions(elementInfoFromList, widgeType); + } else if (IsScrollableWidget(flutterNode) || IsNodeScrollable(flutterNode)) { + // 若当前flutter节点为可滑动组件类型 + FlutterSetElementInfoOperationActions(elementInfoFromList, SCROLL_WIDGET_NAME); + } else { + // 若当前flutter节点为通用组件 + FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); + } - // set elementinfo id - int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); - if (OH_ArkUI_AccessibilityElementInfoSetElementId == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetElementId is null, %{public}s", dlerror()); - } + // 设置当前节点的父节点id + int32_t parentId = GetParentId(elementId); + int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = + OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetParentId); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, parentId) + ); + FML_DLOG(INFO) << "FlutterNodeToElementInfoById GetParentId = " << parentId; + + // 设置可朗读文本 + std::string text = flutterNode.label + flutterNode.value; + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityText); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetAccessibilityText(elementInfoFromList, text.c_str()) + ); + FML_DLOG(INFO) << "FlutterNodeToElementInfoById SetAccessibilityText = " << text; + + // 设置无障碍content文本 + int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetContents); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetContents(elementInfoFromList, text.c_str()) + ); + // 设置hint提示文本 + std::string hint = flutterNode.hint; + int32_t (*OH_ArkUI_AccessibilityElementInfoSetHintText)(ArkUI_AccessibilityElementInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetHintText"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetHintText); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetHintText(elementInfoFromList, hint.c_str()) + ); + + // 设置当前节点的全部孩子节点 + 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]); + FML_DLOG(INFO) << "FlutterNodeToElementInfoById -> elementid=" << elementId + << " childCount=" << childCount + << " childNodeIds=" << childNodeIds[i]; + } + int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = + OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetChildNodeIds); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, flutterNode.id) + OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) ); + } - // 相对-绝对坐标映射 - FlutterRelativeRectToScreenRect(flutterNode); - auto [left, top, right, bottom] = GetAbsoluteScreenRect(flutterNode); - ArkUI_AccessibleRect rect = {static_cast(left), static_cast(top), - static_cast(right), static_cast(bottom)}; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = - OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); - if (OH_ArkUI_AccessibilityElementInfoSetScreenRect == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetScreenRect is null, %{public}s", dlerror()); - } + /** + * 根据当前flutter节点的SemanticsFlags特性,配置对应的elmentinfo属性 + */ + // 判断当前节点组件是否enabled + if (IsNodeEnabled(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEnabled"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetEnabled); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect) + OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfoFromList, true) ); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById -> node.id= " - << flutterNode.id << " SceenRect = (" << left << ", " << top - << ", " << right << ", " << bottom << ")"; - - // 配置arkui的elementinfo可操作动作属性 - if (IsTextField(flutterNode)) { - // 若当前flutter节点为文本输入框组件 - std::string widgeType = flutterNode.HasFlag(FLAGS_::kIsMultiline) ? - EDIT_MULTILINE_TEXT_WIDGET_NAME : EDIT_TEXT_WIDGET_NAME; - FlutterSetElementInfoOperationActions(elementInfoFromList, widgeType); - } else if (IsScrollableWidget(flutterNode) || IsNodeScrollable(flutterNode)) { - // 若当前flutter节点为可滑动组件类型 - FlutterSetElementInfoOperationActions(elementInfoFromList, SCROLL_WIDGET_NAME); - } else { - // 若当前flutter节点为通用组件 - FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); - } - - // 设置当前节点的父节点id - int32_t parentId = GetParentId(elementId); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); - if (OH_ArkUI_AccessibilityElementInfoSetParentId == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetParentId is null, %{public}s", dlerror()); - } + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetEnabled -> true"; + } + // 判断当前节点是否可点击 + if (IsNodeClickable(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetClickable"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetClickable); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, parentId) + OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfoFromList, true) ); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById GetParentId = " << parentId; - - // 设置可朗读文本 - std::string text = flutterNode.label + flutterNode.value; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityText == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText is null, %{public}s", dlerror()); - } + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetClickable -> true"; + } + // 判断当前节点是否可获焦点 + if (IsNodeFocusable(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetFocusable"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetFocusable); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityText(elementInfoFromList, text.c_str()) + OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfoFromList, true) ); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById SetAccessibilityText = " << text; - - // 设置无障碍content文本 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); - if (OH_ArkUI_AccessibilityElementInfoSetContents == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetContents is null, %{public}s", dlerror()); - } + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetFocusable -> true"; + } + // 判断当前节点是否为密码输入框 + if (IsNodePassword(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetIsPassword)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetIsPassword"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetIsPassword); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetContents(elementInfoFromList, text.c_str()) + OH_ArkUI_AccessibilityElementInfoSetIsPassword(elementInfoFromList, true) ); - // 设置hint提示文本 - std::string hint = flutterNode.hint; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetHintText)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetHintText"); - if (OH_ArkUI_AccessibilityElementInfoSetHintText == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetHintText is null, %{public}s", dlerror()); - } + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetIsPassword -> true"; + } + // 判断当前节点是否具备checkable状态 (如:checkbox, radio button) + if (IsNodeCheckable(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetCheckable)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetCheckable"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetCheckable); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetHintText(elementInfoFromList, hint.c_str()) + OH_ArkUI_AccessibilityElementInfoSetCheckable(elementInfoFromList, true) ); - - // 设置当前节点的全部孩子节点 - 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]); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById -> elementid=" << elementId - << " childCount=" << childCount - << " childNodeIds=" << childNodeIds[i]; - } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = - OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); - if (OH_ArkUI_AccessibilityElementInfoSetChildNodeIds == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) - ); - } - - /** - * 根据当前flutter节点的SemanticsFlags特性,配置对应的elmentinfo属性 - */ - // 判断当前节点组件是否enabled - if (IsNodeEnabled(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEnabled"); - if (OH_ArkUI_AccessibilityElementInfoSetEnabled == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetEnabled is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfoFromList, true) - ); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetEnabled -> true"; - } - // 判断当前节点是否可点击 - if (IsNodeClickable(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetClickable"); - if (OH_ArkUI_AccessibilityElementInfoSetClickable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetClickable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfoFromList, true) - ); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetClickable -> true"; - } - // 判断当前节点是否可获焦点 - if (IsNodeFocusable(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetFocusable"); - if (OH_ArkUI_AccessibilityElementInfoSetFocusable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetFocusable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfoFromList, true) - ); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetFocusable -> true"; - } - // 判断当前节点是否为密码输入框 - if (IsNodePassword(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetIsPassword)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetIsPassword"); - if (OH_ArkUI_AccessibilityElementInfoSetIsPassword == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetIsPassword is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetIsPassword(elementInfoFromList, true) - ); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetIsPassword -> true"; - } - // 判断当前节点是否具备checkable状态 (如:checkbox, radio button) - if (IsNodeCheckable(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetCheckable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetCheckable"); - if (OH_ArkUI_AccessibilityElementInfoSetCheckable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetCheckable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetCheckable(elementInfoFromList, true) - ); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetCheckable -> true"; - } - // 判断当前节点(check box/radio button)是否checked/unchecked - if (IsNodeChecked(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChecked)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetChecked"); - if (OH_ArkUI_AccessibilityElementInfoSetChecked == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetChecked is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetChecked(elementInfoFromList, true) - ); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetChecked -> true"; - } - // 判断当前节点组件是否可显示 - if (IsNodeVisible(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetVisible"); - if (OH_ArkUI_AccessibilityElementInfoSetVisible == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetVisible is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfoFromList, true) - ); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetVisible -> true"; - } - // 判断当前节点组件是否选中 - if (IsNodeSelected(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetSelected)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetSelected"); - if (OH_ArkUI_AccessibilityElementInfoSetSelected == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetSelected is null, %{public}s", dlerror()); - } - OH_ArkUI_AccessibilityElementInfoSetSelected(elementInfoFromList, true); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetSelected -> true"; - } - // 判断当前节点组件是否可滑动 - if (IsNodeScrollable(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetScrollable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetScrollable"); - if (OH_ArkUI_AccessibilityElementInfoSetScrollable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetScrollable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetScrollable(elementInfoFromList, true) - ); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetScrollable -> true"; - } - // 判断当前节点组件是否可编辑(文本输入框) - if (IsTextField(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEditable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEditable"); - if (OH_ArkUI_AccessibilityElementInfoSetEditable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetEditable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetEditable(elementInfoFromList, true) - ); - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetEditable -> true"; - } - // 判断当前节点组件是否为滑动条 - if (IsSlider(flutterNode)) { - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetRangeInfo -> true"; - } - // 判断当前节点组件是否支持长按 - if (IsNodeHasLongPress(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetLongClickable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetLongClickable"); - if (OH_ArkUI_AccessibilityElementInfoSetLongClickable == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetLongClickable is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetLongClickable(elementInfoFromList, true) - ); - FML_DLOG(INFO) - << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetLongClickable -> true"; - } - - // 获取当前节点的组件类型 - std::string componentTypeName = GetNodeComponentType(flutterNode); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById componentTypeName = " - << componentTypeName; - // flutter节点对应elementinfo所属的组件类型(如:root, button,text等) - int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); - if (OH_ArkUI_AccessibilityElementInfoSetComponentType == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetComponentType is null, %{public}s", dlerror()); - } - if (elementId == 0) { - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, "root") - ); - } else { - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, - componentTypeName.c_str()) - ); - } - FML_DLOG(INFO) << "FlutterNodeToElementInfoById SetComponentType: " - << componentTypeName; - - /** - * 无障碍重要性,用于控制某个组件是否可被无障碍辅助服务所识别。支持的值为(默认值:“auto”): - * “auto”:根据组件不同会转换为“yes”或者“no” - * “yes”:当前组件可被无障碍辅助服务所识别 - * “no”:当前组件不可被无障碍辅助服务所识别 - * “no-hide-descendants”:当前组件及其所有子组件不可被无障碍辅助服务所识别 - */ - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel is null, %{public}s", dlerror()); - } + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetCheckable -> true"; + } + // 判断当前节点(check box/radio button)是否checked/unchecked + if (IsNodeChecked(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetChecked)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetChecked"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetChecked); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes"); + OH_ArkUI_AccessibilityElementInfoSetChecked(elementInfoFromList, true) ); - // 无障碍组,设置为true时表示该组件及其所有子组件为一整个可以选中的组件,无障碍服务将不再关注其子组件内容。默认值:false - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup is null, %{public}s", dlerror()); - } + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetChecked -> true"; + } + // 判断当前节点组件是否可显示 + if (IsNodeVisible(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetVisible"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetVisible); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfoFromList, true) + ); + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetVisible -> true"; + } + // 判断当前节点组件是否选中 + if (IsNodeSelected(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetSelected)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetSelected"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetSelected); + OH_ArkUI_AccessibilityElementInfoSetSelected(elementInfoFromList, true); + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetSelected -> true"; + } + // 判断当前节点组件是否可滑动 + if (IsNodeScrollable(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetScrollable)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetScrollable"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetScrollable); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetScrollable(elementInfoFromList, true) + ); + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetScrollable -> true"; + } + // 判断当前节点组件是否可编辑(文本输入框) + if (IsTextField(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetEditable)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEditable"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetEditable); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetEditable(elementInfoFromList, true) + ); + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetEditable -> true"; + } + // 判断当前节点组件是否为滑动条 + if (IsSlider(flutterNode)) { + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetRangeInfo -> true"; + } + // 判断当前节点组件是否支持长按 + if (IsNodeHasLongPress(flutterNode)) { + int32_t (*OH_ArkUI_AccessibilityElementInfoSetLongClickable)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetLongClickable"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetLongClickable); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfoFromList, false); + OH_ArkUI_AccessibilityElementInfoSetLongClickable(elementInfoFromList, true) + ); + FML_DLOG(INFO) + << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetLongClickable -> true"; + } + + // 获取当前节点的组件类型 + std::string componentTypeName = GetNodeComponentType(flutterNode); + FML_DLOG(INFO) << "FlutterNodeToElementInfoById componentTypeName = " + << componentTypeName; + // flutter节点对应elementinfo所属的组件类型(如:root, button,text等) + int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetComponentType); + if (elementId == 0) { + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, "root") + ); + } else { + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, + componentTypeName.c_str()) ); } + FML_DLOG(INFO) << "FlutterNodeToElementInfoById SetComponentType: " + << componentTypeName; + + /** + * 无障碍重要性,用于控制某个组件是否可被无障碍辅助服务所识别。支持的值为(默认值:“auto”): + * “auto”:根据组件不同会转换为“yes”或者“no” + * “yes”:当前组件可被无障碍辅助服务所识别 + * “no”:当前组件不可被无障碍辅助服务所识别 + * “no-hide-descendants”:当前组件及其所有子组件不可被无障碍辅助服务所识别 + */ + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = + OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes"); + ); + // 无障碍组,设置为true时表示该组件及其所有子组件为一整个可以选中的组件,无障碍服务将不再关注其子组件内容。默认值:false + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfoFromList, false); + ); } /** @@ -1247,29 +1149,26 @@ void OhosAccessibilityBridge::BuildArkUISemanticsTree( ArkUI_AccessibilityElementInfo* elementInfoFromList, ArkUI_AccessibilityElementInfoList* elementList) { - if (OHOS_API_VERSION >= 13) { - //配置root节点信息 - FlutterNodeToElementInfoById(elementInfoFromList, elementId); - //获取flutter无障碍语义树的节点总数 - auto levelOrderTreeVec = GetLevelOrderTraversalTree(0); - int64_t elementInfoCount = levelOrderTreeVec.size(); - //创建并配置节点id >= 1的全部节点 - for (int64_t i = 1; i < elementInfoCount; i++) { - int64_t levelOrderId = levelOrderTreeVec[i]; - auto newNode = GetFlutterSemanticsNode(levelOrderId); - if (g_flutterSemanticsTree.count(newNode.id)) { - LOGE("BuildArkUISemanticsTree: GetFlutterSemanticsNode id=%{public}ld null", levelOrderId); - } - //当节点为隐藏状态时,自动规避 - auto* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = - OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); - if (OH_ArkUI_AddAndGetAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_AddAndGetAccessibilityElementInfo is null, %{public}s", dlerror()); - } - auto* newElementInfo = OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); - //配置当前子节点信息 - FlutterNodeToElementInfoById(newElementInfo, levelOrderId); - } + if (OHOS_API_VERSION < 13) { return; } + //配置root节点信息 + FlutterNodeToElementInfoById(elementInfoFromList, elementId); + //获取flutter无障碍语义树的节点总数 + auto levelOrderTreeVec = GetLevelOrderTraversalTree(0); + int64_t elementInfoCount = levelOrderTreeVec.size(); + //创建并配置节点id >= 1的全部节点 + for (int64_t i = 1; i < elementInfoCount; i++) { + int64_t levelOrderId = levelOrderTreeVec[i]; + auto newNode = GetFlutterSemanticsNode(levelOrderId); + if (g_flutterSemanticsTree.count(newNode.id)) { + LOGE("BuildArkUISemanticsTree: GetFlutterSemanticsNode id=%{public}ld null", levelOrderId); + } + //当节点为隐藏状态时,自动规避 + auto* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = + OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AddAndGetAccessibilityElementInfo); + auto* newElementInfo = OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); + //配置当前子节点信息 + FlutterNodeToElementInfoById(newElementInfo, levelOrderId); } } @@ -1283,21 +1182,19 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( 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 << " requestId=" << requestId << " elementList= " << elementList; + CHECK_NULL_PTR_WITH_RET(elementList, FindAccessibilityNodeInfosById); if (g_flutterSemanticsTree.size() == 0) { FML_DLOG(INFO) << "FindAccessibilityNodeInfosById g_flutterSemanticsTree is null"; return ARKUI_ACCESSIBILITY_NATIVE_RESULT_FAILED; } - if (elementList == nullptr) { - FML_DLOG(INFO) << "FindAccessibilityNodeInfosById elementList is null"; - return ARKUI_ACCESSIBILITY_NATIVE_RESULT_FAILED; - } - + // 获取当前对应id的flutter节点,若为空则返回错误编码 auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); if (!g_flutterSemanticsTree.count(flutterNode.id)) { @@ -1309,43 +1206,36 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( accessibilityFeatures_->SetAccessibleNavigation(true, native_shell_holder_id_); } - if (OHOS_API_VERSION >= 13) { - // 从elementinfolist中获取elementinfo - auto* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = - OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); - if (OH_ArkUI_AddAndGetAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_AddAndGetAccessibilityElementInfo is null, %{public}s", dlerror()); + // 从elementinfolist中获取elementinfo + auto* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = + OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); + 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)) { + FlutterNodeToElementInfoById(elementInfoFromList, elementId); } - auto* elementInfoFromList = OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); - if (elementInfoFromList == nullptr) { - FML_DLOG(INFO) << "FindAccessibilityNodeInfosById elementInfoFromList is null"; - return ARKUI_ACCESSIBILITY_NATIVE_RESULT_FAILED; + } else if (mode ==ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_SIBLINGS) { + /** Search for sibling nodes. (mode = 2) */ + if (IsNodeVisible(flutterNode)) { + FlutterNodeToElementInfoById(elementInfoFromList, elementId); } - - 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)) { - FlutterNodeToElementInfoById(elementInfoFromList, elementId); - } - } else if (mode ==ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_SIBLINGS) { - /** Search for sibling nodes. (mode = 2) */ - if (IsNodeVisible(flutterNode)) { - FlutterNodeToElementInfoById(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)) { - FlutterNodeToElementInfoById(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 { + } 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)) { FlutterNodeToElementInfoById(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 { + FlutterNodeToElementInfoById(elementInfoFromList, elementId); } FML_DLOG(INFO) << "--- FindAccessibilityNodeInfosById is end ---"; return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL; @@ -1572,29 +1462,26 @@ void OhosAccessibilityBridge::PerformSetText( ArkUI_Accessibility_ActionType action, ArkUI_AccessibilityActionArguments* actionArguments) { - if (OHOS_API_VERSION >= 13) { - int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = - OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); - if (OH_ArkUI_FindAccessibilityActionArgumentByKey == nullptr) { - LOGE("OH_ArkUI_FindAccessibilityActionArgumentByKey is null, %{public}s", dlerror()); - } - const char* key_setText = "setText"; - const char* valueStr = flutterNode.value.c_str(); - char* newValue = strdup(valueStr); - char** value = &newValue; - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); - if (newValue == nullptr) { - LOGE("PerformSetText -> OH_ArkUI_FindAccessibilityActionArgumentByKey get null value"); - } - auto flutterSetTextAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(flutterNode.id, - flutterSetTextAction, - fml::MallocMapping::Copy(newValue, strlen(newValue))); - flutterNode.value = newValue; - flutterNode.valueAttributes = {}; - LOGI("ExecuteAccessibilityAction -> action: set text(%{public}d), newText=%{public}s", action, newValue); - } + if (OHOS_API_VERSION < 13) { return; } + int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = + OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); + CHECK_DLL_NULL_PTR(OH_ArkUI_FindAccessibilityActionArgumentByKey); + + const char* key_setText = "setText"; + const char* valueStr = flutterNode.value.c_str(); + char* newValue = strdup(valueStr); + char** value = &newValue; + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); + CHECK_NULL_PTR(newValue, PerformSetText); + + auto flutterSetTextAction = ArkuiActionsToFlutterActions(action); + DispatchSemanticsAction(flutterNode.id, + flutterSetTextAction, + fml::MallocMapping::Copy(newValue, strlen(newValue))); + flutterNode.value = newValue; + flutterNode.valueAttributes = {}; + LOGI("ExecuteAccessibilityAction -> action: set text(%{public}d), newText=%{public}s", action, newValue); } /** @@ -1606,7 +1493,7 @@ void OhosAccessibilityBridge::PerformSelectText( ArkUI_AccessibilityActionArguments* actionArguments) { FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: select text(" << action << ")"; - return; + } /** @@ -1657,12 +1544,7 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( << elementId << " action=" << action << " requestId=" << requestId << " *actionArguments=" << actionArguments; - - if (actionArguments == nullptr) { - FML_DLOG(ERROR) << "OhosAccessibilityBridge::ExecuteAccessibilityAction " - "actionArguments = null"; - return ARKUI_ACCESSIBILITY_NATIVE_RESULT_FAILED; - } + CHECK_NULL_PTR_WITH_RET(actionArguments, ExecuteAccessibilityAction); // 获取当前elementid对应的flutter语义节点 auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); @@ -1859,95 +1741,72 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( int64_t elementId, ArkUI_AccessibilityEventType eventType) { - if (provider_ == nullptr) { - FML_DLOG(ERROR) << "Flutter_SendAccessibilityAsyncEvent " - "AccessibilityProvider = nullptr"; - return; + if (OHOS_API_VERSION < 13) { return; } + + CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAsyncEvent); + + // 1.创建eventInfo对象 + auto* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = + OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); + auto* eventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); + CHECK_NULL_PTR(eventInfo, Flutter_SendAccessibilityAsyncEvent); + + // 2.创建的elementinfo并根据对应id的flutternode进行属性初始化 + ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = + OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); + ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); + FlutterNodeToElementInfoById(_elementInfo, elementId); + + // 若为获焦事件,则设置当前elementinfo获焦 + int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused)(ArkUI_AccessibilityElementInfo*, bool) = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused); + if (eventType == ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUSED) { + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused(_elementInfo, true) + ); } - if (OHOS_API_VERSION >= 13) { - // 1.创建eventInfo对象 - ArkUI_AccessibilityEventInfo* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); - if (OH_ArkUI_CreateAccessibilityEventInfo == nullptr) { - LOGE("OH_ArkUI_CreateAccessibilityEventInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityEventInfo* eventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); - if (eventInfo == nullptr) { - FML_DLOG(ERROR) << "Flutter_SendAccessibilityAsyncEvent " - "OH_ArkUI_CreateAccessibilityEventInfo eventInfo = null"; - return; - } - // 2.创建的elementinfo并根据对应id的flutternode进行属性初始化 - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); - if (OH_ArkUI_CreateAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_CreateAccessibilityElementInfo is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); - FlutterNodeToElementInfoById(_elementInfo, elementId); - - // 若为获焦事件,则设置当前elementinfo获焦 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused"); - if (OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused == nullptr) { - LOGE("OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused is null, %{public}s", dlerror()); - } - if (eventType == ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUSED) { - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused(_elementInfo, true) - ); - } + // 3.设置发送事件,如配置获焦、失焦、点击、滑动事件 + int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = + OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetEventType); + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetEventType(eventInfo, eventType)); - // 3.设置发送事件,如配置获焦、失焦、点击、滑动事件 - int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = - OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); - if (OH_ArkUI_AccessibilityEventSetEventType == nullptr) { - LOGE("OH_ArkUI_AccessibilityEventSetEventType is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetEventType(eventInfo, eventType)); - - // 4.将eventinfo事件和当前elementinfo进行绑定 - int32_t (*OH_ArkUI_AccessibilityEventSetElementInfo)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadSetEventElemFunc("OH_ArkUI_AccessibilityEventSetElementInfo"); - if (OH_ArkUI_AccessibilityEventSetElementInfo == nullptr) { - LOGE("OH_ArkUI_AccessibilityEventSetElementInfo is null, %{public}s", dlerror()); - } - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetElementInfo(eventInfo, _elementInfo)); - - // 5.调用接口发送到ohos侧 - auto callback = [](int32_t errorCode) { - FML_DLOG(INFO) - << "Flutter_SendAccessibilityAsyncEvent callback-> errorCode =" - << errorCode; - }; - - // 6.发送event到OH侧 - void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = - OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); - if (OH_ArkUI_SendAccessibilityAsyncEvent == nullptr) { - LOGE("OH_ArkUI_SendAccessibilityAsyncEvent is null, %{public}s", dlerror()); - } - OH_ArkUI_SendAccessibilityAsyncEvent(provider_, eventInfo, callback); - - // 7.销毁新创建的elementinfo, eventinfo - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); - if (OH_ArkUI_DestoryAccessibilityElementInfo == nullptr) { - LOGE("OH_ArkUI_DestoryAccessibilityElementInfo is null, %{public}s", dlerror()); - } - OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); - _elementInfo = nullptr; - - void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = - OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); - if (OH_ArkUI_DestoryAccessibilityEventInfo == nullptr) { - LOGE("OH_ArkUI_DestoryAccessibilityEventInfo is null, %{public}s", dlerror()); - } - OH_ArkUI_DestoryAccessibilityEventInfo(eventInfo); - eventInfo = nullptr; - } + // 4.将eventinfo事件和当前elementinfo进行绑定 + int32_t (*OH_ArkUI_AccessibilityEventSetElementInfo)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityElementInfo*) = + OhosAccessibilityDDL::DLLoadSetEventElemFunc("OH_ArkUI_AccessibilityEventSetElementInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetElementInfo); + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetElementInfo(eventInfo, _elementInfo)); + // 5.调用接口发送到ohos侧 + auto callback = [](int32_t errorCode) { + FML_DLOG(INFO) + << "Flutter_SendAccessibilityAsyncEvent callback-> errorCode =" + << errorCode; + }; + + // 6.发送event到OH侧 + void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = + OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); + CHECK_DLL_NULL_PTR(OH_ArkUI_SendAccessibilityAsyncEvent); + OH_ArkUI_SendAccessibilityAsyncEvent(provider_, eventInfo, callback); + + // 7.销毁新创建的elementinfo, eventinfo + void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = + OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityElementInfo); + OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); + _elementInfo = nullptr; + + void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = + OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); + CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityEventInfo); + OH_ArkUI_DestoryAccessibilityEventInfo(eventInfo); + eventInfo = nullptr; + FML_DLOG(INFO) << "OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent is end"; return; } diff --git a/shell/platform/ohos/utils/ddl_utils.h b/shell/platform/ohos/utils/ddl_utils.h index 5ddbb0e954..19e5e5fb18 100644 --- a/shell/platform/ohos/utils/ddl_utils.h +++ b/shell/platform/ohos/utils/ddl_utils.h @@ -21,5 +21,6 @@ using LIBHANDLE = void*; #define LOAD_LIB(libPath) dlopen(libPath, RTLD_LAZY|RTLD_LOCAL) #define CLOSE_LIB(libHandle) dlclose(libHandle) #define LOAD_SYM(libHandle, symbol) dlsym(libHandle, symbol) +#define LOAD_ERROR() dlerror() #endif // FOUNDATION_ACE_INTERFACE_INNERKITS_ACE_UTILS_H -- Gitee From f34b812f366ec494b6d29f502f18623d382138d7 Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 17 Dec 2024 21:10:05 +0800 Subject: [PATCH 23/60] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0selecttext?= =?UTF-8?q?=E5=8A=A8=E4=BD=9C=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9Emap=E5=BA=8F=E5=88=97=E5=8C=96=E5=AD=97?= =?UTF-8?q?=E8=8A=82=E6=95=B0=E7=BB=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 60 +++++++++++++++---- .../accessibility/ohos_accessibility_bridge.h | 4 ++ shell/platform/ohos/utils/ohos_utils.cpp | 38 ++++++++++++ shell/platform/ohos/utils/ohos_utils.h | 7 ++- 4 files changed, 95 insertions(+), 14 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index ba0882e42c..e76880fc77 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -1467,25 +1467,22 @@ void OhosAccessibilityBridge::PerformSetText( OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); CHECK_DLL_NULL_PTR(OH_ArkUI_FindAccessibilityActionArgumentByKey); - const char* key_setText = "setText"; - const char* valueStr = flutterNode.value.c_str(); - char* newValue = strdup(valueStr); - char** value = &newValue; + char* newText; ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, key_setText, value)); - CHECK_NULL_PTR(newValue, PerformSetText); + OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, ARKUI_ACTION_ARG_SET_TEXT, &newText)); + CHECK_NULL_PTR(newText, PerformSetText); auto flutterSetTextAction = ArkuiActionsToFlutterActions(action); - DispatchSemanticsAction(flutterNode.id, - flutterSetTextAction, - fml::MallocMapping::Copy(newValue, strlen(newValue))); - flutterNode.value = newValue; + DispatchSemanticsAction(flutterNode.id, + flutterSetTextAction, + fml::MallocMapping::Copy(newText, strlen(newText))); + flutterNode.value = newText; flutterNode.valueAttributes = {}; - LOGI("ExecuteAccessibilityAction -> action: set text(%{public}d), newText=%{public}s", action, newValue); + LOGI("ExecuteAccessibilityAction -> action: set text(%{public}d), newText=%{public}s", action, newText); } /** - * perform cursor position setting in accessibility status + * perform select text (from base to extent) in accessibility status */ void OhosAccessibilityBridge::PerformSelectText( SemanticsNodeExtent flutterNode, @@ -1493,7 +1490,44 @@ void OhosAccessibilityBridge::PerformSelectText( ArkUI_AccessibilityActionArguments* actionArguments) { FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: select text(" << action << ")"; - + int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = + OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); + CHECK_DLL_NULL_PTR(OH_ArkUI_FindAccessibilityActionArgumentByKey); + + auto flutterSelectTextAction = ArkuiActionsToFlutterActions(action); + + char* textSelectBase; + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, ARKUI_ACTION_ARG_SELECT_TEXT_START, &textSelectBase) + ); + CHECK_NULL_PTR(textSelectBase, PerformSelectText); + + char* textSelectExtent; + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, ARKUI_ACTION_ARG_SELECT_TEXT_END, &textSelectExtent) + ); + CHECK_NULL_PTR(textSelectExtent, PerformSelectText); + + std::map selectionMap; + bool hasSelected = actionArguments != nullptr && + textSelectBase != nullptr && + textSelectExtent != nullptr; + if (hasSelected) { + int32_t base; + int32_t extent; + std::memcpy(&base, textSelectBase, sizeof(base)); + std::memcpy(&extent, textSelectExtent, sizeof(extent)); + selectionMap.insert({ARKUI_ACTION_ARG_SELECT_TEXT_START, base}); + selectionMap.insert({ARKUI_ACTION_ARG_SELECT_TEXT_END, extent}); + } else { + selectionMap.insert({ARKUI_ACTION_ARG_SELECT_TEXT_START, flutterNode.textSelectionBase}); + selectionMap.insert({ARKUI_ACTION_ARG_SELECT_TEXT_END, flutterNode.textSelectionExtent}); + } + // serialize map to byte vector + std::vector encodedData = OHOSUtils::SerializeStringIntMap(selectionMap); + DispatchSemanticsAction(flutterNode.id, + flutterSelectTextAction, + fml::MallocMapping::Copy(encodedData.data(), encodedData.size() * sizeof(uint8_t))); } /** diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 39d14c80eb..5c135ada61 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -175,6 +175,10 @@ private: constexpr static const double SCROLL_EXTENT_FOR_INFINITY = 100000.0; constexpr static const double SCROLL_POSITION_CAP_FOR_INFINITY = 70000.0; + const char* ARKUI_ACTION_ARG_SET_TEXT = "setText"; + const char* ARKUI_ACTION_ARG_SELECT_TEXT_START = "selectTextBegin"; + const char* ARKUI_ACTION_ARG_SELECT_TEXT_END = "selectTextEnd"; + const std::string OTHER_WIDGET_NAME = "View"; const std::string TEXT_WIDGET_NAME = "Text"; const std::string EDIT_TEXT_WIDGET_NAME = "TextInput"; diff --git a/shell/platform/ohos/utils/ohos_utils.cpp b/shell/platform/ohos/utils/ohos_utils.cpp index 23813a7528..96a2e84876 100644 --- a/shell/platform/ohos/utils/ohos_utils.cpp +++ b/shell/platform/ohos/utils/ohos_utils.cpp @@ -27,4 +27,42 @@ bool OHOSUtils::Contains(const std::string source, return source.find(target) != std::string::npos; } +/** + * 将string序列化为uint8字节数组 + */ +void OHOSUtils::SerializeString(const std::string& str, std::vector& buffer) +{ + // store the length of the string as a uint8_t + uint32_t length = str.size(); + buffer.insert(buffer.end(), + reinterpret_cast(&length), + reinterpret_cast(&length) + sizeof(length)); + // store the actual string data + buffer.insert(buffer.end(), str.begin(), str.end()); +} + +/** + * 将map序列化为uint8字节数组 + */ +std::vector OHOSUtils::SerializeStringIntMap(const std::map& mp) +{ + std::vector buffer; + + // Store the number of elements in the map + uint32_t mapSize = mp.size(); + buffer.insert(buffer.end(), + reinterpret_cast(&mapSize), + reinterpret_cast(&mapSize) + sizeof(mapSize)); + + // Iterate over the map and serialize each key-value pair + for (const auto& it : mp) { + SerializeString(it.first, buffer); + buffer.insert(buffer.end(), + reinterpret_cast(&it.second), + reinterpret_cast(&it.second) + sizeof(it.second)); + } + + return buffer; +} + } \ No newline at end of file diff --git a/shell/platform/ohos/utils/ohos_utils.h b/shell/platform/ohos/utils/ohos_utils.h index f76e79bef3..49686b94e9 100644 --- a/shell/platform/ohos/utils/ohos_utils.h +++ b/shell/platform/ohos/utils/ohos_utils.h @@ -16,7 +16,10 @@ #ifndef OHOS_UTILS_H #define OHOS_UTILS_H #include - +#include +#include +#include +#include namespace flutter { class OHOSUtils { @@ -25,6 +28,8 @@ public: ~OHOSUtils(); static bool Contains(const std::string source, const std::string target); + static void SerializeString(const std::string& str, std::vector& buffer); + static std::vector SerializeStringIntMap(const std::map& mp); }; } -- Gitee From 718054325f87377e49ababd3084824d33bdfd39f Mon Sep 17 00:00:00 2001 From: zjxi Date: Wed, 18 Dec 2024 10:54:31 +0800 Subject: [PATCH 24/60] =?UTF-8?q?refactor:=E6=9B=BF=E6=8D=A2=E4=B8=8D?= =?UTF-8?q?=E5=AE=89=E5=85=A8memcpy=E5=87=BD=E6=95=B0=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8strol=E6=96=B9=E5=BC=8F=E8=BF=9B=E8=A1=8C=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=E5=92=8C=E6=95=B0=E5=AD=97=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E6=89=8B=E5=8A=A8=E5=A4=84=E7=90=86=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 10 +++++---- shell/platform/ohos/utils/ohos_utils.cpp | 22 +++++++++++++++++-- shell/platform/ohos/utils/ohos_utils.h | 2 ++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index e76880fc77..e81ecc6946 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -1498,13 +1498,15 @@ void OhosAccessibilityBridge::PerformSelectText( char* textSelectBase; ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, ARKUI_ACTION_ARG_SELECT_TEXT_START, &textSelectBase) + OH_ArkUI_FindAccessibilityActionArgumentByKey( + actionArguments, ARKUI_ACTION_ARG_SELECT_TEXT_START, &textSelectBase) ); CHECK_NULL_PTR(textSelectBase, PerformSelectText); char* textSelectExtent; ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_FindAccessibilityActionArgumentByKey(actionArguments, ARKUI_ACTION_ARG_SELECT_TEXT_END, &textSelectExtent) + OH_ArkUI_FindAccessibilityActionArgumentByKey( + actionArguments, ARKUI_ACTION_ARG_SELECT_TEXT_END, &textSelectExtent) ); CHECK_NULL_PTR(textSelectExtent, PerformSelectText); @@ -1515,8 +1517,8 @@ void OhosAccessibilityBridge::PerformSelectText( if (hasSelected) { int32_t base; int32_t extent; - std::memcpy(&base, textSelectBase, sizeof(base)); - std::memcpy(&extent, textSelectExtent, sizeof(extent)); + OHOSUtils::CharArrayToInt32(textSelectBase, base); + OHOSUtils::CharArrayToInt32(textSelectBase, extent); selectionMap.insert({ARKUI_ACTION_ARG_SELECT_TEXT_START, base}); selectionMap.insert({ARKUI_ACTION_ARG_SELECT_TEXT_END, extent}); } else { diff --git a/shell/platform/ohos/utils/ohos_utils.cpp b/shell/platform/ohos/utils/ohos_utils.cpp index 96a2e84876..1d4058f086 100644 --- a/shell/platform/ohos/utils/ohos_utils.cpp +++ b/shell/platform/ohos/utils/ohos_utils.cpp @@ -34,8 +34,8 @@ void OHOSUtils::SerializeString(const std::string& str, std::vector& bu { // store the length of the string as a uint8_t uint32_t length = str.size(); - buffer.insert(buffer.end(), - reinterpret_cast(&length), + buffer.insert(buffer.end(), + reinterpret_cast(&length), reinterpret_cast(&length) + sizeof(length)); // store the actual string data buffer.insert(buffer.end(), str.begin(), str.end()); @@ -65,4 +65,22 @@ std::vector OHOSUtils::SerializeStringIntMap(const std::map(num); + LOGD("The int32_t value is: %{public}d", target); + } else { + target = 0; + LOGE("Conversion error, non-convertible part: %{public}s", end); + } +} + } \ No newline at end of file diff --git a/shell/platform/ohos/utils/ohos_utils.h b/shell/platform/ohos/utils/ohos_utils.h index 49686b94e9..e9d6b7b683 100644 --- a/shell/platform/ohos/utils/ohos_utils.h +++ b/shell/platform/ohos/utils/ohos_utils.h @@ -20,6 +20,7 @@ #include #include #include +#include "flutter/shell/platform/ohos/ohos_logging.h" namespace flutter { class OHOSUtils { @@ -30,6 +31,7 @@ public: static bool Contains(const std::string source, const std::string target); static void SerializeString(const std::string& str, std::vector& buffer); static std::vector SerializeStringIntMap(const std::map& mp); + static void CharArrayToInt32(const char* str, int32_t& target); }; } -- Gitee From 48281cf724f4cc5f0865bce7a8b5db9417ff23f0 Mon Sep 17 00:00:00 2001 From: zjxi Date: Wed, 18 Dec 2024 11:06:54 +0800 Subject: [PATCH 25/60] =?UTF-8?q?=E5=88=A0=E9=99=A4switch-case=E4=B8=AD?= =?UTF-8?q?=E5=A4=9A=E4=BD=99=E8=8A=B1=E6=8B=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index e81ecc6946..48e06cb30b 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -1597,76 +1597,75 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( // 根据当前elementid和无障碍动作类型,发送无障碍事件 switch (action) { /** Response to a click. 16 */ - case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK: { + 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: { + 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: { + 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: { + 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: { + 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: { + 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: { + 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: { + 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: { + 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: { + 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: { + 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: { + 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: { + case ArkUI_Accessibility_ActionType::ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_INVALID: PerformInvalidAction(elementId, action, flutterNode); break; - } - default: { + + default: /** custom semantics action */ PerformCustomAction(flutterNode, action, actionArguments); - } } FML_DLOG(INFO) << "--- ExecuteAccessibilityAction is end ---"; return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL; -- Gitee From cae6333639e796caecc754b67ff8c9043306764f Mon Sep 17 00:00:00 2001 From: xiaozn Date: Thu, 19 Dec 2024 17:05:57 +0800 Subject: [PATCH 26/60] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DmediaQuery?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=9A=84=E6=95=B0=E6=8D=AE=E4=B8=AD=E5=8C=85?= =?UTF-8?q?=E5=90=AB=E7=9A=84displayFeature=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xiaozn --- .../flutter/src/main/ets/view/FlutterView.ets | 141 +++++++++++++++++- 1 file changed, 137 insertions(+), 4 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index c8b2fd6742..785e7cbd85 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -27,6 +27,7 @@ import PlatformView, { Params } from '../plugin/platform/PlatformView'; import { JSON } from '@kit.ArkTS'; import { accessibility } from '@kit.AccessibilityKit'; import TextInputPlugin from '../plugin/editing/TextInputPlugin'; +import { browser } from '@kit.MDMKit'; const TAG = "FlutterViewTag"; @@ -47,6 +48,7 @@ export class ViewportMetrics { systemGestureInsetBottom: number = 0; systemGestureInsetLeft: number = 0; physicalTouchSlop: number = -1; + displayFeatures: ArrayList = new ArrayList(); clone(): ViewportMetrics { const copy = new ViewportMetrics(); @@ -66,6 +68,7 @@ export class ViewportMetrics { copy.systemGestureInsetBottom = this.systemGestureInsetBottom; copy.systemGestureInsetLeft = this.systemGestureInsetLeft; copy.physicalTouchSlop = this.physicalTouchSlop; + copy.displayFeatures = this.displayFeatures; return copy; } @@ -89,6 +92,62 @@ export class ViewportMetrics { } } +export class DisplayFeature { + bounds: display.Rect[]; + type: DisplayFeatureType; + state: DisplayFeatureState; + + constructor(bounds: display.Rect[], type: DisplayFeatureType, state: DisplayFeatureState) { + this.bounds = bounds; + this.type = type; + this.state = state; + } + + getBounds(): display.Rect[] { + return this.bounds; + } + + getType(): DisplayFeatureType { + return this.type; + } + + getState(): DisplayFeatureState { + return this.state + } + + setBounds(bounds: display.Rect[]): void { + this.bounds = bounds; + } + + setType(type: DisplayFeatureType): void { + this.type = type; + } + + setState(state: DisplayFeatureState): void { + this.state = state; + } +} + +export enum DisplayFeatureType{ + UNKNOWN = 0, + FOLD = 1, + HINGE = 2, + CUTOUT = 3 +}; + +export enum DisplayFeatureState{ + UNKNOWN = 0, + POSTURE_FLAT = 1, + POSTURE_HALF_OPENED = 2, +}; + +export enum DisplayFoldStatus{ + FOLD_STATUS_UNKNOWN = 0, + FOLD_STATUS_EXPANDED = 1, + FOLD_STATUS_FOLDED = 2, + FOLD_STATUS_HALF_FOLDED = 3 +}; + export class PlatformViewParas { width: number = 0.0; height: number = 0.0; @@ -144,6 +203,7 @@ export class FlutterView { this.id = viewId this.displayInfo = display.getDefaultDisplaySync(); this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; + this.buildDisplayFeatures(display.getFoldStatus()); this.mainWindow = FlutterManager.getInstance() .getWindowStage(FlutterManager.getInstance().getUIAbility(context)) .getMainWindowSync(); @@ -164,6 +224,12 @@ export class FlutterView { this.gestureAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); this.keyboardAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + // 监听折叠状态的改变 + display?.on('foldStatusChange', (data: display.FoldStatus) => { + Log.d(TAG, `Fold status change to ${JSON.stringify(data)}`) + this.buildDisplayFeatures(data); + }) + // Subscribes to display changes. Example: event that the display size is changed. try { display.on("change", ()=>{ @@ -179,6 +245,50 @@ export class FlutterView { } } + private async buildDisplayFeatures(foldStatus: display.FoldStatus) { + let displayFeatures: ArrayList = new ArrayList(); + let bound: display.Rect[]; + let state = 0; + let type = 0; + const displayInfos = display.getDefaultDisplaySync(); + if (display.isFoldable()) { + switch (foldStatus) { + case DisplayFoldStatus.FOLD_STATUS_FOLDED.valueOf(): + type = DisplayFeatureType.HINGE; + state = DisplayFeatureState.UNKNOWN; + break; + case DisplayFoldStatus.FOLD_STATUS_EXPANDED.valueOf(): + type = DisplayFeatureType.FOLD; + state = DisplayFeatureState.POSTURE_FLAT; + break; + case DisplayFoldStatus.FOLD_STATUS_HALF_FOLDED.valueOf(): + type = DisplayFeatureType.FOLD; + state = DisplayFeatureState.POSTURE_HALF_OPENED; + break; + default: + type = DisplayFeatureType.UNKNOWN; + state = DisplayFeatureState.UNKNOWN; + break; + } + const displays = await display.getAllDisplays(); + for (let i = 0; i < displays.length; i++) { + let cutoutInfo = await displays[i].getCutoutInfo(); + bound = cutoutInfo.boundingRects; + displayFeatures.add(new DisplayFeature(bound, type, state)); + } + Log.d(TAG, `FOLD device displayFeatures is : ${JSON.stringify(displayFeatures)}`) + } else { + type = DisplayFeatureType.UNKNOWN; + state = DisplayFeatureState.UNKNOWN; + let infos = await displayInfos?.getCutoutInfo(); + bound = infos.boundingRects; + displayFeatures.add(new DisplayFeature(bound, type, state)); + Log.d(TAG, `UNFold device displayFeatures is : ${JSON.stringify(displayFeatures)}`) + } + this.viewportMetrics.displayFeatures = displayFeatures; + this.updateViewportMetrics(); + } + private windowSizeChangeCallback = (data: window.Size) => { Log.i(TAG, "windowSizeChangeCallback w:" + data.width + ", h:" + data.height); if (this.isAttachedToFlutterEngine()) { @@ -213,7 +323,7 @@ export class FlutterView { Log.i(TAG, "keyboardHeightChangeCallback " + data); this.keyboardAvoidArea.bottomRect.height = data; if (this.isAttachedToFlutterEngine()) { - this.onAreaChange(null); + this.onAreaChange(null); } }; @@ -270,6 +380,9 @@ export class FlutterView { Log.i(TAG, `unsubscribe accessibility state change, result: ${JSON.stringify(data)}`); }); this.mainWindow?.off('keyboardHeightChange', this.keyboardHeightChangeCallback); + display.off('foldStatusChange', (status: display.FoldStatus) => { + Log.d(TAG, `foldStatusChange listner destory`); + }) } catch (e) { Log.e(TAG, "mainWindow off error: " + JSON.stringify(e)); } @@ -444,6 +557,26 @@ export class FlutterView { if (this.isAttachedToFlutterEngine()) { Log.i(TAG, 'updateViewportMetrics devicePixelRatio:' + this.viewportMetrics.devicePixelRatio); + const displayFeatures = this.viewportMetrics.displayFeatures; + let boundCount = 0; + for (let i = 0; i < displayFeatures.length; i++) { + boundCount = boundCount + displayFeatures[i].getBounds().length; + } + let displayFeatureBound: number[] = new Array(boundCount * 4); + let displayFeatureType: number[] = new Array(displayFeatures.length); + let displayFeatureStatus: number[] = new Array(displayFeatures.length); + for (let i = 0; i < displayFeatures.length; i++) { + let singleFeatureBound = displayFeatures[i].getBounds(); + for (let j = 0; j < singleFeatureBound.length; j++) { + displayFeatureBound[4*i + 4*j] = singleFeatureBound[j].left; + displayFeatureBound[4*i + 4*j + 1] = singleFeatureBound[j].top + displayFeatureBound[4*i + 4*j + 2] = singleFeatureBound[j].width; + displayFeatureBound[4*i + 4*j + 3] = singleFeatureBound[j].height; + } + displayFeatureType[i] = displayFeatures[i].getType(); + displayFeatureStatus[i] = displayFeatures[i].getState(); + } + this?.flutterEngine?.getFlutterNapi()?.setViewportMetrics(this.viewportMetrics.devicePixelRatio, this.viewportMetrics.physicalWidth, this.viewportMetrics.physicalHeight, @@ -460,9 +593,9 @@ export class FlutterView { this.viewportMetrics.systemGestureInsetBottom, this.viewportMetrics.systemGestureInsetLeft, this.viewportMetrics.physicalTouchSlop, - new Array(0), - new Array(0), - new Array(0)) + displayFeatureBound, + displayFeatureType, + displayFeatureStatus) return true; } return false; -- Gitee From 5f0693fabec1cf1ededcf16eb8774a799e5a2c69 Mon Sep 17 00:00:00 2001 From: xiaozn Date: Thu, 19 Dec 2024 17:09:18 +0800 Subject: [PATCH 27/60] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DmediaQuery?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=9A=84=E6=95=B0=E6=8D=AE=E4=B8=AD=E5=8C=85?= =?UTF-8?q?=E5=90=AB=E7=9A=84displayFeature=E6=95=B0=E6=8D=AE=EF=BC=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E6=95=88import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xiaozn --- .../flutter_embedding/flutter/src/main/ets/view/FlutterView.ets | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index 785e7cbd85..c974a8fd92 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -27,7 +27,6 @@ import PlatformView, { Params } from '../plugin/platform/PlatformView'; import { JSON } from '@kit.ArkTS'; import { accessibility } from '@kit.AccessibilityKit'; import TextInputPlugin from '../plugin/editing/TextInputPlugin'; -import { browser } from '@kit.MDMKit'; const TAG = "FlutterViewTag"; -- Gitee From 0f86d44138f203038edd4fbfbdab633c41d99646 Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Thu, 19 Dec 2024 16:39:32 +0800 Subject: [PATCH 28/60] =?UTF-8?q?=E4=BF=AE=E6=94=B9ctrl=E7=BB=84=E5=90=88?= =?UTF-8?q?=E9=94=AE=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- .../ets/embedding/ohos/KeyEventHandler.ets | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets index 0c9dadf394..3aff0a47bc 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets @@ -32,6 +32,8 @@ export class KeyEventHandler { private shiftMap : HashMap = new HashMap(); private isShiftMode: boolean = false; private isControlMode: boolean = false; + // 记录输入的keyCode,确保有down和up事件才输入字符 + private inputMap: HashMap = new HashMap(); constructor(textInputPlugin?: TextInputPlugin) { this.textInputPlugin = textInputPlugin; @@ -155,21 +157,25 @@ export class KeyEventHandler { "name": "handleKeyEvent", "event": event, })); + let text = this.getCharByEvent(event); if (event.type == KeyType.Down) { if (!this.isControlMode) { this.isControlMode = CONTROL_KEYS.findIndex((it) => it == event.keyCode) >= 0; } - } - Log.i(TAG, "isControlMode=" + this.isControlMode) - if (event.type == KeyType.Up) { - if (!this.isControlMode) { - this.isControlMode = CONTROL_KEYS.findIndex((it) => it == event.keyCode) >= 0; - } else { + this.inputMap.set(event.keyCode, text); + } else if (event.type == KeyType.Up) { + if (CONTROL_KEYS.findIndex((it) => it == event.keyCode) >= 0) { + // Ctrl/Alt 键抬起,重置状态 + this.isControlMode = false; + return; + } else if (this.isControlMode) { + // Ctrl/Alt 键按下的状态,不输入字符(字母/数字/符号) return; } // 处理字符按键相关逻辑 - if (this.charMap.hasKey(event.keyCode)) { - this.textInputPlugin?.getEditingState().handleInsertTextEvent(this.getCharByEvent(event)) + if (this.inputMap.hasKey(event.keyCode) && this.charMap.hasKey(event.keyCode)) { + this.inputMap.remove(event.keyCode) + this.textInputPlugin?.getEditingState().handleInsertTextEvent(text) } } this.isShiftMode = event.keyCode == KeyCode.KEYCODE_SHIFT_LEFT -- Gitee From bc675f64e52eaf772dabed38a804bb555a8f04f7 Mon Sep 17 00:00:00 2001 From: asklie <760956257@qq.com> Date: Sat, 21 Dec 2024 16:21:46 +0800 Subject: [PATCH 29/60] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=9A=E4=B8=AAwebvi?= =?UTF-8?q?ew=E7=82=B9=E5=87=BB=E7=A9=BF=E9=80=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: asklie <760956257@qq.com> --- .../platform/PlatformViewsController.ets | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets index 5c929c8418..7cf46fab2b 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets @@ -65,6 +65,20 @@ class DVModelJson { this.build = build; } } +enum TouchEventType { + /// Action code for when a primary pointer touched the screen. + ACTION_DOWN = 0, + /// Action code for when a primary pointer stopped touching the screen. + ACTION_UP = 1, + /// Action code for when the event only includes information about pointer movement. + ACTION_MOVE = 2, + /// Action code for when a motion event has been canceled. + ACTION_CANCEL = 3, + /// Action code for when a secondary pointer touched the screen. + ACTION_POINTER_DOWN = 5, + /// Action code for when a secondary pointer touched the screen. + ACTION_POINTER_UP = 6, +} const TAG = "PlatformViewsController" @@ -203,12 +217,12 @@ export default class PlatformViewsController implements PlatformViewsAccessibili let dvModel = viewWrapper.getDvModel() let params = dvModel.getLayoutParams() as Record; //接收到点击类型为down的时候 - if (touch.action == 0) { + if (touch.action === TouchEventType.ACTION_DOWN) { //将当前点击状态设置为true params['down'] = true //首次收到触控点击类型为 OH_NATIVEXCOMPONENT_DOWN ,则将存到列表中的事件分发出去 let touchEventArray: Array | undefined = params['touchEvent'] as Array - if (touchEventArray != undefined) { + if (touchEventArray !== undefined) { let nodeController = params['nodeController'] as EmbeddingNodeController; for (let it of touchEventArray) { nodeController.postEvent(it) @@ -216,9 +230,10 @@ export default class PlatformViewsController implements PlatformViewsAccessibili //首次执行完之后,将列表数据置空 params['touchEvent'] = undefined } - //当前接收的事件类型为up的时候 - } else if (touch.action == 1) { + //当前接收的事件类型为up的时候 + } else if (touch.action === TouchEventType.ACTION_UP || touch.action === TouchEventType.ACTION_CANCEL) { //手指抬起之后,将当前点击状态设置为false。测试了一下,多个手指突然抬起,最后返回的状态也是1 + // 手指移动点击的时候,会直接触发取消,不再触发up事件。 //所以,这边就以状态抬起,代表当前用户不点击platformview了 params['down'] = false } -- Gitee From 2eb93cb1b9ff1ab025660dafd96e8d516082d1a9 Mon Sep 17 00:00:00 2001 From: asklie <760956257@qq.com> Date: Mon, 23 Dec 2024 16:26:59 +0800 Subject: [PATCH 30/60] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E7=A9=BF=E9=80=8F=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: asklie <760956257@qq.com> --- .../src/main/ets/embedding/ohos/TouchEventProcessor.ets | 4 ++++ .../src/main/ets/plugin/platform/PlatformViewsController.ets | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/TouchEventProcessor.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/TouchEventProcessor.ets index e6100e0833..582d2dca29 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/TouchEventProcessor.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/TouchEventProcessor.ets @@ -257,6 +257,10 @@ export default class TouchEventProcessor { //如果flutter端判断当前platformView是可点击的,则将事件分发出去 let touchEvent = TouchEventProcessor.getInstance().constureCustomTouchEvent(strings, top, left); let nodeController = params['nodeController'] as EmbeddingNodeController; + // 保证platformviewcontroller.ets的onTouch的down属性正常结束 + if (touchEvent.type === TouchType.Up) { + params['down'] === false; + } nodeController.postEvent(touchEvent) } else { //如果触摸事件为OH_NATIVEXCOMPONENT_DOWN=0,且只有一个手指,说明是下一次点击了,这时候需要清空上一次的数据 diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets index 7cf46fab2b..45c4177ae2 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets @@ -231,9 +231,8 @@ export default class PlatformViewsController implements PlatformViewsAccessibili params['touchEvent'] = undefined } //当前接收的事件类型为up的时候 - } else if (touch.action === TouchEventType.ACTION_UP || touch.action === TouchEventType.ACTION_CANCEL) { - //手指抬起之后,将当前点击状态设置为false。测试了一下,多个手指突然抬起,最后返回的状态也是1 - // 手指移动点击的时候,会直接触发取消,不再触发up事件。 + } else if (touch.action === TouchEventType.ACTION_UP) { + //手指抬起之后,将当前点击状态设置为false。测试了一下,多个手指突然抬起,最后返回的状态也是ACTION_UP //所以,这边就以状态抬起,代表当前用户不点击platformview了 params['down'] = false } -- Gitee From 0930c1645a435a519aa797ed650326f8f10b91a9 Mon Sep 17 00:00:00 2001 From: xiaozn Date: Mon, 23 Dec 2024 19:27:02 +0800 Subject: [PATCH 31/60] =?UTF-8?q?fix:=20displayFeature=E5=B0=86=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E6=95=B4=E4=B8=AA=E9=A1=B5=E9=9D=A2=E7=9A=84=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=EF=BC=8C=E5=8C=85=E6=8B=AC=E6=8A=98=E5=8F=A0=E5=8C=BA?= =?UTF-8?q?=E5=9F=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xiaozn --- .../flutter/src/main/ets/view/FlutterView.ets | 171 +++++++++--------- 1 file changed, 86 insertions(+), 85 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index c974a8fd92..84c8751741 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -27,6 +27,9 @@ import PlatformView, { Params } from '../plugin/platform/PlatformView'; import { JSON } from '@kit.ArkTS'; import { accessibility } from '@kit.AccessibilityKit'; import TextInputPlugin from '../plugin/editing/TextInputPlugin'; +import { cert } from '@kit.DeviceCertificateKit'; +import json from '@ohos.util.json'; +import { data } from '@kit.TelephonyKit'; const TAG = "FlutterViewTag"; @@ -47,7 +50,7 @@ export class ViewportMetrics { systemGestureInsetBottom: number = 0; systemGestureInsetLeft: number = 0; physicalTouchSlop: number = -1; - displayFeatures: ArrayList = new ArrayList(); + displayFeatures: DisplayFeature[] = []; clone(): ViewportMetrics { const copy = new ViewportMetrics(); @@ -92,17 +95,17 @@ export class ViewportMetrics { } export class DisplayFeature { - bounds: display.Rect[]; + bounds: display.Rect; type: DisplayFeatureType; state: DisplayFeatureState; - constructor(bounds: display.Rect[], type: DisplayFeatureType, state: DisplayFeatureState) { + constructor(bounds: display.Rect, type: DisplayFeatureType, state: DisplayFeatureState = DisplayFeatureState.UNKNOWN) { this.bounds = bounds; this.type = type; this.state = state; } - getBounds(): display.Rect[] { + getBounds(): display.Rect { return this.bounds; } @@ -114,7 +117,7 @@ export class DisplayFeature { return this.state } - setBounds(bounds: display.Rect[]): void { + setBounds(bounds: display.Rect): void { this.bounds = bounds; } @@ -196,13 +199,15 @@ export class FlutterView { private gestureAvoidArea: window.AvoidArea; private keyboardAvoidArea: window.AvoidArea; private needSetViewport: boolean = false; + private displayFeaturesCache: Map> + = new Map>(); constructor(viewId: string, context: Context) { this.id = viewId this.displayInfo = display.getDefaultDisplaySync(); this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; - this.buildDisplayFeatures(display.getFoldStatus()); + this.mainWindow = FlutterManager.getInstance() .getWindowStage(FlutterManager.getInstance().getUIAbility(context)) .getMainWindowSync(); @@ -223,69 +228,77 @@ export class FlutterView { this.gestureAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); this.keyboardAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); - // 监听折叠状态的改变 - display?.on('foldStatusChange', (data: display.FoldStatus) => { - Log.d(TAG, `Fold status change to ${JSON.stringify(data)}`) - this.buildDisplayFeatures(data); - }) - // Subscribes to display changes. Example: event that the display size is changed. try { - display.on("change", ()=>{ - this.displayInfo = display.getDefaultDisplaySync(); - if (this.viewportMetrics.devicePixelRatio != this.displayInfo?.densityPixels) { - this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; - Log.i(TAG, "Display on: " + JSON.stringify(this.displayInfo)) - this.updateViewportMetrics() - } - }); + display.on("change", this.displayChangeCallback); } catch (e) { Log.e(TAG, "displayInfo error" + JSON.stringify(e)); } } - private async buildDisplayFeatures(foldStatus: display.FoldStatus) { - let displayFeatures: ArrayList = new ArrayList(); - let bound: display.Rect[]; - let state = 0; - let type = 0; - const displayInfos = display.getDefaultDisplaySync(); - if (display.isFoldable()) { - switch (foldStatus) { - case DisplayFoldStatus.FOLD_STATUS_FOLDED.valueOf(): - type = DisplayFeatureType.HINGE; - state = DisplayFeatureState.UNKNOWN; - break; - case DisplayFoldStatus.FOLD_STATUS_EXPANDED.valueOf(): - type = DisplayFeatureType.FOLD; - state = DisplayFeatureState.POSTURE_FLAT; - break; - case DisplayFoldStatus.FOLD_STATUS_HALF_FOLDED.valueOf(): - type = DisplayFeatureType.FOLD; - state = DisplayFeatureState.POSTURE_HALF_OPENED; - break; - default: - type = DisplayFeatureType.UNKNOWN; - state = DisplayFeatureState.UNKNOWN; - break; + private displayChangeCallback = async (data: number) => { + this.displayInfo = display.getDefaultDisplaySync(); + if (this.viewportMetrics.devicePixelRatio != this.displayInfo?.densityPixels) { + this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; + let displayFeatures: Array = await this.buildDisplayFeatures(); + Log.i(TAG, "Display on: " + JSON.stringify(this.displayInfo)) + this.viewportMetrics.displayFeatures = displayFeatures; + this.updateViewportMetrics() + } + } + + private async buildDisplayFeatures(): Promise> { + let displayMode: display.FoldDisplayMode = display.getFoldDisplayMode(); + if (this.displayFeaturesCache.has(displayMode)) { + return this.displayFeaturesCache.get(displayMode)!; + } + let displayFeatures: Array = []; + let foldCreaseRegion: display.FoldCreaseRegion = display.getCurrentFoldCreaseRegion(); + if (foldCreaseRegion != undefined) { + let type: DisplayFeatureType = DisplayFeatureType.FOLD; + let state: DisplayFeatureState = DisplayFeatureState.UNKNOWN; + + if (displayMode == display.FoldDisplayMode.FOLD_DISPLAY_MODE_FULL || + displayMode == display.FoldDisplayMode.FOLD_DISPLAY_MODE_COORDINATION) { + state = DisplayFeatureState.POSTURE_FLAT; + } else if (displayMode == display.FoldDisplayMode.FOLD_DISPLAY_MODE_MAIN + || displayMode == display.FoldDisplayMode.FOLD_DISPLAY_MODE_SUB) { + state = DisplayFeatureState.POSTURE_HALF_OPENED; } - const displays = await display.getAllDisplays(); - for (let i = 0; i < displays.length; i++) { - let cutoutInfo = await displays[i].getCutoutInfo(); - bound = cutoutInfo.boundingRects; - displayFeatures.add(new DisplayFeature(bound, type, state)); + foldCreaseRegion.creaseRects.forEach((rect: display.Rect) => { + displayFeatures.push(new DisplayFeature(rect, type, state)); + }); + } + + let cutoutInfo: display.CutoutInfo | undefined = await this.displayInfo?.getCutoutInfo(); + if (cutoutInfo != undefined) { + cutoutInfo.boundingRects.forEach((bounding: display.Rect) => { + displayFeatures.push(new DisplayFeature(bounding, DisplayFeatureType.CUTOUT)); + }); + + let waterFallRect: display.WaterfallDisplayAreaRects = cutoutInfo.waterfallDisplayAreaRects; + if (!this.isEmptyRect(waterFallRect.left)) { + displayFeatures.push(new DisplayFeature(waterFallRect.left, DisplayFeatureType.FOLD)); } - Log.d(TAG, `FOLD device displayFeatures is : ${JSON.stringify(displayFeatures)}`) - } else { - type = DisplayFeatureType.UNKNOWN; - state = DisplayFeatureState.UNKNOWN; - let infos = await displayInfos?.getCutoutInfo(); - bound = infos.boundingRects; - displayFeatures.add(new DisplayFeature(bound, type, state)); - Log.d(TAG, `UNFold device displayFeatures is : ${JSON.stringify(displayFeatures)}`) + if (!this.isEmptyRect(waterFallRect.right)) { + displayFeatures.push(new DisplayFeature(waterFallRect.right, DisplayFeatureType.FOLD)); + } + if (!this.isEmptyRect(waterFallRect.top)) { + displayFeatures.push(new DisplayFeature(waterFallRect.top, DisplayFeatureType.FOLD)); + } + if (!this.isEmptyRect(waterFallRect.bottom)) { + displayFeatures.push(new DisplayFeature(waterFallRect.bottom, DisplayFeatureType.FOLD)); + } + } + this.displayFeaturesCache.set(displayMode, displayFeatures); + return displayFeatures; + } + + private isEmptyRect(rect: display.Rect | null | undefined) { + if (rect == null || rect == undefined) { + return true } - this.viewportMetrics.displayFeatures = displayFeatures; - this.updateViewportMetrics(); + return rect.left == 0 && rect.top ==0 && rect.width == 0 && rect.height == 0; } private windowSizeChangeCallback = (data: window.Size) => { @@ -388,12 +401,7 @@ export class FlutterView { this.mainWindow = null; try { - display.off("change", ()=>{ - this.displayInfo = display.getDefaultDisplaySync(); - this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; - Log.i(TAG, "Display Info: " + JSON.stringify(this.displayInfo)) - this.updateViewportMetrics() - }); + display.off("change", this.displayChangeCallback); } catch (e) { Log.e(TAG, "displayInfo off error" + JSON.stringify(e)); } @@ -555,27 +563,20 @@ export class FlutterView { private updateViewportMetrics(): boolean { if (this.isAttachedToFlutterEngine()) { Log.i(TAG, 'updateViewportMetrics devicePixelRatio:' + this.viewportMetrics.devicePixelRatio); - - const displayFeatures = this.viewportMetrics.displayFeatures; - let boundCount = 0; - for (let i = 0; i < displayFeatures.length; i++) { - boundCount = boundCount + displayFeatures[i].getBounds().length; - } - let displayFeatureBound: number[] = new Array(boundCount * 4); - let displayFeatureType: number[] = new Array(displayFeatures.length); - let displayFeatureStatus: number[] = new Array(displayFeatures.length); - for (let i = 0; i < displayFeatures.length; i++) { - let singleFeatureBound = displayFeatures[i].getBounds(); - for (let j = 0; j < singleFeatureBound.length; j++) { - displayFeatureBound[4*i + 4*j] = singleFeatureBound[j].left; - displayFeatureBound[4*i + 4*j + 1] = singleFeatureBound[j].top - displayFeatureBound[4*i + 4*j + 2] = singleFeatureBound[j].width; - displayFeatureBound[4*i + 4*j + 3] = singleFeatureBound[j].height; - } - displayFeatureType[i] = displayFeatures[i].getType(); - displayFeatureStatus[i] = displayFeatures[i].getState(); + let disPlayFeature = this.viewportMetrics.displayFeatures; + let displayFeatureBound: number[] = new Array(disPlayFeature.length * 4); + let displayFeatureType: number[] = new Array(disPlayFeature.length); + let displayFeatureStatus: number[] = new Array(disPlayFeature.length); + + for (let i = 0; i < disPlayFeature.length; i++) { + displayFeatureBound[4 * i] = disPlayFeature[i].bounds.left; + displayFeatureBound[4 * i + 1] = disPlayFeature[i].bounds.top; + displayFeatureBound[4 * i + 2] = disPlayFeature[i].bounds.width; + displayFeatureBound[4 * i + 3] = disPlayFeature[i].bounds.height; + displayFeatureType[i] = disPlayFeature[i].type; + displayFeatureStatus[i] = disPlayFeature[i].state; } - + Log.d(TAG, 'update displayFeatureBound is:' + json.stringify(disPlayFeature)); this?.flutterEngine?.getFlutterNapi()?.setViewportMetrics(this.viewportMetrics.devicePixelRatio, this.viewportMetrics.physicalWidth, this.viewportMetrics.physicalHeight, -- Gitee From 10f9ef6fb38fb07aa3cfb3f0dd686cbc61bd087e Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 23 Dec 2024 20:41:20 +0800 Subject: [PATCH 32/60] =?UTF-8?q?refactor:=E5=A2=9E=E5=8A=A0=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E5=AE=89=E5=85=A8=E7=89=88=E6=97=A0=E9=9A=9C=E7=A2=8D?= =?UTF-8?q?=E5=8D=95=E4=BE=8B=E6=A8=A1=E5=BC=8F=EF=BC=8C=E5=87=8F=E5=B0=91?= =?UTF-8?q?=E6=97=A0=E9=9A=9C=E7=A2=8D=E5=8A=A8=E6=80=81=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E5=86=97=E4=BD=99=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E6=97=A0=E9=9A=9C=E7=A2=8DC-API=E6=8E=A5=E5=8F=A3=E5=90=8D?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=EF=BC=8C=E5=A2=9E=E5=BC=BA=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=8F=AF=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- shell/platform/ohos/BUILD.gn | 3 +- .../ohos_accessibility_bridge.cpp | 340 +++++++++--------- .../accessibility/ohos_accessibility_bridge.h | 9 +- .../ohos/utils/arkui_accessibility_constant.h | 88 +++++ 4 files changed, 257 insertions(+), 183 deletions(-) create mode 100644 shell/platform/ohos/utils/arkui_accessibility_constant.h diff --git a/shell/platform/ohos/BUILD.gn b/shell/platform/ohos/BUILD.gn index 7dd1671fa5..62c781f18d 100644 --- a/shell/platform/ohos/BUILD.gn +++ b/shell/platform/ohos/BUILD.gn @@ -91,7 +91,8 @@ source_set("flutter_ohos_sources") { "./accessibility/native_accessibility_channel.h", "./accessibility/ohos_accessibility_ddl.h", "./utils/ddl_utils.h", - "./utils/ohos_utils.h" + "./utils/ohos_utils.h", + "./utils/arkui_accessibility_constant.h" ] #configs += [ "//flutter/shell/platform/ohos/config:gtk" ] diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 48e06cb30b..0554028b42 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -15,8 +15,6 @@ #include "ohos_accessibility_bridge.h" #include #include -#include -#include #include #include "flutter/fml/logging.h" #include "flutter/shell/platform/ohos/ohos_logging.h" @@ -69,23 +67,20 @@ namespace flutter { const int32_t OhosAccessibilityBridge::OHOS_API_VERSION = OH_GetSdkApiVersion(); -OhosAccessibilityBridge* OhosAccessibilityBridge::bridgeInstance = nullptr; +std::unique_ptr OhosAccessibilityBridge::bridgeInstance_ = nullptr; +/** + * 采用局部静态变量配合call-once特性,实现线程安全的单例模式 + */ OhosAccessibilityBridge* OhosAccessibilityBridge::GetInstance() { - if(!bridgeInstance) { - bridgeInstance = new OhosAccessibilityBridge(); - } - return bridgeInstance; -} - -void OhosAccessibilityBridge::DestroyInstance() { - delete bridgeInstance; - bridgeInstance = nullptr; + static std::once_flag onceFlag; + std::call_once(onceFlag, []() { + bridgeInstance_.reset(new OhosAccessibilityBridge()); + }); + return bridgeInstance_.get(); } -OhosAccessibilityBridge::OhosAccessibilityBridge() {} - /** * 监听当前ohos平台是否开启无障碍屏幕朗读服务 */ @@ -177,8 +172,8 @@ void OhosAccessibilityBridge::UpdateSemantics( // 当滑动节点产生滑动,并执行滑动处理 if (HasScrolled(nodeEx)) { LOGD("UpdateSemantics -> has scrolled"); - auto* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); + auto OH_ArkUI_CreateAccessibilityElementInfo = + OhosAccessibilityDDL::DLLoadCreateElemInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); auto* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); @@ -191,8 +186,8 @@ void OhosAccessibilityBridge::UpdateSemantics( static_cast(accessibilityFocusedNode.id), ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_FOCUS_NODE_UPDATE); - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); + auto OH_ArkUI_DestoryAccessibilityElementInfo = + OhosAccessibilityDDL::DLLoadDestroyElemFunc(ArkUIAccessibilityConstant::ARKUI_DESTORY_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityElementInfo); OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); _elementInfo = nullptr; @@ -255,24 +250,24 @@ void OhosAccessibilityBridge::FlutterScrollExecution( if (node.scrollChildren > 0) { // 配置当前滑动组件的子节点总数 int32_t itemCount = node.scrollChildren; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetItemCount)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetItemCount"); + auto OH_ArkUI_AccessibilityElementInfoSetItemCount = + OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_ITEM_COUNT); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetItemCount); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetItemCount(elementInfoFromList, itemCount)); // 设置当前页面可见的起始滑动index int32_t startItemIndex = node.scrollIndex; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetStartItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetStartItemIndex"); + auto OH_ArkUI_AccessibilityElementInfoSetStartItemIndex = + OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_START_ITEM_IDX); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetStartItemIndex); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetStartItemIndex(elementInfoFromList, startItemIndex)); // 设置当前获焦节点的当前index int32_t currItemIndex = accessibilityFocusedNode.id; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex"); + auto OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex = + OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_CURR_ITEM_IDX); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex(elementInfoFromList, currItemIndex)); @@ -298,12 +293,11 @@ void OhosAccessibilityBridge::FlutterScrollExecution( } // 设置当前页面可见的末尾滑动index int32_t endItemIndex = node.scrollIndex + visibleChildren - 1; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEndItemIndex)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetEndItemIndex"); + auto OH_ArkUI_AccessibilityElementInfoSetEndItemIndex = + OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_END_ITEM_IDX); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetEndItemIndex); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetEndItemIndex(elementInfoFromList, endItemIndex) - ); + OH_ArkUI_AccessibilityElementInfoSetEndItemIndex(elementInfoFromList, endItemIndex)); } } @@ -315,18 +309,18 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) if (OHOS_API_VERSION < 13) { return; } CHECK_NULL_PTR(provider_, RequestFocusWhenPageUpdate); - auto* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); + auto OH_ArkUI_CreateAccessibilityEventInfo = + OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); auto* reqFocusEventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); - auto* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); + auto OH_ArkUI_CreateAccessibilityElementInfo = + OhosAccessibilityDDL::DLLoadCreateElemInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); auto* elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); - int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = - OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); + auto OH_ArkUI_AccessibilityEventSetEventType = + OhosAccessibilityDDL::DLLoadSetEventFunc(ArkUIAccessibilityConstant::ARKUI_SET_EVENT_TYPE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetEventType); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityEventSetEventType( @@ -335,15 +329,15 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_REQUEST_ACCESSIBILITY_FOCUS) ); - int32_t (*OH_ArkUI_AccessibilityEventSetRequestFocusId)(ArkUI_AccessibilityEventInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetReqFocusFunc("OH_ArkUI_AccessibilityEventSetRequestFocusId"); + auto OH_ArkUI_AccessibilityEventSetRequestFocusId = + OhosAccessibilityDDL::DLLoadSetReqFocusFunc(ArkUIAccessibilityConstant::ARKUI_SET_REQ_FOCUSED_ID); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetRequestFocusId); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityEventSetRequestFocusId(reqFocusEventInfo, requestFocusId) ); - int32_t (*OH_ArkUI_AccessibilityEventSetElementInfo)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadSetEventElemFunc("OH_ArkUI_AccessibilityEventSetElementInfo"); + auto OH_ArkUI_AccessibilityEventSetElementInfo = + OhosAccessibilityDDL::DLLoadSetEventElemFunc(ArkUIAccessibilityConstant::ARKUI_EVENT_SET_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetElementInfo); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityEventSetElementInfo(reqFocusEventInfo, elementInfo) @@ -353,19 +347,19 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) FML_DLOG(WARNING) << "PageStateUpdate callback-> errorCode =" << errorCode; }; - void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = - OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); + auto OH_ArkUI_SendAccessibilityAsyncEvent = + OhosAccessibilityDDL::DLLoadSendAsyncEventFunc(ArkUIAccessibilityConstant::ARKUI_SEND_A11Y_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_SendAccessibilityAsyncEvent); OH_ArkUI_SendAccessibilityAsyncEvent(provider_, reqFocusEventInfo, callback); - void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = - OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); + auto OH_ArkUI_DestoryAccessibilityEventInfo = + OhosAccessibilityDDL::DLLoadDestroyEventFunc(ArkUIAccessibilityConstant::ARKUI_DESTORY_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityEventInfo); OH_ArkUI_DestoryAccessibilityEventInfo(reqFocusEventInfo); reqFocusEventInfo = nullptr; - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); + auto OH_ArkUI_DestoryAccessibilityElementInfo = + OhosAccessibilityDDL::DLLoadDestroyElemFunc(ArkUIAccessibilityConstant::ARKUI_DESTORY_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityElementInfo); OH_ArkUI_DestoryAccessibilityElementInfo(elementInfo); elementInfo = nullptr; @@ -380,41 +374,39 @@ void OhosAccessibilityBridge::Announce(std::unique_ptr& message) CHECK_NULL_PTR(provider_, Announce); // 创建并设置屏幕朗读事件 - auto* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); + auto OH_ArkUI_CreateAccessibilityEventInfo = + OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); auto* announceEventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); - int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = - OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); + auto OH_ArkUI_AccessibilityEventSetEventType = + OhosAccessibilityDDL::DLLoadSetEventFunc(ArkUIAccessibilityConstant::ARKUI_SET_EVENT_TYPE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetEventType); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityEventSetEventType( announceEventInfo, - ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ANNOUNCE_FOR_ACCESSIBILITY) - ); + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ANNOUNCE_FOR_ACCESSIBILITY)); - int32_t (*OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility)(ArkUI_AccessibilityEventInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetEventStringFunc("OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility"); + auto OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility = + OhosAccessibilityDDL::DLLoadSetEventStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_ANNOUNCED_TEXT); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility( - announceEventInfo, message.get()) - ); + announceEventInfo, message.get())); FML_DLOG(INFO) << ("announce -> message: ") << (message.get()); auto callback = [](int32_t errorCode) { FML_DLOG(WARNING) << "announce callback-> errorCode =" << errorCode; }; - void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = - OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); + auto OH_ArkUI_SendAccessibilityAsyncEvent = + OhosAccessibilityDDL::DLLoadSendAsyncEventFunc(ArkUIAccessibilityConstant::ARKUI_SEND_A11Y_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_SendAccessibilityAsyncEvent); OH_ArkUI_SendAccessibilityAsyncEvent(provider_, announceEventInfo, callback); - void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = - OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); + auto OH_ArkUI_DestoryAccessibilityEventInfo = + OhosAccessibilityDDL::DLLoadDestroyEventFunc(ArkUIAccessibilityConstant::ARKUI_DESTORY_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityEventInfo); OH_ArkUI_DestoryAccessibilityEventInfo(announceEventInfo); announceEventInfo = nullptr; @@ -612,12 +604,11 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( int32_t right = static_cast(flutterNode.rect.fRight); int32_t bottom = static_cast(flutterNode.rect.fBottom); ArkUI_AccessibleRect rect = {left, top, right, bottom}; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = - OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); + auto OH_ArkUI_AccessibilityElementInfoSetScreenRect = + OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc(ArkUIAccessibilityConstant::ARKUI_SET_SCREEN_RECT); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetScreenRect); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect) - ); + OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect)); // 设置root节点的屏幕绝对坐标rect SetAbsoluteScreenRect(flutterNode, left, top, right, bottom); @@ -626,47 +617,44 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); // 根据flutternode信息配置对应的elementinfo - int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); + auto OH_ArkUI_AccessibilityElementInfoSetElementId = + OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_NODE_ID); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetElementId); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, 0)); // NOTE: arkui无障碍子系统强制设置root的父节点id = -2100000 (严禁更改) - int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); + auto OH_ArkUI_AccessibilityElementInfoSetParentId = + OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_PARENT_ID); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetParentId); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, ARKUI_ACCESSIBILITY_ROOT_PARENT_ID) - ); + OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, ARKUI_ACCESSIBILITY_ROOT_PARENT_ID)); // 设置无障碍播报文本 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); + auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityText = + OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_TEXT); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityText); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityText( elementInfoFromList, flutterNode.label.empty() ? - flutterNode.value.c_str() : flutterNode.label.c_str()) - ); + flutterNode.value.c_str() : flutterNode.label.c_str())); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"); + auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel = + OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_LEVEL); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes") - ); + OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes")); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"); + auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_GROUP); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfoFromList, false) - ); + OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfoFromList, false)); // 配置child节点信息 int32_t childCount = flutterNode.childrenInTraversalOrder.size(); if (childCount > 0) { auto childrenIdsVec = flutterNode.childrenInTraversalOrder; + // 孩子id升序排列,以便于对接自动化测试框架 std::sort(childrenIdsVec.begin(), childrenIdsVec.end()); int64_t childNodeIds[childCount]; for (int32_t i = 0; i < childCount; i++) { @@ -675,42 +663,41 @@ void OhosAccessibilityBridge::FlutterNodeToElementInfoById( << "FlutterNodeToElementInfoById -> elementid=0 childCount=" << childCount << " childNodeIds=" << childNodeIds[i]; } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = - OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); + auto OH_ArkUI_AccessibilityElementInfoSetChildNodeIds = + OhosAccessibilityDDL::DLLoadSetElemChildFunc(ArkUIAccessibilityConstant::ARKUI_SET_CHILD_IDS); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetChildNodeIds); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) - ); + OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds)); } // 配置root节点常用属性 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEnabled"); + auto OH_ArkUI_AccessibilityElementInfoSetEnabled = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_ENABLED); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetEnabled); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetClickable"); + auto OH_ArkUI_AccessibilityElementInfoSetClickable = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_CLICKABLE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetClickable); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetFocusable"); + auto OH_ArkUI_AccessibilityElementInfoSetFocusable = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_FOCUSABLE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetFocusable); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetVisible"); + auto OH_ArkUI_AccessibilityElementInfoSetVisible = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_VISIBLE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetVisible); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfoFromList, true)); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); + auto OH_ArkUI_AccessibilityElementInfoSetComponentType = + OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_COMPONENT_TYPE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetComponentType); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, "root")); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); + auto OH_ArkUI_AccessibilityElementInfoSetContents = + OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_CONTENTS); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetContents); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetContents(elementInfoFromList, flutterNode.label.c_str())); } else { @@ -729,8 +716,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( std::string widget_type) { if (OHOS_API_VERSION < 13) { return; } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetOperationActions)(ArkUI_AccessibilityElementInfo*, int32_t, ArkUI_AccessibleAction*) = - OhosAccessibilityDDL::DLLoadSetElemOperActionsFunc("OH_ArkUI_AccessibilityElementInfoSetOperationActions"); + 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)) { @@ -846,8 +833,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( } // set elementinfo id - int32_t (*OH_ArkUI_AccessibilityElementInfoSetElementId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetElementId"); + auto OH_ArkUI_AccessibilityElementInfoSetElementId = + OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_NODE_ID); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetElementId); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, flutterNode.id) @@ -857,16 +844,16 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( FlutterRelativeRectToScreenRect(flutterNode); auto [left, top, right, bottom] = GetAbsoluteScreenRect(flutterNode); ArkUI_AccessibleRect rect = {static_cast(left), static_cast(top), - static_cast(right), static_cast(bottom)}; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetScreenRect)(ArkUI_AccessibilityElementInfo*, ArkUI_AccessibleRect*) = - OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc("OH_ArkUI_AccessibilityElementInfoSetScreenRect"); + static_cast(right), static_cast(bottom)}; + auto OH_ArkUI_AccessibilityElementInfoSetScreenRect = + OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc(ArkUIAccessibilityConstant::ARKUI_SET_SCREEN_RECT); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetScreenRect); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect) ); FML_DLOG(INFO) << "FlutterNodeToElementInfoById -> node.id= " - << flutterNode.id << " SceenRect = (" << left << ", " << top - << ", " << right << ", " << bottom << ")"; + << flutterNode.id << " SceenRect = (" << left << ", " << top + << ", " << right << ", " << bottom << ")"; // 配置arkui的elementinfo可操作动作属性 if (IsTextField(flutterNode)) { @@ -884,8 +871,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( // 设置当前节点的父节点id int32_t parentId = GetParentId(elementId); - int32_t (*OH_ArkUI_AccessibilityElementInfoSetParentId)(ArkUI_AccessibilityElementInfo*, int32_t) = - OhosAccessibilityDDL::DLLoadSetElemIntFunc("OH_ArkUI_AccessibilityElementInfoSetParentId"); + auto OH_ArkUI_AccessibilityElementInfoSetParentId = + OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_PARENT_ID); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetParentId); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, parentId) @@ -894,8 +881,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( // 设置可朗读文本 std::string text = flutterNode.label + flutterNode.value; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityText)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"); + auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityText = + OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_TEXT); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityText); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityText(elementInfoFromList, text.c_str()) @@ -903,16 +890,16 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( FML_DLOG(INFO) << "FlutterNodeToElementInfoById SetAccessibilityText = " << text; // 设置无障碍content文本 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetContents)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetContents"); + auto OH_ArkUI_AccessibilityElementInfoSetContents = + OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_CONTENTS); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetContents); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetContents(elementInfoFromList, text.c_str()) ); // 设置hint提示文本 std::string hint = flutterNode.hint; - int32_t (*OH_ArkUI_AccessibilityElementInfoSetHintText)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetHintText"); + auto OH_ArkUI_AccessibilityElementInfoSetHintText = + OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_HINT); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetHintText); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetHintText(elementInfoFromList, hint.c_str()) @@ -930,8 +917,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( << " childCount=" << childCount << " childNodeIds=" << childNodeIds[i]; } - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChildNodeIds)(ArkUI_AccessibilityElementInfo*, int32_t, int64_t*) = - OhosAccessibilityDDL::DLLoadSetElemChildFunc("OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"); + auto OH_ArkUI_AccessibilityElementInfoSetChildNodeIds = + OhosAccessibilityDDL::DLLoadSetElemChildFunc(ArkUIAccessibilityConstant::ARKUI_SET_CHILD_IDS); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetChildNodeIds); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds) @@ -943,74 +930,74 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( */ // 判断当前节点组件是否enabled if (IsNodeEnabled(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEnabled)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEnabled"); + auto OH_ArkUI_AccessibilityElementInfoSetEnabled = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_ENABLED); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetEnabled); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfoFromList, true) ); FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetEnabled -> true"; + << " OH_ArkUI_AccessibilityElementInfoSetEnabled -> true"; } // 判断当前节点是否可点击 if (IsNodeClickable(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetClickable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetClickable"); + auto OH_ArkUI_AccessibilityElementInfoSetClickable = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_CLICKABLE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetClickable); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfoFromList, true) ); FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetClickable -> true"; + << " OH_ArkUI_AccessibilityElementInfoSetClickable -> true"; } // 判断当前节点是否可获焦点 if (IsNodeFocusable(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetFocusable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetFocusable"); + auto OH_ArkUI_AccessibilityElementInfoSetFocusable = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_FOCUSABLE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetFocusable); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfoFromList, true) ); FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetFocusable -> true"; + << " OH_ArkUI_AccessibilityElementInfoSetFocusable -> true"; } // 判断当前节点是否为密码输入框 if (IsNodePassword(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetIsPassword)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetIsPassword"); + auto OH_ArkUI_AccessibilityElementInfoSetIsPassword = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_IS_PASSWORD); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetIsPassword); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetIsPassword(elementInfoFromList, true) ); FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetIsPassword -> true"; + << " OH_ArkUI_AccessibilityElementInfoSetIsPassword -> true"; } // 判断当前节点是否具备checkable状态 (如:checkbox, radio button) if (IsNodeCheckable(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetCheckable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetCheckable"); + auto OH_ArkUI_AccessibilityElementInfoSetCheckable = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_CHECKABLE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetCheckable); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetCheckable(elementInfoFromList, true) ); FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetCheckable -> true"; + << " OH_ArkUI_AccessibilityElementInfoSetCheckable -> true"; } // 判断当前节点(check box/radio button)是否checked/unchecked if (IsNodeChecked(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetChecked)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetChecked"); + auto OH_ArkUI_AccessibilityElementInfoSetChecked = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_CHECKED); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetChecked); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetChecked(elementInfoFromList, true) ); FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetChecked -> true"; + << " OH_ArkUI_AccessibilityElementInfoSetChecked -> true"; } // 判断当前节点组件是否可显示 if (IsNodeVisible(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetVisible)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetVisible"); + auto OH_ArkUI_AccessibilityElementInfoSetVisible = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_VISIBLE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetVisible); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfoFromList, true) @@ -1020,17 +1007,17 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( } // 判断当前节点组件是否选中 if (IsNodeSelected(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetSelected)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetSelected"); + auto OH_ArkUI_AccessibilityElementInfoSetSelected = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_SELECTED); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetSelected); OH_ArkUI_AccessibilityElementInfoSetSelected(elementInfoFromList, true); FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetSelected -> true"; + << " OH_ArkUI_AccessibilityElementInfoSetSelected -> true"; } // 判断当前节点组件是否可滑动 if (IsNodeScrollable(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetScrollable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetScrollable"); + auto OH_ArkUI_AccessibilityElementInfoSetScrollable = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_SCROLLABLE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetScrollable); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetScrollable(elementInfoFromList, true) @@ -1040,8 +1027,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( } // 判断当前节点组件是否可编辑(文本输入框) if (IsTextField(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetEditable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetEditable"); + auto OH_ArkUI_AccessibilityElementInfoSetEditable = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_EDITABLE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetEditable); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetEditable(elementInfoFromList, true) @@ -1049,15 +1036,10 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id << " OH_ArkUI_AccessibilityElementInfoSetEditable -> true"; } - // 判断当前节点组件是否为滑动条 - if (IsSlider(flutterNode)) { - FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id - << " OH_ArkUI_AccessibilityElementInfoSetRangeInfo -> true"; - } // 判断当前节点组件是否支持长按 if (IsNodeHasLongPress(flutterNode)) { - int32_t (*OH_ArkUI_AccessibilityElementInfoSetLongClickable)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetLongClickable"); + auto OH_ArkUI_AccessibilityElementInfoSetLongClickable = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_LONG_PRESS); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetLongClickable); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetLongClickable(elementInfoFromList, true) @@ -1072,8 +1054,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( FML_DLOG(INFO) << "FlutterNodeToElementInfoById componentTypeName = " << componentTypeName; // flutter节点对应elementinfo所属的组件类型(如:root, button,text等) - int32_t (*OH_ArkUI_AccessibilityElementInfoSetComponentType)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetComponentType"); + auto OH_ArkUI_AccessibilityElementInfoSetComponentType = + OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_COMPONENT_TYPE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetComponentType); if (elementId == 0) { ARKUI_ACCESSIBILITY_CALL_CHECK( @@ -1095,15 +1077,15 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( * “no”:当前组件不可被无障碍辅助服务所识别 * “no-hide-descendants”:当前组件及其所有子组件不可被无障碍辅助服务所识别 */ - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel)(ArkUI_AccessibilityElementInfo*, const char*) = - OhosAccessibilityDDL::DLLoadSetElemStringFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"); + auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel = + OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_LEVEL); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes"); ); // 无障碍组,设置为true时表示该组件及其所有子组件为一整个可以选中的组件,无障碍服务将不再关注其子组件内容。默认值:false - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"); + auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_GROUP); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfoFromList, false); @@ -1163,8 +1145,8 @@ void OhosAccessibilityBridge::BuildArkUISemanticsTree( LOGE("BuildArkUISemanticsTree: GetFlutterSemanticsNode id=%{public}ld null", levelOrderId); } //当节点为隐藏状态时,自动规避 - auto* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = - OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); + auto OH_ArkUI_AddAndGetAccessibilityElementInfo = + OhosAccessibilityDDL::DLLoadGetElemFunc(ArkUIAccessibilityConstant::ARKUI_GET_A11Y_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_AddAndGetAccessibilityElementInfo); auto* newElementInfo = OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); //配置当前子节点信息 @@ -1207,8 +1189,8 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( } // 从elementinfolist中获取elementinfo - auto* (*OH_ArkUI_AddAndGetAccessibilityElementInfo)(ArkUI_AccessibilityElementInfoList*) = - OhosAccessibilityDDL::DLLoadGetElemFunc("OH_ArkUI_AddAndGetAccessibilityElementInfo"); + 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); @@ -1463,8 +1445,8 @@ void OhosAccessibilityBridge::PerformSetText( ArkUI_AccessibilityActionArguments* actionArguments) { if (OHOS_API_VERSION < 13) { return; } - int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = - OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); + auto OH_ArkUI_FindAccessibilityActionArgumentByKey = + OhosAccessibilityDDL::DLLoadGetFindActionArgs(ArkUIAccessibilityConstant::ARKUI_FIND_ACTION_ARG_BY_KEY); CHECK_DLL_NULL_PTR(OH_ArkUI_FindAccessibilityActionArgumentByKey); char* newText; @@ -1490,8 +1472,8 @@ void OhosAccessibilityBridge::PerformSelectText( ArkUI_AccessibilityActionArguments* actionArguments) { FML_DLOG(INFO) << "ExecuteAccessibilityAction -> action: select text(" << action << ")"; - int32_t (*OH_ArkUI_FindAccessibilityActionArgumentByKey)(ArkUI_AccessibilityActionArguments*, const char*, char**) = - OhosAccessibilityDDL::DLLoadGetFindActionArgs("OH_ArkUI_FindAccessibilityActionArgumentByKey"); + auto OH_ArkUI_FindAccessibilityActionArgumentByKey = + OhosAccessibilityDDL::DLLoadGetFindActionArgs(ArkUIAccessibilityConstant::ARKUI_FIND_ACTION_ARG_BY_KEY); CHECK_DLL_NULL_PTR(OH_ArkUI_FindAccessibilityActionArgumentByKey); auto flutterSelectTextAction = ArkuiActionsToFlutterActions(action); @@ -1781,22 +1763,22 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAsyncEvent); // 1.创建eventInfo对象 - auto* (*OH_ArkUI_CreateAccessibilityEventInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateEventInfoFunc("OH_ArkUI_CreateAccessibilityEventInfo"); + auto OH_ArkUI_CreateAccessibilityEventInfo = + OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); auto* eventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); CHECK_NULL_PTR(eventInfo, Flutter_SendAccessibilityAsyncEvent); // 2.创建的elementinfo并根据对应id的flutternode进行属性初始化 - ArkUI_AccessibilityElementInfo* (*OH_ArkUI_CreateAccessibilityElementInfo)(void) = - OhosAccessibilityDDL::DLLoadCreateElemInfoFunc("OH_ArkUI_CreateAccessibilityElementInfo"); + auto OH_ArkUI_CreateAccessibilityElementInfo = + OhosAccessibilityDDL::DLLoadCreateElemInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); FlutterNodeToElementInfoById(_elementInfo, elementId); // 若为获焦事件,则设置当前elementinfo获焦 - int32_t (*OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused)(ArkUI_AccessibilityElementInfo*, bool) = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc("OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused"); + auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_FOCUSED); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused); if (eventType == ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUSED) { ARKUI_ACCESSIBILITY_CALL_CHECK( @@ -1805,14 +1787,14 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( } // 3.设置发送事件,如配置获焦、失焦、点击、滑动事件 - int32_t (*OH_ArkUI_AccessibilityEventSetEventType)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityEventType) = - OhosAccessibilityDDL::DLLoadSetEventFunc("OH_ArkUI_AccessibilityEventSetEventType"); + auto OH_ArkUI_AccessibilityEventSetEventType = + OhosAccessibilityDDL::DLLoadSetEventFunc(ArkUIAccessibilityConstant::ARKUI_SET_EVENT_TYPE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetEventType); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetEventType(eventInfo, eventType)); // 4.将eventinfo事件和当前elementinfo进行绑定 - int32_t (*OH_ArkUI_AccessibilityEventSetElementInfo)(ArkUI_AccessibilityEventInfo*, ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadSetEventElemFunc("OH_ArkUI_AccessibilityEventSetElementInfo"); + auto OH_ArkUI_AccessibilityEventSetElementInfo = + OhosAccessibilityDDL::DLLoadSetEventElemFunc(ArkUIAccessibilityConstant::ARKUI_EVENT_SET_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetElementInfo); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetElementInfo(eventInfo, _elementInfo)); @@ -1824,20 +1806,20 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( }; // 6.发送event到OH侧 - void (*OH_ArkUI_SendAccessibilityAsyncEvent)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityEventInfo*, void (*callback)(int32_t)) = - OhosAccessibilityDDL::DLLoadSendAsyncEventFunc("OH_ArkUI_SendAccessibilityAsyncEvent"); + auto OH_ArkUI_SendAccessibilityAsyncEvent = + OhosAccessibilityDDL::DLLoadSendAsyncEventFunc(ArkUIAccessibilityConstant::ARKUI_SEND_A11Y_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_SendAccessibilityAsyncEvent); OH_ArkUI_SendAccessibilityAsyncEvent(provider_, eventInfo, callback); // 7.销毁新创建的elementinfo, eventinfo - void (*OH_ArkUI_DestoryAccessibilityElementInfo)(ArkUI_AccessibilityElementInfo*) = - OhosAccessibilityDDL::DLLoadDestroyElemFunc("OH_ArkUI_DestoryAccessibilityElementInfo"); + auto OH_ArkUI_DestoryAccessibilityElementInfo = + OhosAccessibilityDDL::DLLoadDestroyElemFunc(ArkUIAccessibilityConstant::ARKUI_DESTORY_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityElementInfo); OH_ArkUI_DestoryAccessibilityElementInfo(_elementInfo); _elementInfo = nullptr; - void (*OH_ArkUI_DestoryAccessibilityEventInfo)(ArkUI_AccessibilityEventInfo*) = - OhosAccessibilityDDL::DLLoadDestroyEventFunc("OH_ArkUI_DestoryAccessibilityEventInfo"); + auto OH_ArkUI_DestoryAccessibilityEventInfo = + OhosAccessibilityDDL::DLLoadDestroyEventFunc(ArkUIAccessibilityConstant::ARKUI_DESTORY_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityEventInfo); OH_ArkUI_DestoryAccessibilityEventInfo(eventInfo); eventInfo = nullptr; diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 5c135ada61..a8c6eb9678 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include "flutter/fml/mapping.h" #include "flutter/lib/ui/semantics/custom_accessibility_action.h" @@ -27,6 +29,7 @@ #include "ohos_accessibility_features.h" #include "ohos_accessibility_ddl.h" #include "flutter/shell/platform/ohos/utils/ohos_utils.h" +#include "flutter/shell/platform/ohos/utils/arkui_accessibility_constant.h" namespace flutter { typedef flutter::SemanticsFlags FLAGS_; @@ -72,7 +75,6 @@ struct SemanticsNodeExtent : flutter::SemanticsNode { class OhosAccessibilityBridge { public: static OhosAccessibilityBridge* GetInstance(); - static void DestroyInstance(); OhosAccessibilityBridge(const OhosAccessibilityBridge&) = delete; OhosAccessibilityBridge& operator=(const OhosAccessibilityBridge&) = delete; @@ -152,8 +154,9 @@ public: void ClearFlutterSemanticsCaches(); private: - OhosAccessibilityBridge(); - static OhosAccessibilityBridge* bridgeInstance; + OhosAccessibilityBridge() = default; + static std::unique_ptr bridgeInstance_; + std::shared_ptr nativeAccessibilityChannel_; std::shared_ptr accessibilityFeatures_; diff --git a/shell/platform/ohos/utils/arkui_accessibility_constant.h b/shell/platform/ohos/utils/arkui_accessibility_constant.h new file mode 100644 index 0000000000..a5226aad6a --- /dev/null +++ b/shell/platform/ohos/utils/arkui_accessibility_constant.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ARKUI_ACCESSIBILITY_CONSTANT_H +#define ARKUI_ACCESSIBILITY_CONSTANT_H +namespace flutter { + +/** + * 封装ArkUI无障碍C-API的符号表中接口名称常量, + * 方便动态加载libflutter_accessiblity.so中的无障碍接口 + */ +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_SEND_A11Y_EVENT[] = "OH_ArkUI_SendAccessibilityAsyncEvent"; + static constexpr char ARKUI_GET_A11Y_NODE[] = "OH_ArkUI_AddAndGetAccessibilityElementInfo"; + + static constexpr char ARKUI_CREATE_NODE[] = "OH_ArkUI_CreateAccessibilityElementInfo"; + static constexpr char ARKUI_DESTORY_NODE[] = "OH_ArkUI_DestoryAccessibilityElementInfo"; + static constexpr char ARKUI_CREATE_EVENT[] = "OH_ArkUI_CreateAccessibilityEventInfo"; + static constexpr char ARKUI_DESTORY_EVENT[] = "OH_ArkUI_DestoryAccessibilityEventInfo"; + + static constexpr char ARKUI_SET_NODE_ID[] = "OH_ArkUI_AccessibilityElementInfoSetElementId"; + static constexpr char ARKUI_SET_PARENT_ID[] = "OH_ArkUI_AccessibilityElementInfoSetParentId"; + static constexpr char ARKUI_SET_COMPONENT_TYPE[] = "OH_ArkUI_AccessibilityElementInfoSetComponentType"; + static constexpr char ARKUI_SET_CONTENTS[] = "OH_ArkUI_AccessibilityElementInfoSetContents"; + static constexpr char ARKUI_SET_HINT[] = "OH_ArkUI_AccessibilityElementInfoSetHintText"; + static constexpr char ARKUI_SET_A11Y_TEXT[] = "OH_ArkUI_AccessibilityElementInfoSetAccessibilityText"; + static constexpr char ARKUI_SET_A11Y_DESC[] = "OH_ArkUI_AccessibilityElementInfoSetAccessibilityDescription"; + static constexpr char ARKUI_SET_CHILD_IDS[] = "OH_ArkUI_AccessibilityElementInfoSetChildNodeIds"; + static constexpr char ARKUI_SET_ACTIONS[] = "OH_ArkUI_AccessibilityElementInfoSetOperationActions"; + static constexpr char ARKUI_SET_SCREEN_RECT[] = "OH_ArkUI_AccessibilityElementInfoSetScreenRect"; + static constexpr char ARKUI_SET_CHECKABLE[] = "OH_ArkUI_AccessibilityElementInfoSetCheckable"; + static constexpr char ARKUI_SET_CHECKED[] = "OH_ArkUI_AccessibilityElementInfoSetChecked"; + static constexpr char ARKUI_SET_FOCUSABLE[] = "OH_ArkUI_AccessibilityElementInfoSetFocusable"; + static constexpr char ARKUI_SET_FOCUSED[] = "OH_ArkUI_AccessibilityElementInfoSetFocused"; + static constexpr char ARKUI_SET_VISIBLE[] = "OH_ArkUI_AccessibilityElementInfoSetVisible"; + static constexpr char ARKUI_SET_A11Y_FOCUSED[] = "OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused"; + static constexpr char ARKUI_SET_SELECTED[] = "OH_ArkUI_AccessibilityElementInfoSetSelected"; + static constexpr char ARKUI_SET_CLICKABLE[] = "OH_ArkUI_AccessibilityElementInfoSetClickable"; + static constexpr char ARKUI_SET_LONG_PRESS[] = "OH_ArkUI_AccessibilityElementInfoSetLongClickable"; + static constexpr char ARKUI_SET_ENABLED[] = "OH_ArkUI_AccessibilityElementInfoSetEnabled"; + static constexpr char ARKUI_SET_IS_PASSWORD[] = "OH_ArkUI_AccessibilityElementInfoSetIsPassword"; + static constexpr char ARKUI_SET_SCROLLABLE[] = "OH_ArkUI_AccessibilityElementInfoSetScrollable"; + static constexpr char ARKUI_SET_EDITABLE[] = "OH_ArkUI_AccessibilityElementInfoSetEditable"; + static constexpr char ARKUI_SET_IS_HINT[] = "OH_ArkUI_AccessibilityElementInfoSetIsHint"; + static constexpr char ARKUI_SET_A11Y_GROUP[] = "OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup"; + static constexpr char ARKUI_SET_A11Y_LEVEL[] = "OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel"; + + static constexpr char ARKUI_SET_CURR_ITEM_IDX[] = "OH_ArkUI_AccessibilityElementInfoSetCurrentItemIndex"; + static constexpr char ARKUI_SET_START_ITEM_IDX[] = "OH_ArkUI_AccessibilityElementInfoSetStartItemIndex"; + static constexpr char ARKUI_SET_END_ITEM_IDX[] = "OH_ArkUI_AccessibilityElementInfoSetEndItemIndex"; + static constexpr char ARKUI_SET_ITEM_COUNT[] = "OH_ArkUI_AccessibilityElementInfoSetItemCount"; + + static constexpr char ARKUI_SET_EVENT_TYPE[] = "OH_ArkUI_AccessibilityEventSetEventType"; + static constexpr char ARKUI_SET_ANNOUNCED_TEXT[] = "OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility"; + static constexpr char ARKUI_SET_REQ_FOCUSED_ID[] = "OH_ArkUI_AccessibilityEventSetRequestFocusId"; + static constexpr char ARKUI_EVENT_SET_NODE[] = "OH_ArkUI_AccessibilityEventSetElementInfo"; + + static constexpr char ARKUI_SET_SELECTED_START[] = "OH_ArkUI_AccessibilityElementInfoSetSelectedTextStart"; + static constexpr char ARKUI_SET_SELECTED_END[] = "OH_ArkUI_AccessibilityElementInfoSetSelectedTextEnd"; + static constexpr char ARKUI_FIND_ACTION_ARG_BY_KEY[] = "OH_ArkUI_FindAccessibilityActionArgumentByKey"; + + static constexpr char ARKUI_SET_RANGE_INFO[] = "OH_ArkUI_AccessibilityElementInfoSetRangeInfo"; + static constexpr char ARKUI_SET_GRID_INFO[] = "OH_ArkUI_AccessibilityElementInfoSetGridInfo"; + static constexpr char ARKUI_SET_A11Y_OFFSET[] = "OH_ArkUI_AccessibilityElementInfoSetAccessibilityOffset"; + static constexpr char ARKUI_SET_Z_INDEX[] = "OH_ArkUI_AccessibilityElementInfoSetZIndex"; + static constexpr char ARKUI_SET_A11Y_OPACITY[] = "OH_ArkUI_AccessibilityElementInfoSetAccessibilityOpacity"; + static constexpr char ARKUI_SET_BACKGROUND_COLOR[] = "OH_ArkUI_AccessibilityElementInfoSetBackgroundColor"; + static constexpr char ARKUI_SET_BRACKGROUND_IMG[] = "OH_ArkUI_AccessibilityElementInfoSetBackgroundImage"; + static constexpr char ARKUI_SET_BLUR[] = "OH_ArkUI_AccessibilityElementInfoSetBlur"; + static constexpr char ARKUI_SET_HIT_TEST_BEHAVIOR[] = "OH_ArkUI_AccessibilityElementInfoSetHitTestBehavior"; +}; + +} +#endif \ No newline at end of file -- Gitee From 0e384fb20821487151f434918d7e73214dd80239 Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 23 Dec 2024 21:23:00 +0800 Subject: [PATCH 33/60] =?UTF-8?q?refactor:=E5=B0=86=E4=B8=A4=E4=B8=AA?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=90=88=E5=B9=B6=E6=88=90=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=EF=BC=8C=E5=87=8F=E5=B0=91=E5=86=97=E4=BD=99=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=87=8F=EF=BC=8C=E6=8F=90=E9=AB=98=E5=A4=8D=E7=94=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 221 ++++-------------- .../accessibility/ohos_accessibility_bridge.h | 3 - 2 files changed, 44 insertions(+), 180 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 0554028b42..a4b72aa9e0 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -177,7 +177,7 @@ void OhosAccessibilityBridge::UpdateSemantics( CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); auto* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); - FlutterNodeToElementInfoById(_elementInfo, static_cast(nodeEx.id)); + FlutterSetElementInfoProperties(_elementInfo, static_cast(nodeEx.id)); // flutter滑动组件滑动处理逻辑 FlutterScrollExecution(nodeEx, _elementInfo); @@ -449,7 +449,7 @@ int32_t OhosAccessibilityBridge::GetParentId(int64_t elementId) FML_DLOG(WARNING) << "OhosAccessibilityBridge::GetParentId parentChildIdMap.size()=0"; return ARKUI_ACCESSIBILITY_ROOT_PARENT_ID; } - if (elementId == -1) { + if (elementId == -1 || elementId == 0) { return ARKUI_ACCESSIBILITY_ROOT_PARENT_ID; } int32_t childElementId = static_cast(elementId); @@ -580,134 +580,6 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( } } -/** - * 实现对特定id的flutter节点到arkui的elementinfo节点转化 - */ -void OhosAccessibilityBridge::FlutterNodeToElementInfoById( - ArkUI_AccessibilityElementInfo* elementInfoFromList, - int64_t elementId) -{ - CHECK_NULL_PTR(elementInfoFromList, FlutterNodeToElementInfoById); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById elementId = " << elementId; - - // 当elementId = -1或0时,创建root节点 - if (elementId == 0 || elementId == -1) { - // 获取flutter的root节点 - SemanticsNodeExtent flutterNode = GetFlutterSemanticsNode(static_cast(0)); - if (flutterNode.isNull) { - LOGE("FlutterNodeToElementInfoById: GetFlutterSemanticsNode id=%{public}ld null", elementId); - } - - // 设置elementinfo的屏幕坐标范围 - int32_t left = static_cast(flutterNode.rect.fLeft); - int32_t top = static_cast(flutterNode.rect.fTop); - int32_t right = static_cast(flutterNode.rect.fRight); - int32_t bottom = static_cast(flutterNode.rect.fBottom); - ArkUI_AccessibleRect rect = {left, top, right, bottom}; - auto OH_ArkUI_AccessibilityElementInfoSetScreenRect = - OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc(ArkUIAccessibilityConstant::ARKUI_SET_SCREEN_RECT); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetScreenRect); - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect)); - - // 设置root节点的屏幕绝对坐标rect - SetAbsoluteScreenRect(flutterNode, left, top, right, bottom); - - // 设置root节点的action类型 - FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); - - // 根据flutternode信息配置对应的elementinfo - auto OH_ArkUI_AccessibilityElementInfoSetElementId = - OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_NODE_ID); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetElementId); - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetElementId(elementInfoFromList, 0)); - - // NOTE: arkui无障碍子系统强制设置root的父节点id = -2100000 (严禁更改) - auto OH_ArkUI_AccessibilityElementInfoSetParentId = - OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_PARENT_ID); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetParentId); - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, ARKUI_ACCESSIBILITY_ROOT_PARENT_ID)); - - // 设置无障碍播报文本 - auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityText = - OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_TEXT); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityText); - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityText( - elementInfoFromList, flutterNode.label.empty() ? - flutterNode.value.c_str() : flutterNode.label.c_str())); - - auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel = - OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_LEVEL); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel); - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes")); - - auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_GROUP); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup); - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup(elementInfoFromList, false)); - - // 配置child节点信息 - int32_t childCount = flutterNode.childrenInTraversalOrder.size(); - if (childCount > 0) { - auto childrenIdsVec = flutterNode.childrenInTraversalOrder; - // 孩子id升序排列,以便于对接自动化测试框架 - std::sort(childrenIdsVec.begin(), childrenIdsVec.end()); - int64_t childNodeIds[childCount]; - for (int32_t i = 0; i < childCount; i++) { - childNodeIds[i] = static_cast(childrenIdsVec[i]); - FML_DLOG(INFO) - << "FlutterNodeToElementInfoById -> elementid=0 childCount=" - << childCount << " childNodeIds=" << childNodeIds[i]; - } - auto OH_ArkUI_AccessibilityElementInfoSetChildNodeIds = - OhosAccessibilityDDL::DLLoadSetElemChildFunc(ArkUIAccessibilityConstant::ARKUI_SET_CHILD_IDS); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetChildNodeIds); - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetChildNodeIds(elementInfoFromList, childCount, childNodeIds)); - } - - // 配置root节点常用属性 - auto OH_ArkUI_AccessibilityElementInfoSetEnabled = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_ENABLED); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetEnabled); - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetEnabled(elementInfoFromList, true)); - - auto OH_ArkUI_AccessibilityElementInfoSetClickable = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_CLICKABLE); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetClickable); - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetClickable(elementInfoFromList, true)); - - auto OH_ArkUI_AccessibilityElementInfoSetFocusable = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_FOCUSABLE); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetFocusable); - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetFocusable(elementInfoFromList, true)); - - auto OH_ArkUI_AccessibilityElementInfoSetVisible = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_VISIBLE); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetVisible); - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetVisible(elementInfoFromList, true)); - - auto OH_ArkUI_AccessibilityElementInfoSetComponentType = - OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_COMPONENT_TYPE); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetComponentType); - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, "root")); - - auto OH_ArkUI_AccessibilityElementInfoSetContents = - OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_CONTENTS); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetContents); - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityElementInfoSetContents(elementInfoFromList, flutterNode.label.c_str())); - } else { - //当elementId >= 1时,根据flutter节点信息配置elementinfo无障碍属性 - FlutterSetElementInfoProperties(elementInfoFromList, elementId); - } - - FML_DLOG(INFO) << "=== OhosAccessibilityBridge::FlutterNodeToElementInfoById is end ==="; -} - /** * 配置arkui节点的可操作动作类型 */ @@ -820,6 +692,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( } /** + * 实现对特定id的flutter节点到arkui的elementinfo节点转化, * 根据flutter节点信息配置elementinfo无障碍属性 */ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( @@ -827,12 +700,12 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( int64_t elementId) { if (OHOS_API_VERSION < 13) { return; } - auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); + auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId > 0 ? elementId : 0)); if (!g_flutterSemanticsTree.count(flutterNode.id)) { LOGE("FlutterSetElementInfoProperties: GetFlutterSemanticsNode id=%{public}ld null", elementId); } - // set elementinfo id + // 设置当前节点id auto OH_ArkUI_AccessibilityElementInfoSetElementId = OhosAccessibilityDDL::DLLoadSetElemIntFunc(ArkUIAccessibilityConstant::ARKUI_SET_NODE_ID); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetElementId); @@ -841,32 +714,35 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( ); // 相对-绝对坐标映射 - FlutterRelativeRectToScreenRect(flutterNode); - auto [left, top, right, bottom] = GetAbsoluteScreenRect(flutterNode); - ArkUI_AccessibleRect rect = {static_cast(left), static_cast(top), - static_cast(right), static_cast(bottom)}; + ArkUI_AccessibleRect rect; + if (elementId < 1) { // 若当前节点为root + int32_t left = flutterNode.rect.fLeft; + int32_t top = flutterNode.rect.fTop; + int32_t right = flutterNode.rect.fRight; + int32_t bottom = flutterNode.rect.fBottom; + SetAbsoluteScreenRect(flutterNode, left, top, right, bottom); + rect = {static_cast(left), static_cast(top), + static_cast(right), static_cast(bottom)}; + } else { // 若当前节点为id >= 1的节点 + FlutterRelativeRectToScreenRect(flutterNode); + auto [left, top, right, bottom] = GetAbsoluteScreenRect(flutterNode); + rect = {static_cast(left), static_cast(top), + static_cast(right), static_cast(bottom)}; + } auto OH_ArkUI_AccessibilityElementInfoSetScreenRect = OhosAccessibilityDDL::DLLoadSetElemSreenRectFunc(ArkUIAccessibilityConstant::ARKUI_SET_SCREEN_RECT); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetScreenRect); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetScreenRect(elementInfoFromList, &rect) ); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById -> node.id= " - << flutterNode.id << " SceenRect = (" << left << ", " << top - << ", " << right << ", " << bottom << ")"; // 配置arkui的elementinfo可操作动作属性 - if (IsTextField(flutterNode)) { - // 若当前flutter节点为文本输入框组件 - std::string widgeType = flutterNode.HasFlag(FLAGS_::kIsMultiline) ? - EDIT_MULTILINE_TEXT_WIDGET_NAME : EDIT_TEXT_WIDGET_NAME; - FlutterSetElementInfoOperationActions(elementInfoFromList, widgeType); - } else if (IsScrollableWidget(flutterNode) || IsNodeScrollable(flutterNode)) { - // 若当前flutter节点为可滑动组件类型 - FlutterSetElementInfoOperationActions(elementInfoFromList, SCROLL_WIDGET_NAME); - } else { - // 若当前flutter节点为通用组件 + // 设置root节点的action类型 + std::string widgeType = GetNodeComponentType(flutterNode); + if (elementId < 1) { FlutterSetElementInfoOperationActions(elementInfoFromList, OTHER_WIDGET_NAME); + } else { + FlutterSetElementInfoOperationActions(elementInfoFromList, widgeType); } // 设置当前节点的父节点id @@ -877,7 +753,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetParentId(elementInfoFromList, parentId) ); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById GetParentId = " << parentId; + FML_DLOG(INFO) << "FlutterSetElementInfoProperties GetParentId = " << parentId; // 设置可朗读文本 std::string text = flutterNode.label + flutterNode.value; @@ -887,7 +763,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetAccessibilityText(elementInfoFromList, text.c_str()) ); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById SetAccessibilityText = " << text; + FML_DLOG(INFO) << "FlutterSetElementInfoProperties SetAccessibilityText = " << text; // 设置无障碍content文本 auto OH_ArkUI_AccessibilityElementInfoSetContents = @@ -913,9 +789,9 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( int64_t childNodeIds[childCount]; for (int32_t i = 0; i < childCount; i++) { childNodeIds[i] = static_cast(childrenIdsVec[i]); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById -> elementid=" << elementId - << " childCount=" << childCount - << " childNodeIds=" << childNodeIds[i]; + FML_DLOG(INFO) << "FlutterSetElementInfoProperties -> elementid=" << elementId + << " childCount=" << childCount + << " childNodeIds=" << childNodeIds[i]; } auto OH_ArkUI_AccessibilityElementInfoSetChildNodeIds = OhosAccessibilityDDL::DLLoadSetElemChildFunc(ArkUIAccessibilityConstant::ARKUI_SET_CHILD_IDS); @@ -925,9 +801,6 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( ); } - /** - * 根据当前flutter节点的SemanticsFlags特性,配置对应的elmentinfo属性 - */ // 判断当前节点组件是否enabled if (IsNodeEnabled(flutterNode)) { auto OH_ArkUI_AccessibilityElementInfoSetEnabled = @@ -1051,24 +924,18 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( // 获取当前节点的组件类型 std::string componentTypeName = GetNodeComponentType(flutterNode); - FML_DLOG(INFO) << "FlutterNodeToElementInfoById componentTypeName = " + FML_DLOG(INFO) << "FlutterSetElementInfoProperties componentTypeName = " << componentTypeName; // flutter节点对应elementinfo所属的组件类型(如:root, button,text等) auto OH_ArkUI_AccessibilityElementInfoSetComponentType = OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_COMPONENT_TYPE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetComponentType); - if (elementId == 0) { - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, "root") - ); - } else { - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetComponentType(elementInfoFromList, - componentTypeName.c_str()) - ); - } - FML_DLOG(INFO) << "FlutterNodeToElementInfoById SetComponentType: " - << componentTypeName; + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetComponentType( + elementInfoFromList, elementId < 1 ? "root" : componentTypeName.c_str()) + ); + FML_DLOG(INFO) << "FlutterSetElementInfoProperties SetComponentType: " + << componentTypeName; /** * 无障碍重要性,用于控制某个组件是否可被无障碍辅助服务所识别。支持的值为(默认值:“auto”): @@ -1133,7 +1000,7 @@ void OhosAccessibilityBridge::BuildArkUISemanticsTree( { if (OHOS_API_VERSION < 13) { return; } //配置root节点信息 - FlutterNodeToElementInfoById(elementInfoFromList, elementId); + FlutterSetElementInfoProperties(elementInfoFromList, elementId); //获取flutter无障碍语义树的节点总数 auto levelOrderTreeVec = GetLevelOrderTraversalTree(0); int64_t elementInfoCount = levelOrderTreeVec.size(); @@ -1150,7 +1017,7 @@ void OhosAccessibilityBridge::BuildArkUISemanticsTree( CHECK_DLL_NULL_PTR(OH_ArkUI_AddAndGetAccessibilityElementInfo); auto* newElementInfo = OH_ArkUI_AddAndGetAccessibilityElementInfo(elementList); //配置当前子节点信息 - FlutterNodeToElementInfoById(newElementInfo, levelOrderId); + FlutterSetElementInfoProperties(newElementInfo, levelOrderId); } } @@ -1201,23 +1068,23 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( } else if (mode ==ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_PREDECESSORS) { /** Search for parent nodes. (mode = 1) */ if (IsNodeVisible(flutterNode)) { - FlutterNodeToElementInfoById(elementInfoFromList, elementId); + FlutterSetElementInfoProperties(elementInfoFromList, elementId); } } else if (mode ==ArkUI_AccessibilitySearchMode::ARKUI_ACCESSIBILITY_NATIVE_SEARCH_MODE_PREFETCH_SIBLINGS) { /** Search for sibling nodes. (mode = 2) */ if (IsNodeVisible(flutterNode)) { - FlutterNodeToElementInfoById(elementInfoFromList, elementId); + 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)) { - FlutterNodeToElementInfoById(elementInfoFromList, elementId); + 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 { - FlutterNodeToElementInfoById(elementInfoFromList, elementId); + FlutterSetElementInfoProperties(elementInfoFromList, elementId); } FML_DLOG(INFO) << "--- FindAccessibilityNodeInfosById is end ---"; return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL; @@ -1774,7 +1641,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( OhosAccessibilityDDL::DLLoadCreateElemInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); - FlutterNodeToElementInfoById(_elementInfo, elementId); + FlutterSetElementInfoProperties(_elementInfo, elementId); // 若为获焦事件,则设置当前elementinfo获焦 auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused = diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index a8c6eb9678..517b9b36c6 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -132,9 +132,6 @@ public: void Flutter_SendAccessibilityAsyncEvent( int64_t elementId, ArkUI_AccessibilityEventType eventType); - void FlutterNodeToElementInfoById( - ArkUI_AccessibilityElementInfo* elementInfoFromList, - int64_t elementId); int32_t GetParentId(int64_t elementId); void FlutterRelativeRectToScreenRect(SemanticsNodeExtent node); -- Gitee From 1215ad478550277ef4bacd4dca98b73636d003d8 Mon Sep 17 00:00:00 2001 From: xiaozn Date: Mon, 23 Dec 2024 23:39:42 +0800 Subject: [PATCH 34/60] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=9B=91?= =?UTF-8?q?=E5=90=AC=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xiaozn --- .../flutter/src/main/ets/view/FlutterView.ets | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index 84c8751741..5320925562 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import FlutterEngine from '../embedding/engine/FlutterEngine'; import Log from '../util/Log'; import { DVModel, DVModelChildren, DVModelEvents, DVModelParameters } from './DynamicView/dynamicView'; @@ -27,9 +28,7 @@ import PlatformView, { Params } from '../plugin/platform/PlatformView'; import { JSON } from '@kit.ArkTS'; import { accessibility } from '@kit.AccessibilityKit'; import TextInputPlugin from '../plugin/editing/TextInputPlugin'; -import { cert } from '@kit.DeviceCertificateKit'; import json from '@ohos.util.json'; -import { data } from '@kit.TelephonyKit'; const TAG = "FlutterViewTag"; @@ -202,7 +201,6 @@ export class FlutterView { private displayFeaturesCache: Map> = new Map>(); - constructor(viewId: string, context: Context) { this.id = viewId this.displayInfo = display.getDefaultDisplaySync(); @@ -238,12 +236,18 @@ export class FlutterView { private displayChangeCallback = async (data: number) => { this.displayInfo = display.getDefaultDisplaySync(); - if (this.viewportMetrics.devicePixelRatio != this.displayInfo?.densityPixels) { - this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; - let displayFeatures: Array = await this.buildDisplayFeatures(); + let displayFeatures: Array = await this.buildDisplayFeatures(); + let devicePixelRatio: number = this.displayInfo?.densityPixels; + let physicalTouchSlop: number = 1.0 * this.displayInfo?.densityPixels; + + if (devicePixelRatio != this.viewportMetrics.devicePixelRatio || + physicalTouchSlop != this.viewportMetrics.physicalTouchSlop || + displayFeatures != this.viewportMetrics.displayFeatures) { + this.viewportMetrics.devicePixelRatio = devicePixelRatio; + this.viewportMetrics.physicalTouchSlop = physicalTouchSlop; Log.i(TAG, "Display on: " + JSON.stringify(this.displayInfo)) this.viewportMetrics.displayFeatures = displayFeatures; - this.updateViewportMetrics() + // this.updateViewportMetrics() } } @@ -392,9 +396,7 @@ export class FlutterView { Log.i(TAG, `unsubscribe accessibility state change, result: ${JSON.stringify(data)}`); }); this.mainWindow?.off('keyboardHeightChange', this.keyboardHeightChangeCallback); - display.off('foldStatusChange', (status: display.FoldStatus) => { - Log.d(TAG, `foldStatusChange listner destory`); - }) + } catch (e) { Log.e(TAG, "mainWindow off error: " + JSON.stringify(e)); } -- Gitee From f62a62db5a742b2cac97a5a314c1c2447f5eda53 Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 24 Dec 2024 12:11:01 +0800 Subject: [PATCH 35/60] =?UTF-8?q?refactor:=E5=B0=81=E8=A3=85=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E9=83=A8=E5=88=86=E6=97=A0=E9=9A=9C=E7=A2=8D=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E6=B6=88=E9=99=A4=E9=AD=94=E9=AC=BC=E6=95=B0?= =?UTF-8?q?=EF=BC=8C=E5=87=8F=E5=B0=91=E5=86=97=E4=BD=99=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=90=E9=AB=98=E5=8F=AF=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 132 ++++++------------ .../accessibility/ohos_accessibility_bridge.h | 2 +- .../platform/ohos/ohos_xcomponent_adapter.cpp | 67 +++++---- shell/platform/ohos/ohos_xcomponent_adapter.h | 2 + shell/platform/ohos/utils/ddl_utils.h | 39 ++++++ 5 files changed, 113 insertions(+), 129 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index a4b72aa9e0..844dfeba63 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -24,45 +24,6 @@ #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkScalar.h" -#define ARKUI_SUCCEED_CODE 0 -#define ARKUI_FAILED_CODE -1 -#define ARKUI_BAD_PARAM_CODE -2 -#define ARKUI_OOM_CODE -3 - -#define ARKUI_ACCESSIBILITY_CALL_CHECK(X) \ - do { \ - int32_t RET = X; \ - if (RET != ARKUI_SUCCEED_CODE) { \ - LOGE("Failed function %{public}s call, error code:%{public}d",\ - #X, RET); \ - } \ - } while (false) \ - -#define CHECK_DLL_NULL_PTR(func) \ - do { \ - if (func == nullptr) { \ - LOGE("Error: Function %{public}s is nullptr, %{public}s", \ - #func, LOAD_ERROR()); \ - } \ - } while (false) \ - -#define CHECK_NULL_PTR(PARAM, FUNC) \ - do { \ - if (PARAM == nullptr) { \ - LOGE("Error: %{public}s -> %{public}s is nullptr", \ - #FUNC, #PARAM); \ - } \ - } while (false) \ - -#define CHECK_NULL_PTR_WITH_RET(PARAM, FUNC) \ - do { \ - if (PARAM == nullptr) { \ - LOGE("Error: %{public}s -> %{public}s is nullptr", \ - #FUNC, #PARAM); \ - return ARKUI_FAILED_CODE; \ - } \ - } while (false) \ - namespace flutter { const int32_t OhosAccessibilityBridge::OHOS_API_VERSION = OH_GetSdkApiVersion(); @@ -596,46 +557,37 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( // set elementinfo action types int32_t actionTypeNum = 10; ArkUI_AccessibleAction actions[actionTypeNum]; - - actions[0].actionType = ArkUI_Accessibility_ActionType:: + int32_t idx = 0; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; - actions[0].description = "获取焦点"; - - actions[1].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "获取焦点"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; - actions[1].description = "清除焦点"; - - actions[2].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "清除焦点"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; - actions[2].description = "点击操作"; - - actions[3].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "点击操作"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_LONG_CLICK; - actions[3].description = "长按操作"; - - actions[4].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "长按操作"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_COPY; - actions[4].description = "文本复制"; - - actions[5].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "文本复制"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_PASTE; - actions[5].description = "文本粘贴"; - - actions[6].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "文本粘贴"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CUT; - actions[6].description = "文本剪切"; - - actions[7].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "文本剪切"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SELECT_TEXT; - actions[7].description = "文本选择"; - - actions[8].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "文本选择"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_TEXT; - actions[8].description = "文本内容设置"; - - actions[9].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "文本内容设置"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SET_CURSOR_POSITION; - actions[9].description = "光标位置设置"; + actions[idx].description = "光标位置设置"; ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) @@ -644,26 +596,22 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( // if node is a scrollable component int32_t actionTypeNum = 5; ArkUI_AccessibleAction actions[actionTypeNum]; - - actions[0].actionType = ArkUI_Accessibility_ActionType:: + int32_t idx = 0; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; - actions[0].description = "获取焦点"; - - actions[1].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "获取焦点"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; - actions[1].description = "清除焦点"; - - actions[2].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "清除焦点"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; - actions[2].description = "点击动作"; - - actions[3].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "点击动作"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_FORWARD; - actions[3].description = "向上滑动"; - - actions[4].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "向上滑动"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_SCROLL_BACKWARD; - actions[4].description = "向下滑动"; + actions[idx].description = "向下滑动"; ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) @@ -672,18 +620,16 @@ void OhosAccessibilityBridge::FlutterSetElementInfoOperationActions( // set common component action types int32_t actionTypeNum = 3; ArkUI_AccessibleAction actions[actionTypeNum]; - - actions[0].actionType = ArkUI_Accessibility_ActionType:: + int32_t idx = 0; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_GAIN_ACCESSIBILITY_FOCUS; - actions[0].description = "获取焦点"; - - actions[1].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "获取焦点"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLEAR_ACCESSIBILITY_FOCUS; - actions[1].description = "清除焦点"; - - actions[2].actionType = ArkUI_Accessibility_ActionType:: + actions[idx++].description = "清除焦点"; + actions[idx].actionType = ArkUI_Accessibility_ActionType:: ARKUI_ACCESSIBILITY_NATIVE_ACTION_TYPE_CLICK; - actions[2].description = "点击动作"; + actions[idx].description = "点击动作"; ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityElementInfoSetOperationActions(elementInfoFromList, actionTypeNum, actions) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 517b9b36c6..057d0f4f23 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -80,7 +80,7 @@ public: bool IS_FLUTTER_NAVIGATE = false; int64_t native_shell_holder_id_; - ArkUI_AccessibilityProvider* provider_; + ArkUI_AccessibilityProvider* provider_ = nullptr; void OnOhosAccessibilityStateChange( int64_t shellHolderId, diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index e9a0e82d03..83827eb469 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -18,6 +18,7 @@ #include "types.h" #include "ohos_logging.h" #include +#include "flutter/shell/platform/ohos/utils/ddl_utils.h" namespace flutter { @@ -369,47 +370,43 @@ void XComponentBase::DetachFlutterEngine() { isEngineAttached_ = false; } +void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nativeXComponent) +{ + if (OH_GetSdkApiVersion() < 13) { return; } + LOGD("api version: %{public}d", OH_GetSdkApiVersion()); + BindAccessibilityProviderCallback(); + + auto OH_NativeXComponent_GetNativeAccessibilityProvider = + OhosAccessibilityDDL::DLLoadGetNativeA11yProvider(ArkUIAccessibilityConstant::OH_GET_A11Y_PROVIDER); + CHECK_DLL_NULL_PTR(OH_NativeXComponent_GetNativeAccessibilityProvider); + + ArkUI_AccessibilityProvider* accessibilityProvider = nullptr; + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_NativeXComponent_GetNativeAccessibilityProvider(nativeXComponent, &accessibilityProvider) + ); + + auto OH_ArkUI_AccessibilityProviderRegisterCallback = + OhosAccessibilityDDL::DLLoadRegisterFunc(ArkUIAccessibilityConstant::ARKUI_REGISTER_CALLBACK); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityProviderRegisterCallback); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityProviderRegisterCallback(accessibilityProvider, &accessibilityProviderCallback_) + ); + + //将ArkUI_AccessibilityProvider传到无障碍bridge类 + auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); + ohosAccessibilityBridge->provider_ = accessibilityProvider; + + LOGI("XComponentBase::SetNativeXComponent OH_ArkUI_AccessibilityProviderRegisterCallback is succeed"); +} + void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ nativeXComponent_ = nativeXComponent; if (nativeXComponent_ != nullptr) { BindXComponentCallback(); OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent_, &mouseCallback_); - - if (OH_GetSdkApiVersion() >= 13) { - LOGD("api version: %{public}d", OH_GetSdkApiVersion()); - BindAccessibilityProviderCallback(); - - int32_t (*OH_NativeXComponent_GetNativeAccessibilityProvider)(OH_NativeXComponent*, ArkUI_AccessibilityProvider**) = - OhosAccessibilityDDL::DLLoadGetNativeA11yProvider("OH_NativeXComponent_GetNativeAccessibilityProvider"); - if (OH_NativeXComponent_GetNativeAccessibilityProvider == nullptr) { - LOGE("OH_NativeXComponent_GetNativeAccessibilityProvider is null, %{public}s", dlerror()); - } - ArkUI_AccessibilityProvider* accessibilityProvider = nullptr; - int32_t ret1 = OH_NativeXComponent_GetNativeAccessibilityProvider(nativeXComponent_, &accessibilityProvider); - if (ret1 != 0) { - LOGE("OH_NativeXComponent_GetNativeAccessibilityProvider is failed"); - return; - } - - int32_t (*OH_ArkUI_AccessibilityProviderRegisterCallback)(ArkUI_AccessibilityProvider*, ArkUI_AccessibilityProviderCallbacks*) = - OhosAccessibilityDDL::DLLoadRegisterFunc("OH_ArkUI_AccessibilityProviderRegisterCallback"); - if (OH_ArkUI_AccessibilityProviderRegisterCallback == nullptr) { - LOGE("OH_ArkUI_AccessibilityProviderRegisterCallback is null, %{public}s", dlerror()); - } - int32_t ret2 = OH_ArkUI_AccessibilityProviderRegisterCallback(accessibilityProvider, &accessibilityProviderCallback_); - if (ret2 != 0) { - LOGE("OH_ArkUI_AccessibilityProviderRegisterCallback is failed"); - return; - } - LOGE("OH_ArkUI_AccessibilityProviderRegisterCallback is %{public}d", ret2); - - //将ArkUI_AccessibilityProvider传到无障碍bridge类 - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); - ohosAccessibilityBridge->provider_ = accessibilityProvider; - - LOGI("XComponentBase::SetNativeXComponent OH_ArkUI_AccessibilityProviderRegisterCallback is succeed"); - } + // 注册ArkUI无障碍服务 + RegisterArkUIAccessibilityService(nativeXComponent_); } } diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.h b/shell/platform/ohos/ohos_xcomponent_adapter.h index d2c1414613..040956522e 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.h +++ b/shell/platform/ohos/ohos_xcomponent_adapter.h @@ -50,6 +50,8 @@ public: void OnDispatchMouseEvent(OH_NativeXComponent* component, void* window); void OnDispatchMouseWheelEvent(mouseWheelEvent event); + void RegisterArkUIAccessibilityService(OH_NativeXComponent* nativeXComponent); + OH_NativeXComponent_TouchEvent touchEvent_; OH_NativeXComponent_Callback callback_; OH_NativeXComponent_MouseEvent_Callback mouseCallback_; diff --git a/shell/platform/ohos/utils/ddl_utils.h b/shell/platform/ohos/utils/ddl_utils.h index 19e5e5fb18..0e5eca65a8 100644 --- a/shell/platform/ohos/utils/ddl_utils.h +++ b/shell/platform/ohos/utils/ddl_utils.h @@ -23,4 +23,43 @@ using LIBHANDLE = void*; #define LOAD_SYM(libHandle, symbol) dlsym(libHandle, symbol) #define LOAD_ERROR() dlerror() +#define ARKUI_SUCCEED_CODE 0 +#define ARKUI_FAILED_CODE -1 +#define ARKUI_BAD_PARAM_CODE -2 +#define ARKUI_OOM_CODE -3 + +#define ARKUI_ACCESSIBILITY_CALL_CHECK(X) \ + do { \ + int32_t RET = X; \ + if (RET != ARKUI_SUCCEED_CODE) { \ + LOGE("Failed function %{public}s call, error code:%{public}d",\ + #X, RET); \ + } \ + } while (false) \ + +#define CHECK_DLL_NULL_PTR(func) \ + do { \ + if (func == nullptr) { \ + LOGE("Error: Function %{public}s is nullptr, %{public}s", \ + #func, LOAD_ERROR()); \ + } \ + } while (false) \ + +#define CHECK_NULL_PTR(PARAM, FUNC) \ + do { \ + if (PARAM == nullptr) { \ + LOGE("Error: %{public}s -> %{public}s is nullptr", \ + #FUNC, #PARAM); \ + } \ + } while (false) \ + +#define CHECK_NULL_PTR_WITH_RET(PARAM, FUNC) \ + do { \ + if (PARAM == nullptr) { \ + LOGE("Error: %{public}s -> %{public}s is nullptr", \ + #FUNC, #PARAM); \ + return ARKUI_FAILED_CODE; \ + } \ + } while (false) \ + #endif // FOUNDATION_ACE_INTERFACE_INNERKITS_ACE_UTILS_H -- Gitee From 2e8c734bf528933c2ec27530591cb1644b1613b3 Mon Sep 17 00:00:00 2001 From: shijie Date: Tue, 24 Dec 2024 16:58:54 +0800 Subject: [PATCH 36/60] =?UTF-8?q?fix:=20=E5=9B=9E=E9=80=80displayFeature?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=9A=84=E8=AE=BE=E5=A4=87=E4=BF=A1=E6=81=AF?= =?UTF-8?q?,=E8=A7=A3=E5=86=B3=E8=BF=94=E5=9B=9E=E6=8A=98=E7=97=95?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E5=AF=BC=E8=87=B4=E5=BC=B9=E7=AA=97=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E5=81=8F=E9=A1=B6=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xiaozn --- .../flutter/src/main/ets/view/FlutterView.ets | 183 +++++++++--------- 1 file changed, 91 insertions(+), 92 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index 5320925562..9e8e971fdd 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -28,7 +28,6 @@ import PlatformView, { Params } from '../plugin/platform/PlatformView'; import { JSON } from '@kit.ArkTS'; import { accessibility } from '@kit.AccessibilityKit'; import TextInputPlugin from '../plugin/editing/TextInputPlugin'; -import json from '@ohos.util.json'; const TAG = "FlutterViewTag"; @@ -49,7 +48,7 @@ export class ViewportMetrics { systemGestureInsetBottom: number = 0; systemGestureInsetLeft: number = 0; physicalTouchSlop: number = -1; - displayFeatures: DisplayFeature[] = []; + displayFeatures: ArrayList = new ArrayList(); clone(): ViewportMetrics { const copy = new ViewportMetrics(); @@ -89,22 +88,23 @@ export class ViewportMetrics { this.systemGestureInsetRight === other.systemGestureInsetRight && this.systemGestureInsetBottom === other.systemGestureInsetBottom && this.systemGestureInsetLeft === other.systemGestureInsetLeft && - this.physicalTouchSlop === other.physicalTouchSlop; + this.physicalTouchSlop === other.physicalTouchSlop && + this.displayFeatures == other.displayFeatures; } } export class DisplayFeature { - bounds: display.Rect; + bounds: display.Rect[]; type: DisplayFeatureType; state: DisplayFeatureState; - constructor(bounds: display.Rect, type: DisplayFeatureType, state: DisplayFeatureState = DisplayFeatureState.UNKNOWN) { + constructor(bounds: display.Rect[], type: DisplayFeatureType, state: DisplayFeatureState) { this.bounds = bounds; this.type = type; this.state = state; } - getBounds(): display.Rect { + getBounds(): display.Rect[] { return this.bounds; } @@ -116,7 +116,7 @@ export class DisplayFeature { return this.state } - setBounds(bounds: display.Rect): void { + setBounds(bounds: display.Rect[]): void { this.bounds = bounds; } @@ -198,14 +198,13 @@ export class FlutterView { private gestureAvoidArea: window.AvoidArea; private keyboardAvoidArea: window.AvoidArea; private needSetViewport: boolean = false; - private displayFeaturesCache: Map> - = new Map>(); + constructor(viewId: string, context: Context) { this.id = viewId this.displayInfo = display.getDefaultDisplaySync(); this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; - + this.buildDisplayFeatures(display.getFoldStatus()); this.mainWindow = FlutterManager.getInstance() .getWindowStage(FlutterManager.getInstance().getUIAbility(context)) .getMainWindowSync(); @@ -226,83 +225,69 @@ export class FlutterView { this.gestureAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); this.keyboardAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + // 监听折叠状态的改变 + display?.on('foldStatusChange', (data: display.FoldStatus) => { + Log.d(TAG, `Fold status change to ${JSON.stringify(data)}`) + this.buildDisplayFeatures(data); + }) + // Subscribes to display changes. Example: event that the display size is changed. try { - display.on("change", this.displayChangeCallback); + display.on("change", ()=>{ + this.displayInfo = display.getDefaultDisplaySync(); + if (this.viewportMetrics.devicePixelRatio != this.displayInfo?.densityPixels) { + this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; + Log.i(TAG, "Display on: " + JSON.stringify(this.displayInfo)) + this.updateViewportMetrics() + } + }); } catch (e) { Log.e(TAG, "displayInfo error" + JSON.stringify(e)); } } - private displayChangeCallback = async (data: number) => { - this.displayInfo = display.getDefaultDisplaySync(); - let displayFeatures: Array = await this.buildDisplayFeatures(); - let devicePixelRatio: number = this.displayInfo?.densityPixels; - let physicalTouchSlop: number = 1.0 * this.displayInfo?.densityPixels; - - if (devicePixelRatio != this.viewportMetrics.devicePixelRatio || - physicalTouchSlop != this.viewportMetrics.physicalTouchSlop || - displayFeatures != this.viewportMetrics.displayFeatures) { - this.viewportMetrics.devicePixelRatio = devicePixelRatio; - this.viewportMetrics.physicalTouchSlop = physicalTouchSlop; - Log.i(TAG, "Display on: " + JSON.stringify(this.displayInfo)) - this.viewportMetrics.displayFeatures = displayFeatures; - // this.updateViewportMetrics() - } - } - - private async buildDisplayFeatures(): Promise> { - let displayMode: display.FoldDisplayMode = display.getFoldDisplayMode(); - if (this.displayFeaturesCache.has(displayMode)) { - return this.displayFeaturesCache.get(displayMode)!; - } - let displayFeatures: Array = []; - let foldCreaseRegion: display.FoldCreaseRegion = display.getCurrentFoldCreaseRegion(); - if (foldCreaseRegion != undefined) { - let type: DisplayFeatureType = DisplayFeatureType.FOLD; - let state: DisplayFeatureState = DisplayFeatureState.UNKNOWN; - - if (displayMode == display.FoldDisplayMode.FOLD_DISPLAY_MODE_FULL || - displayMode == display.FoldDisplayMode.FOLD_DISPLAY_MODE_COORDINATION) { - state = DisplayFeatureState.POSTURE_FLAT; - } else if (displayMode == display.FoldDisplayMode.FOLD_DISPLAY_MODE_MAIN - || displayMode == display.FoldDisplayMode.FOLD_DISPLAY_MODE_SUB) { - state = DisplayFeatureState.POSTURE_HALF_OPENED; + private async buildDisplayFeatures(foldStatus: display.FoldStatus) { + let displayFeatures: ArrayList = new ArrayList(); + let bound: display.Rect[]; + let state: DisplayFeatureState = DisplayFeatureState.UNKNOWN; + let type: DisplayFeatureType = DisplayFeatureType.FOLD; + const displayInfos = display.getDefaultDisplaySync(); + if (display.isFoldable()) { + switch (foldStatus) { + case display.FoldStatus.FOLD_STATUS_EXPANDED: + type = DisplayFeatureType.FOLD; + state = DisplayFeatureState.POSTURE_FLAT; + break; + case display.FoldStatus.FOLD_STATUS_HALF_FOLDED: + type = DisplayFeatureType.FOLD; + state = DisplayFeatureState.POSTURE_HALF_OPENED; + break; + case display.FoldStatus.FOLD_STATUS_UNKNOWN: + type = DisplayFeatureType.UNKNOWN; + state = DisplayFeatureState.UNKNOWN; + break; + default: + state = DisplayFeatureState.UNKNOWN; + type = DisplayFeatureType.FOLD; + break; } - foldCreaseRegion.creaseRects.forEach((rect: display.Rect) => { - displayFeatures.push(new DisplayFeature(rect, type, state)); - }); - } - - let cutoutInfo: display.CutoutInfo | undefined = await this.displayInfo?.getCutoutInfo(); - if (cutoutInfo != undefined) { - cutoutInfo.boundingRects.forEach((bounding: display.Rect) => { - displayFeatures.push(new DisplayFeature(bounding, DisplayFeatureType.CUTOUT)); - }); - - let waterFallRect: display.WaterfallDisplayAreaRects = cutoutInfo.waterfallDisplayAreaRects; - if (!this.isEmptyRect(waterFallRect.left)) { - displayFeatures.push(new DisplayFeature(waterFallRect.left, DisplayFeatureType.FOLD)); - } - if (!this.isEmptyRect(waterFallRect.right)) { - displayFeatures.push(new DisplayFeature(waterFallRect.right, DisplayFeatureType.FOLD)); - } - if (!this.isEmptyRect(waterFallRect.top)) { - displayFeatures.push(new DisplayFeature(waterFallRect.top, DisplayFeatureType.FOLD)); - } - if (!this.isEmptyRect(waterFallRect.bottom)) { - displayFeatures.push(new DisplayFeature(waterFallRect.bottom, DisplayFeatureType.FOLD)); + const displays = await display.getAllDisplays(); + for (let i = 0; i < displays.length; i++) { + let cutoutInfo = await displays[i].getCutoutInfo(); + bound = cutoutInfo.boundingRects; + displayFeatures.add(new DisplayFeature(bound, type, state)); } + Log.d(TAG, `FOLD device displayFeatures is : ${JSON.stringify(displayFeatures)}`) + } else { + type = DisplayFeatureType.CUTOUT; + state = DisplayFeatureState.UNKNOWN; + let infos = await displayInfos?.getCutoutInfo(); + bound = infos.boundingRects; + displayFeatures.add(new DisplayFeature(bound, type, state)); + Log.d(TAG, `UNFold device displayFeatures is : ${JSON.stringify(displayFeatures)}`) } - this.displayFeaturesCache.set(displayMode, displayFeatures); - return displayFeatures; - } - - private isEmptyRect(rect: display.Rect | null | undefined) { - if (rect == null || rect == undefined) { - return true - } - return rect.left == 0 && rect.top ==0 && rect.width == 0 && rect.height == 0; + this.viewportMetrics.displayFeatures = displayFeatures; + this.updateViewportMetrics(); } private windowSizeChangeCallback = (data: window.Size) => { @@ -396,14 +381,21 @@ export class FlutterView { Log.i(TAG, `unsubscribe accessibility state change, result: ${JSON.stringify(data)}`); }); this.mainWindow?.off('keyboardHeightChange', this.keyboardHeightChangeCallback); - + display.off('foldStatusChange', (status: display.FoldStatus) => { + Log.d(TAG, `foldStatusChange listner destory`); + }) } catch (e) { Log.e(TAG, "mainWindow off error: " + JSON.stringify(e)); } this.mainWindow = null; try { - display.off("change", this.displayChangeCallback); + display.off("change", ()=>{ + this.displayInfo = display.getDefaultDisplaySync(); + this.viewportMetrics.devicePixelRatio = this.displayInfo?.densityPixels; + Log.i(TAG, "Display Info: " + JSON.stringify(this.displayInfo)) + this.updateViewportMetrics() + }); } catch (e) { Log.e(TAG, "displayInfo off error" + JSON.stringify(e)); } @@ -565,20 +557,27 @@ export class FlutterView { private updateViewportMetrics(): boolean { if (this.isAttachedToFlutterEngine()) { Log.i(TAG, 'updateViewportMetrics devicePixelRatio:' + this.viewportMetrics.devicePixelRatio); - let disPlayFeature = this.viewportMetrics.displayFeatures; - let displayFeatureBound: number[] = new Array(disPlayFeature.length * 4); - let displayFeatureType: number[] = new Array(disPlayFeature.length); - let displayFeatureStatus: number[] = new Array(disPlayFeature.length); - - for (let i = 0; i < disPlayFeature.length; i++) { - displayFeatureBound[4 * i] = disPlayFeature[i].bounds.left; - displayFeatureBound[4 * i + 1] = disPlayFeature[i].bounds.top; - displayFeatureBound[4 * i + 2] = disPlayFeature[i].bounds.width; - displayFeatureBound[4 * i + 3] = disPlayFeature[i].bounds.height; - displayFeatureType[i] = disPlayFeature[i].type; - displayFeatureStatus[i] = disPlayFeature[i].state; + + const displayFeatures = this.viewportMetrics.displayFeatures; + let boundCount = 0; + for (let i = 0; i < displayFeatures.length; i++) { + boundCount = boundCount + displayFeatures[i].getBounds().length; + } + let displayFeatureBound: number[] = new Array(boundCount * 4); + let displayFeatureType: number[] = new Array(displayFeatures.length); + let displayFeatureStatus: number[] = new Array(displayFeatures.length); + for (let i = 0; i < displayFeatures.length; i++) { + let singleFeatureBound = displayFeatures[i].getBounds(); + for (let j = 0; j < singleFeatureBound.length; j++) { + displayFeatureBound[4*i + 4*j] = singleFeatureBound[j].left; + displayFeatureBound[4*i + 4*j + 1] = singleFeatureBound[j].top + displayFeatureBound[4*i + 4*j + 2] = singleFeatureBound[j].width; + displayFeatureBound[4*i + 4*j + 3] = singleFeatureBound[j].height; + } + displayFeatureType[i] = displayFeatures[i].getType(); + displayFeatureStatus[i] = displayFeatures[i].getState(); } - Log.d(TAG, 'update displayFeatureBound is:' + json.stringify(disPlayFeature)); + this?.flutterEngine?.getFlutterNapi()?.setViewportMetrics(this.viewportMetrics.devicePixelRatio, this.viewportMetrics.physicalWidth, this.viewportMetrics.physicalHeight, -- Gitee From 376b13f2f6602feb5c08453ff4f1fe26d55711cc Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 24 Dec 2024 17:17:42 +0800 Subject: [PATCH 37/60] =?UTF-8?q?=E6=94=B9=E5=8F=98=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E6=89=93=E5=8D=B0=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- shell/platform/ohos/napi/platform_view_ohos_napi.cpp | 2 ++ shell/platform/ohos/ohos_xcomponent_adapter.cpp | 3 ++- shell/platform/ohos/ohos_xcomponent_adapter.h | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 431ff15b31..7af907cc1f 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -1875,6 +1875,8 @@ napi_value PlatformViewOHOSNapi::nativeAccessibilityStateChange( if (OHOS_API_VERSION >= 13) { auto a11y_bridge = OhosAccessibilityBridge::GetInstance(); a11y_bridge->OnOhosAccessibilityStateChange(shell_holder_id, state); + FML_LOG(WARNING) << "nativeAccessibilityStateChange -> birdgeInstance addr: " << a11y_bridge + << ", provider addr:" << a11y_bridge->provider_; } FML_DLOG(INFO) << "nativeAccessibilityStateChange: state=" << state << " shell_holder_id=" << shell_holder_id; diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index 83827eb469..dbb53fb2f7 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -18,7 +18,6 @@ #include "types.h" #include "ohos_logging.h" #include -#include "flutter/shell/platform/ohos/utils/ddl_utils.h" namespace flutter { @@ -395,6 +394,8 @@ void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nati //将ArkUI_AccessibilityProvider传到无障碍bridge类 auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); ohosAccessibilityBridge->provider_ = accessibilityProvider; + FML_LOG(WARNING) << "RegisterArkUIAccessibilityService -> birdgeInstance addr: " << ohosAccessibilityBridge + << ", provider addr:" << ohosAccessibilityBridge->provider_; LOGI("XComponentBase::SetNativeXComponent OH_ArkUI_AccessibilityProviderRegisterCallback is succeed"); } diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.h b/shell/platform/ohos/ohos_xcomponent_adapter.h index 040956522e..cf370fa62c 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.h +++ b/shell/platform/ohos/ohos_xcomponent_adapter.h @@ -25,6 +25,7 @@ #include "napi/native_api.h" #include "napi_common.h" #include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" +#include "flutter/shell/platform/ohos/utils/ddl_utils.h" namespace flutter { -- Gitee From 50b338e01c63fab8d8bfc3f36f875f39cbb353dd Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 24 Dec 2024 18:11:44 +0800 Subject: [PATCH 38/60] =?UTF-8?q?refactor:=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=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_bridge.cpp | 3 +- .../accessibility/ohos_accessibility_bridge.h | 3 +- .../src/main/ets/view/AccessibilityBridge.ets | 42 +------------------ 3 files changed, 4 insertions(+), 44 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 844dfeba63..672307a8ba 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -75,7 +75,6 @@ void OhosAccessibilityBridge::UpdateSemantics( flutter::CustomAccessibilityActionUpdates actions) { FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics()"; - isFlutterSemanticsTreeUpdated = true; std::vector updatedFlutterNodes; // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) @@ -1055,7 +1054,7 @@ void OhosAccessibilityBridge::DispatchSemanticsAction( */ void OhosAccessibilityBridge::DoubleClickRouteToNewPage(SemanticsNodeExtent node) { - if (isFlutterSemanticsTreeUpdated && node.HasFlag(FLAGS_::kIsButton)) { + if (node.HasFlag(FLAGS_::kIsButton)) { RequestFocusWhenPageUpdate(0); } } diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 057d0f4f23..3e61c171ab 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -162,8 +162,7 @@ private: std::unordered_map g_screenRectMap; std::unordered_map g_actions_mp; std::vector g_flutterNavigationVec; - - bool isFlutterSemanticsTreeUpdated = false; + SemanticsNodeExtent inputFocusedNode; SemanticsNodeExtent lastInputFocusedNode; SemanticsNodeExtent accessibilityFocusedNode; diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/AccessibilityBridge.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/AccessibilityBridge.ets index c7122f4870..c1cca165b6 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/AccessibilityBridge.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/AccessibilityBridge.ets @@ -18,46 +18,8 @@ import Log from '../util/Log'; const TAG = "AccessibilityBridge"; -export default class AccessibilityBridge implements AccessibilityMessageHandler { - - private accessibilityChannel: AccessibilityChannel | null = null; - - constructor(){ - - } - - announce(message: string): void { - throw new Error('Method not implemented.'); - // android -> rootAccessibilityView.announceForAccessibility(message); - } - - onTap(nodeId: number): void { - throw new Error('Method not implemented.'); - // android -> sendAccessibilityEvent(nodeId, AccessibilityEvent.TYPE_VIEW_CLICKED); - } - - onLongPress(nodeId: number): void { - throw new Error('Method not implemented.'); - // android -> sendAccessibilityEvent(nodeId, AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); - } - - onTooltip(nodeId: string): void { - throw new Error('Method not implemented.'); - } - - updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void { - Log.d(TAG, "AccessibilityBridge.ets updateSemantics is called"); - } - - updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void { - Log.d(TAG, "AccessibilityBridge.ets updateCustomAccessibilityActions is called"); - - } - - accessibilityStateChange(state: Boolean): void{ - Log.d(TAG, "AccessibilityBridge.ets accessibilityStateChange is called"); - } - +export default class AccessibilityBridge { + constructor() {} } export class AccessibilityManager { -- Gitee From c44e27e569486ad935a1194d3c127ee8b0cc2c3a Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 24 Dec 2024 19:22:02 +0800 Subject: [PATCH 39/60] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=9C=B0=E5=9D=80?= =?UTF-8?q?=E6=89=93=E5=8D=B0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- shell/platform/ohos/napi/platform_view_ohos_napi.cpp | 2 -- shell/platform/ohos/ohos_xcomponent_adapter.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 7af907cc1f..431ff15b31 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -1875,8 +1875,6 @@ napi_value PlatformViewOHOSNapi::nativeAccessibilityStateChange( if (OHOS_API_VERSION >= 13) { auto a11y_bridge = OhosAccessibilityBridge::GetInstance(); a11y_bridge->OnOhosAccessibilityStateChange(shell_holder_id, state); - FML_LOG(WARNING) << "nativeAccessibilityStateChange -> birdgeInstance addr: " << a11y_bridge - << ", provider addr:" << a11y_bridge->provider_; } FML_DLOG(INFO) << "nativeAccessibilityStateChange: state=" << state << " shell_holder_id=" << shell_holder_id; diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index dbb53fb2f7..0d1f936023 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -394,8 +394,6 @@ void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nati //将ArkUI_AccessibilityProvider传到无障碍bridge类 auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); ohosAccessibilityBridge->provider_ = accessibilityProvider; - FML_LOG(WARNING) << "RegisterArkUIAccessibilityService -> birdgeInstance addr: " << ohosAccessibilityBridge - << ", provider addr:" << ohosAccessibilityBridge->provider_; LOGI("XComponentBase::SetNativeXComponent OH_ArkUI_AccessibilityProviderRegisterCallback is succeed"); } -- Gitee From 0ac55ff22f39c52468738eb1ccd4a4b3ed07e4ea Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Tue, 24 Dec 2024 17:38:37 +0800 Subject: [PATCH 40/60] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=A3=80=E8=A7=86=E6=84=8F=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- .../main/ets/embedding/ohos/KeyEventHandler.ets | 15 ++++++++------- shell/platform/ohos/ohos_touch_processor.cpp | 5 ++++- shell/platform/ohos/ohos_xcomponent_adapter.cpp | 3 ++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets index 3aff0a47bc..5fd76b3d62 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets @@ -21,7 +21,8 @@ import { KeyCode } from "@kit.InputKit"; const TAG = "KeyEventHandler"; -const CONTROL_KEYS = [ +// 组合键 +const COMBINATION_KEYS = [ KeyCode.KEYCODE_CTRL_LEFT, KeyCode.KEYCODE_CTRL_RIGHT, KeyCode.KEYCODE_ALT_LEFT, KeyCode.KEYCODE_ALT_RIGHT ]; @@ -31,7 +32,7 @@ export class KeyEventHandler { private charMap : HashMap = new HashMap(); private shiftMap : HashMap = new HashMap(); private isShiftMode: boolean = false; - private isControlMode: boolean = false; + private isCombinationKey: boolean = false; // 记录输入的keyCode,确保有down和up事件才输入字符 private inputMap: HashMap = new HashMap(); @@ -159,16 +160,16 @@ export class KeyEventHandler { })); let text = this.getCharByEvent(event); if (event.type == KeyType.Down) { - if (!this.isControlMode) { - this.isControlMode = CONTROL_KEYS.findIndex((it) => it == event.keyCode) >= 0; + if (!this.isCombinationKey) { + this.isCombinationKey = COMBINATION_KEYS.findIndex((it) => it == event.keyCode) >= 0; } this.inputMap.set(event.keyCode, text); } else if (event.type == KeyType.Up) { - if (CONTROL_KEYS.findIndex((it) => it == event.keyCode) >= 0) { + if (COMBINATION_KEYS.findIndex((it) => it == event.keyCode) >= 0) { // Ctrl/Alt 键抬起,重置状态 - this.isControlMode = false; + this.isCombinationKey = false; return; - } else if (this.isControlMode) { + } else if (this.isCombinationKey) { // Ctrl/Alt 键按下的状态,不输入字符(字母/数字/符号) return; } diff --git a/shell/platform/ohos/ohos_touch_processor.cpp b/shell/platform/ohos/ohos_touch_processor.cpp index b820d49e4a..17b715b328 100644 --- a/shell/platform/ohos/ohos_touch_processor.cpp +++ b/shell/platform/ohos/ohos_touch_processor.cpp @@ -179,7 +179,10 @@ void OhosTouchProcessor::HandleTouchEvent( OH_NativeXComponent_TouchPointToolType toolType; OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType); pointerData.kind = getPointerDeviceTypeForToolType(toolType); - pointerData.buttons = kPointerButtonTouchContact; + if (pointerData.change == PointerData::Change::kDown || + pointerData.change == PointerData::Change::kMove) { + pointerData.buttons = kPointerButtonTouchContact; + } pointerData.pan_x = 0.0; pointerData.pan_y = 0.0; // Delta will be generated in pointer_data_packet_converter.cc. diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index b9294e1166..450e71cd57 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -532,7 +532,8 @@ void XComponentBase::OnDispatchMouseWheelEvent(mouseWheelEvent event) } if (event.eventType == "actionUpdate") { OH_NativeXComponent_MouseEvent mouseEvent; - double scrollY = -(event.offsetY - g_scrollDistance); + // 调整鼠标滚轮滚动时,列表滑动的方向。和Windows保持一致。 + double scrollY = g_scrollDistance - event.offsetY; g_scrollDistance = event.offsetY; // fix resize ratio mouseEvent.x = event.globalX / g_resizeRate; -- Gitee From ec6ab44a729ccad46d963fcfdfea7ab91f5d94b7 Mon Sep 17 00:00:00 2001 From: chenbaodi Date: Wed, 25 Dec 2024 12:34:42 +0800 Subject: [PATCH 41/60] =?UTF-8?q?Flutter=203.7.12=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=94=AF=E6=8C=81x86=E6=A8=A1=E6=8B=9F=E5=99=A8(1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenbaodi --- attachment/repos/dart.patch0 | 295 +++++++++++++++++++++++------------ 1 file changed, 199 insertions(+), 96 deletions(-) diff --git a/attachment/repos/dart.patch0 b/attachment/repos/dart.patch0 index 8094cc2e31..6eb95a2a1a 100644 --- a/attachment/repos/dart.patch0 +++ b/attachment/repos/dart.patch0 @@ -76,7 +76,7 @@ index 33be98fc0aa..eda146a0580 100644 String? _authCode; diff --git a/pkg/vm/lib/transformations/ffi/abi.dart b/pkg/vm/lib/transformations/ffi/abi.dart -index cc2d86bafd7..e703419eed7 100644 +index cc2d86bafd7..47368356a2e 100644 --- a/pkg/vm/lib/transformations/ffi/abi.dart +++ b/pkg/vm/lib/transformations/ffi/abi.dart @@ -40,6 +40,7 @@ enum _OS { @@ -87,48 +87,83 @@ index cc2d86bafd7..e703419eed7 100644 } /// An application binary interface (ABI). -@@ -71,6 +72,9 @@ class Abi { - /// The application binary interface for Fuchsia on the X64 architecture. - static const fuchsiaX64 = _fuchsiaX64; +@@ -65,6 +66,15 @@ class Abi { + /// The application binary interface for android on the X64 architecture. + static const androidX64 = _androidX64; ++ /// The application binary interface for Ohos on the X64 architecture. ++ static const ohosArm = _ohosArm; ++ ++ /// The application binary interface for Ohos on the X64 architecture. ++ static const ohosArm64 = _ohosArm64; ++ + /// The application binary interface for Ohos on the X64 architecture. + static const ohosX64 = _ohosX64; + - /// The application binary interface for iOS on the Arm architecture. - static const iosArm = _iosArm; + /// The application binary interface for Fuchsia on the Arm64 architecture. + static const fuchsiaArm64 = _fuchsiaArm64; -@@ -131,6 +135,7 @@ class Abi { +@@ -129,6 +139,9 @@ class Abi { + androidArm64, + androidIA32, androidX64, ++ ohosArm, ++ ohosArm64, ++ ohosX64, fuchsiaArm64, fuchsiaX64, -+ ohosX64, iosArm, - iosArm64, - iosX64, -@@ -176,6 +181,7 @@ class Abi { +@@ -174,6 +187,9 @@ class Abi { + static const _androidArm64 = Abi._(_Architecture.arm64, _OS.android); + static const _androidIA32 = Abi._(_Architecture.ia32, _OS.android); static const _androidX64 = Abi._(_Architecture.x64, _OS.android); ++ static const _ohosArm = Abi._(_Architecture.arm, _OS.ohos); ++ static const _ohosArm64 = Abi._(_Architecture.arm64, _OS.ohos); ++ static const _ohosX64 = Abi._(_Architecture.x64, _OS.ohos); static const _fuchsiaArm64 = Abi._(_Architecture.arm64, _OS.fuchsia); static const _fuchsiaX64 = Abi._(_Architecture.x64, _OS.fuchsia); -+ static const _ohosX64 = Abi._(_Architecture.x64, _OS.ohos); static const _iosArm = Abi._(_Architecture.arm, _OS.ios); - static const _iosArm64 = Abi._(_Architecture.arm64, _OS.ios); - static const _iosX64 = Abi._(_Architecture.x64, _OS.ios); -@@ -200,6 +206,7 @@ const Map abiNames = { +@@ -198,6 +214,9 @@ const Map abiNames = { + Abi.androidArm64: 'androidArm64', + Abi.androidIA32: 'androidIA32', Abi.androidX64: 'androidX64', ++ Abi.ohosArm: 'ohosArm', ++ Abi.ohosArm64: 'ohosArm64', ++ Abi.ohosX64: 'ohosX64', Abi.fuchsiaArm64: 'fuchsiaArm64', Abi.fuchsiaX64: 'fuchsiaX64', -+ Abi.ohosX64: 'ohosX64', Abi.iosArm: 'iosArm', - Abi.iosArm64: 'iosArm64', - Abi.iosX64: 'iosX64', -@@ -239,6 +246,7 @@ const Map> nonSizeAlignment = { +@@ -239,6 +258,8 @@ const Map> nonSizeAlignment = { // _wordSize64 Abi.androidArm64: _wordSize64, Abi.androidX64: _wordSize64, ++ Abi.ohosArm64: _wordSize64, + Abi.ohosX64: _wordSize64, Abi.fuchsiaArm64: _wordSize64, Abi.fuchsiaX64: _wordSize64, Abi.iosArm64: _wordSize64, +@@ -256,6 +277,7 @@ const Map> nonSizeAlignment = { + Abi.linuxIA32: _wordSize32Align32, + // _wordSize32Align64 + Abi.androidArm: _wordSize32Align64, ++ Abi.ohosArm: _wordSize32Align64, + Abi.linuxArm: _wordSize32Align64, + Abi.linuxRiscv32: _wordSize32Align64, + Abi.windowsIA32: _wordSize32Align64, +diff --git a/pkg/vm/testcases/transformations/ffi/abi_specific_int.dart b/pkg/vm/testcases/transformations/ffi/abi_specific_int.dart +index f926b9d46c1..a72516ac911 100644 +--- a/pkg/vm/testcases/transformations/ffi/abi_specific_int.dart ++++ b/pkg/vm/testcases/transformations/ffi/abi_specific_int.dart +@@ -9,6 +9,9 @@ import 'dart:ffi'; + Abi.androidArm64: Uint32(), + Abi.androidIA32: Uint32(), + Abi.androidX64: Uint32(), ++ Abi.ohosArm: Uint32(), ++ Abi.ohosArm64: Uint32(), ++ Abi.ohosX64: Uint32(), + Abi.fuchsiaArm64: Uint64(), + Abi.fuchsiaX64: Uint32(), + Abi.iosArm: Uint32(), diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn index 13bfd0a724b..042b6a45f7e 100644 --- a/runtime/BUILD.gn @@ -7674,166 +7709,234 @@ index b7e5be3eab5..8a8f873f6c5 100644 bool _isAllowedOrigin(String origin) { Uri uri; +diff --git a/sdk/lib/_internal/vm/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart +index 4e719feb5d4..df1aecdb4f8 100644 +--- a/sdk/lib/_internal/vm/lib/ffi_patch.dart ++++ b/sdk/lib/_internal/vm/lib/ffi_patch.dart +@@ -27,6 +27,9 @@ int get _intPtrSize => (const [ + 8, // androidArm64, + 4, // androidIA32, + 8, // androidX64, ++ 4, // ohosArm, ++ 8, // ohosArm64, ++ 8, // ohosX64, + 8, // fuchsiaArm64, + 8, // fuchsiaX64, + 4, // iosArm, diff --git a/sdk/lib/ffi/abi.dart b/sdk/lib/ffi/abi.dart -index e6f08b37d25..5af605a8764 100644 +index e6f08b37d25..342c5c63c22 100644 --- a/sdk/lib/ffi/abi.dart +++ b/sdk/lib/ffi/abi.dart -@@ -34,6 +34,9 @@ class Abi { - /// The application binary interface for Fuchsia on the X64 architecture. - static const fuchsiaX64 = _fuchsiaX64; +@@ -28,6 +28,15 @@ class Abi { + /// The application binary interface for android on the X64 architecture. + static const androidX64 = _androidX64; -+ /// The application binary interface for Ohos on the X64 architecture. ++ /// The application binary interface for android on the X64 architecture. ++ static const ohosArm = _ohosArm; ++ ++ /// The application binary interface for android on the X64 architecture. ++ static const ohosArm64 = _ohosArm64; ++ ++ /// The application binary interface for android on the X64 architecture. + static const ohosX64 = _ohosX64; + - /// The application binary interface for iOS on the Arm architecture. - static const iosArm = _iosArm; + /// The application binary interface for Fuchsia on the Arm64 architecture. + static const fuchsiaArm64 = _fuchsiaArm64; -@@ -94,6 +97,7 @@ class Abi { +@@ -92,6 +101,9 @@ class Abi { + androidArm64, + androidIA32, androidX64, ++ ohosArm, ++ ohosArm64, ++ ohosX64, fuchsiaArm64, fuchsiaX64, -+ ohosX64, iosArm, - iosArm64, - iosX64, -@@ -136,6 +140,7 @@ class Abi { +@@ -134,6 +146,9 @@ class Abi { + static const _androidArm64 = Abi._(_Architecture.arm64, _OS.android); + static const _androidIA32 = Abi._(_Architecture.ia32, _OS.android); static const _androidX64 = Abi._(_Architecture.x64, _OS.android); ++ static const _ohosArm = Abi._(_Architecture.arm, _OS.ohos); ++ static const _ohosArm64 = Abi._(_Architecture.arm64, _OS.ohos); ++ static const _ohosX64 = Abi._(_Architecture.x64, _OS.ohos); static const _fuchsiaArm64 = Abi._(_Architecture.arm64, _OS.fuchsia); static const _fuchsiaX64 = Abi._(_Architecture.x64, _OS.fuchsia); -+ static const _ohosX64 = Abi._(_Architecture.x64, _OS.ohos); static const _iosArm = Abi._(_Architecture.arm, _OS.ios); - static const _iosArm64 = Abi._(_Architecture.arm64, _OS.ios); - static const _iosX64 = Abi._(_Architecture.x64, _OS.ios); -@@ -170,4 +175,5 @@ enum _OS { +@@ -170,4 +185,5 @@ enum _OS { linux, macos, windows, + ohos, } +diff --git a/sdk/lib/ffi/abi_specific.dart b/sdk/lib/ffi/abi_specific.dart +index 61eb867be17..8aff498845a 100644 +--- a/sdk/lib/ffi/abi_specific.dart ++++ b/sdk/lib/ffi/abi_specific.dart +@@ -24,6 +24,9 @@ part of dart.ffi; + /// Abi.androidArm64: Uint64(), + /// Abi.androidIA32: Uint32(), + /// Abi.androidX64: Uint64(), ++/// Abi.ohosArm: Uint32(), ++/// Abi.ohosArm64: Uint64(), ++/// Abi.ohosX64: Uint64(), + /// Abi.fuchsiaArm64: Uint64(), + /// Abi.fuchsiaX64: Uint64(), + /// Abi.iosArm: Uint32(), diff --git a/sdk/lib/ffi/c_type.dart b/sdk/lib/ffi/c_type.dart -index ee358c2f79d..1f9e629beb9 100644 +index ee358c2f79d..e87207e9e4b 100644 --- a/sdk/lib/ffi/c_type.dart +++ b/sdk/lib/ffi/c_type.dart -@@ -29,6 +29,7 @@ part of dart.ffi; +@@ -27,6 +27,9 @@ part of dart.ffi; + Abi.androidArm64: Uint8(), + Abi.androidIA32: Int8(), Abi.androidX64: Int8(), ++ Abi.ohosArm: Uint8(), ++ Abi.ohosArm64: Uint8(), ++ Abi.ohosX64: Int8(), Abi.fuchsiaArm64: Uint8(), Abi.fuchsiaX64: Int8(), -+ Abi.ohosX64: Int8(), Abi.iosArm: Int8(), - Abi.iosArm64: Int8(), - Abi.iosX64: Int8(), -@@ -66,6 +67,7 @@ class Char extends AbiSpecificInteger { +@@ -64,6 +67,9 @@ class Char extends AbiSpecificInteger { + Abi.androidArm64: Int8(), + Abi.androidIA32: Int8(), Abi.androidX64: Int8(), ++ Abi.ohosArm: Int8(), ++ Abi.ohosArm64: Int8(), ++ Abi.ohosX64: Int8(), Abi.fuchsiaArm64: Int8(), Abi.fuchsiaX64: Int8(), -+ Abi.ohosX64: Int8(), Abi.iosArm: Int8(), - Abi.iosArm64: Int8(), - Abi.iosX64: Int8(), -@@ -103,6 +105,7 @@ class SignedChar extends AbiSpecificInteger { +@@ -101,6 +107,9 @@ class SignedChar extends AbiSpecificInteger { + Abi.androidArm64: Uint8(), + Abi.androidIA32: Uint8(), Abi.androidX64: Uint8(), ++ Abi.ohosArm: Uint8(), ++ Abi.ohosArm64: Uint8(), ++ Abi.ohosX64: Uint8(), Abi.fuchsiaArm64: Uint8(), Abi.fuchsiaX64: Uint8(), -+ Abi.ohosX64: Uint8(), Abi.iosArm: Uint8(), - Abi.iosArm64: Uint8(), - Abi.iosX64: Uint8(), -@@ -140,6 +143,7 @@ class UnsignedChar extends AbiSpecificInteger { +@@ -138,6 +147,9 @@ class UnsignedChar extends AbiSpecificInteger { + Abi.androidArm64: Int16(), + Abi.androidIA32: Int16(), Abi.androidX64: Int16(), ++ Abi.ohosArm: Int16(), ++ Abi.ohosArm64: Int16(), ++ Abi.ohosX64: Int16(), Abi.fuchsiaArm64: Int16(), Abi.fuchsiaX64: Int16(), -+ Abi.ohosX64: Int16(), Abi.iosArm: Int16(), - Abi.iosArm64: Int16(), - Abi.iosX64: Int16(), -@@ -177,6 +181,7 @@ class Short extends AbiSpecificInteger { +@@ -175,6 +187,9 @@ class Short extends AbiSpecificInteger { + Abi.androidArm64: Uint16(), + Abi.androidIA32: Uint16(), Abi.androidX64: Uint16(), ++ Abi.ohosArm: Uint16(), ++ Abi.ohosArm64: Uint16(), ++ Abi.ohosX64: Uint16(), Abi.fuchsiaArm64: Uint16(), Abi.fuchsiaX64: Uint16(), -+ Abi.ohosX64: Uint16(), Abi.iosArm: Uint16(), - Abi.iosArm64: Uint16(), - Abi.iosX64: Uint16(), -@@ -214,6 +219,7 @@ class UnsignedShort extends AbiSpecificInteger { +@@ -212,6 +227,9 @@ class UnsignedShort extends AbiSpecificInteger { + Abi.androidArm64: Int32(), + Abi.androidIA32: Int32(), Abi.androidX64: Int32(), ++ Abi.ohosArm: Int32(), ++ Abi.ohosArm64: Int32(), ++ Abi.ohosX64: Int32(), Abi.fuchsiaArm64: Int32(), Abi.fuchsiaX64: Int32(), -+ Abi.ohosX64: Int32(), Abi.iosArm: Int32(), - Abi.iosArm64: Int32(), - Abi.iosX64: Int32(), -@@ -251,6 +257,7 @@ class Int extends AbiSpecificInteger { +@@ -249,6 +267,9 @@ class Int extends AbiSpecificInteger { + Abi.androidArm64: Uint32(), + Abi.androidIA32: Uint32(), Abi.androidX64: Uint32(), ++ Abi.ohosArm: Uint32(), ++ Abi.ohosArm64: Uint32(), ++ Abi.ohosX64: Uint32(), Abi.fuchsiaArm64: Uint32(), Abi.fuchsiaX64: Uint32(), -+ Abi.ohosX64: Uint32(), Abi.iosArm: Uint32(), - Abi.iosArm64: Uint32(), - Abi.iosX64: Uint32(), -@@ -289,6 +296,7 @@ class UnsignedInt extends AbiSpecificInteger { +@@ -287,6 +308,9 @@ class UnsignedInt extends AbiSpecificInteger { + Abi.androidArm64: Int64(), + Abi.androidIA32: Int32(), Abi.androidX64: Int64(), ++ Abi.ohosArm: Int32(), ++ Abi.ohosArm64: Int64(), ++ Abi.ohosX64: Int64(), Abi.fuchsiaArm64: Int64(), Abi.fuchsiaX64: Int64(), -+ Abi.ohosX64: Int64(), Abi.iosArm: Int32(), - Abi.iosArm64: Int64(), - Abi.iosX64: Int64(), -@@ -327,6 +335,7 @@ class Long extends AbiSpecificInteger { +@@ -325,6 +349,9 @@ class Long extends AbiSpecificInteger { + Abi.androidArm64: Uint64(), + Abi.androidIA32: Uint32(), Abi.androidX64: Uint64(), ++ Abi.ohosArm: Uint32(), ++ Abi.ohosArm64: Uint64(), ++ Abi.ohosX64: Uint64(), Abi.fuchsiaArm64: Uint64(), Abi.fuchsiaX64: Uint64(), -+ Abi.ohosX64: Uint64(), Abi.iosArm: Uint32(), - Abi.iosArm64: Uint64(), - Abi.iosX64: Uint64(), -@@ -364,6 +373,7 @@ class UnsignedLong extends AbiSpecificInteger { +@@ -362,6 +389,9 @@ class UnsignedLong extends AbiSpecificInteger { + Abi.androidArm64: Int64(), + Abi.androidIA32: Int64(), Abi.androidX64: Int64(), ++ Abi.ohosArm: Int64(), ++ Abi.ohosArm64: Int64(), ++ Abi.ohosX64: Int64(), Abi.fuchsiaArm64: Int64(), Abi.fuchsiaX64: Int64(), -+ Abi.ohosX64: Int64(), Abi.iosArm: Int64(), - Abi.iosArm64: Int64(), - Abi.iosX64: Int64(), -@@ -401,6 +411,7 @@ class LongLong extends AbiSpecificInteger { +@@ -399,6 +429,9 @@ class LongLong extends AbiSpecificInteger { + Abi.androidArm64: Uint64(), + Abi.androidIA32: Uint64(), Abi.androidX64: Uint64(), ++ Abi.ohosArm: Uint64(), ++ Abi.ohosArm64: Uint64(), ++ Abi.ohosX64: Uint64(), Abi.fuchsiaArm64: Uint64(), Abi.fuchsiaX64: Uint64(), -+ Abi.ohosX64: Uint64(), Abi.iosArm: Uint64(), - Abi.iosArm64: Uint64(), - Abi.iosX64: Uint64(), -@@ -433,6 +444,7 @@ class UnsignedLongLong extends AbiSpecificInteger { +@@ -431,6 +464,9 @@ class UnsignedLongLong extends AbiSpecificInteger { + Abi.androidArm64: Int64(), + Abi.androidIA32: Int32(), Abi.androidX64: Int64(), ++ Abi.ohosArm: Int32(), ++ Abi.ohosArm64: Int64(), ++ Abi.ohosX64: Int64(), Abi.fuchsiaArm64: Int64(), Abi.fuchsiaX64: Int64(), -+ Abi.ohosX64: Int64(), Abi.iosArm: Int32(), - Abi.iosArm64: Int64(), - Abi.iosX64: Int64(), -@@ -466,6 +478,7 @@ class IntPtr extends AbiSpecificInteger { +@@ -464,6 +500,9 @@ class IntPtr extends AbiSpecificInteger { + Abi.androidArm64: Uint64(), + Abi.androidIA32: Uint32(), Abi.androidX64: Uint64(), ++ Abi.ohosArm: Uint32(), ++ Abi.ohosArm64: Uint64(), ++ Abi.ohosX64: Uint64(), Abi.fuchsiaArm64: Uint64(), Abi.fuchsiaX64: Uint64(), -+ Abi.ohosX64: Uint64(), Abi.iosArm: Uint32(), - Abi.iosArm64: Uint64(), - Abi.iosX64: Uint64(), -@@ -499,6 +512,7 @@ class UintPtr extends AbiSpecificInteger { +@@ -497,6 +536,9 @@ class UintPtr extends AbiSpecificInteger { + Abi.androidArm64: Uint64(), + Abi.androidIA32: Uint32(), Abi.androidX64: Uint64(), ++ Abi.ohosArm: Uint32(), ++ Abi.ohosArm64: Uint64(), ++ Abi.ohosX64: Uint64(), Abi.fuchsiaArm64: Uint64(), Abi.fuchsiaX64: Uint64(), -+ Abi.ohosX64: Uint64(), Abi.iosArm: Uint32(), - Abi.iosArm64: Uint64(), - Abi.iosX64: Uint64(), -@@ -535,6 +549,7 @@ class Size extends AbiSpecificInteger { +@@ -533,6 +575,9 @@ class Size extends AbiSpecificInteger { + Abi.androidArm64: Uint32(), + Abi.androidIA32: Uint32(), Abi.androidX64: Uint32(), ++ Abi.ohosArm: Uint32(), ++ Abi.ohosArm64: Uint32(), ++ Abi.ohosX64: Uint32(), Abi.fuchsiaArm64: Uint32(), Abi.fuchsiaX64: Int32(), -+ Abi.ohosX64: Int32(), Abi.iosArm: Int32(), - Abi.iosArm64: Int32(), - Abi.iosX64: Int32(), diff --git a/sdk_args.gni b/sdk_args.gni index 4b2a1e4ea63..a864344ee8d 100644 --- a/sdk_args.gni -- Gitee From b4649b42a18c6b4be297e43353c12d5724956ec6 Mon Sep 17 00:00:00 2001 From: shijie Date: Wed, 25 Dec 2024 15:50:38 +0800 Subject: [PATCH 42/60] =?UTF-8?q?fix:=20=E5=9B=9E=E9=80=80displayFeature?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=9A=84=E8=AE=BE=E5=A4=87=E4=BF=A1=E6=81=AF?= =?UTF-8?q?,=E4=BF=AE=E6=AD=A3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xiaozn --- .../flutter_embedding/flutter/src/main/ets/view/FlutterView.ets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index 9e8e971fdd..012c7608f9 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -89,7 +89,7 @@ export class ViewportMetrics { this.systemGestureInsetBottom === other.systemGestureInsetBottom && this.systemGestureInsetLeft === other.systemGestureInsetLeft && this.physicalTouchSlop === other.physicalTouchSlop && - this.displayFeatures == other.displayFeatures; + this.displayFeatures === other.displayFeatures; } } -- Gitee From 8edf1e03fc8585e54e22ef44974eebebea7fe3d4 Mon Sep 17 00:00:00 2001 From: gengfei Date: Thu, 19 Dec 2024 18:09:40 +0800 Subject: [PATCH 43/60] Using length in handleDeleteEvent. cherry pick from 3.22 e1fb699632330a5222699d9012eecfc59dcd39dc Signed-off-by: hezhengyi --- .../plugin/editing/ListenableEditingState.ets | 22 ++++++++++++++++--- .../ets/plugin/editing/TextInputPlugin.ets | 8 +++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets index 351277019b..42f1cec3c5 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets @@ -253,7 +253,12 @@ export class ListenableEditingState { } handleDeleteEvent(leftOrRight: boolean, length: number): void { - let start = this.mSelectionStartCache < this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; + if (length === 0) { + return; + } + + let start = + this.mSelectionStartCache < this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; let end = this.mSelectionStartCache > this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; if (leftOrRight == false) { @@ -261,9 +266,15 @@ export class ListenableEditingState { if (start == 0 && end == 0) { return; } + let unicodeStart = start; if (start == end) { - unicodeStart = FlutterTextUtils.getOffsetBefore(this.mStringCache, start); + for (let i = 0; i < length; i++) { + unicodeStart = FlutterTextUtils.getOffsetBefore(this.mStringCache, unicodeStart); + if (unicodeStart === 0) { + break; + } + } } this.replace(unicodeStart, end, "", 0, 0); this.mSelectionStartCache = unicodeStart; @@ -277,7 +288,12 @@ export class ListenableEditingState { } let unicodeEnd = end; if (start == end) { - unicodeEnd = FlutterTextUtils.getOffsetAfter(this.mStringCache, start); + for (let i = 0; i < length; i++) { + unicodeEnd = FlutterTextUtils.getOffsetAfter(this.mStringCache, unicodeEnd); + if (unicodeEnd === this.mStringCache.length) { + break; + } + } } this.replace(start, unicodeEnd, "", 0, 0); this.mSelectionEndCache = start; diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets index 5f3a67c362..da04fb7838 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets @@ -307,6 +307,14 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { } private deleteLeftCallback = (length: number) => { + /// 暂时规避方案 + /// OS机制与Android不一致,需要去监听软键盘事件才能发送KeyEvent事件 + if (this.mEditable.getStringCache() == "") { + for (let i = 0; i < length; i++) { + this.sendKeyboardEvent(KeyType.Down, KeyCode.KEYCODE_DEL) + this.sendKeyboardEvent(KeyType.Up, KeyCode.KEYCODE_DEL) + } + } this.mEditable.handleDeleteEvent(false, length); } -- Gitee From 9bf944e3272c74e164ee3be5bf32187f7477c7d0 Mon Sep 17 00:00:00 2001 From: zjxi Date: Wed, 25 Dec 2024 19:19:07 +0800 Subject: [PATCH 44/60] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E4=BE=A7=E5=8F=91=E9=80=81=E5=88=B0native=E6=97=A0=E9=9A=9C?= =?UTF-8?q?=E7=A2=8D=E9=80=9A=E9=81=93=E7=9A=84ontap,=20onlongpress,=20ont?= =?UTF-8?q?ooltip=E6=8E=A5=E5=8F=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../native_accessibility_channel.cpp | 30 ++++ .../ohos_accessibility_bridge.cpp | 165 +++++++++++------- .../accessibility/ohos_accessibility_bridge.h | 14 +- .../src/main/cpp/types/libflutter/index.d.ets | 8 +- .../systemchannels/AccessibilityChannel.ets | 16 +- shell/platform/ohos/library_loader.cpp | 13 +- .../ohos/napi/platform_view_ohos_napi.cpp | 66 ++++++- .../ohos/napi/platform_view_ohos_napi.h | 12 +- 8 files changed, 247 insertions(+), 77 deletions(-) diff --git a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp index d8ba25cb99..d93a12e20e 100644 --- a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp +++ b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp @@ -105,4 +105,34 @@ namespace flutter { auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); ohos_a11y_bridge->Announce(message); } + + /** + * 利用通道内部类AccessibilityMessageHandler处理主动点击给定id组件事件 + */ + void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTap( + int32_t nodeId) + { + auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); + ohos_a11y_bridge->OnTap(nodeId); + } + + /** + * 利用通道内部类AccessibilityMessageHandler处理主动长按给定id组件事件 + */ + void NativeAccessibilityChannel::AccessibilityMessageHandler::OnLongPress( + int32_t nodeId) + { + auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); + ohos_a11y_bridge->OnLongPress(nodeId); + } + + /** + * 利用通道内部类AccessibilityMessageHandler处理提示文字事件 + */ + void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTooltip( + std::unique_ptr& message) + { + auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); + ohos_a11y_bridge->OnTooltip(message); + } } \ No newline at end of file diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 672307a8ba..27ce3230a4 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -54,6 +54,7 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( accessibilityFeatures_ = std::make_shared(); if (ohosAccessibilityEnabled) { + isAccessibilityEnabled_ = ohosAccessibilityEnabled; nativeAccessibilityChannel_->OnOhosAccessibilityEnabled(native_shell_holder_id_); } else { accessibilityFeatures_->SetAccessibleNavigation(false, native_shell_holder_id_); @@ -326,50 +327,49 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) } /** - * 主动播报特定文本 + * 业务侧通过无障碍通道主动播报自定义文本内容 */ void OhosAccessibilityBridge::Announce(std::unique_ptr& message) { - if (OHOS_API_VERSION < 13) { return; } - CHECK_NULL_PTR(provider_, Announce); - - // 创建并设置屏幕朗读事件 - auto OH_ArkUI_CreateAccessibilityEventInfo = - OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); - CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); - auto* announceEventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); - - - auto OH_ArkUI_AccessibilityEventSetEventType = - OhosAccessibilityDDL::DLLoadSetEventFunc(ArkUIAccessibilityConstant::ARKUI_SET_EVENT_TYPE); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetEventType); - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityEventSetEventType( - announceEventInfo, - ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ANNOUNCE_FOR_ACCESSIBILITY)); - - auto OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility = - OhosAccessibilityDDL::DLLoadSetEventStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_ANNOUNCED_TEXT); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility); - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility( - announceEventInfo, message.get())); - FML_DLOG(INFO) << ("announce -> message: ") << (message.get()); + if (!isAccessibilityEnabled_) { return; } + Flutter_SendAccessibilityAnnounceEvent( + message, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ANNOUNCE_FOR_ACCESSIBILITY); + LOGD("Announce -> message: %{public}s", message.get()); +} - auto callback = [](int32_t errorCode) { - FML_DLOG(WARNING) << "announce callback-> errorCode =" << errorCode; - }; +/** + * 业务侧通过无障碍通道主动点击给定id的组件节点 + */ +void OhosAccessibilityBridge::OnTap(int32_t nodeId) +{ + if (!isAccessibilityEnabled_) { return; } + Flutter_SendAccessibilityAsyncEvent(static_cast(nodeId), + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_CLICKED); + LOGD("OnTap -> nodeId: %{public}d", nodeId); +} - auto OH_ArkUI_SendAccessibilityAsyncEvent = - OhosAccessibilityDDL::DLLoadSendAsyncEventFunc(ArkUIAccessibilityConstant::ARKUI_SEND_A11Y_EVENT); - CHECK_DLL_NULL_PTR(OH_ArkUI_SendAccessibilityAsyncEvent); - OH_ArkUI_SendAccessibilityAsyncEvent(provider_, announceEventInfo, callback); +/** + * 业务侧通过无障碍通道主动长按给定id的组件节点 + */ +void OhosAccessibilityBridge::OnLongPress(int32_t nodeId) +{ + if (!isAccessibilityEnabled_) { return; } + Flutter_SendAccessibilityAsyncEvent(static_cast(nodeId), + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_LONG_CLICKED); + LOGD("OnLongPress -> nodeId: %{public}d", nodeId); +} - auto OH_ArkUI_DestoryAccessibilityEventInfo = - OhosAccessibilityDDL::DLLoadDestroyEventFunc(ArkUIAccessibilityConstant::ARKUI_DESTORY_EVENT); - CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityEventInfo); - OH_ArkUI_DestoryAccessibilityEventInfo(announceEventInfo); - announceEventInfo = nullptr; +/** + * 业务侧通过无障碍通道主动长按给定id的组件节点 + */ +void OhosAccessibilityBridge::OnTooltip(std::unique_ptr& message) +{ + if (!isAccessibilityEnabled_) { return; } + Flutter_SendAccessibilityAsyncEvent(static_cast(ROOT_NODE_ID), + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); + Flutter_SendAccessibilityAnnounceEvent( + message, ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ANNOUNCE_FOR_ACCESSIBILITY); + LOGD("OnTooltip -> message: %{public}s", message.get()); } //获取根节点 @@ -779,6 +779,16 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id << " OH_ArkUI_AccessibilityElementInfoSetFocusable -> true"; } + if (IsNodeFocused(flutterNode)) { + auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused = + OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_FOCUSED); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused(elementInfoFromList, true) + ); + FML_DLOG(INFO) << "flutterNode.id=" << flutterNode.id + << " OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused -> true"; + } // 判断当前节点是否为密码输入框 if (IsNodePassword(flutterNode)) { auto OH_ArkUI_AccessibilityElementInfoSetIsPassword = @@ -1563,6 +1573,51 @@ flutter::SemanticsAction OhosAccessibilityBridge::ArkuiActionsToFlutterActions( } } +/** + * flutter发送无障碍自定义主动播报事件 + */ +void OhosAccessibilityBridge::Flutter_SendAccessibilityAnnounceEvent( + std::unique_ptr& message, + ArkUI_AccessibilityEventType eventType) +{ + // 创建并设置屏幕朗读事件 + auto OH_ArkUI_CreateAccessibilityEventInfo = + OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); + CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); + auto* announceEventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); + + auto OH_ArkUI_AccessibilityEventSetEventType = + OhosAccessibilityDDL::DLLoadSetEventFunc(ArkUIAccessibilityConstant::ARKUI_SET_EVENT_TYPE); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetEventType); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityEventSetEventType( + announceEventInfo, + ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ANNOUNCE_FOR_ACCESSIBILITY)); + + auto OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility = + OhosAccessibilityDDL::DLLoadSetEventStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_ANNOUNCED_TEXT); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility); + ARKUI_ACCESSIBILITY_CALL_CHECK( + OH_ArkUI_AccessibilityEventSetTextAnnouncedForAccessibility( + announceEventInfo, message.get())); + FML_DLOG(INFO) << ("announce -> message: ") << (message.get()); + + auto callback = [](int32_t errorCode) { + FML_DLOG(WARNING) << "announce callback-> errorCode =" << errorCode; + }; + + auto OH_ArkUI_SendAccessibilityAsyncEvent = + OhosAccessibilityDDL::DLLoadSendAsyncEventFunc(ArkUIAccessibilityConstant::ARKUI_SEND_A11Y_EVENT); + CHECK_DLL_NULL_PTR(OH_ArkUI_SendAccessibilityAsyncEvent); + OH_ArkUI_SendAccessibilityAsyncEvent(provider_, announceEventInfo, callback); + + auto OH_ArkUI_DestoryAccessibilityEventInfo = + OhosAccessibilityDDL::DLLoadDestroyEventFunc(ArkUIAccessibilityConstant::ARKUI_DESTORY_EVENT); + CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityEventInfo); + OH_ArkUI_DestoryAccessibilityEventInfo(announceEventInfo); + announceEventInfo = nullptr; +} + /** * 自定义无障碍异步事件发送 */ @@ -1574,56 +1629,46 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAsyncEvent); - // 1.创建eventInfo对象 + // 创建eventInfo对象 auto OH_ArkUI_CreateAccessibilityEventInfo = OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); auto* eventInfo = OH_ArkUI_CreateAccessibilityEventInfo(); CHECK_NULL_PTR(eventInfo, Flutter_SendAccessibilityAsyncEvent); - // 2.创建的elementinfo并根据对应id的flutternode进行属性初始化 + // 创建的elementinfo并根据对应id的flutternode进行属性初始化 auto OH_ArkUI_CreateAccessibilityElementInfo = OhosAccessibilityDDL::DLLoadCreateElemInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); ArkUI_AccessibilityElementInfo* _elementInfo = OH_ArkUI_CreateAccessibilityElementInfo(); FlutterSetElementInfoProperties(_elementInfo, elementId); - // 若为获焦事件,则设置当前elementinfo获焦 - auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused = - OhosAccessibilityDDL::DLLoadSetElemBoolFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_FOCUSED); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused); - if (eventType == ArkUI_AccessibilityEventType::ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_ACCESSIBILITY_FOCUSED) { - ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityFocused(_elementInfo, true) - ); - } + // 将eventinfo事件和当前elementinfo进行绑定 + auto OH_ArkUI_AccessibilityEventSetElementInfo = + OhosAccessibilityDDL::DLLoadSetEventElemFunc(ArkUIAccessibilityConstant::ARKUI_EVENT_SET_NODE); + CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetElementInfo); + ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetElementInfo(eventInfo, _elementInfo)); - // 3.设置发送事件,如配置获焦、失焦、点击、滑动事件 + // 设置发送事件,如配置获焦、失焦、点击、滑动事件 auto OH_ArkUI_AccessibilityEventSetEventType = OhosAccessibilityDDL::DLLoadSetEventFunc(ArkUIAccessibilityConstant::ARKUI_SET_EVENT_TYPE); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetEventType); ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetEventType(eventInfo, eventType)); - // 4.将eventinfo事件和当前elementinfo进行绑定 - auto OH_ArkUI_AccessibilityEventSetElementInfo = - OhosAccessibilityDDL::DLLoadSetEventElemFunc(ArkUIAccessibilityConstant::ARKUI_EVENT_SET_NODE); - CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityEventSetElementInfo); - ARKUI_ACCESSIBILITY_CALL_CHECK(OH_ArkUI_AccessibilityEventSetElementInfo(eventInfo, _elementInfo)); - - // 5.调用接口发送到ohos侧 + // 调用接口发送到ohos侧 auto callback = [](int32_t errorCode) { FML_DLOG(INFO) << "Flutter_SendAccessibilityAsyncEvent callback-> errorCode =" << errorCode; }; - // 6.发送event到OH侧 + // 发送event到OH侧 auto OH_ArkUI_SendAccessibilityAsyncEvent = OhosAccessibilityDDL::DLLoadSendAsyncEventFunc(ArkUIAccessibilityConstant::ARKUI_SEND_A11Y_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_SendAccessibilityAsyncEvent); OH_ArkUI_SendAccessibilityAsyncEvent(provider_, eventInfo, callback); - // 7.销毁新创建的elementinfo, eventinfo + // 销毁新创建的elementinfo, eventinfo auto OH_ArkUI_DestoryAccessibilityElementInfo = OhosAccessibilityDDL::DLLoadDestroyElemFunc(ArkUIAccessibilityConstant::ARKUI_DESTORY_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_DestoryAccessibilityElementInfo); @@ -1934,8 +1979,6 @@ void OhosAccessibilityBridge::ClearFlutterSemanticsCaches() g_flutterSemanticsTree.clear(); g_parentChildIdVec.clear(); g_screenRectMap.clear(); - g_actions_mp.clear(); - g_flutterNavigationVec.clear(); } /** diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 3e61c171ab..257adf502f 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -96,8 +96,12 @@ public: fml::MallocMapping args); void Announce(std::unique_ptr& message); + void OnTap(int32_t nodeId); + void OnLongPress(int32_t nodeId); + void OnTooltip(std::unique_ptr& message); SemanticsNodeExtent GetFlutterSemanticsNode(int32_t id); + int32_t GetParentId(int64_t elementId); int32_t FindAccessibilityNodeInfosById( int64_t elementId, @@ -132,7 +136,9 @@ public: void Flutter_SendAccessibilityAsyncEvent( int64_t elementId, ArkUI_AccessibilityEventType eventType); - int32_t GetParentId(int64_t elementId); + void Flutter_SendAccessibilityAnnounceEvent( + std::unique_ptr& message, + ArkUI_AccessibilityEventType eventType); void FlutterRelativeRectToScreenRect(SemanticsNodeExtent node); AbsoluteRect GetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode); @@ -152,17 +158,15 @@ public: private: OhosAccessibilityBridge() = default; + bool isAccessibilityEnabled_ = false; static std::unique_ptr bridgeInstance_; - std::shared_ptr nativeAccessibilityChannel_; std::shared_ptr accessibilityFeatures_; std::vector> g_parentChildIdVec; std::map g_flutterSemanticsTree; std::unordered_map g_screenRectMap; - std::unordered_map g_actions_mp; - std::vector g_flutterNavigationVec; - + SemanticsNodeExtent inputFocusedNode; SemanticsNodeExtent lastInputFocusedNode; SemanticsNodeExtent accessibilityFocusedNode; 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 629988a893..279c97baa1 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 @@ -148,7 +148,13 @@ export const nativeSetAccessibilityFeatures: (accessibilityFeatureFlags: number, export const nativeAccessibilityStateChange: (nativeShellHolderId: number, state: Boolean) => void; -export const nativeAnnounce: (message: string) => void; +export const nativeAccessibilityAnnounce: (message: string) => void; + +export const nativeAccessibilityOnTap: (nodeId: number) => void; + +export const nativeAccessibilityOnLongPress: (nodeId: number) => void; + +export const nativeAccessibilityOnTooltip: (message: string) => void; export const nativeSetSemanticsEnabled: (nativeShellHolderId: number, enabled: boolean) => void; diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets index bbc5a658ea..1a6eba7bc9 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets @@ -122,24 +122,32 @@ export interface AccessibilityMessageHandler extends AccessibilityDelegate { announce(message: string): void; onTap(nodeId: number): void; onLongPress(nodeId: number): void; - onTooltip(nodeId: string): void; + onTooltip(message: string): void; } export class DefaultHandler implements AccessibilityMessageHandler { - private static TAG = "AccessibilityMessageHandler"; + private static TAG = "AccessibilityMessageHandler"; + announce(message: string): void { Log.i(DefaultHandler.TAG, "handler announce."); - flutter.nativeAnnounce(message); + flutter.nativeAccessibilityAnnounce(message); } + onTap(nodeId: number): void { Log.i(DefaultHandler.TAG, "handler onTap."); + flutter.nativeAccessibilityOnTap(nodeId); } + onLongPress(nodeId: number): void { Log.i(DefaultHandler.TAG, "handler onLongPress."); + flutter.nativeAccessibilityOnLongPress(nodeId); } - onTooltip(nodeId: string): void { + + onTooltip(message: string): void { Log.i(DefaultHandler.TAG, "handler onTooltip."); + flutter.nativeAccessibilityOnTooltip(message); } + updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void { Log.i(DefaultHandler.TAG, "handler updateSemantics"); } diff --git a/shell/platform/ohos/library_loader.cpp b/shell/platform/ohos/library_loader.cpp index 4f7216d73e..7b2c7da1c0 100644 --- a/shell/platform/ohos/library_loader.cpp +++ b/shell/platform/ohos/library_loader.cpp @@ -146,8 +146,17 @@ static napi_value Init(napi_env env, napi_value exports) { "nativeAccessibilityStateChange", flutter::PlatformViewOHOSNapi::nativeAccessibilityStateChange), DECLARE_NAPI_FUNCTION( - "nativeAnnounce", - flutter::PlatformViewOHOSNapi::nativeAnnounce), + "nativeAccessibilityAnnounce", + flutter::PlatformViewOHOSNapi::nativeAccessibilityAnnounce), + DECLARE_NAPI_FUNCTION( + "nativeAccessibilityOnTap", + flutter::PlatformViewOHOSNapi::nativeAccessibilityOnTap), + DECLARE_NAPI_FUNCTION( + "nativeAccessibilityOnLongPress", + flutter::PlatformViewOHOSNapi::nativeAccessibilityOnLongPress), + DECLARE_NAPI_FUNCTION( + "nativeAccessibilityOnTooltip", + flutter::PlatformViewOHOSNapi::nativeAccessibilityOnTooltip), DECLARE_NAPI_FUNCTION( "nativeSetSemanticsEnabled", flutter::PlatformViewOHOSNapi::nativeSetSemanticsEnabled), diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 431ff15b31..33535deff8 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -40,6 +40,7 @@ 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 @@ -1881,7 +1882,7 @@ napi_value PlatformViewOHOSNapi::nativeAccessibilityStateChange( return nullptr; } -napi_value PlatformViewOHOSNapi::nativeAnnounce( +napi_value PlatformViewOHOSNapi::nativeAccessibilityAnnounce( napi_env env, napi_callback_info info) { size_t argc = 1; @@ -1895,8 +1896,8 @@ napi_value PlatformViewOHOSNapi::nativeAnnounce( auto char_array = std::make_unique(null_terminated_length); napi_get_value_string_utf8(env, args[0], char_array.get(), null_terminated_length, nullptr); - LOGD("PlatformViewOHOSNapi::nativeAnnounce message: %{public}s", char_array.get()); - const int32_t OHOS_API_VERSION = OH_GetSdkApiVersion(); + LOGD("PlatformViewOHOSNapi::nativeAccessibilityAnnounce message: %{public}s", char_array.get()); + if (OHOS_API_VERSION >= 13) { auto handler = std::make_shared(); handler->Announce(char_array); @@ -1904,6 +1905,65 @@ napi_value PlatformViewOHOSNapi::nativeAnnounce( return nullptr; } +napi_value PlatformViewOHOSNapi::nativeAccessibilityOnTap( + napi_env env, + napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + int32_t nodeId; + napi_get_value_int32(env, args[0], &nodeId); + + if (OHOS_API_VERSION >= 13) { + auto handler = std::make_shared(); + handler->OnTap(nodeId); + LOGI("nativeAccessibilityOnTap -> nodeId:%{public}d", nodeId); + } + return nullptr; +} + +napi_value PlatformViewOHOSNapi::nativeAccessibilityOnLongPress( + napi_env env, + napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + int32_t nodeId; + napi_get_value_int32(env, args[0], &nodeId);; + + if (OHOS_API_VERSION >= 13) { + auto handler = std::make_shared(); + handler->OnLongPress(nodeId); + LOGI("nativeAccessibilityOnLongPress -> nodeId:%{public}d", nodeId); + } + return nullptr; +} + +napi_value PlatformViewOHOSNapi::nativeAccessibilityOnTooltip( + napi_env env, + napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + size_t length = 0; + napi_get_value_string_utf8(env, args[0], nullptr, 0, &length); + + auto null_terminated_length = length + 1; + auto char_array = std::make_unique(null_terminated_length); + napi_get_value_string_utf8(env, args[0], char_array.get(), + null_terminated_length, nullptr); + LOGD("PlatformViewOHOSNapi::nativeAccessibilityOnTooltip message: %{public}s", char_array.get()); + +if (OHOS_API_VERSION >= 13) { + auto handler = std::make_shared(); + handler->OnTooltip(char_array); + } + return nullptr; +} + napi_value PlatformViewOHOSNapi::nativeSetSemanticsEnabled(napi_env env, napi_callback_info info) { napi_status ret; size_t argc = 2; diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.h b/shell/platform/ohos/napi/platform_view_ohos_napi.h index b246ad75c0..013557aeae 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.h +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.h @@ -219,7 +219,16 @@ class PlatformViewOHOSNapi { static napi_value nativeAccessibilityStateChange( napi_env env, napi_callback_info info); - static napi_value nativeAnnounce( + static napi_value nativeAccessibilityAnnounce( + napi_env env, + napi_callback_info info); + static napi_value nativeAccessibilityOnTap( + napi_env env, + napi_callback_info info); + static napi_value nativeAccessibilityOnLongPress( + napi_env env, + napi_callback_info info); + static napi_value nativeAccessibilityOnTooltip( napi_env env, napi_callback_info info); static napi_value nativeSetSemanticsEnabled(napi_env env, napi_callback_info info); @@ -266,6 +275,7 @@ class PlatformViewOHOSNapi { static std::vector system_languages; fml::RefPtr platform_task_runner_; static int64_t napi_shell_holder_id_; + static const int32_t OHOS_API_VERSION; }; } // namespace flutter -- Gitee From a0bfde5c236d9886db9cdaa2c19641f4bab866d1 Mon Sep 17 00:00:00 2001 From: liujiake Date: Wed, 25 Dec 2024 20:27:27 +0800 Subject: [PATCH 45/60] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A4=96=E6=8E=A5?= =?UTF-8?q?=E7=BA=B9=E7=90=86=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9F=E5=87=BD?= =?UTF-8?q?=E6=95=B0OnGrContextDestroyed=E7=9A=84=E5=86=85=E5=AE=B9?= =?UTF-8?q?=EF=BC=8C=E5=8F=8A=E6=97=B6=E9=87=8A=E6=94=BE=E7=BA=B9=E7=90=86?= =?UTF-8?q?=E8=B5=84=E6=BA=90=EF=BC=8C=E9=81=BF=E5=85=8D=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=B3=84=E9=9C=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liujiake --- .../ohos/ohos_external_texture_gl.cpp | 103 +++++++++++++++--- .../platform/ohos/ohos_external_texture_gl.h | 6 +- shell/platform/ohos/platform_view_ohos.cpp | 6 +- 3 files changed, 98 insertions(+), 17 deletions(-) diff --git a/shell/platform/ohos/ohos_external_texture_gl.cpp b/shell/platform/ohos/ohos_external_texture_gl.cpp index 8078821bb1..23ee4e2c6a 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.cpp +++ b/shell/platform/ohos/ohos_external_texture_gl.cpp @@ -280,14 +280,74 @@ void OHOSExternalTextureGL::Paint(PaintContext& context, } } +void OHOSExternalTextureGL::Show() +{ + if (state_ != AttachmentState::hide) { + FML_LOG(WARNING) << "OHOSExternalTextureGL show, state is not hide, ignore this call"; + return; + } + OHOSSurface* ohos_surface_ptr = ohos_surface_.get(); + OhosSurfaceGLSkia* ohosSurfaceGLSkia_ = (OhosSurfaceGLSkia*)ohos_surface_ptr; + if (ohosSurfaceGLSkia_->GetOnscreenSurface() == nullptr) { + FML_LOG(ERROR) << "OHOSExternalTextureGL show, GetSurface failed"; + return; + } + auto result = ohosSurfaceGLSkia_->GLContextMakeCurrent(); + if (result->GetResult()) { + FML_DLOG(INFO) << "OHOSExternalTextureGL show, MakeCurrent successed"; + glGenTextures(1, &texture_name_); + FML_DLOG(INFO) << "OHOSExternalTextureGL show, glGenTextures texture_name_=" + << texture_name_ << ", Id()=" << Id(); + int32_t ret = OH_NativeImage_AttachContext(nativeImage_, texture_name_); + if (ret != 0) { + FML_LOG(ERROR) << "OHOSExternalTextureGL show, AttachContext failed, err code:" << ret; + } + state_ = AttachmentState::attached; + } else { + FML_LOG(ERROR) << "OHOSExternalTextureGL show, MakeCurrent failed"; + return; + } +} + void OHOSExternalTextureGL::OnGrContextCreated() { FML_DLOG(INFO) << " OHOSExternalTextureGL::OnGrContextCreated" << ", texture_name_=" << texture_name_ << ", Id()=" << Id(); - if (state_ == AttachmentState::attached) { - delegate_.OnPlatformViewMarkTextureFrameAvailable(Id()); + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetRasterTaskRunner(), + [this]() { + Show(); + }); + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetPlatformTaskRunner(), + [this]() { + delegate_.OnPlatformViewMarkTextureFrameAvailable(Id()); + }); +} + +void OHOSExternalTextureGL::Hide() +{ + if (state_ != AttachmentState::attached) { + FML_LOG(WARNING) << "OHOSExternalTextureGL hide, state is not attached, ignore this call"; + return; + } + if (nativeImage_ != nullptr) { + OH_NativeImage_DetachContext(nativeImage_); + if (backGroundTextureName_ != 0) { + glDeleteTextures(1, &texture_name_); + texture_name_ = 0; + } + } + if (backGroundNativeWindow_ != nullptr) { + OH_NativeImage_DetachContext(backGroundNativeImage_); + if (backGroundTextureName_ != 0) { + infoMap.erase(backGroundTextureName_); + glDeleteTextures(1, &backGroundTextureName_); + backGroundTextureName_ = 0; + } } + state_ = AttachmentState::hide; } void OHOSExternalTextureGL::OnGrContextDestroyed() @@ -295,6 +355,11 @@ void OHOSExternalTextureGL::OnGrContextDestroyed() FML_DLOG(INFO) << " OHOSExternalTextureGL::OnGrContextDestroyed" << ", texture_name_=" << texture_name_ << ", Id()=" << Id(); + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetRasterTaskRunner(), + [this]() { + Hide(); + }); } void OHOSExternalTextureGL::MarkNewFrameAvailable() @@ -320,10 +385,14 @@ void OHOSExternalTextureGL::OnTextureUnregistered() << ", nativeImage_=" << nativeImage_ << ", backGroundNativeImage_=" << backGroundNativeImage_; first_update_ = false; - if (state_ == AttachmentState::attached) { - Detach(); - state_ = AttachmentState::detached; - } + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetRasterTaskRunner(), + [this]() { + if (state_ == AttachmentState::attached || state_ == AttachmentState::hide) { + Detach(); + state_ = AttachmentState::detached; + } + }); } bool OHOSExternalTextureGL::IsContextCurrent() @@ -372,12 +441,14 @@ void OHOSExternalTextureGL::Update() void OHOSExternalTextureGL::Detach() { FML_LOG(INFO) << "OHOSExternalTextureGL::Detach, texture_name_=" << texture_name_; - if (state_ != AttachmentState::attached) { - FML_LOG(ERROR) << "OHOSExternalTextureGL::Detach, the current status is not attached"; + if (state_ != AttachmentState::attached && state_ != AttachmentState::hide) { + FML_LOG(ERROR) << "OHOSExternalTextureGL::Detach, the current status is not attached or hide"; return; } if (nativeImage_ != nullptr) { - OH_NativeImage_DetachContext(nativeImage_); + if (state_ == AttachmentState::attached) { + OH_NativeImage_DetachContext(nativeImage_); + } OH_NativeImage_UnsetOnFrameAvailableListener(nativeImage_); OH_NativeImage_Destroy(&nativeImage_); nativeImage_ = nullptr; @@ -388,7 +459,9 @@ void OHOSExternalTextureGL::Detach() } if (backGroundNativeImage_ != nullptr) { - OH_NativeImage_DetachContext(backGroundNativeImage_); + if (state_ == AttachmentState::attached) { + OH_NativeImage_DetachContext(backGroundNativeImage_); + } OH_NativeImage_Destroy(&backGroundNativeImage_); backGroundNativeImage_ = nullptr; } @@ -396,10 +469,12 @@ void OHOSExternalTextureGL::Detach() OH_NativeWindow_DestroyNativeWindow(backGroundNativeWindow_); backGroundNativeWindow_ = nullptr; } - glDeleteTextures(1, &texture_name_); - glDeleteTextures(1, &backGroundTextureName_); - if (backGroundTextureName_ != 0) { - infoMap.erase(backGroundTextureName_); + if (state_ == AttachmentState::attached) { + glDeleteTextures(1, &texture_name_); + glDeleteTextures(1, &backGroundTextureName_); + if (backGroundTextureName_ != 0) { + infoMap.erase(backGroundTextureName_); + } } } diff --git a/shell/platform/ohos/ohos_external_texture_gl.h b/shell/platform/ohos/ohos_external_texture_gl.h index 5ddd50b573..113aeb5296 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.h +++ b/shell/platform/ohos/ohos_external_texture_gl.h @@ -87,6 +87,10 @@ class OHOSExternalTextureGL : public flutter::Texture, public std::enable_shared void Detach(); + void Hide(); + + void Show(); + void UpdateTransform(OH_NativeImage *image); EGLDisplay GetPlatformEglDisplay(EGLenum platform, void *native_display, const EGLint *attrib_list); @@ -101,7 +105,7 @@ class OHOSExternalTextureGL : public flutter::Texture, public std::enable_shared void ProducePixelMapToBackGroundImage(); - enum class AttachmentState { uninitialized, attached, detached }; + enum class AttachmentState { uninitialized, attached, detached, hide }; AttachmentState state_; diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index 58b1056978..2ba37590a3 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -120,8 +120,10 @@ PlatformViewOHOS::~PlatformViewOHOS() { for (auto const &it : external_texture_gl_) { if (it.second != nullptr) { FML_LOG(INFO) << " nativeImage of textureId " << it.first << " will destroy"; - OH_NativeImage_Destroy(&(it.second->nativeImage_)); - it.second->nativeImage_ = nullptr; + if (it.second->nativeImage_ != nullptr) { + OH_NativeImage_Destroy(&(it.second->nativeImage_)); + it.second->nativeImage_ = nullptr; + } } } external_texture_gl_.clear(); -- Gitee From dd1ba04cf855b6579db58a81173c089d9343e3a2 Mon Sep 17 00:00:00 2001 From: liujiake Date: Wed, 25 Dec 2024 21:35:49 +0800 Subject: [PATCH 46/60] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A4=96=E6=8E=A5?= =?UTF-8?q?=E7=BA=B9=E7=90=86OnGrContextCreated=E4=B8=AD=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E7=BA=B9=E7=90=86=E5=92=8C=E8=A7=A6=E5=8F=91paint=E7=9A=84?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=EF=BC=8C=E7=A1=AE=E4=BF=9D=E7=BA=BF=E6=80=A7?= =?UTF-8?q?=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liujiake --- .../ohos/ohos_external_texture_gl.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/shell/platform/ohos/ohos_external_texture_gl.cpp b/shell/platform/ohos/ohos_external_texture_gl.cpp index 23ee4e2c6a..69b1a5646b 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.cpp +++ b/shell/platform/ohos/ohos_external_texture_gl.cpp @@ -303,6 +303,11 @@ void OHOSExternalTextureGL::Show() FML_LOG(ERROR) << "OHOSExternalTextureGL show, AttachContext failed, err code:" << ret; } state_ = AttachmentState::attached; + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetPlatformTaskRunner(), + [this]() { + delegate_.OnPlatformViewMarkTextureFrameAvailable(Id()); + }); } else { FML_LOG(ERROR) << "OHOSExternalTextureGL show, MakeCurrent failed"; return; @@ -319,11 +324,6 @@ void OHOSExternalTextureGL::OnGrContextCreated() [this]() { Show(); }); - fml::TaskRunner::RunNowOrPostTask( - task_runners_.GetPlatformTaskRunner(), - [this]() { - delegate_.OnPlatformViewMarkTextureFrameAvailable(Id()); - }); } void OHOSExternalTextureGL::Hide() @@ -386,13 +386,13 @@ void OHOSExternalTextureGL::OnTextureUnregistered() << ", backGroundNativeImage_=" << backGroundNativeImage_; first_update_ = false; fml::TaskRunner::RunNowOrPostTask( - task_runners_.GetRasterTaskRunner(), - [this]() { - if (state_ == AttachmentState::attached || state_ == AttachmentState::hide) { - Detach(); - state_ = AttachmentState::detached; - } - }); + task_runners_.GetRasterTaskRunner(), + [this]() { + if (state_ == AttachmentState::attached || state_ == AttachmentState::hide) { + Detach(); + state_ = AttachmentState::detached; + } + }); } bool OHOSExternalTextureGL::IsContextCurrent() -- Gitee From 2322fe3884d812fcbbf96a53194e03e51173155d Mon Sep 17 00:00:00 2001 From: gxzmf <279822581@qq.com> Date: Wed, 25 Dec 2024 21:36:12 +0800 Subject: [PATCH 47/60] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: gxzmf <279822581@qq.com> --- .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md index 47f158371d..ff5ca685ed 100644 --- a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md +++ b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md @@ -17,7 +17,6 @@ - [ ] 评估不涉及 **合入前自检**: -- [ ] 不涉及非兼容性变更;若涉及,已通过相应评审。 - [ ] 不涉及性能或已进行性能测试且无性能劣化。 - [ ] 符合对应的编码规范。 - [ ] 不涉及文档更新,或已更新了文档。 -- Gitee From bb6439e6c69f0a64cc58422e3e64be2ef99854d9 Mon Sep 17 00:00:00 2001 From: gxzmf <279822581@qq.com> Date: Wed, 25 Dec 2024 14:44:59 +0000 Subject: [PATCH 48/60] =?UTF-8?q?=E5=9B=9E=E9=80=80=20'Pull=20Request=20!5?= =?UTF-8?q?67=20:=20=E9=80=82=E9=85=8D2in1=EF=BC=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=BC=A0=E6=A0=87=E6=BB=9A=E8=BD=AE=E6=96=B9=E5=90=91=E5=92=8C?= =?UTF-8?q?keyEvent=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: gxzmf <279822581@qq.com> --- .../ets/embedding/ohos/KeyEventHandler.ets | 37 ++++--------------- .../plugin/editing/ListenableEditingState.ets | 22 ++--------- .../ets/plugin/editing/TextInputPlugin.ets | 8 ---- shell/platform/ohos/ohos_touch_processor.cpp | 10 +++-- .../platform/ohos/ohos_xcomponent_adapter.cpp | 3 +- 5 files changed, 18 insertions(+), 62 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets index 5fd76b3d62..58133fd461 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/KeyEventHandler.ets @@ -21,20 +21,11 @@ import { KeyCode } from "@kit.InputKit"; const TAG = "KeyEventHandler"; -// 组合键 -const COMBINATION_KEYS = [ - KeyCode.KEYCODE_CTRL_LEFT, KeyCode.KEYCODE_CTRL_RIGHT, - KeyCode.KEYCODE_ALT_LEFT, KeyCode.KEYCODE_ALT_RIGHT -]; - export class KeyEventHandler { private textInputPlugin?: TextInputPlugin; private charMap : HashMap = new HashMap(); private shiftMap : HashMap = new HashMap(); private isShiftMode: boolean = false; - private isCombinationKey: boolean = false; - // 记录输入的keyCode,确保有down和up事件才输入字符 - private inputMap: HashMap = new HashMap(); constructor(textInputPlugin?: TextInputPlugin) { this.textInputPlugin = textInputPlugin; @@ -156,30 +147,18 @@ export class KeyEventHandler { handleKeyEvent(event: KeyEvent) { Log.i(TAG, JSON.stringify({ "name": "handleKeyEvent", - "event": event, + "event": event })); - let text = this.getCharByEvent(event); - if (event.type == KeyType.Down) { - if (!this.isCombinationKey) { - this.isCombinationKey = COMBINATION_KEYS.findIndex((it) => it == event.keyCode) >= 0; - } - this.inputMap.set(event.keyCode, text); - } else if (event.type == KeyType.Up) { - if (COMBINATION_KEYS.findIndex((it) => it == event.keyCode) >= 0) { - // Ctrl/Alt 键抬起,重置状态 - this.isCombinationKey = false; - return; - } else if (this.isCombinationKey) { - // Ctrl/Alt 键按下的状态,不输入字符(字母/数字/符号) - return; - } + if (event.type == KeyType.Up) { // 处理字符按键相关逻辑 - if (this.inputMap.hasKey(event.keyCode) && this.charMap.hasKey(event.keyCode)) { - this.inputMap.remove(event.keyCode) - this.textInputPlugin?.getEditingState().handleInsertTextEvent(text) + if (this.charMap.hasKey(event.keyCode)) { + this.textInputPlugin?.getEditingState().handleInsertTextEvent(this.getCharByEvent(event)) + } + // 处理非字符按键 + if (event.keyCode == KeyCode.KEYCODE_DEL) { + this.textInputPlugin?.getEditingState().handleDeleteEvent(false, 0) } } this.isShiftMode = event.keyCode == KeyCode.KEYCODE_SHIFT_LEFT - || event.keyCode == KeyCode.KEYCODE_SHIFT_RIGHT } } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets index 42f1cec3c5..351277019b 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/ListenableEditingState.ets @@ -253,12 +253,7 @@ export class ListenableEditingState { } handleDeleteEvent(leftOrRight: boolean, length: number): void { - if (length === 0) { - return; - } - - let start = - this.mSelectionStartCache < this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; + let start = this.mSelectionStartCache < this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; let end = this.mSelectionStartCache > this.mSelectionEndCache ? this.mSelectionStartCache : this.mSelectionEndCache; if (leftOrRight == false) { @@ -266,15 +261,9 @@ export class ListenableEditingState { if (start == 0 && end == 0) { return; } - let unicodeStart = start; if (start == end) { - for (let i = 0; i < length; i++) { - unicodeStart = FlutterTextUtils.getOffsetBefore(this.mStringCache, unicodeStart); - if (unicodeStart === 0) { - break; - } - } + unicodeStart = FlutterTextUtils.getOffsetBefore(this.mStringCache, start); } this.replace(unicodeStart, end, "", 0, 0); this.mSelectionStartCache = unicodeStart; @@ -288,12 +277,7 @@ export class ListenableEditingState { } let unicodeEnd = end; if (start == end) { - for (let i = 0; i < length; i++) { - unicodeEnd = FlutterTextUtils.getOffsetAfter(this.mStringCache, unicodeEnd); - if (unicodeEnd === this.mStringCache.length) { - break; - } - } + unicodeEnd = FlutterTextUtils.getOffsetAfter(this.mStringCache, start); } this.replace(start, unicodeEnd, "", 0, 0); this.mSelectionEndCache = start; diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets index 0b7fd575a4..50be54c4b0 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets @@ -307,14 +307,6 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { } private deleteLeftCallback = (length: number) => { - /// 暂时规避方案 - /// OS机制与Android不一致,需要去监听软键盘事件才能发送KeyEvent事件 - if (this.mEditable.getStringCache() == "") { - for (let i = 0; i < length; i++) { - this.sendKeyboardEvent(KeyType.Down, KeyCode.KEYCODE_DEL) - this.sendKeyboardEvent(KeyType.Up, KeyCode.KEYCODE_DEL) - } - } this.mEditable.handleDeleteEvent(false, length); } diff --git a/shell/platform/ohos/ohos_touch_processor.cpp b/shell/platform/ohos/ohos_touch_processor.cpp index 17b715b328..32d2ed1ef8 100644 --- a/shell/platform/ohos/ohos_touch_processor.cpp +++ b/shell/platform/ohos/ohos_touch_processor.cpp @@ -179,9 +179,11 @@ void OhosTouchProcessor::HandleTouchEvent( OH_NativeXComponent_TouchPointToolType toolType; OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType); pointerData.kind = getPointerDeviceTypeForToolType(toolType); - if (pointerData.change == PointerData::Change::kDown || - pointerData.change == PointerData::Change::kMove) { - pointerData.buttons = kPointerButtonTouchContact; + if (pointerData.kind == PointerData::DeviceKind::kTouch) { + if (pointerData.change == PointerData::Change::kDown || + pointerData.change == PointerData::Change::kMove) { + pointerData.buttons = kPointerButtonTouchContact; + } } pointerData.pan_x = 0.0; pointerData.pan_y = 0.0; @@ -259,7 +261,7 @@ void OhosTouchProcessor::HandleMouseEvent( pointerData.pressure = 0.0; pointerData.pressure_max = 1.0; pointerData.pressure_min = 0.0; - pointerData.kind = PointerData::DeviceKind::kMouse; // kMouse支持鼠标框选文字 + pointerData.kind = PointerData::DeviceKind::kTouch; pointerData.buttons = getPointerButtonFromMouse(mouseEvent.button); // hover support if (mouseEvent.button == OH_NATIVEXCOMPONENT_NONE_BUTTON && pointerData.change == PointerData::Change::kMove) { diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index 6067b74b5d..0d1f936023 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -528,8 +528,7 @@ void XComponentBase::OnDispatchMouseWheelEvent(mouseWheelEvent event) } if (event.eventType == "actionUpdate") { OH_NativeXComponent_MouseEvent mouseEvent; - // 调整鼠标滚轮滚动时,列表滑动的方向。和Windows保持一致。 - double scrollY = g_scrollDistance - event.offsetY; + double scrollY = event.offsetY - g_scrollDistance; g_scrollDistance = event.offsetY; // fix resize ratio mouseEvent.x = event.globalX / g_resizeRate; -- Gitee From 4aad8ab5d5390f620b0e222f216d33feaf9c1060 Mon Sep 17 00:00:00 2001 From: zjxi Date: Thu, 26 Dec 2024 11:49:33 +0800 Subject: [PATCH 49/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8Dapp=E6=82=AC?= =?UTF-8?q?=E6=B5=AE=E7=AA=97=E6=A8=A1=E5=BC=8F=E9=A1=B6=E9=83=A8=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=A0=8F=E8=A7=84=E9=81=BF=E4=BA=8B=E4=BB=B6=E6=9C=AA?= =?UTF-8?q?=E7=94=9F=E6=95=88=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=AF=B9=E6=82=AC?= =?UTF-8?q?=E6=B5=AE=E7=AA=97=E6=A8=A1=E5=BC=8F=E7=9A=84=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../flutter/src/main/ets/view/FlutterView.ets | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index c11e307b96..afbb97ca41 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -501,7 +501,9 @@ export class FlutterView { } // 根据是否全屏显示,设置标题栏高度(若全屏,则及时规避) - if (this.checkFullScreen && (setFullScreen || this.mainWindow?.getWindowProperties().isLayoutFullScreen)) { // 全屏显示 + let isUseFullScreen = FlutterManager.getInstance().getFullScreenListener().useFullScreen(); + let isLayoutFullScreen = this.mainWindow?.getWindowProperties().isLayoutFullScreen; + if (this.checkFullScreen && (setFullScreen || isLayoutFullScreen || isUseFullScreen)) { // 全屏显示 this.viewportMetrics.physicalViewPaddingTop = this.systemAvoidArea?.topRect.height ?? this.viewportMetrics.physicalViewPaddingTop; this.viewportMetrics.physicalViewPaddingBottom = -- Gitee From 92473e98e7ee0bade0402251d03d68579f455e48 Mon Sep 17 00:00:00 2001 From: zjxi Date: Sat, 28 Dec 2024 18:26:07 +0800 Subject: [PATCH 50/60] =?UTF-8?q?refactor:=E5=87=8F=E5=B0=91xcomponent?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E6=97=B6=E5=8D=B3=E8=8E=B7=E5=8F=96=E6=97=A0?= =?UTF-8?q?=E9=9A=9C=E7=A2=8D=E6=A1=A5=E6=8E=A5=E5=8D=95=E4=BE=8B=E7=B1=BB?= =?UTF-8?q?=E7=9A=84=E9=A2=9D=E5=A4=96=E5=BC=80=E9=94=80=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=9E=84=E9=80=A0=E5=87=BD=E6=95=B0=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E5=88=97=E8=A1=A8=E8=BF=9B=E8=A1=8C=E6=88=90=E5=91=98?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../accessibility/ohos_accessibility_bridge.cpp | 9 +++++++-- .../ohos/accessibility/ohos_accessibility_bridge.h | 6 +++--- .../platform/ohos/napi/platform_view_ohos_napi.cpp | 7 ++----- shell/platform/ohos/ohos_xcomponent_adapter.cpp | 13 +++++-------- shell/platform/ohos/ohos_xcomponent_adapter.h | 1 + 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 27ce3230a4..b3a8116f59 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -23,6 +23,7 @@ #include "flutter/shell/platform/ohos/ohos_shell_holder.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkScalar.h" +#include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" namespace flutter { @@ -42,6 +43,9 @@ OhosAccessibilityBridge* OhosAccessibilityBridge::GetInstance() return bridgeInstance_.get(); } +OhosAccessibilityBridge::OhosAccessibilityBridge() + : isFlutterNavigated_(false), provider_(nullptr) {} + /** * 监听当前ohos平台是否开启无障碍屏幕朗读服务 */ @@ -50,6 +54,7 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( bool ohosAccessibilityEnabled) { native_shell_holder_id_ = shellHolderId; + provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; nativeAccessibilityChannel_ = std::make_shared(); accessibilityFeatures_ = std::make_shared(); @@ -79,12 +84,12 @@ void OhosAccessibilityBridge::UpdateSemantics( std::vector updatedFlutterNodes; // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) - if (IS_FLUTTER_NAVIGATE) { + if (isFlutterNavigated_) { Flutter_SendAccessibilityAsyncEvent(0, ArkUI_AccessibilityEventType:: ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); RequestFocusWhenPageUpdate(0); - IS_FLUTTER_NAVIGATE = false; + isFlutterNavigated_ = false; } /** 获取并分析每个语义节点的更新属性 */ diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 257adf502f..98dc4dd93e 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -78,9 +78,9 @@ public: OhosAccessibilityBridge(const OhosAccessibilityBridge&) = delete; OhosAccessibilityBridge& operator=(const OhosAccessibilityBridge&) = delete; - bool IS_FLUTTER_NAVIGATE = false; + bool isFlutterNavigated_; int64_t native_shell_holder_id_; - ArkUI_AccessibilityProvider* provider_ = nullptr; + ArkUI_AccessibilityProvider* provider_; void OnOhosAccessibilityStateChange( int64_t shellHolderId, @@ -157,7 +157,7 @@ public: void ClearFlutterSemanticsCaches(); private: - OhosAccessibilityBridge() = default; + OhosAccessibilityBridge(); bool isAccessibilityEnabled_ = false; static std::unique_ptr bridgeInstance_; std::shared_ptr nativeAccessibilityChannel_; diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 33535deff8..1fc61d507a 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -1872,10 +1872,8 @@ napi_value PlatformViewOHOSNapi::nativeAccessibilityStateChange( (state ? "true" : "false")); //send to accessibility bridge - const int32_t OHOS_API_VERSION = OH_GetSdkApiVersion(); if (OHOS_API_VERSION >= 13) { - auto a11y_bridge = OhosAccessibilityBridge::GetInstance(); - a11y_bridge->OnOhosAccessibilityStateChange(shell_holder_id, state); + OhosAccessibilityBridge::GetInstance()->OnOhosAccessibilityStateChange(shell_holder_id, state); } FML_DLOG(INFO) << "nativeAccessibilityStateChange: state=" << state << " shell_holder_id=" << shell_holder_id; @@ -2169,8 +2167,7 @@ napi_value PlatformViewOHOSNapi::nativeGetFlutterNavigationAction(napi_env env, return nullptr; } - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); - ohosAccessibilityBridge->IS_FLUTTER_NAVIGATE = isNavigate; + OhosAccessibilityBridge::GetInstance()->isFlutterNavigated_ = isNavigate; FML_DLOG(INFO) << "PlatformViewOHOSNapi::nativeGetFlutterNavigationAction -> "<provider_ = accessibilityProvider; - + XComponentAdapter::GetInstance()->accessibilityProvider_ = a11yProvider; LOGI("XComponentBase::SetNativeXComponent OH_ArkUI_AccessibilityProviderRegisterCallback is succeed"); } @@ -404,7 +401,7 @@ void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ BindXComponentCallback(); OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent_, &mouseCallback_); - // 注册ArkUI无障碍服务 + // register the OH_ArkUI accessibility callbacks RegisterArkUIAccessibilityService(nativeXComponent_); } } diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.h b/shell/platform/ohos/ohos_xcomponent_adapter.h index cf370fa62c..24fd7b0e7e 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.h +++ b/shell/platform/ohos/ohos_xcomponent_adapter.h @@ -84,6 +84,7 @@ class XComponentAdapter { public: std::map xcomponetMap_; + ArkUI_AccessibilityProvider* accessibilityProvider_; private: static XComponentAdapter mXComponentAdapter; -- Gitee From 8c9d2a127c3e644ca1853fe5c1625214e83bd44d Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 30 Dec 2024 19:35:44 +0800 Subject: [PATCH 51/60] =?UTF-8?q?refactor:=E5=88=A0=E5=87=8F=E5=86=97?= =?UTF-8?q?=E4=BD=99=E4=BB=A3=E7=A0=81,=E4=BC=98=E5=8C=96=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E6=96=B9=E6=B3=95=E6=89=A7=E8=A1=8C=E6=95=88=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../native_accessibility_channel.cpp | 15 ++-- .../ohos_accessibility_bridge.cpp | 79 ++++++++----------- 2 files changed, 36 insertions(+), 58 deletions(-) diff --git a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp index d93a12e20e..b772ab6603 100644 --- a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp +++ b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp @@ -83,8 +83,7 @@ namespace flutter { flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) { - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); - ohos_a11y_bridge->UpdateSemantics(update, actions); + OhosAccessibilityBridge::GetInstance()->UpdateSemantics(update, actions); } /** @@ -102,8 +101,7 @@ namespace flutter { void NativeAccessibilityChannel::AccessibilityMessageHandler::Announce( std::unique_ptr& message) { - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); - ohos_a11y_bridge->Announce(message); + OhosAccessibilityBridge::GetInstance()->Announce(message); } /** @@ -112,8 +110,7 @@ namespace flutter { void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTap( int32_t nodeId) { - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); - ohos_a11y_bridge->OnTap(nodeId); + OhosAccessibilityBridge::GetInstance()->OnTap(nodeId); } /** @@ -122,8 +119,7 @@ namespace flutter { void NativeAccessibilityChannel::AccessibilityMessageHandler::OnLongPress( int32_t nodeId) { - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); - ohos_a11y_bridge->OnLongPress(nodeId); + OhosAccessibilityBridge::GetInstance()->OnLongPress(nodeId); } /** @@ -132,7 +128,6 @@ namespace flutter { void NativeAccessibilityChannel::AccessibilityMessageHandler::OnTooltip( std::unique_ptr& message) { - auto ohos_a11y_bridge = OhosAccessibilityBridge::GetInstance(); - ohos_a11y_bridge->OnTooltip(message); + OhosAccessibilityBridge::GetInstance()->OnTooltip(message); } } \ No newline at end of file diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index b3a8116f59..e6909b5f99 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -93,7 +93,7 @@ void OhosAccessibilityBridge::UpdateSemantics( } /** 获取并分析每个语义节点的更新属性 */ - for (auto& item : update) { + for (const auto& item : update) { // 获取当前更新的节点node const auto& node = item.second; @@ -464,24 +464,18 @@ std::pair OhosAccessibilityBridge::GetRealScaleFactor() } /** - * flutter无障碍语义树的子节点相对坐标系转化为屏幕绝对坐标的映射算法 - * 目前暂未考虑旋转、透视场景,不影响屏幕朗读功能 + * flutter语义树中相对坐标系转化为屏幕绝对坐标的映射算法实现 + * NOTE:目前暂未考虑旋转、透视场景,不影响屏幕朗读功能 + * (SkMatrix::kMSkewX, SkMatrix::kMSkewY, SkMatrix::kMPersp0, + * SkMatrix::kMPersp1, SkMatrix::kMPersp2) */ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( SemanticsNodeExtent currNode) { // 获取当前flutter节点的相对rect - auto currLeft = static_cast(currNode.rect.fLeft); - auto currTop = static_cast(currNode.rect.fTop); - auto currRight = static_cast(currNode.rect.fRight); - auto currBottom = static_cast(currNode.rect.fBottom); + auto [currLeft, currTop, currRight, currBottom] = currNode.rect; - /** - * 获取当前flutter节点的缩放、平移、透视等矩阵坐标转换 - * 以下矩阵坐标变换参数(如:旋转/错切、透视)场景目前暂不考虑 - * NOTE: SkMatrix::kMSkewX, SkMatrix::kMSkewY, - * SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 - */ + // 获取当前flutter节点的缩放、平移、透视等矩阵坐标转换以下矩阵坐标变换参数 SkMatrix transform = currNode.transform.asM33(); auto _kMScaleX = transform.get(SkMatrix::kMScaleX); auto _kMTransX = transform.get(SkMatrix::kMTransX); @@ -491,7 +485,7 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( // 获取当前flutter节点的父节点的相对rect int32_t parentId = GetParentId(currNode.id); auto parentNode = GetFlutterSemanticsNode(parentId); - if (!g_flutterSemanticsTree.count(parentId)) { + if (g_flutterSemanticsTree.find(parentId) != g_flutterSemanticsTree.end()) { LOGE("FlutterRelativeRectToScreenRect: GetFlutterSemanticsNode id=%{public}d null", parentId); } @@ -507,41 +501,30 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( // 获取真实缩放系数 auto [realScaleXFactor, realScaleYFactor] = GetRealScaleFactor(); - // 更新后的节点屏幕坐标 - float newLeft = 0.0; - float newTop = 0.0; - float newRight = 0.0; - float newBottom = 0.0; - - if (_kMScaleX > 1 && _kMScaleY > 1) { - // 子节点相对父节点进行变化(缩放、 平移) - newLeft = currLeft + _kMTransX * _kMScaleX; - newTop = currTop + _kMTransY * _kMScaleY; - newRight = currRight * _kMScaleX; - newBottom = currBottom * _kMScaleY; - // 更新当前flutter节点currNode的相对坐标 -> 屏幕绝对坐标 - SetAbsoluteScreenRect(currNode, newLeft, newTop, newRight, newBottom); + // 更新后的节点屏幕坐标,子节点的屏幕绝对坐标转换,包括offset偏移值计算、缩放系数变换 + bool isRectScaleChanged = _kMScaleX > 1 && _kMScaleY > 1; + float newLeft = isRectScaleChanged ? + currLeft + _kMTransX * _kMScaleX : (currLeft + _kMTransX) * realScaleXFactor + realParentLeft; + float newTop = isRectScaleChanged ? + currTop + _kMTransY * _kMScaleY : (currTop + _kMTransY) * realScaleYFactor + realParentTop; + float newRight = isRectScaleChanged ? + currRight * _kMScaleX : newLeft + currRight * realScaleXFactor; + float newBottom = isRectScaleChanged ? + currBottom * _kMScaleY : newTop + currBottom * realScaleYFactor; + + // 若子节点rect超过父节点则跳过显示(单个屏幕显示不下,滑动再重新显示) + const bool isExceedScreeArea = newLeft < realParentLeft || newTop < realParentTop || + newRight > realParentRight || newBottom > realParentBottom || + newLeft >= newRight || newTop >= newBottom || + newRight > rootWidth || newBottom > rootHeight; + if (isExceedScreeArea) { + FML_DLOG(WARNING) << "RelativeRectToScreenRect -> childRect exceeds parentRect {Id: " + << currNode.id << ", (" << newLeft << ", " << newTop + << ", " << newRight << ", " << newBottom << ")}"; + // 防止滑动场景下绿框坐标超出屏幕范围,进行正则化处理 + SetAbsoluteScreenRect(currNode, rootWidth, rootHeight, 0, 0); } else { - // 子节点的屏幕绝对坐标转换,包括offset偏移值计算、缩放系数变换 - newLeft = (currLeft + _kMTransX) * realScaleXFactor + realParentLeft; - newTop = (currTop + _kMTransY) * realScaleYFactor + realParentTop; - newRight = newLeft + currRight * realScaleXFactor; - newBottom = newTop + currBottom * realScaleYFactor; - - // 若子节点rect超过父节点则跳过显示(单个屏幕显示不下,滑动再重新显示) - const bool IS_OVER_SCREEN_AREA = newLeft < realParentLeft || newTop < realParentTop || - newRight > realParentRight || newBottom > realParentBottom || - newLeft >= newRight || newTop >= newBottom || - newRight > rootWidth || newBottom > rootHeight; - if (IS_OVER_SCREEN_AREA) { - FML_DLOG(WARNING) << "RelativeRectToScreenRect -> childRect exceeds parentRect {Id: " - << currNode.id << ", (" << newLeft << ", " << newTop - << ", " << newRight << ", " << newBottom << ")}"; - // 防止滑动场景下绿框坐标超出屏幕范围,进行正则化处理 - SetAbsoluteScreenRect(currNode, rootWidth, rootHeight, 0, 0); - } else { - SetAbsoluteScreenRect(currNode, newLeft, newTop, newRight, newBottom); - } + SetAbsoluteScreenRect(currNode, newLeft, newTop, newRight, newBottom); } } -- Gitee From 0aa2bbe313733d0a3fed63d74a174cef80fc21ac Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 31 Dec 2024 19:27:00 +0800 Subject: [PATCH 52/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E5=BC=80=E5=90=AF?= =?UTF-8?q?=E6=97=A0=E9=9A=9C=E7=A2=8D=E6=9C=8D=E5=8A=A1=E5=86=8D=E5=86=B7?= =?UTF-8?q?=E5=90=AF=E5=8A=A8app=E9=80=A0=E6=88=90=E7=9A=84=E5=85=88?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E5=86=8D=E6=B3=A8=E5=86=8C=E7=9A=84bug?= =?UTF-8?q?=EF=BC=8C=E5=AF=BC=E8=87=B4=E6=97=A0=E9=9A=9C=E7=A2=8D=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=B8=AD=E4=BA=8B=E4=BB=B6=E5=8F=91=E9=80=81=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E7=9A=84provider=E6=8C=87=E9=92=88=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 17 +++++++++--- .../accessibility/ohos_accessibility_bridge.h | 2 +- .../ets/embedding/ohos/FlutterAbility.ets | 8 ------ .../main/ets/embedding/ohos/FlutterPage.ets | 2 ++ .../flutter/src/main/ets/view/FlutterView.ets | 10 +++++++ .../platform/ohos/ohos_xcomponent_adapter.cpp | 26 ++++++++----------- shell/platform/ohos/ohos_xcomponent_adapter.h | 1 - 7 files changed, 37 insertions(+), 29 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index e6909b5f99..d173fdba5c 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -44,7 +44,7 @@ OhosAccessibilityBridge* OhosAccessibilityBridge::GetInstance() } OhosAccessibilityBridge::OhosAccessibilityBridge() - : isFlutterNavigated_(false), provider_(nullptr) {} + : isFlutterNavigated_(false), provider_(nullptr), isAccessibilityEnabled_(false) {} /** * 监听当前ohos平台是否开启无障碍屏幕朗读服务 @@ -274,7 +274,10 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) { if (OHOS_API_VERSION < 13) { return; } CHECK_NULL_PTR(provider_, RequestFocusWhenPageUpdate); - + if (provider_ == nullptr) { + return; + } + auto OH_ArkUI_CreateAccessibilityEventInfo = OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); @@ -485,7 +488,7 @@ void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( // 获取当前flutter节点的父节点的相对rect int32_t parentId = GetParentId(currNode.id); auto parentNode = GetFlutterSemanticsNode(parentId); - if (g_flutterSemanticsTree.find(parentId) != g_flutterSemanticsTree.end()) { + if (g_flutterSemanticsTree.find(parentId) == g_flutterSemanticsTree.end()) { LOGE("FlutterRelativeRectToScreenRect: GetFlutterSemanticsNode id=%{public}d null", parentId); } @@ -1568,7 +1571,12 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAnnounceEvent( std::unique_ptr& message, ArkUI_AccessibilityEventType eventType) { - // 创建并设置屏幕朗读事件 + if (OHOS_API_VERSION < 13) { return; } + + CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAnnounceEvent); + if (provider_ == nullptr) { return; } + + // 创建并设置屏幕朗读事件 auto OH_ArkUI_CreateAccessibilityEventInfo = OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityEventInfo); @@ -1616,6 +1624,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( if (OHOS_API_VERSION < 13) { return; } CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAsyncEvent); + if (provider_ == nullptr) { return; } // 创建eventInfo对象 auto OH_ArkUI_CreateAccessibilityEventInfo = diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index 98dc4dd93e..d3ae2d4bf2 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -158,7 +158,7 @@ public: private: OhosAccessibilityBridge(); - bool isAccessibilityEnabled_ = false; + bool isAccessibilityEnabled_; static std::unique_ptr bridgeInstance_; std::shared_ptr nativeAccessibilityChannel_; std::shared_ptr accessibilityFeatures_; diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets index 9eb08c3d5e..00bd702866 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets @@ -36,7 +36,6 @@ import appRecovery from '@ohos.app.ability.appRecovery'; import FlutterManager from './FlutterManager'; import { FlutterView } from '../../view/FlutterView'; import ApplicationInfoLoader from '../engine/loader/ApplicationInfoLoader'; -import { accessibility } from '@kit.AccessibilityKit'; import { AccessibilityManager } from '../../view/AccessibilityBridge'; const TAG = "FlutterAbility"; @@ -107,13 +106,6 @@ export class FlutterAbility extends UIAbility implements Host { if (flutterApplicationInfo.isDebugMode) { this.delegate?.initWindow(); } - - //冷启动对os是否开启无障碍服务进行查询 - let accessibilityState: boolean = accessibility.isOpenAccessibilitySync(); - if(accessibilityState) { - this.delegate?.getFlutterNapi()?.accessibilityStateChange(accessibilityState); - } - Log.i(TAG, `accessibility isOpen state -> ${JSON.stringify(accessibilityState)}`); } onDestroy() { diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets index f5f641c4ec..533e1e6a51 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets @@ -56,6 +56,7 @@ export struct FlutterPage { .onLoad((context) => { this.flutterView?.onSurfaceCreated() Log.d(TAG, "XComponent onLoad "); + this.flutterView?.onAccessibilityIsOpen() }) .onDestroy(() => { Log.d(TAG, "XComponent onDestroy "); @@ -135,6 +136,7 @@ export struct FlutterPage { .onLoad((context) => { this.flutterView?.onSurfaceCreated() Log.d(TAG, "XComponent onLoad "); + this.flutterView?.onAccessibilityIsOpen() }) .onDestroy(() => { Log.d(TAG, "XComponent onDestroy "); diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index afbb97ca41..f6b9d9b7b7 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -492,6 +492,16 @@ export class FlutterView { } } + onAccessibilityIsOpen() { + Log.i(TAG, `accessibility isOpen state -> 1`); + let accessibilityState: boolean = accessibility.isOpenAccessibilitySync(); + if(accessibilityState) { + Log.i(TAG, `accessibility isOpen state -> 2`); + this.flutterEngine?.getFlutterNapi()?.accessibilityStateChange(accessibilityState) + } + Log.i(TAG, `accessibility isOpen state -> ${JSON.stringify(accessibilityState)}`); + } + onAreaChange(newArea: Area | null, setFullScreen: boolean = false) { const originalMetrics = this.viewportMetrics.clone(); diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index b538a7c47a..8490fd1ade 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -18,6 +18,7 @@ #include "types.h" #include "ohos_logging.h" #include +#include "flutter/fml/logging.h" namespace flutter { @@ -247,9 +248,8 @@ int32_t FindAccessibilityNodeInfosById( int32_t requestId, ArkUI_AccessibilityElementInfoList* elementList) { - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); - ohosAccessibilityBridge->FindAccessibilityNodeInfosById(elementId, mode, requestId, elementList); - LOGD("accessibilityProviderCallback_.FindAccessibilityNodeInfosById"); + OhosAccessibilityBridge::GetInstance()->FindAccessibilityNodeInfosById(elementId, mode, requestId, elementList); + FML_DLOG(INFO) << "accessibilityProviderCallback_.FindAccessibilityNodeInfosById"; return 0; } @@ -260,8 +260,7 @@ int32_t FindAccessibilityNodeInfosByText( int32_t requestId, ArkUI_AccessibilityElementInfoList* elementList) { - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); - ohosAccessibilityBridge->FindAccessibilityNodeInfosByText(elementId, text, requestId, elementList); + OhosAccessibilityBridge::GetInstance()->FindAccessibilityNodeInfosByText(elementId, text, requestId, elementList); LOGD("accessibilityProviderCallback_.FindAccessibilityNodeInfosByText"); return 0; } @@ -273,8 +272,7 @@ int32_t FindFocusedAccessibilityNode( int32_t requestId, ArkUI_AccessibilityElementInfo* elementinfo) { - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); - ohosAccessibilityBridge->FindFocusedAccessibilityNode(elementId, focusType, requestId, elementinfo); + OhosAccessibilityBridge::GetInstance()->FindFocusedAccessibilityNode(elementId, focusType, requestId, elementinfo); LOGD("accessibilityProviderCallback_.FindFocusedAccessibilityNode"); return 0; } @@ -286,8 +284,7 @@ int32_t FindNextFocusAccessibilityNode( int32_t requestId, ArkUI_AccessibilityElementInfo *elementList) { - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); - ohosAccessibilityBridge->FindNextFocusAccessibilityNode(elementId, direction, requestId, elementList); + OhosAccessibilityBridge::GetInstance()->FindNextFocusAccessibilityNode(elementId, direction, requestId, elementList); LOGD("accessibilityProviderCallback_.FindNextFocusAccessibilityNode"); return 0; } @@ -299,8 +296,7 @@ int32_t ExecuteAccessibilityAction( ArkUI_AccessibilityActionArguments* actionArguments, int32_t requestId) { - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); - ohosAccessibilityBridge->ExecuteAccessibilityAction(elementId, action, actionArguments, requestId); + OhosAccessibilityBridge::GetInstance()->ExecuteAccessibilityAction(elementId, action, actionArguments, requestId); LOGD("accessibilityProviderCallback_.ExecuteAccessibilityAction"); return 0; } @@ -318,8 +314,7 @@ int32_t GetAccessibilityNodeCursorPosition( int32_t requestId, int32_t* index) { - auto ohosAccessibilityBridge = OhosAccessibilityBridge::GetInstance(); - ohosAccessibilityBridge->GetAccessibilityNodeCursorPosition(elementId, requestId, index); + OhosAccessibilityBridge::GetInstance()->GetAccessibilityNodeCursorPosition(elementId, requestId, index); LOGD("accessibilityProviderCallback_.GetAccessibilityNodeCursorPosition"); return 0; } @@ -373,12 +368,12 @@ void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nati { if (OH_GetSdkApiVersion() < 13) { return; } LOGD("api version: %{public}d", OH_GetSdkApiVersion()); + 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) @@ -387,12 +382,13 @@ void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nati auto OH_ArkUI_AccessibilityProviderRegisterCallback = OhosAccessibilityDDL::DLLoadRegisterFunc(ArkUIAccessibilityConstant::ARKUI_REGISTER_CALLBACK); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityProviderRegisterCallback); + CHECK_NULL_PTR(a11yProvider, RegisterArkUIAccessibilityService); ARKUI_ACCESSIBILITY_CALL_CHECK( OH_ArkUI_AccessibilityProviderRegisterCallback(a11yProvider, &accessibilityProviderCallback_) ); XComponentAdapter::GetInstance()->accessibilityProvider_ = a11yProvider; - LOGI("XComponentBase::SetNativeXComponent OH_ArkUI_AccessibilityProviderRegisterCallback is succeed"); + FML_DLOG(INFO) << "RegisterArkUIAccessibilityService is finished"; } void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.h b/shell/platform/ohos/ohos_xcomponent_adapter.h index 24fd7b0e7e..529a1d226b 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.h +++ b/shell/platform/ohos/ohos_xcomponent_adapter.h @@ -26,7 +26,6 @@ #include "napi_common.h" #include "flutter/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h" #include "flutter/shell/platform/ohos/utils/ddl_utils.h" - namespace flutter { class XComponentBase -- Gitee From 04a209ae64118572a59309c650e8877be7c8236a Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 31 Dec 2024 19:34:15 +0800 Subject: [PATCH 53/60] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../flutter_embedding/flutter/src/main/ets/view/FlutterView.ets | 2 -- 1 file changed, 2 deletions(-) diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index f6b9d9b7b7..c38327f4fb 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -493,10 +493,8 @@ export class FlutterView { } onAccessibilityIsOpen() { - Log.i(TAG, `accessibility isOpen state -> 1`); let accessibilityState: boolean = accessibility.isOpenAccessibilitySync(); if(accessibilityState) { - Log.i(TAG, `accessibility isOpen state -> 2`); this.flutterEngine?.getFlutterNapi()?.accessibilityStateChange(accessibilityState) } Log.i(TAG, `accessibility isOpen state -> ${JSON.stringify(accessibilityState)}`); -- Gitee From 01aa727096d2ce31aafffa5a6b7a0dd21dc390d9 Mon Sep 17 00:00:00 2001 From: zjxi Date: Thu, 2 Jan 2025 20:41:34 +0800 Subject: [PATCH 54/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8Dxcomponent=E9=94=80?= =?UTF-8?q?=E6=AF=81=E6=97=B6=E5=8F=8A=E6=97=B6=E5=9C=A8onSurfaceDestroy()?= =?UTF-8?q?=E9=87=8C=E5=AF=B9=E6=97=A0=E9=9A=9C=E7=A2=8Dprovider=E8=B5=8B?= =?UTF-8?q?=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 26 ++++++++++++------- .../platform/ohos/ohos_xcomponent_adapter.cpp | 2 ++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index d173fdba5c..d22b4be20c 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -44,7 +44,9 @@ OhosAccessibilityBridge* OhosAccessibilityBridge::GetInstance() } OhosAccessibilityBridge::OhosAccessibilityBridge() - : isFlutterNavigated_(false), provider_(nullptr), isAccessibilityEnabled_(false) {} + : isFlutterNavigated_(false), + provider_(nullptr), + isAccessibilityEnabled_(false) {} /** * 监听当前ohos平台是否开启无障碍屏幕朗读服务 @@ -81,15 +83,17 @@ void OhosAccessibilityBridge::UpdateSemantics( flutter::CustomAccessibilityActionUpdates actions) { FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics()"; + provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + std::vector updatedFlutterNodes; // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) if (isFlutterNavigated_) { - Flutter_SendAccessibilityAsyncEvent(0, - ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); - RequestFocusWhenPageUpdate(0); - isFlutterNavigated_ = false; + Flutter_SendAccessibilityAsyncEvent(0, + ArkUI_AccessibilityEventType:: + ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); + RequestFocusWhenPageUpdate(0); + isFlutterNavigated_ = false; } /** 获取并分析每个语义节点的更新属性 */ @@ -274,9 +278,7 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) { if (OHOS_API_VERSION < 13) { return; } CHECK_NULL_PTR(provider_, RequestFocusWhenPageUpdate); - if (provider_ == nullptr) { - return; - } + if (provider_ == nullptr) { return; } auto OH_ArkUI_CreateAccessibilityEventInfo = OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); @@ -1377,6 +1379,8 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( << " *actionArguments=" << actionArguments; CHECK_NULL_PTR_WITH_RET(actionArguments, ExecuteAccessibilityAction); + provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + // 获取当前elementid对应的flutter语义节点 auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); if (!g_flutterSemanticsTree.count(flutterNode.id)) { @@ -1572,7 +1576,8 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAnnounceEvent( ArkUI_AccessibilityEventType eventType) { if (OHOS_API_VERSION < 13) { return; } - + + provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAnnounceEvent); if (provider_ == nullptr) { return; } @@ -1623,6 +1628,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( { if (OHOS_API_VERSION < 13) { return; } + provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAsyncEvent); if (provider_ == nullptr) { return; } diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index 8490fd1ade..e5d0395b6c 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -388,6 +388,7 @@ void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nati ); XComponentAdapter::GetInstance()->accessibilityProvider_ = a11yProvider; + FML_DLOG(INFO) << "RegisterArkUIAccessibilityService is finished"; } @@ -455,6 +456,7 @@ void XComponentBase::OnSurfaceChanged(OH_NativeXComponent* component, void* wind void XComponentBase::OnSurfaceDestroyed(OH_NativeXComponent* component, void* window) { window_ = nullptr; + XComponentAdapter::GetInstance()->accessibilityProvider_ = nullptr; LOGD("XComponentManger::OnSurfaceDestroyed"); if (isEngineAttached_) { PlatformViewOHOSNapi::SurfaceDestroyed(std::stoll(shellholderId_)); -- Gitee From b549660cd7ab2e7375773ccb59e63d6e36cb569c Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 6 Jan 2025 11:34:06 +0800 Subject: [PATCH 55/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E6=97=A0=E9=9A=9C?= =?UTF-8?q?=E7=A2=8Dxcomponent=E5=A4=9A=E5=AE=9E=E4=BE=8B=E9=97=AA?= =?UTF-8?q?=E9=80=80bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../native_accessibility_channel.cpp | 2 +- .../ohos_accessibility_bridge.cpp | 34 +++++++------------ .../accessibility/ohos_accessibility_bridge.h | 11 +++--- .../ohos/napi/platform_view_ohos_napi.cpp | 20 +++++------ .../platform/ohos/ohos_xcomponent_adapter.cpp | 8 ++--- shell/platform/ohos/ohos_xcomponent_adapter.h | 2 ++ shell/platform/ohos/platform_view_ohos.cpp | 8 +++-- 7 files changed, 40 insertions(+), 45 deletions(-) diff --git a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp index b772ab6603..7d571f3528 100644 --- a/shell/platform/ohos/accessibility/native_accessibility_channel.cpp +++ b/shell/platform/ohos/accessibility/native_accessibility_channel.cpp @@ -73,7 +73,7 @@ namespace flutter { { auto ohos_shell_holder = reinterpret_cast(shellHolderId); - ohos_shell_holder->GetPlatformView()->PlatformView::DispatchSemanticsAction(id, action, fml::MallocMapping()); + ohos_shell_holder->GetPlatformView()->PlatformView::DispatchSemanticsAction(id, action, std::move(args)); } /** diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index d22b4be20c..1a79f88257 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -44,18 +44,16 @@ OhosAccessibilityBridge* OhosAccessibilityBridge::GetInstance() } OhosAccessibilityBridge::OhosAccessibilityBridge() - : isFlutterNavigated_(false), - provider_(nullptr), + : isFlutterNavigated_(false), provider_(nullptr), isAccessibilityEnabled_(false) {} /** * 监听当前ohos平台是否开启无障碍屏幕朗读服务 */ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( - int64_t shellHolderId, - bool ohosAccessibilityEnabled) + bool ohosAccessibilityEnabled, int64_t shellholderId) { - native_shell_holder_id_ = shellHolderId; + native_shell_holder_id_ = shellholderId; provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; nativeAccessibilityChannel_ = std::make_shared(); accessibilityFeatures_ = std::make_shared(); @@ -80,11 +78,10 @@ void OhosAccessibilityBridge::SetNativeShellHolderId(int64_t id) */ void OhosAccessibilityBridge::UpdateSemantics( flutter::SemanticsNodeUpdates update, - flutter::CustomAccessibilityActionUpdates actions) + flutter::CustomAccessibilityActionUpdates action) { FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics()"; provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; - std::vector updatedFlutterNodes; // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) @@ -108,11 +105,7 @@ void OhosAccessibilityBridge::UpdateSemantics( GetSemanticsNodeDebugInfo(nodeEx); GetSemanticsFlagsDebugInfo(nodeEx); - /** - * 构建flutter无障碍语义节点树 - * NOTE: 若使用g_flutterSemanticsTree.insert({node.id, node})方式 - * 来添加新增的语义节点会导致已有key值自动忽略,不会更新原有key对应的value - */ + // 构建flutter无障碍语义节点树 g_flutterSemanticsTree[nodeEx.id] = nodeEx; // 若当前节点为获焦 @@ -277,6 +270,7 @@ void OhosAccessibilityBridge::FlutterScrollExecution( void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) { if (OHOS_API_VERSION < 13) { return; } + provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; CHECK_NULL_PTR(provider_, RequestFocusWhenPageUpdate); if (provider_ == nullptr) { return; } @@ -967,6 +961,8 @@ void OhosAccessibilityBridge::BuildArkUISemanticsTree( //配置当前子节点信息 FlutterSetElementInfoProperties(newElementInfo, levelOrderId); } + // 对于不同xcomponent窗口添加不同的屏幕坐标映射map + // g_xcomponentScreenRectMaps[xcomponentId_] = g_screenRectMap; } /** @@ -982,8 +978,7 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( if (OHOS_API_VERSION < 13) { return ARKUI_FAILED_CODE; } FML_DLOG(INFO) << "#### FindAccessibilityNodeInfosById input-params ####: elementId = " - << elementId << " mode=" << mode << " requestId=" << requestId - << " elementList= " << elementList; + << elementId << " mode=" << mode; CHECK_NULL_PTR_WITH_RET(elementList, FindAccessibilityNodeInfosById); if (g_flutterSemanticsTree.size() == 0) { @@ -1035,6 +1030,7 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( FlutterSetElementInfoProperties(elementInfoFromList, elementId); } FML_DLOG(INFO) << "--- FindAccessibilityNodeInfosById is end ---"; + return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL; } @@ -1049,7 +1045,7 @@ void OhosAccessibilityBridge::DispatchSemanticsAction( nativeAccessibilityChannel_->DispatchSemanticsAction(native_shell_holder_id_, id, action, - fml::MallocMapping()); + std::move(args)); } /** @@ -1374,13 +1370,9 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( int32_t requestId) { FML_DLOG(INFO) << "ExecuteAccessibilityAction input-params-> elementId=" - << elementId << " action=" << action - << " requestId=" << requestId - << " *actionArguments=" << actionArguments; + << elementId << " action=" << action; CHECK_NULL_PTR_WITH_RET(actionArguments, ExecuteAccessibilityAction); - provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; - // 获取当前elementid对应的flutter语义节点 auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); if (!g_flutterSemanticsTree.count(flutterNode.id)) { @@ -1576,7 +1568,6 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAnnounceEvent( ArkUI_AccessibilityEventType eventType) { if (OHOS_API_VERSION < 13) { return; } - provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAnnounceEvent); if (provider_ == nullptr) { return; } @@ -1627,7 +1618,6 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( ArkUI_AccessibilityEventType eventType) { if (OHOS_API_VERSION < 13) { return; } - provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAsyncEvent); if (provider_ == nullptr) { return; } diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index d3ae2d4bf2..e77aa65426 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -82,9 +82,7 @@ public: int64_t native_shell_holder_id_; ArkUI_AccessibilityProvider* provider_; - void OnOhosAccessibilityStateChange( - int64_t shellHolderId, - bool ohosAccessibilityEnabled); + void OnOhosAccessibilityStateChange(bool ohosAccessibilityEnabled, int64_t shellholderId); void SetNativeShellHolderId(int64_t id); @@ -162,9 +160,13 @@ private: static std::unique_ptr bridgeInstance_; std::shared_ptr nativeAccessibilityChannel_; std::shared_ptr accessibilityFeatures_; + std::string xcomponentId_; + std::unordered_map> g_flutterXcomponentTrees; + std::unordered_map>> g_xcomponentParentChildMaps; + std::unordered_map> g_xcomponentScreenRectMaps; + std::unordered_map g_flutterSemanticsTree; std::vector> g_parentChildIdVec; - std::map g_flutterSemanticsTree; std::unordered_map g_screenRectMap; SemanticsNodeExtent inputFocusedNode; @@ -325,6 +327,7 @@ private: std::pair GetRealScaleFactor(); void DoubleClickRouteToNewPage(SemanticsNodeExtent node); void GetSemanticsDebugInfo(); + void AccessibiltiyChangesWithXComponentId(); }; enum class AccessibilityAction : int32_t { diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 1fc61d507a..d1bf9ed472 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -1850,14 +1850,14 @@ napi_value PlatformViewOHOSNapi::nativeAccessibilityStateChange( << ret; return nullptr; } - int64_t shell_holder_id; - ret = napi_get_value_int64(env, args[0], &shell_holder_id); + + int64_t shellHolder = 0; + ret = napi_get_value_int64(env, args[0], &shellHolder); if (ret != napi_ok) { - FML_DLOG(ERROR) << "PlatformViewOHOSNapi::nativeAccessibilityStateChange " - "napi_get_value_int64 error:" - << ret; + LOGE("nativeAccessibilityStateChange shellHolder napi_get_value_int64 error"); return nullptr; } + bool state = false; ret = napi_get_value_bool(env, args[1], &state); if (ret != napi_ok) { @@ -1866,17 +1866,13 @@ napi_value PlatformViewOHOSNapi::nativeAccessibilityStateChange( << ret; return nullptr; } - LOGD( - "PlatformViewOHOSNapi::nativeAccessibilityStateChange state is: " - "%{public}s", - (state ? "true" : "false")); + LOGD("PlatformViewOHOSNapi::nativeAccessibilityStateChange state is: " + "%{public}s, shellholderId: %{public}ld", (state ? "true" : "false"), shellHolder); //send to accessibility bridge if (OHOS_API_VERSION >= 13) { - OhosAccessibilityBridge::GetInstance()->OnOhosAccessibilityStateChange(shell_holder_id, state); + OhosAccessibilityBridge::GetInstance()->OnOhosAccessibilityStateChange(state, shellHolder); } - FML_DLOG(INFO) << "nativeAccessibilityStateChange: state=" << state - << " shell_holder_id=" << shell_holder_id; return nullptr; } diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index e5d0395b6c..424123a0c6 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -366,14 +366,12 @@ void XComponentBase::DetachFlutterEngine() { void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nativeXComponent) { - if (OH_GetSdkApiVersion() < 13) { return; } - LOGD("api version: %{public}d", OH_GetSdkApiVersion()); - 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) @@ -399,7 +397,9 @@ void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent_, &mouseCallback_); // register the OH_ArkUI accessibility callbacks - RegisterArkUIAccessibilityService(nativeXComponent_); + if (OH_GetSdkApiVersion() >= 13) { + RegisterArkUIAccessibilityService(nativeXComponent_); + } } } diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.h b/shell/platform/ohos/ohos_xcomponent_adapter.h index 529a1d226b..7698e3a8f2 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.h +++ b/shell/platform/ohos/ohos_xcomponent_adapter.h @@ -20,6 +20,7 @@ #include #include #include + #include "flutter/shell/platform/ohos/ohos_touch_processor.h" #include "flutter/shell/platform/ohos/napi/platform_view_ohos_napi.h" #include "napi/native_api.h" @@ -66,6 +67,7 @@ public: uint64_t width_; uint64_t height_; OhosTouchProcessor ohosTouchProcessor_; + ArkUI_AccessibilityProvider* accessibilityProvider_; }; diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index 2ba37590a3..96ccee9e41 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -27,6 +27,7 @@ #include "flutter/shell/platform/ohos/platform_view_ohos_delegate.h" #include + namespace flutter { OhosSurfaceFactoryImpl::OhosSurfaceFactoryImpl( @@ -297,9 +298,12 @@ void PlatformViewOHOS::UpdateAssetResolverByType( void PlatformViewOHOS::UpdateSemantics( flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) { + task_runners_.GetPlatformTaskRunner()->PostTask( + [update = std::move(update), actions = std::move(actions)]() { + auto nativeAccessibilityChannel_ = std::make_shared(); + nativeAccessibilityChannel_->UpdateSemantics(update, actions); + }); FML_DLOG(INFO) << "PlatformViewOHOS::UpdateSemantics is called"; - auto nativeAccessibilityChannel_ = std::make_shared(); - nativeAccessibilityChannel_->UpdateSemantics(update, actions); } // |PlatformView| -- Gitee From f4122f9f0369ad90175ed2d473bebb6dc26922ed Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 6 Jan 2025 12:14:02 +0800 Subject: [PATCH 56/60] =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=88=90=E5=91=98=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- shell/platform/ohos/accessibility/ohos_accessibility_bridge.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index e77aa65426..f4e03364ce 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -160,11 +160,7 @@ private: static std::unique_ptr bridgeInstance_; std::shared_ptr nativeAccessibilityChannel_; std::shared_ptr accessibilityFeatures_; - std::string xcomponentId_; - std::unordered_map> g_flutterXcomponentTrees; - std::unordered_map>> g_xcomponentParentChildMaps; - std::unordered_map> g_xcomponentScreenRectMaps; std::unordered_map g_flutterSemanticsTree; std::vector> g_parentChildIdVec; std::unordered_map g_screenRectMap; -- Gitee From eb8a8c02f319075a5902746ca6c9c793fcdf1591 Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 6 Jan 2025 14:13:59 +0800 Subject: [PATCH 57/60] =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=90=8D=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 1a79f88257..6ebdfa6bbc 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -78,7 +78,7 @@ void OhosAccessibilityBridge::SetNativeShellHolderId(int64_t id) */ void OhosAccessibilityBridge::UpdateSemantics( flutter::SemanticsNodeUpdates update, - flutter::CustomAccessibilityActionUpdates action) + flutter::CustomAccessibilityActionUpdates actions) { FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics()"; provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; -- Gitee From c55ac614128101faa9609b4c2108b95080ec3edf Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 6 Jan 2025 15:25:19 +0800 Subject: [PATCH 58/60] =?UTF-8?q?=E6=B6=88=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=A2=9E=E5=8A=A0=E8=BF=94=E5=9B=9E?= =?UTF-8?q?void=E7=9A=84=E7=A9=BA=E6=8C=87=E9=92=88=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E5=AE=8F=E5=87=BD=E6=95=B0?= 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 | 11 +++-------- shell/platform/ohos/platform_view_ohos.cpp | 2 +- shell/platform/ohos/utils/ddl_utils.h | 9 +++++++++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 6ebdfa6bbc..dbb1a076e9 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -271,8 +271,7 @@ void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) { if (OHOS_API_VERSION < 13) { return; } provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; - CHECK_NULL_PTR(provider_, RequestFocusWhenPageUpdate); - if (provider_ == nullptr) { return; } + CHECK_NULL_PTR_RET_VOID(provider_, RequestFocusWhenPageUpdate); auto OH_ArkUI_CreateAccessibilityEventInfo = OhosAccessibilityDDL::DLLoadCreateEventInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_EVENT); @@ -961,8 +960,6 @@ void OhosAccessibilityBridge::BuildArkUISemanticsTree( //配置当前子节点信息 FlutterSetElementInfoProperties(newElementInfo, levelOrderId); } - // 对于不同xcomponent窗口添加不同的屏幕坐标映射map - // g_xcomponentScreenRectMaps[xcomponentId_] = g_screenRectMap; } /** @@ -1569,8 +1566,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAnnounceEvent( { if (OHOS_API_VERSION < 13) { return; } provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; - CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAnnounceEvent); - if (provider_ == nullptr) { return; } + CHECK_NULL_PTR_RET_VOID(provider_, Flutter_SendAccessibilityAnnounceEvent); // 创建并设置屏幕朗读事件 auto OH_ArkUI_CreateAccessibilityEventInfo = @@ -1619,8 +1615,7 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( { if (OHOS_API_VERSION < 13) { return; } provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; - CHECK_NULL_PTR(provider_, Flutter_SendAccessibilityAsyncEvent); - if (provider_ == nullptr) { return; } + CHECK_NULL_PTR_RET_VOID(provider_, Flutter_SendAccessibilityAsyncEvent); // 创建eventInfo对象 auto OH_ArkUI_CreateAccessibilityEventInfo = diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index 96ccee9e41..6d860f66aa 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -302,8 +302,8 @@ void PlatformViewOHOS::UpdateSemantics( [update = std::move(update), actions = std::move(actions)]() { auto nativeAccessibilityChannel_ = std::make_shared(); nativeAccessibilityChannel_->UpdateSemantics(update, actions); + FML_DLOG(INFO) << "PlatformViewOHOS::UpdateSemantics is called"; }); - FML_DLOG(INFO) << "PlatformViewOHOS::UpdateSemantics is called"; } // |PlatformView| diff --git a/shell/platform/ohos/utils/ddl_utils.h b/shell/platform/ohos/utils/ddl_utils.h index 0e5eca65a8..60f89db6d3 100644 --- a/shell/platform/ohos/utils/ddl_utils.h +++ b/shell/platform/ohos/utils/ddl_utils.h @@ -62,4 +62,13 @@ using LIBHANDLE = void*; } \ } while (false) \ +#define CHECK_NULL_PTR_RET_VOID(PARAM, FUNC) \ + do { \ + if (PARAM == nullptr) { \ + LOGE("Error: %{public}s -> %{public}s is nullptr", \ + #FUNC, #PARAM); \ + return; \ + } \ + } while (false) \ + #endif // FOUNDATION_ACE_INTERFACE_INNERKITS_ACE_UTILS_H -- Gitee From 341de6adc4da4ea8bba55a7f40ef97bac4f2d278 Mon Sep 17 00:00:00 2001 From: zjxi Date: Tue, 7 Jan 2025 15:02:36 +0800 Subject: [PATCH 59/60] =?UTF-8?q?fix:=E6=97=A0=E9=9A=9C=E7=A2=8D=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=A4=9Axcomponent=E5=9C=BA=E6=99=AF=EF=BC=8C?= =?UTF-8?q?=E4=BD=86=E4=BC=9A=E5=81=B6=E7=8E=B0=E9=87=8E=E6=8C=87=E9=92=88?= =?UTF-8?q?=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 53 +++++++++++++++++-- .../accessibility/ohos_accessibility_bridge.h | 5 ++ .../src/main/cpp/types/libflutter/index.d.ets | 4 +- .../main/ets/embedding/ohos/FlutterPage.ets | 30 +++++++++-- shell/platform/ohos/library_loader.cpp | 3 ++ .../ohos/napi/platform_view_ohos_napi.cpp | 19 +++++++ .../ohos/napi/platform_view_ohos_napi.h | 4 ++ .../platform/ohos/ohos_xcomponent_adapter.cpp | 23 +++++--- shell/platform/ohos/ohos_xcomponent_adapter.h | 6 +-- 9 files changed, 127 insertions(+), 20 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index dbb1a076e9..09bbe8cece 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -31,6 +31,37 @@ const int32_t OhosAccessibilityBridge::OHOS_API_VERSION = OH_GetSdkApiVersion(); std::unique_ptr OhosAccessibilityBridge::bridgeInstance_ = nullptr; +/** + * flutter无障碍相关语义树、句柄指针provider等参数 + * 跟随xcomponentid显示切换,而加载对应xcomponent的语义树和provider指针 + * @NOTE: 当屏幕同时显示多个xcomponent时,无法通过聚焦事件而触发xcomponentid改变 + */ +void OhosAccessibilityBridge::AccessibiltiyChangesWithXComponentId() +{ + auto xcompMap = XComponentAdapter::GetInstance()->xcomponetMap_; + // 获取当前显示的xcomponetid + std::string currXcompId = XComponentAdapter::GetInstance()->currentXComponentId_; + if (xcomponentId_ == currXcompId) { return; } + + auto it = xcompMap.find(currXcompId); + if (!xcompMap.empty() && it != xcompMap.end()) { + // 更新xcompid,shellholderId,provider指针 + xcomponentId_ = currXcompId; + native_shell_holder_id_ = std::stoll(it->second->shellholderId_); + provider_ = it->second->accessibilityProvider_; + g_flutterSemanticsTree = g_flutterSemanticsTreeXComponents[xcomponentId_]; + g_parentChildIdVec = g_parentChildIdVecXComponents[xcomponentId_]; + + FML_DLOG(INFO) << "AccessibiltiyChangesWithXComponentId -> xcomponentid:" << xcomponentId_; + } else { + xcomponentId_ = "oh_flutter_1"; + provider_ = nullptr; + g_flutterSemanticsTree = g_flutterSemanticsTreeXComponents[xcomponentId_]; + g_parentChildIdVec = g_parentChildIdVecXComponents[xcomponentId_]; + FML_DLOG(INFO) << "AccessibiltiyChangesWithXComponentId -> xcomponentid:" << xcomponentId_; + } +} + /** * 采用局部静态变量配合call-once特性,实现线程安全的单例模式 */ @@ -54,7 +85,8 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( bool ohosAccessibilityEnabled, int64_t shellholderId) { native_shell_holder_id_ = shellholderId; - provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + AccessibiltiyChangesWithXComponentId(); + // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; nativeAccessibilityChannel_ = std::make_shared(); accessibilityFeatures_ = std::make_shared(); @@ -81,7 +113,7 @@ void OhosAccessibilityBridge::UpdateSemantics( flutter::CustomAccessibilityActionUpdates actions) { FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics()"; - provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; std::vector updatedFlutterNodes; // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) @@ -124,6 +156,10 @@ void OhosAccessibilityBridge::UpdateSemantics( } } + // 将更新后的flutter语义树和父子节点id映射缓存,保存到相应的xcomponent里面 + g_flutterSemanticsTreeXComponents[xcomponentId_] = g_flutterSemanticsTree; + g_parentChildIdVecXComponents[xcomponentId_] = g_parentChildIdVec; + // 页面内容更新事件 Flutter_SendAccessibilityAsyncEvent(0, ArkUI_AccessibilityEventType:: @@ -270,7 +306,8 @@ void OhosAccessibilityBridge::FlutterScrollExecution( void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) { if (OHOS_API_VERSION < 13) { return; } - provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + AccessibiltiyChangesWithXComponentId(); + // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; CHECK_NULL_PTR_RET_VOID(provider_, RequestFocusWhenPageUpdate); auto OH_ArkUI_CreateAccessibilityEventInfo = @@ -978,6 +1015,8 @@ int32_t OhosAccessibilityBridge::FindAccessibilityNodeInfosById( << elementId << " mode=" << mode; CHECK_NULL_PTR_WITH_RET(elementList, FindAccessibilityNodeInfosById); + AccessibiltiyChangesWithXComponentId(); + if (g_flutterSemanticsTree.size() == 0) { FML_DLOG(INFO) << "FindAccessibilityNodeInfosById g_flutterSemanticsTree is null"; @@ -1370,6 +1409,8 @@ int32_t OhosAccessibilityBridge::ExecuteAccessibilityAction( << elementId << " action=" << action; CHECK_NULL_PTR_WITH_RET(actionArguments, ExecuteAccessibilityAction); + AccessibiltiyChangesWithXComponentId(); + // 获取当前elementid对应的flutter语义节点 auto flutterNode = GetFlutterSemanticsNode(static_cast(elementId)); if (!g_flutterSemanticsTree.count(flutterNode.id)) { @@ -1565,7 +1606,8 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAnnounceEvent( ArkUI_AccessibilityEventType eventType) { if (OHOS_API_VERSION < 13) { return; } - provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + AccessibiltiyChangesWithXComponentId(); + // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; CHECK_NULL_PTR_RET_VOID(provider_, Flutter_SendAccessibilityAnnounceEvent); // 创建并设置屏幕朗读事件 @@ -1614,7 +1656,8 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( ArkUI_AccessibilityEventType eventType) { if (OHOS_API_VERSION < 13) { return; } - provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + AccessibiltiyChangesWithXComponentId(); + // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; 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 f4e03364ce..d202f7e6ec 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -78,6 +78,7 @@ public: OhosAccessibilityBridge(const OhosAccessibilityBridge&) = delete; OhosAccessibilityBridge& operator=(const OhosAccessibilityBridge&) = delete; + std::string xcomponentId_; bool isFlutterNavigated_; int64_t native_shell_holder_id_; ArkUI_AccessibilityProvider* provider_; @@ -161,6 +162,10 @@ private: 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; 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 279c97baa1..a683639641 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 @@ -175,4 +175,6 @@ export const nativeUnicodeIsEmojiModifierBase: (code: number) => number; export const nativeUnicodeIsVariationSelector: (code: number) => number; -export const nativeUnicodeIsRegionalIndicatorSymbol: (code: number) => number; \ No newline at end of file +export const nativeUnicodeIsRegionalIndicatorSymbol: (code: number) => number; + +export const nativeGetXComponentId: (id: string) => number; \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets index 533e1e6a51..64497b3d8c 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets @@ -17,7 +17,7 @@ import Log from '../../util/Log'; import { FlutterView } from '../../view/FlutterView'; import FlutterManager from './FlutterManager'; import { DVModel, DVModelChildren, DynamicView } from '../../view/DynamicView/dynamicView'; - +import flutter from 'libflutter.so'; const TAG = "FlutterPage"; export const OHOS_FLUTTER_PAGE_UPDATE = "ohos_flutter_page_update"; @@ -56,7 +56,19 @@ export struct FlutterPage { .onLoad((context) => { this.flutterView?.onSurfaceCreated() Log.d(TAG, "XComponent onLoad "); - this.flutterView?.onAccessibilityIsOpen() + // 当xcomponent窗口部分显示或完全隐藏时触发回调 + this.getUIContext()?.getAttachedFrameNodeById(this.viewId)?.commonEvent.setOnVisibleAreaApproximateChange( + { ratios: [0.0, 1.0], expectedUpdateInterval: 0 }, + (ratioInc: boolean, ratio: number) => { + if (ratioInc) { + Log.i(TAG, "setOnVisibleAreaApproximateChange -> xcomponentId: " + this.viewId + + " ratioInc: " + ratioInc + " ratio: " + ratio); + flutter.nativeGetXComponentId(this.viewId); + // 保证获取xcomponentid之后再使用无障碍 + this.flutterView?.onAccessibilityIsOpen(); + } + } + ) }) .onDestroy(() => { Log.d(TAG, "XComponent onDestroy "); @@ -136,7 +148,19 @@ export struct FlutterPage { .onLoad((context) => { this.flutterView?.onSurfaceCreated() Log.d(TAG, "XComponent onLoad "); - this.flutterView?.onAccessibilityIsOpen() + // 当xcomponent窗口部分显示或完全隐藏时触发回调 + this.getUIContext()?.getAttachedFrameNodeById(this.viewId)?.commonEvent.setOnVisibleAreaApproximateChange( + { ratios: [0.0, 1.0], expectedUpdateInterval: 0 }, + (ratioInc: boolean, ratio: number) => { + if (ratioInc) { + Log.i(TAG, "setOnVisibleAreaApproximateChange -> xcomponentId: " + this.viewId + + " ratioInc: " + ratioInc + " ratio: " + ratio); + flutter.nativeGetXComponentId(this.viewId); + // 保证获取xcomponentid之后再使用无障碍 + this.flutterView?.onAccessibilityIsOpen(); + } + } + ) }) .onDestroy(() => { Log.d(TAG, "XComponent onDestroy "); diff --git a/shell/platform/ohos/library_loader.cpp b/shell/platform/ohos/library_loader.cpp index 7b2c7da1c0..91ceec8956 100644 --- a/shell/platform/ohos/library_loader.cpp +++ b/shell/platform/ohos/library_loader.cpp @@ -190,6 +190,9 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_FUNCTION( "nativeUnicodeIsRegionalIndicatorSymbol", flutter::PlatformViewOHOSNapi::nativeUnicodeIsRegionalIndicatorSymbol), + DECLARE_NAPI_FUNCTION( + "nativeGetXComponentId", + flutter::PlatformViewOHOSNapi::nativeGetXComponentId), }; FML_DLOG(INFO) << "Init NAPI size=" << sizeof(desc) / sizeof(desc[0]); diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index d1bf9ed472..78f4cc842f 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -2277,4 +2277,23 @@ napi_value PlatformViewOHOSNapi::nativeUnicodeIsRegionalIndicatorSymbol(napi_env napi_create_int32(env, (int)is_emoji, &result); return result; } + +napi_value PlatformViewOHOSNapi::nativeGetXComponentId(napi_env env, napi_callback_info info) +{ + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + std::string xcomponentId; + bool ret = fml::napi::GetString(env, args[0], xcomponentId); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeGetXComponentId xcomponentId: " << xcomponentId; + return nullptr; + } + // obtain the current visible xcomponent id from the ets callback event + XComponentAdapter::GetInstance()->currentXComponentId_ = xcomponentId; + FML_DLOG(ERROR) << "nativeGetXComponentId -> xcomponentId: " << xcomponentId; + return nullptr; +} + } // namespace flutter \ No newline at end of file diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.h b/shell/platform/ohos/napi/platform_view_ohos_napi.h index 013557aeae..84ea45af1e 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.h +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.h @@ -269,6 +269,10 @@ class PlatformViewOHOSNapi { napi_env env, napi_callback_info info); + static napi_value nativeGetXComponentId( + napi_env env, + napi_callback_info info); + private: static napi_env env_; napi_ref ref_napi_obj_; diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index 424123a0c6..c130995549 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -99,6 +99,10 @@ void XComponentAdapter::AttachFlutterEngine(std::string& id, auto findIter = xcomponetMap_.find(id); if (findIter != xcomponetMap_.end()) { findIter->second->AttachFlutterEngine(shellholderId); + // register the OH_ArkUI accessibility callbacks + if (OH_GetSdkApiVersion() >= 13) { + findIter->second->RegisterArkUIAccessibilityService(findIter->second->nativeXComponent_, shellholderId); + } } } @@ -201,6 +205,8 @@ void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window) { if(it->second->nativeXComponent_ == component) { it->second->OnSurfaceDestroyed(component, window); delete it->second; + // 将当前要销毁的xcomponent对应的无障碍provider指针置nullptr + it->second->accessibilityProvider_ = nullptr; it = XComponentAdapter::GetInstance()->xcomponetMap_.erase(it); } else { ++it; @@ -364,7 +370,8 @@ void XComponentBase::DetachFlutterEngine() { isEngineAttached_ = false; } -void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nativeXComponent) +void XComponentBase::RegisterArkUIAccessibilityService( + OH_NativeXComponent* nativeXComponent, const std::string& shellholderId) { BindAccessibilityProviderCallback(); @@ -385,8 +392,11 @@ void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nati OH_ArkUI_AccessibilityProviderRegisterCallback(a11yProvider, &accessibilityProviderCallback_) ); - XComponentAdapter::GetInstance()->accessibilityProvider_ = a11yProvider; - + auto* base = XComponentAdapter::GetInstance()->xcomponetMap_[id_]; + base->shellholderId_ = shellholderId; + base->accessibilityProvider_ = a11yProvider; + base->nativeXComponent_ = nativeXComponent; + FML_DLOG(INFO) << "RegisterArkUIAccessibilityService is finished"; } @@ -396,10 +406,6 @@ void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ BindXComponentCallback(); OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent_, &mouseCallback_); - // register the OH_ArkUI accessibility callbacks - if (OH_GetSdkApiVersion() >= 13) { - RegisterArkUIAccessibilityService(nativeXComponent_); - } } } @@ -456,7 +462,8 @@ void XComponentBase::OnSurfaceChanged(OH_NativeXComponent* component, void* wind void XComponentBase::OnSurfaceDestroyed(OH_NativeXComponent* component, void* window) { window_ = nullptr; - XComponentAdapter::GetInstance()->accessibilityProvider_ = nullptr; + // XComponentAdapter::GetInstance()->accessibilityProvider_ = nullptr; + LOGD("XComponentManger::OnSurfaceDestroyed"); if (isEngineAttached_) { PlatformViewOHOSNapi::SurfaceDestroyed(std::stoll(shellholderId_)); diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.h b/shell/platform/ohos/ohos_xcomponent_adapter.h index 7698e3a8f2..3500fabdb4 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.h +++ b/shell/platform/ohos/ohos_xcomponent_adapter.h @@ -51,7 +51,8 @@ public: void OnDispatchMouseEvent(OH_NativeXComponent* component, void* window); void OnDispatchMouseWheelEvent(mouseWheelEvent event); - void RegisterArkUIAccessibilityService(OH_NativeXComponent* nativeXComponent); + void RegisterArkUIAccessibilityService( + OH_NativeXComponent* nativeXComponent, const std::string& shellholderId); OH_NativeXComponent_TouchEvent touchEvent_; OH_NativeXComponent_Callback callback_; @@ -68,7 +69,6 @@ public: uint64_t height_; OhosTouchProcessor ohosTouchProcessor_; ArkUI_AccessibilityProvider* accessibilityProvider_; - }; class XComponentAdapter { @@ -85,7 +85,7 @@ class XComponentAdapter { public: std::map xcomponetMap_; - ArkUI_AccessibilityProvider* accessibilityProvider_; + std::string currentXComponentId_; private: static XComponentAdapter mXComponentAdapter; -- Gitee From 2a72ee9798de354d21dbe3d2389c35096517e996 Mon Sep 17 00:00:00 2001 From: zjxi Date: Mon, 20 Jan 2025 13:02:02 +0800 Subject: [PATCH 60/60] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E6=97=A0=E9=9A=9C?= =?UTF-8?q?=E7=A2=8D=E5=8D=95=E5=AE=9E=E4=BE=8Bxcomponent=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E9=97=AA=E9=80=80=E9=97=AE=E9=A2=98=E3=80=81=E7=9B=B8?= =?UTF-8?q?=E5=AF=B9-=E7=BB=9D=E5=AF=B9=E5=9D=90=E6=A0=87=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E7=AE=97=E6=B3=95bug=E5=AF=BC=E8=87=B4hypium=E4=B8=8B?= =?UTF-8?q?=E6=BB=91=E5=8A=A8=E5=B8=83=E5=B1=80=E8=8A=82=E7=82=B9=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zjxi --- .../ohos_accessibility_bridge.cpp | 197 +++++++++--------- .../accessibility/ohos_accessibility_bridge.h | 20 +- .../platform/ohos/ohos_xcomponent_adapter.cpp | 25 ++- shell/platform/ohos/ohos_xcomponent_adapter.h | 7 +- 4 files changed, 139 insertions(+), 110 deletions(-) diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp index 09bbe8cece..16f9d4b7b6 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.cpp @@ -21,8 +21,6 @@ #include "flutter/shell/common/platform_view.h" #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/ohos/ohos_shell_holder.h" -#include "third_party/skia/include/core/SkMatrix.h" -#include "third_party/skia/include/core/SkScalar.h" #include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" namespace flutter { @@ -48,14 +46,11 @@ void OhosAccessibilityBridge::AccessibiltiyChangesWithXComponentId() // 更新xcompid,shellholderId,provider指针 xcomponentId_ = currXcompId; native_shell_holder_id_ = std::stoll(it->second->shellholderId_); - provider_ = it->second->accessibilityProvider_; g_flutterSemanticsTree = g_flutterSemanticsTreeXComponents[xcomponentId_]; g_parentChildIdVec = g_parentChildIdVecXComponents[xcomponentId_]; - FML_DLOG(INFO) << "AccessibiltiyChangesWithXComponentId -> xcomponentid:" << xcomponentId_; } else { xcomponentId_ = "oh_flutter_1"; - provider_ = nullptr; g_flutterSemanticsTree = g_flutterSemanticsTreeXComponents[xcomponentId_]; g_parentChildIdVec = g_parentChildIdVecXComponents[xcomponentId_]; FML_DLOG(INFO) << "AccessibiltiyChangesWithXComponentId -> xcomponentid:" << xcomponentId_; @@ -75,7 +70,7 @@ OhosAccessibilityBridge* OhosAccessibilityBridge::GetInstance() } OhosAccessibilityBridge::OhosAccessibilityBridge() - : isFlutterNavigated_(false), provider_(nullptr), + : isFlutterNavigated_(false), isAccessibilityEnabled_(false) {} /** @@ -86,7 +81,6 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( { native_shell_holder_id_ = shellholderId; AccessibiltiyChangesWithXComponentId(); - // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; nativeAccessibilityChannel_ = std::make_shared(); accessibilityFeatures_ = std::make_shared(); @@ -99,9 +93,18 @@ void OhosAccessibilityBridge::OnOhosAccessibilityStateChange( } } -void OhosAccessibilityBridge::SetNativeShellHolderId(int64_t id) +/** + * build the id mapping betwween parent node and its children nodes + */ +void OhosAccessibilityBridge::BuildParentChildNodeIdRelation( + const SemanticsNodeExtent& node) { - this->native_shell_holder_id_ = id; + 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)); + } } /** @@ -113,14 +116,10 @@ void OhosAccessibilityBridge::UpdateSemantics( flutter::CustomAccessibilityActionUpdates actions) { FML_DLOG(INFO) << "OhosAccessibilityBridge::UpdateSemantics()"; - // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; std::vector updatedFlutterNodes; // 当flutter页面状态更新(路由新页面)时,自动请求root节点组件获焦(规避滑动组件更新干扰) if (isFlutterNavigated_) { - Flutter_SendAccessibilityAsyncEvent(0, - ArkUI_AccessibilityEventType:: - ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_STATE_UPDATE); RequestFocusWhenPageUpdate(0); isFlutterNavigated_ = false; } @@ -129,16 +128,20 @@ 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; + // 构建flutter节点的父子id映射关系 + BuildParentChildNodeIdRelation(nodeEx); + //print semantics node and flags info for debugging GetSemanticsNodeDebugInfo(nodeEx); GetSemanticsFlagsDebugInfo(nodeEx); - // 构建flutter无障碍语义节点树 - g_flutterSemanticsTree[nodeEx.id] = nodeEx; + if (!IsNodeVisible(nodeEx)) { continue; } // 若当前节点为获焦 if (IsNodeFocused(nodeEx)) { @@ -147,12 +150,7 @@ void OhosAccessibilityBridge::UpdateSemantics( // 若当前节点和更新前节点信息不同,则加入更新节点数组 if (nodeEx.hadPreviousConfig) { updatedFlutterNodes.emplace_back(nodeEx); - } - - // 获取当前flutter节点的全部子节点数量,并构建父子节点id映射关系 - int32_t childNodeCount = nodeEx.childrenInTraversalOrder.size(); - for (int32_t i = 0; i < childNodeCount; i++) { - g_parentChildIdVec.emplace_back(std::make_pair(nodeEx.id, nodeEx.childrenInTraversalOrder[i])); + FML_DLOG(INFO) << "updatedFlutterNodes -> node.id=" << nodeEx.id; } } @@ -167,10 +165,12 @@ void OhosAccessibilityBridge::UpdateSemantics( LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); /* 针对更新后的节点进行事件处理 */ - for (const auto& nodeEx: updatedFlutterNodes) { + for (auto& nodeEx: updatedFlutterNodes) { + FML_DLOG(INFO) << "*#*#* updated node.id=" << nodeEx.id; + // 当滑动节点产生滑动,并执行滑动处理 if (HasScrolled(nodeEx)) { - LOGD("UpdateSemantics -> has scrolled"); + LOGD("UpdateSemantics -> nodeId = %{public}d has scrolled", nodeEx.id); auto OH_ArkUI_CreateAccessibilityElementInfo = OhosAccessibilityDDL::DLLoadCreateElemInfoFunc(ArkUIAccessibilityConstant::ARKUI_CREATE_NODE); CHECK_DLL_NULL_PTR(OH_ArkUI_CreateAccessibilityElementInfo); @@ -192,16 +192,16 @@ void OhosAccessibilityBridge::UpdateSemantics( _elementInfo = nullptr; } - // 判断是否触发liveRegion活动区,当前节点是否活跃 + // 判断是否触发liveRegion活动区,当前节点是否活跃 nodeEx.HasFlag(FLAGS_::kIsLiveRegion) if (nodeEx.HasFlag(FLAGS_::kIsLiveRegion) && HasChangedLabel(nodeEx)) { - FML_DLOG(INFO) << "UpdateSemantics -> page content update, nodeEx.id=" << nodeEx.id; + FML_DLOG(INFO) << "liveRegion -> page content update, nodeEx.id=" << nodeEx.id; Flutter_SendAccessibilityAsyncEvent(static_cast(nodeEx.id), ArkUI_AccessibilityEventType:: ARKUI_ACCESSIBILITY_NATIVE_EVENT_TYPE_PAGE_CONTENT_UPDATE); - LOGD("Flutter_SendAccessibilityAsyncEvent -> PAGE_CONTENT_UPDATE"); } } - + // calculate the global tranfomr matrix for each node + ComputeGlobalTransform(); // 输出flutter语义树相关重要语义信息debug日志 GetSemanticsDebugInfo(); FML_DLOG(INFO) << "=== UpdateSemantics() is finished ==="; @@ -241,7 +241,7 @@ void OhosAccessibilityBridge::FlutterScrollExecution( if (node.HasAction(ACTIONS_::kScrollUp) || node.HasAction(ACTIONS_::kScrollDown)) { } else if (node.HasAction(ACTIONS_::kScrollLeft) || - node.HasAction(ACTIONS_::kScrollRight)) { + node.HasAction(ACTIONS_::kScrollRight)) { LOGD("current flutterNode has scroll up/down/left/right"); } @@ -306,8 +306,8 @@ void OhosAccessibilityBridge::FlutterScrollExecution( void OhosAccessibilityBridge::RequestFocusWhenPageUpdate(int32_t requestFocusId) { if (OHOS_API_VERSION < 13) { return; } - AccessibiltiyChangesWithXComponentId(); - // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); + auto provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); CHECK_NULL_PTR_RET_VOID(provider_, RequestFocusWhenPageUpdate); auto OH_ArkUI_CreateAccessibilityEventInfo = @@ -499,68 +499,66 @@ std::pair OhosAccessibilityBridge::GetRealScaleFactor() } /** - * flutter语义树中相对坐标系转化为屏幕绝对坐标的映射算法实现 - * NOTE:目前暂未考虑旋转、透视场景,不影响屏幕朗读功能 - * (SkMatrix::kMSkewX, SkMatrix::kMSkewY, SkMatrix::kMPersp0, - * SkMatrix::kMPersp1, SkMatrix::kMPersp2) + * calculate the global transform matrix for each node */ -void OhosAccessibilityBridge::FlutterRelativeRectToScreenRect( - SemanticsNodeExtent currNode) -{ - // 获取当前flutter节点的相对rect - auto [currLeft, currTop, currRight, currBottom] = currNode.rect; - - // 获取当前flutter节点的缩放、平移、透视等矩阵坐标转换以下矩阵坐标变换参数 - SkMatrix transform = currNode.transform.asM33(); - auto _kMScaleX = transform.get(SkMatrix::kMScaleX); - auto _kMTransX = transform.get(SkMatrix::kMTransX); - auto _kMScaleY = transform.get(SkMatrix::kMScaleY); - auto _kMTransY = transform.get(SkMatrix::kMTransY); - - // 获取当前flutter节点的父节点的相对rect - int32_t parentId = GetParentId(currNode.id); - auto parentNode = GetFlutterSemanticsNode(parentId); - if (g_flutterSemanticsTree.find(parentId) == g_flutterSemanticsTree.end()) { - LOGE("FlutterRelativeRectToScreenRect: GetFlutterSemanticsNode id=%{public}d null", parentId); - } - - // 获取当前flutter节点的父节点的绝对坐标 - auto [realParentLeft, realParentTop, realParentRight, realParentBottom] = GetAbsoluteScreenRect(parentNode); - - //获取root节点的绝对坐标 - auto rootNode = GetFlutterSemanticsNode(0); - auto rootRect = GetAbsoluteScreenRect(rootNode); - auto rootWidth = rootRect.right; - auto rootHeight = rootRect.bottom; - - // 获取真实缩放系数 - auto [realScaleXFactor, realScaleYFactor] = GetRealScaleFactor(); - - // 更新后的节点屏幕坐标,子节点的屏幕绝对坐标转换,包括offset偏移值计算、缩放系数变换 - bool isRectScaleChanged = _kMScaleX > 1 && _kMScaleY > 1; - float newLeft = isRectScaleChanged ? - currLeft + _kMTransX * _kMScaleX : (currLeft + _kMTransX) * realScaleXFactor + realParentLeft; - float newTop = isRectScaleChanged ? - currTop + _kMTransY * _kMScaleY : (currTop + _kMTransY) * realScaleYFactor + realParentTop; - float newRight = isRectScaleChanged ? - currRight * _kMScaleX : newLeft + currRight * realScaleXFactor; - float newBottom = isRectScaleChanged ? - currBottom * _kMScaleY : newTop + currBottom * realScaleYFactor; - - // 若子节点rect超过父节点则跳过显示(单个屏幕显示不下,滑动再重新显示) - const bool isExceedScreeArea = newLeft < realParentLeft || newTop < realParentTop || - newRight > realParentRight || newBottom > realParentBottom || - newLeft >= newRight || newTop >= newBottom || - newRight > rootWidth || newBottom > rootHeight; - if (isExceedScreeArea) { - FML_DLOG(WARNING) << "RelativeRectToScreenRect -> childRect exceeds parentRect {Id: " - << currNode.id << ", (" << newLeft << ", " << newTop - << ", " << newRight << ", " << newBottom << ")}"; - // 防止滑动场景下绿框坐标超出屏幕范围,进行正则化处理 - SetAbsoluteScreenRect(currNode, rootWidth, rootHeight, 0, 0); - } else { - SetAbsoluteScreenRect(currNode, newLeft, newTop, newRight, newBottom); +void OhosAccessibilityBridge::ComputeGlobalTransform() +{ + std::queue semanticsQue; + + auto root = GetFlutterSemanticsNode(0); + semanticsQue.push(root); + g_globalTransformMap[root.id] = root.transform; + + while (!semanticsQue.empty()) { + uint32_t queSize = semanticsQue.size(); + for (uint32_t i=0; i Transformed points can't make a rect "; + } + globalRect.setBounds(points, 4); + + SetAbsoluteScreenRect(node, globalRect.left(), globalRect.top(), + globalRect.right(), globalRect.bottom()); } /** @@ -692,7 +690,7 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( rect = {static_cast(left), static_cast(top), static_cast(right), static_cast(bottom)}; } else { // 若当前节点为id >= 1的节点 - FlutterRelativeRectToScreenRect(flutterNode); + RelativeRectToScreenRect(flutterNode); auto [left, top, right, bottom] = GetAbsoluteScreenRect(flutterNode); rect = {static_cast(left), static_cast(top), static_cast(right), static_cast(bottom)}; @@ -926,7 +924,8 @@ void OhosAccessibilityBridge::FlutterSetElementInfoProperties( OhosAccessibilityDDL::DLLoadSetElemStringFunc(ArkUIAccessibilityConstant::ARKUI_SET_A11Y_LEVEL); CHECK_DLL_NULL_PTR(OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel); ARKUI_ACCESSIBILITY_CALL_CHECK( - OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel(elementInfoFromList, "yes"); + OH_ArkUI_AccessibilityElementInfoSetAccessibilityLevel( + elementInfoFromList, componentTypeName != OTHER_WIDGET_NAME ? "yes" : "no"); ); // 无障碍组,设置为true时表示该组件及其所有子组件为一整个可以选中的组件,无障碍服务将不再关注其子组件内容。默认值:false auto OH_ArkUI_AccessibilityElementInfoSetAccessibilityGroup = @@ -954,6 +953,7 @@ std::vector OhosAccessibilityBridge::GetLevelOrderTraversalTree(int32_t uint32_t queSize = semanticsQue.size(); for (uint32_t i=0; i(currNode.id)); @@ -961,6 +961,7 @@ std::vector OhosAccessibilityBridge::GetLevelOrderTraversalTree(int32_t currNode.childrenInTraversalOrder.end()); for (const auto& childId: currNode.childrenInTraversalOrder) { auto childNode = GetFlutterSemanticsNode(childId); + semanticsQue.push(childNode); } } @@ -1607,7 +1608,8 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAnnounceEvent( { if (OHOS_API_VERSION < 13) { return; } AccessibiltiyChangesWithXComponentId(); - // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); + auto provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); CHECK_NULL_PTR_RET_VOID(provider_, Flutter_SendAccessibilityAnnounceEvent); // 创建并设置屏幕朗读事件 @@ -1657,7 +1659,8 @@ void OhosAccessibilityBridge::Flutter_SendAccessibilityAsyncEvent( { if (OHOS_API_VERSION < 13) { return; } AccessibiltiyChangesWithXComponentId(); - // provider_ = XComponentAdapter::GetInstance()->accessibilityProvider_; + std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); + auto provider_ = XComponentAdapter::GetInstance()->GetAccessibilityProvider(xcomponentId_); CHECK_NULL_PTR_RET_VOID(provider_, Flutter_SendAccessibilityAsyncEvent); // 创建eventInfo对象 @@ -2010,6 +2013,10 @@ 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); + accessibilityFocusedNode = {}; } /** diff --git a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h index d202f7e6ec..673f762d37 100644 --- a/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h +++ b/shell/platform/ohos/accessibility/ohos_accessibility_bridge.h @@ -30,6 +30,9 @@ #include "ohos_accessibility_ddl.h" #include "flutter/shell/platform/ohos/utils/ohos_utils.h" #include "flutter/shell/platform/ohos/utils/arkui_accessibility_constant.h" +#include "third_party/skia/include/core/SkMatrix.h" +#include "third_party/skia/include/core/SkScalar.h" +#include "third_party/skia/include/core/SkPoint.h" namespace flutter { typedef flutter::SemanticsFlags FLAGS_; @@ -43,9 +46,15 @@ struct AbsoluteRect { static constexpr AbsoluteRect MakeEmpty() { return AbsoluteRect{0.0, 0.0, 0.0, 0.0}; } + static constexpr AbsoluteRect MakeRect( + float left, float top, float right, float bottom) { + return AbsoluteRect{left, top, right, bottom}; + } + }; struct SemanticsNodeExtent : flutter::SemanticsNode { bool isNull = false; + SkM44 globalTransform = SkM44{}; AbsoluteRect absoluteRect = AbsoluteRect::MakeEmpty(); int32_t parentId = -1; bool hadPreviousConfig = false; @@ -81,12 +90,9 @@ public: std::string xcomponentId_; bool isFlutterNavigated_; int64_t native_shell_holder_id_; - ArkUI_AccessibilityProvider* provider_; void OnOhosAccessibilityStateChange(bool ohosAccessibilityEnabled, int64_t shellholderId); - void SetNativeShellHolderId(int64_t id); - void UpdateSemantics(flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions); @@ -139,7 +145,7 @@ public: std::unique_ptr& message, ArkUI_AccessibilityEventType eventType); - void FlutterRelativeRectToScreenRect(SemanticsNodeExtent node); + void RelativeRectToScreenRect(SemanticsNodeExtent& node); AbsoluteRect GetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode); void SetAbsoluteScreenRect(SemanticsNodeExtent& flutterNode, float left, @@ -169,6 +175,7 @@ private: std::unordered_map g_flutterSemanticsTree; std::vector> g_parentChildIdVec; std::unordered_map g_screenRectMap; + std::unordered_map g_globalTransformMap; SemanticsNodeExtent inputFocusedNode; SemanticsNodeExtent lastInputFocusedNode; @@ -255,6 +262,11 @@ private: flutter::SemanticsAction ArkuiActionsToFlutterActions( ArkUI_Accessibility_ActionType arkui_action); + void BuildParentChildNodeIdRelation(const SemanticsNodeExtent& node); + void ComputeGlobalTransform(); + void ConvertRectToGlobal(SemanticsNodeExtent& node); + SkPoint ApplyTransform(SkPoint& point, const SkM44& transform); + bool HasScrolled(const SemanticsNodeExtent& flutterNode); bool HasChangedLabel(const SemanticsNodeExtent& flutterNode); diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index c130995549..68d1a5debf 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -99,10 +99,6 @@ void XComponentAdapter::AttachFlutterEngine(std::string& id, auto findIter = xcomponetMap_.find(id); if (findIter != xcomponetMap_.end()) { findIter->second->AttachFlutterEngine(shellholderId); - // register the OH_ArkUI accessibility callbacks - if (OH_GetSdkApiVersion() >= 13) { - findIter->second->RegisterArkUIAccessibilityService(findIter->second->nativeXComponent_, shellholderId); - } } } @@ -199,6 +195,7 @@ void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window) { } void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window) { + std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); for(auto it = XComponentAdapter::GetInstance()->xcomponetMap_.begin(); it != XComponentAdapter::GetInstance()->xcomponetMap_.end();) { @@ -370,8 +367,17 @@ void XComponentBase::DetachFlutterEngine() { isEngineAttached_ = false; } -void XComponentBase::RegisterArkUIAccessibilityService( - OH_NativeXComponent* nativeXComponent, const std::string& shellholderId) +ArkUI_AccessibilityProvider* XComponentAdapter::GetAccessibilityProvider(const std::string& xcompId) +{ + auto it = xcomponetMap_.find(xcompId); + if (it != xcomponetMap_.end()) { + return it->second->accessibilityProvider_; + } else { + return nullptr; + } +} + +void XComponentBase::RegisterArkUIAccessibilityService(OH_NativeXComponent* nativeXComponent) { BindAccessibilityProviderCallback(); @@ -392,8 +398,8 @@ void XComponentBase::RegisterArkUIAccessibilityService( OH_ArkUI_AccessibilityProviderRegisterCallback(a11yProvider, &accessibilityProviderCallback_) ); + std::lock_guard lock(XComponentAdapter::GetInstance()->mutex_); auto* base = XComponentAdapter::GetInstance()->xcomponetMap_[id_]; - base->shellholderId_ = shellholderId; base->accessibilityProvider_ = a11yProvider; base->nativeXComponent_ = nativeXComponent; @@ -406,6 +412,9 @@ void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ BindXComponentCallback(); OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent_, &mouseCallback_); + // register the OH_ArkUI accessibility callbacks + if (OH_GetSdkApiVersion() < 13) { return; } + RegisterArkUIAccessibilityService(nativeXComponent_); } } @@ -462,8 +471,6 @@ void XComponentBase::OnSurfaceChanged(OH_NativeXComponent* component, void* wind void XComponentBase::OnSurfaceDestroyed(OH_NativeXComponent* component, void* window) { window_ = nullptr; - // XComponentAdapter::GetInstance()->accessibilityProvider_ = nullptr; - LOGD("XComponentManger::OnSurfaceDestroyed"); if (isEngineAttached_) { PlatformViewOHOSNapi::SurfaceDestroyed(std::stoll(shellholderId_)); diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.h b/shell/platform/ohos/ohos_xcomponent_adapter.h index 3500fabdb4..632e9d216d 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.h +++ b/shell/platform/ohos/ohos_xcomponent_adapter.h @@ -20,7 +20,7 @@ #include #include #include - +#include #include "flutter/shell/platform/ohos/ohos_touch_processor.h" #include "flutter/shell/platform/ohos/napi/platform_view_ohos_napi.h" #include "napi/native_api.h" @@ -52,7 +52,7 @@ public: void OnDispatchMouseWheelEvent(mouseWheelEvent event); void RegisterArkUIAccessibilityService( - OH_NativeXComponent* nativeXComponent, const std::string& shellholderId); + OH_NativeXComponent* nativeXComponent); OH_NativeXComponent_TouchEvent touchEvent_; OH_NativeXComponent_Callback callback_; @@ -83,9 +83,12 @@ class XComponentAdapter { void DetachFlutterEngine(std::string& id); void OnMouseWheel(std::string& id, mouseWheelEvent event); + ArkUI_AccessibilityProvider* GetAccessibilityProvider(const std::string& xcompId); + public: std::map xcomponetMap_; std::string currentXComponentId_; + std::mutex mutex_; private: static XComponentAdapter mXComponentAdapter; -- Gitee