Merge "Fix crash in a11y cache" into oc-dev

This commit is contained in:
Phil Weaver
2017-05-09 15:30:24 +00:00
committed by Android (Google) Code Review
2 changed files with 32 additions and 0 deletions

View File

@@ -309,6 +309,13 @@ public final class AccessibilityCache {
final int oldChildCount = oldInfo.getChildCount();
for (int i = 0; i < oldChildCount; i++) {
if (nodes.get(sourceId) == null) {
// We've removed (and thus recycled) this node because it was its own
// ancestor (the app gave us bad data), we can't continue using it.
// Clear the cache for this window and give up on adding the node.
clearNodesForWindowLocked(windowId);
return;
}
final long oldChildId = oldInfo.getChildId(i);
// If the child is no longer present, remove the sub-tree.
if (newChildrenIds == null || newChildrenIds.indexOf(oldChildId) < 0) {

View File

@@ -54,6 +54,7 @@ public class AccessibilityCacheTest {
private static int OTHER_VIEW_ID = 0xCAB2;
private static int PARENT_VIEW_ID = 0xFED4;
private static int CHILD_VIEW_ID = 0xFEED;
private static int OTHER_CHILD_VIEW_ID = 0xACE2;
private static int MOCK_CONNECTION_ID = 1;
AccessibilityCache mAccessibilityCache;
@@ -481,6 +482,30 @@ public class AccessibilityCacheTest {
AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
}
@Test
public void addNode_whenNodeBeingReplacedIsOwnGrandparent_doesntCrash() {
AccessibilityNodeInfo parentNodeInfo =
getNodeWithA11yAndWindowId(PARENT_VIEW_ID, WINDOW_ID_1);
parentNodeInfo.addChild(getMockViewWithA11yAndWindowIds(CHILD_VIEW_ID, WINDOW_ID_1));
parentNodeInfo.addChild(getMockViewWithA11yAndWindowIds(OTHER_CHILD_VIEW_ID, WINDOW_ID_1));
AccessibilityNodeInfo childNodeInfo =
getNodeWithA11yAndWindowId(CHILD_VIEW_ID, WINDOW_ID_1);
childNodeInfo.setParent(getMockViewWithA11yAndWindowIds(PARENT_VIEW_ID, WINDOW_ID_1));
childNodeInfo.addChild(getMockViewWithA11yAndWindowIds(PARENT_VIEW_ID, WINDOW_ID_1));
AccessibilityNodeInfo replacementParentNodeInfo =
getNodeWithA11yAndWindowId(PARENT_VIEW_ID, WINDOW_ID_1);
try {
mAccessibilityCache.add(parentNodeInfo);
mAccessibilityCache.add(childNodeInfo);
mAccessibilityCache.add(replacementParentNodeInfo);
} finally {
parentNodeInfo.recycle();
childNodeInfo.recycle();
replacementParentNodeInfo.recycle();
}
}
@Test
public void testCacheCriticalEventList_doesntLackEvents() {
for (int i = 0; i < 32; i++) {