Android A11Y: Check for active surface before calling into native code
This fixes a deadlock. The deadlock occurs on an application state change. During this state change the QML plugin requests Android to create a new surface for drawing and waits on the Android thread to complete the request (QAndroidPlatformOpenGLWindow::eglSurface()). In the meantime the android a11y delegate gets requests from the android a11y interface. The delegate tries to access the a11y information through the native interface, where it has to wait for the main loop thread to get the a11y information from the QtQuick objects. This leads to a deadlock in which the main loop thread waits on the quick rendering thread, the rendering thread waits on the android thread and the android thread waits on the main loop thread. This workaround avoids this issue by not calling into native code until a rendering surface has been created. Task-number: QTBUG-105958 Pick-to: 6.4 6.3 6.2 5.15 Change-Id: Ib99145aa689d1d62e25d25e1f4f8598d53eee3a9 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
parent
216fe24ca1
commit
b8a9527544
@ -282,6 +282,9 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
|
||||
return null;
|
||||
}
|
||||
|
||||
if (m_activityDelegate.getSurfaceCount() == 0)
|
||||
return null;
|
||||
|
||||
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
|
||||
|
||||
event.setEnabled(true);
|
||||
@ -344,9 +347,11 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
|
||||
// Spit out the entire hierarchy for debugging purposes
|
||||
// dumpNodes(-1);
|
||||
|
||||
int[] ids = QtNativeAccessibility.childIdListForAccessibleObject(-1);
|
||||
for (int i = 0; i < ids.length; ++i)
|
||||
result.addChild(m_view, ids[i]);
|
||||
if (m_activityDelegate.getSurfaceCount() != 0) {
|
||||
int[] ids = QtNativeAccessibility.childIdListForAccessibleObject(-1);
|
||||
for (int i = 0; i < ids.length; ++i)
|
||||
result.addChild(m_view, ids[i]);
|
||||
}
|
||||
|
||||
// The offset values have changed, so we need to re-focus the
|
||||
// currently focused item, otherwise it will have an incorrect
|
||||
@ -374,8 +379,9 @@ 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))
|
||||
if (m_activityDelegate.getSurfaceCount() == 0 || !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);
|
||||
@ -425,7 +431,7 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
|
||||
@Override
|
||||
public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId)
|
||||
{
|
||||
if (virtualViewId == View.NO_ID) {
|
||||
if (virtualViewId == View.NO_ID || m_activityDelegate.getSurfaceCount() == 0) {
|
||||
return getNodeForView();
|
||||
}
|
||||
return getNodeForVirtualViewId(virtualViewId);
|
||||
|
Loading…
Reference in New Issue
Block a user