a11y Android: Set a RangeInfo by using the ValueInterface

This enables components to provide more detailed information about the
value to the a11y-interface.

For the ProgressBar this controls the pitch of the sound which TalkBack
uses to represent the current value of the ProgressBar.

Task-number: QTBUG-139712
Pick-to: 6.8 6.9 6.10
Change-Id: I0b2694e8e47b264d75e3fcecbbe900c310aa4e19
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
Julian Greilich 2025-09-02 12:01:15 +02:00
parent d9a8d80c87
commit 7ae2b8bc44
1 changed files with 39 additions and 0 deletions

View File

@ -40,6 +40,7 @@ namespace QtAndroidAccessibility
static jmethodID m_setHeadingMethodID = 0;
static jmethodID m_setScrollableMethodID = 0;
static jmethodID m_setTextSelectionMethodID = 0;
static jmethodID m_setRangeInfoMethodID = 0;
static jmethodID m_setVisibleToUserMethodID = 0;
static bool m_accessibilityActivated = false;
@ -645,6 +646,11 @@ namespace QtAndroidAccessibility
bool hasTextSelection = false;
int selectionStart = 0;
int selectionEnd = 0;
bool hasValue = false;
QVariant minValue = 0;
QVariant maxValue = 0;
QVariant currentValue = 0;
QVariant valueStepSize = 0;
};
static NodeInfo populateNode_helper(int objectId)
@ -663,6 +669,14 @@ namespace QtAndroidAccessibility
info.hasTextSelection = true;
textIface->selection(0, &info.selectionStart, &info.selectionEnd);
}
QAccessibleValueInterface *valueInterface = iface->valueInterface();
if (valueInterface) {
info.hasValue = true;
info.minValue = valueInterface->minimumValue();
info.maxValue = valueInterface->maximumValue();
info.currentValue = valueInterface->currentValue();
info.valueStepSize = valueInterface->minimumStepSize();
}
}
return info;
}
@ -697,6 +711,28 @@ namespace QtAndroidAccessibility
info.selectionEnd);
}
if (info.hasValue && m_setRangeInfoMethodID) {
int valueType = info.currentValue.typeId();
jint rangeType = 3; // RANGE_TYPE_INDETERMINATE
switch (valueType) {
case QMetaType::Float:
case QMetaType::Double:
rangeType = 1; // RANGE_TYPE_FLOAT
break;
case QMetaType::Int:
rangeType = 0; // RANGE_TYPE_INT
break;
}
QJniObject rangeInfo("android/view/accessibility/AccessibilityNodeInfo$RangeInfo",
"(IFFF)V", rangeType, info.minValue.toFloat(),
info.maxValue.toFloat(), info.currentValue.toFloat());
if (rangeInfo.isValid()) {
env->CallVoidMethod(node, m_setRangeInfoMethodID, rangeInfo.object());
}
}
env->CallVoidMethod(node, m_setCheckableMethodID, (bool)info.state.checkable);
env->CallVoidMethod(node, m_setCheckedMethodID, (bool)info.state.checked);
env->CallVoidMethod(node, m_setEditableMethodID, info.state.editable);
@ -778,6 +814,9 @@ namespace QtAndroidAccessibility
GET_AND_CHECK_STATIC_METHOD(m_setScrollableMethodID, nodeInfoClass, "setScrollable", "(Z)V");
GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V");
GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
GET_AND_CHECK_STATIC_METHOD(
m_setRangeInfoMethodID, nodeInfoClass, "setRangeInfo",
"(Landroid/view/accessibility/AccessibilityNodeInfo$RangeInfo;)V");
return true;
}