summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/accessibility/AccessibilityCache.java10
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java25
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;