Accessibility Android: Fix crash for invalid interfaces

When asked for an accessibility interface with invalid ID we still
return an AccessibilityNodeInfo. But instead of setting that interfaces'
ID to the invalid ID, rather return one with no ID set so it will simply
fall back to the view.

Task-number: QTBUG-38829
Change-Id: If66f5b1b42ba46949d94a547050c7a2cfc7ee9b7
Reviewed-by: Jan Arve Sæther <jan-arve.saether@digia.com>
This commit is contained in:
Frederik Gladhorn 2014-05-07 12:56:13 +02:00 committed by The Qt Project
parent c8de2a8b5f
commit 06e27c2a52
3 changed files with 12 additions and 6 deletions

View File

@ -240,8 +240,12 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
node.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME);
node.setPackageName(m_view.getContext().getPackageName());
if (!QtNativeAccessibility.populateNode(virtualViewId, node))
return node;
// set only if valid, otherwise we return a node that is invalid and will crash when accessed
node.setSource(m_view, virtualViewId);
QtNativeAccessibility.populateNode(virtualViewId, node);
if (TextUtils.isEmpty(node.getText()) && TextUtils.isEmpty(node.getContentDescription()))
Log.w(TAG, "AccessibilityNodeInfo with empty contentDescription: " + virtualViewId);

View File

@ -54,5 +54,5 @@ class QtNativeAccessibility
static native int hitTest(float x, float y);
static native boolean clickAction(int objectId);
static native void populateNode(int objectId, AccessibilityNodeInfo node);
static native boolean populateNode(int objectId, AccessibilityNodeInfo node);
}

View File

@ -170,7 +170,7 @@ if (!clazz) { \
jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \
if (!method) { \
__android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
return; \
return false; \
} \
env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \
}
@ -190,12 +190,12 @@ if (!clazz) { \
return jdesc;
}
static void populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node)
static bool populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node)
{
QAccessibleInterface *iface = interfaceFromId(objectId);
if (!iface || !iface->isValid()) {
__android_log_print(ANDROID_LOG_WARN, m_qtTag, "Accessibility: populateNode for Invalid ID");
return;
return false;
}
QAccessible::State state = iface->state();
@ -235,6 +235,8 @@ if (!clazz) { \
jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size());
//CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc)
CALL_METHOD(node, "setContentDescription", "(Ljava/lang/CharSequence;)V", jdesc)
return true;
}
static JNINativeMethod methods[] = {
@ -244,7 +246,7 @@ if (!clazz) { \
{"descriptionForAccessibleObject", "(I)Ljava/lang/String;", (jstring)descriptionForAccessibleObject},
{"screenRect", "(I)Landroid/graphics/Rect;", (jobject)screenRect},
{"hitTest", "(FF)I", (void*)hitTest},
{"populateNode", "(ILandroid/view/accessibility/AccessibilityNodeInfo;)V", (void*)populateNode},
{"populateNode", "(ILandroid/view/accessibility/AccessibilityNodeInfo;)Z", (void*)populateNode},
{"clickAction", "(I)Z", (void*)clickAction},
};