diff options
| -rw-r--r-- | core/java/android/view/accessibility/AccessibilityCache.java | 10 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java | 25 |
2 files changed, 29 insertions, 6 deletions
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java index b4d9c53aedb8..5d59e4205579 100644 --- a/core/java/android/view/accessibility/AccessibilityCache.java +++ b/core/java/android/view/accessibility/AccessibilityCache.java @@ -306,6 +306,11 @@ public class AccessibilityCache { final int oldChildCount = oldInfo.getChildCount(); for (int i = 0; i < oldChildCount; i++) { + final long oldChildId = oldInfo.getChildId(i); + // If the child is no longer present, remove the sub-tree. + if (newChildrenIds == null || newChildrenIds.indexOf(oldChildId) < 0) { + clearSubTreeLocked(windowId, oldChildId); + } 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. @@ -313,11 +318,6 @@ public class AccessibilityCache { 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) { - clearSubTreeLocked(windowId, oldChildId); - } } // Also be careful if the parent has changed since the new diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java index ec80d20e3179..7f675ffffee5 100644 --- a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java +++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java @@ -501,7 +501,7 @@ public class AccessibilityCacheTest { } @Test - public void addNode_whenNodeBeingReplacedIsOwnGrandparent_doesntCrash() { + public void addNode_whenNodeBeingReplacedIsOwnGrandparentWithTwoChildren_doesntCrash() { AccessibilityNodeInfo parentNodeInfo = getNodeWithA11yAndWindowId(PARENT_VIEW_ID, WINDOW_ID_1); parentNodeInfo.addChild(getMockViewWithA11yAndWindowIds(CHILD_VIEW_ID, WINDOW_ID_1)); @@ -525,6 +525,29 @@ public class AccessibilityCacheTest { } @Test + public void addNode_whenNodeBeingReplacedIsOwnGrandparentWithOneChild_doesntCrash() { + AccessibilityNodeInfo parentNodeInfo = + getNodeWithA11yAndWindowId(PARENT_VIEW_ID, WINDOW_ID_1); + parentNodeInfo.addChild(getMockViewWithA11yAndWindowIds(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++) { int eventType = 1 << i; |