diff --git a/src/android/jar/CMakeLists.txt b/src/android/jar/CMakeLists.txt index 707fe4ccfbb..c9731786a6b 100644 --- a/src/android/jar/CMakeLists.txt +++ b/src/android/jar/CMakeLists.txt @@ -42,6 +42,7 @@ set(java_sources src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java src/org/qtproject/qt/android/BackendRegister.java src/org/qtproject/qt/android/QtWindowInterface.java + src/org/qtproject/qt/android/QtAccessibilityInterface.java ) qt_internal_add_jar(Qt${QtBase_VERSION_MAJOR}Android diff --git a/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java index d23c87e7923..8558e42c3b8 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java @@ -61,6 +61,8 @@ class QtAccessibilityDelegate extends View.AccessibilityDelegate } // TODO do we want to have one QtAccessibilityDelegate for the whole app (QtRootLayout) or // e.g. one per window? + // FIXME make QtAccessibilityDelegate window based or verify current way works + // also for child windows: QTBUG-120685 public QtAccessibilityDelegate(QtLayout layout) { m_layout = layout; diff --git a/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityInterface.java b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityInterface.java new file mode 100644 index 00000000000..41d0c4c6122 --- /dev/null +++ b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityInterface.java @@ -0,0 +1,14 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +package org.qtproject.qt.android; + +@UsedFromNativeCode +public interface QtAccessibilityInterface { + default void initializeAccessibility() { } + default void notifyLocationChange(int viewId) { } + default void notifyObjectHide(int viewId, int parentId) { } + default void notifyObjectFocus(int viewId) { } + default void notifyScrolledEvent(int viewId) { } + default void notifyValueChanged(int viewId, String value) { } + default void notifyObjectShow(int parentId) { } +} diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java index 169140afbde..fac42bc221c 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java @@ -31,7 +31,8 @@ import android.widget.PopupMenu; import java.util.HashMap; -class QtActivityDelegate extends QtActivityDelegateBase implements QtWindowInterface +class QtActivityDelegate + extends QtActivityDelegateBase implements QtWindowInterface, QtAccessibilityInterface { private static final String QtTAG = "QtActivityDelegate"; @@ -42,7 +43,7 @@ class QtActivityDelegate extends QtActivityDelegateBase implements QtWindowInter private View m_dummyView = null; private HashMap m_nativeViews = new HashMap(); - + private QtAccessibilityDelegate m_accessibilityDelegate = null; QtActivityDelegate(Activity activity) { @@ -58,6 +59,8 @@ class QtActivityDelegate extends QtActivityDelegateBase implements QtWindowInter m_backendsRegistered = true; BackendRegister.registerBackend(QtWindowInterface.class, (QtWindowInterface)QtActivityDelegate.this); + BackendRegister.registerBackend(QtAccessibilityInterface.class, + (QtAccessibilityInterface)QtActivityDelegate.this); } } @@ -66,6 +69,7 @@ class QtActivityDelegate extends QtActivityDelegateBase implements QtWindowInter if (m_backendsRegistered) { m_backendsRegistered = false; BackendRegister.unregisterBackend(QtWindowInterface.class); + BackendRegister.unregisterBackend(QtAccessibilityInterface.class); } } @@ -226,7 +230,55 @@ class QtActivityDelegate extends QtActivityDelegateBase implements QtWindowInter }); } - @UsedFromNativeCode + @Override + public void notifyLocationChange(int viewId) + { + if (m_accessibilityDelegate == null) + return; + m_accessibilityDelegate.notifyLocationChange(viewId); + } + + @Override + public void notifyObjectHide(int viewId, int parentId) + { + if (m_accessibilityDelegate == null) + return; + m_accessibilityDelegate.notifyObjectHide(viewId, parentId); + } + + @Override + public void notifyObjectShow(int parentId) + { + if (m_accessibilityDelegate == null) + return; + m_accessibilityDelegate.notifyObjectShow(parentId); + } + + @Override + public void notifyObjectFocus(int viewId) + { + if (m_accessibilityDelegate == null) + return; + m_accessibilityDelegate.notifyObjectFocus(viewId); + } + + @Override + public void notifyValueChanged(int viewId, String value) + { + if (m_accessibilityDelegate == null) + return; + m_accessibilityDelegate.notifyValueChanged(viewId, value); + } + + @Override + public void notifyScrolledEvent(int viewId) + { + if (m_accessibilityDelegate == null) + return; + m_accessibilityDelegate.notifyScrolledEvent(viewId); + } + + @Override public void initializeAccessibility() { QtNative.runAction(() -> { @@ -362,16 +414,6 @@ class QtActivityDelegate extends QtActivityDelegateBase implements QtWindowInter }); } - @Override - QtAccessibilityDelegate createAccessibilityDelegate() - { - if (m_layout != null) - return new QtAccessibilityDelegate(m_layout); - - Log.w(QtTAG, "Null layout, failed to initialize accessibility delegate."); - return null; - } - private void setActivityBackgroundDrawable() { TypedValue attr = new TypedValue(); diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegateBase.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegateBase.java index 9f8738b042d..4a9df33a36f 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegateBase.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegateBase.java @@ -37,7 +37,6 @@ abstract class QtActivityDelegateBase { protected Activity m_activity; protected HashMap m_topLevelWindows; - protected QtAccessibilityDelegate m_accessibilityDelegate = null; protected QtDisplayManager m_displayManager = null; protected QtInputDelegate m_inputDelegate = null; @@ -46,7 +45,6 @@ abstract class QtActivityDelegateBase // Subclass must implement these abstract void startNativeApplicationImpl(String appParams, String mainLib); - abstract QtAccessibilityDelegate createAccessibilityDelegate(); abstract QtLayout getQtLayout(); // With these we are okay with default implementation doing nothing @@ -153,62 +151,6 @@ abstract class QtActivityDelegateBase hideSplashScreen(0); } - @UsedFromNativeCode - public void notifyLocationChange(int viewId) - { - if (m_accessibilityDelegate == null) - return; - m_accessibilityDelegate.notifyLocationChange(viewId); - } - - @UsedFromNativeCode - public void notifyObjectHide(int viewId, int parentId) - { - if (m_accessibilityDelegate == null) - return; - m_accessibilityDelegate.notifyObjectHide(viewId, parentId); - } - - @UsedFromNativeCode - public void notifyObjectShow(int parentId) - { - if (m_accessibilityDelegate == null) - return; - m_accessibilityDelegate.notifyObjectShow(parentId); - } - - @UsedFromNativeCode - public void notifyObjectFocus(int viewId) - { - if (m_accessibilityDelegate == null) - return; - m_accessibilityDelegate.notifyObjectFocus(viewId); - } - - @UsedFromNativeCode - public void notifyValueChanged(int viewId, String value) - { - if (m_accessibilityDelegate == null) - return; - m_accessibilityDelegate.notifyValueChanged(viewId, value); - } - - @UsedFromNativeCode - public void notifyScrolledEvent(int viewId) - { - if (m_accessibilityDelegate == null) - return; - m_accessibilityDelegate.notifyScrolledEvent(viewId); - } - - @UsedFromNativeCode - public void initializeAccessibility() - { - QtNative.runAction(() -> { - m_accessibilityDelegate = createAccessibilityDelegate(); - }); - } - void handleUiModeChange(int uiMode) { // QTBUG-108365 diff --git a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java index 78e1b5e2654..20d34180007 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtEmbeddedDelegate.java @@ -122,14 +122,6 @@ class QtEmbeddedDelegate extends QtActivityDelegateBase QtNative.startApplication(appParams, mainLib); } - @Override - QtAccessibilityDelegate createAccessibilityDelegate() - { - // FIXME make QtAccessibilityDelegate window based or verify current way works - // also for child windows: QTBUG-120685 - return null; - } - @UsedFromNativeCode @Override QtLayout getQtLayout() diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java index 29f1d1790fd..22152f7e69e 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceEmbeddedDelegate.java @@ -28,6 +28,7 @@ class QtServiceEmbeddedDelegate implements QtEmbeddedViewInterface, QtNative.App m_service = service; QtNative.registerAppStateListener(this); QtNative.setService(service); + // QTBUG-122920 TODO Implement accessibility for service UIs } @UsedFromNativeCode diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index da5b63ef219..805616e481a 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -82,7 +82,7 @@ namespace QtAndroidAccessibility void initialize() { - QtAndroid::qtActivityDelegate().callMethod("initializeAccessibility"); + QtAndroid::initializeAccessibility(); } bool isActive() diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 08a56039e43..35dfeb6a42d 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -95,6 +95,7 @@ Q_CONSTINIT static QBasicAtomicInt startQtAndroidPluginCalled = Q_BASIC_ATOMIC_I Q_DECLARE_JNI_CLASS(QtEmbeddedDelegateFactory, "org/qtproject/qt/android/QtEmbeddedDelegateFactory") Q_DECLARE_JNI_CLASS(QtWindowInterface, "org/qtproject/qt/android/QtWindowInterface") +Q_DECLARE_JNI_CLASS(QtAccessibilityInterface, "org/qtproject/qt/android/QtAccessibilityInterface"); namespace QtAndroid { @@ -237,36 +238,46 @@ namespace QtAndroid return true; } + void initializeAccessibility() + { + m_backendRegister->callInterface( + "initializeAccessibility"); + } + void notifyAccessibilityLocationChange(uint accessibilityObjectId) { - qtActivityDelegate().callMethod("notifyLocationChange", accessibilityObjectId); + m_backendRegister->callInterface( + "notifyLocationChange", accessibilityObjectId); } void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId) { - qtActivityDelegate().callMethod("notifyObjectHide", - accessibilityObjectId, parentObjectId); + m_backendRegister->callInterface( + "notifyObjectHide", accessibilityObjectId, parentObjectId); } void notifyObjectShow(uint parentObjectId) { - qtActivityDelegate().callMethod("notifyObjectShow", - parentObjectId); + m_backendRegister->callInterface( + "notifyObjectShow", parentObjectId); } void notifyObjectFocus(uint accessibilityObjectId) { - qtActivityDelegate().callMethod("notifyObjectFocus", accessibilityObjectId); + m_backendRegister->callInterface( + "notifyObjectFocus", accessibilityObjectId); } void notifyValueChanged(uint accessibilityObjectId, jstring value) { - qtActivityDelegate().callMethod("notifyValueChanged", accessibilityObjectId, value); + m_backendRegister->callInterface( + "notifyValueChanged", accessibilityObjectId, value); } void notifyScrolledEvent(uint accessibilityObjectId) { - qtActivityDelegate().callMethod("notifyScrolledEvent", accessibilityObjectId); + m_backendRegister->callInterface( + "notifyScrolledEvent", accessibilityObjectId); } void notifyNativePluginIntegrationReady(bool ready) diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h index 755b69ad726..40db9e86827 100644 --- a/src/plugins/platforms/android/androidjnimain.h +++ b/src/plugins/platforms/android/androidjnimain.h @@ -65,6 +65,7 @@ namespace QtAndroid jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env); jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = nullptr); + void initializeAccessibility(); void notifyAccessibilityLocationChange(uint accessibilityObjectId); void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId); void notifyObjectShow(uint parentObjectId);