diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2022-02-10 11:53:24 +0100 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2022-02-15 17:51:33 +0100 |
commit | b238f83380dcaa2830999a8f413f4b648db80beb (patch) | |
tree | 2bfc5166d67adef9cc821fcae54b4706e53bf444 /src/plugins/platforms/android | |
parent | e5ba8380457f823f5bd4a475ffb808b3c5b9dd42 (diff) |
Android A11Y: handle valueChanged events
Before this patch Android A11Y implementation was missing
ValueChanged event handling. As a result, no update was given
when the element's value was changed.
Handling these events allows us to announce value changes on such
objects like Slider, SpinBox, etc...
This is a universal method of value-change announcement, so it
supports all sorts of A11Y gestures.
On the Java side a new function was introduced to announce the
values, because we need to use the actual element's *value*,
not its accessible name or description.
Task-number: QTBUG-93396
Pick-to: 6.3 6.2 5.15
Change-Id: Ic44abd5f01b9b6f5468962131466edaf6a49d498
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Reviewed-by: Rami Potinkara <rami.potinkara@qt.io>
Diffstat (limited to 'src/plugins/platforms/android')
5 files changed, 40 insertions, 3 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index bf492a8bd2..97d5692a47 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -149,6 +149,14 @@ namespace QtAndroidAccessibility QtAndroid::notifyObjectFocus(accessibilityObjectId); } + static jstring jvalueForAccessibleObject(int objectId); // forward declaration + + void notifyValueChanged(uint accessibilityObjectId) + { + jstring value = jvalueForAccessibleObject(accessibilityObjectId); + QtAndroid::notifyValueChanged(accessibilityObjectId, value); + } + static QVarLengthArray<int, 8> childIdListForAccessibleObject_helper(int objectId) { QAccessibleInterface *iface = interfaceFromId(objectId); @@ -345,6 +353,27 @@ if (!clazz) { \ //__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); + static QString textFromValue(QAccessibleInterface *iface) + { + QString valueStr; + QAccessibleValueInterface *valueIface = iface->valueInterface(); + if (valueIface) { + // TODO: fix double-to-string conversion + valueStr = valueIface->currentValue().toString(); + } + return valueStr; + } + + static jstring jvalueForAccessibleObject(int objectId) + { + QAccessibleInterface *iface = interfaceFromId(objectId); + const QString value = textFromValue(iface); + QJniEnvironment env; + jstring jstr = env->NewString((jchar*)value.constData(), (jsize)value.size()); + if (env.checkAndClearExceptions()) + __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Failed to create jstring"); + return jstr; + } static QString descriptionForInterface(QAccessibleInterface *iface) { @@ -356,9 +385,7 @@ if (!clazz) { \ if (desc.isEmpty()) { desc = iface->text(QAccessible::Value); if (desc.isEmpty()) { - if (QAccessibleValueInterface *valueIface = iface->valueInterface()) { - desc= valueIface->currentValue().toString(); - } + desc = textFromValue(iface); } } } diff --git a/src/plugins/platforms/android/androidjniaccessibility.h b/src/plugins/platforms/android/androidjniaccessibility.h index a9044a32b1..a6e2edee5e 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.h +++ b/src/plugins/platforms/android/androidjniaccessibility.h @@ -54,6 +54,7 @@ namespace QtAndroidAccessibility void notifyLocationChange(); void notifyObjectHide(uint accessibilityObjectId); void notifyObjectFocus(uint accessibilityObjectId); + void notifyValueChanged(uint accessibilityObjectId); void createAccessibilityContextObject(QObject *parent); } diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 9816dfb93e..b62624c7b5 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -226,6 +226,12 @@ namespace QtAndroid QJniObject::callStaticMethod<void>(m_applicationClass, "notifyObjectFocus","(I)V", accessibilityObjectId); } + void notifyValueChanged(uint accessibilityObjectId, jstring value) + { + QJniObject::callStaticMethod<void>(m_applicationClass, "notifyValueChanged", + "(ILjava/lang/String;)V", accessibilityObjectId, value); + } + void notifyQtAndroidPluginRunning(bool running) { QJniObject::callStaticMethod<void>(m_applicationClass, "notifyQtAndroidPluginRunning","(Z)V", running); diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h index 5ebf8c5048..d8e40f8b7f 100644 --- a/src/plugins/platforms/android/androidjnimain.h +++ b/src/plugins/platforms/android/androidjnimain.h @@ -103,6 +103,7 @@ namespace QtAndroid void notifyAccessibilityLocationChange(); void notifyObjectHide(uint accessibilityObjectId, uint parentObjectId); void notifyObjectFocus(uint accessibilityObjectId); + void notifyValueChanged(uint accessibilityObjectId, jstring value); void notifyQtAndroidPluginRunning(bool running); const char *classErrorMsgFmt(); diff --git a/src/plugins/platforms/android/qandroidplatformaccessibility.cpp b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp index 75333d3f08..706d1bb4fa 100644 --- a/src/plugins/platforms/android/qandroidplatformaccessibility.cpp +++ b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp @@ -66,6 +66,8 @@ void QAndroidPlatformAccessibility::notifyAccessibilityUpdate(QAccessibleEvent * QtAndroidAccessibility::notifyObjectHide(event->uniqueId()); } else if (event->type() == QAccessible::Focus) { QtAndroidAccessibility::notifyObjectFocus(event->uniqueId()); + } else if (event->type() == QAccessible::ValueChanged) { + QtAndroidAccessibility::notifyValueChanged(event->uniqueId()); } } |