Loading core/java/android/view/accessibility/AccessibilityCache.java +28 −49 Original line number Diff line number Diff line Loading @@ -158,6 +158,7 @@ public class AccessibilityCache { * @param event An event. */ public void onAccessibilityEvent(AccessibilityEvent event) { AccessibilityNodeInfo nodeToRefresh = null; synchronized (mLock) { if (DEBUG) { Log.i(LOG_TAG, "onAccessibilityEvent(" + event + ")"); Loading @@ -166,17 +167,19 @@ public class AccessibilityCache { switch (eventType) { case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: { if (mAccessibilityFocus != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { refreshCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); removeCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); } mAccessibilityFocus = event.getSourceNodeId(); mAccessibilityFocusedWindow = event.getWindowId(); refreshCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); nodeToRefresh = removeCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); } break; case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: { if (mAccessibilityFocus == event.getSourceNodeId() && mAccessibilityFocusedWindow == event.getWindowId()) { refreshCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); nodeToRefresh = removeCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); mAccessibilityFocus = AccessibilityNodeInfo.UNDEFINED_ITEM_ID; mAccessibilityFocusedWindow = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID; } Loading @@ -184,17 +187,18 @@ public class AccessibilityCache { case AccessibilityEvent.TYPE_VIEW_FOCUSED: { if (mInputFocus != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { refreshCachedNodeLocked(event.getWindowId(), mInputFocus); removeCachedNodeLocked(event.getWindowId(), mInputFocus); } mInputFocus = event.getSourceNodeId(); refreshCachedNodeLocked(event.getWindowId(), mInputFocus); nodeToRefresh = removeCachedNodeLocked(event.getWindowId(), mInputFocus); } break; case AccessibilityEvent.TYPE_VIEW_SELECTED: case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: case AccessibilityEvent.TYPE_VIEW_CLICKED: case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: { refreshCachedNodeLocked(event.getWindowId(), event.getSourceNodeId()); nodeToRefresh = removeCachedNodeLocked(event.getWindowId(), event.getSourceNodeId()); } break; case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: { Loading @@ -205,7 +209,7 @@ public class AccessibilityCache { & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) != 0) { clearSubTreeLocked(windowId, sourceId); } else { refreshCachedNodeLocked(windowId, sourceId); nodeToRefresh = removeCachedNodeLocked(windowId, sourceId); } } } break; Loading @@ -218,8 +222,8 @@ public class AccessibilityCache { if (event.getWindowChanges() == AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED) { // Don't need to clear all cache. Unless the changes are related to // content, we won't clear all cache here. refreshCachedWindowLocked(event.getWindowId()); // content, we won't clear all cache here with clear(). clearWindowCacheLocked(); break; } case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: { Loading @@ -228,59 +232,34 @@ public class AccessibilityCache { } } if (nodeToRefresh != null) { if (DEBUG) { Log.i(LOG_TAG, "Refreshing and re-adding cached node."); } if (mAccessibilityNodeRefresher.refreshNode(nodeToRefresh, true)) { add(nodeToRefresh); } } if (CHECK_INTEGRITY) { checkIntegrity(); } } private void refreshCachedNodeLocked(int windowId, long sourceId) { private AccessibilityNodeInfo removeCachedNodeLocked(int windowId, long sourceId) { if (DEBUG) { Log.i(LOG_TAG, "Refreshing cached node."); Log.i(LOG_TAG, "Removing cached node."); } LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId); if (nodes == null) { return; return null; } AccessibilityNodeInfo cachedInfo = nodes.get(sourceId); // If the source is not in the cache - nothing to do. if (cachedInfo == null) { return; } // The node changed so we will just refresh it right now. if (mAccessibilityNodeRefresher.refreshNode(cachedInfo, true)) { return; } // Weird, we could not refresh. Just evict the entire sub-tree. clearSubTreeLocked(windowId, sourceId); } private void refreshCachedWindowLocked(int windowId) { if (DEBUG) { Log.i(LOG_TAG, "Refreshing cached window."); } if (windowId == AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { return; } final int displayCounts = mWindowCacheByDisplay.size(); for (int i = 0; i < displayCounts; i++) { final SparseArray<AccessibilityWindowInfo> windowsOfDisplay = mWindowCacheByDisplay.valueAt(i); if (windowsOfDisplay == null) { continue; } final AccessibilityWindowInfo window = windowsOfDisplay.get(windowId); if (window == null) { continue; } if (!mAccessibilityNodeRefresher.refreshWindow(window)) { // If we fail to refresh the window, clear all windows. clearWindowCacheLocked(); } return; return null; } nodes.remove(sourceId); return cachedInfo; } /** Loading Loading @@ -450,7 +429,7 @@ public class AccessibilityCache { if (clone.isAccessibilityFocused()) { if (mAccessibilityFocus != AccessibilityNodeInfo.UNDEFINED_ITEM_ID && mAccessibilityFocus != sourceId) { refreshCachedNodeLocked(windowId, mAccessibilityFocus); removeCachedNodeLocked(windowId, mAccessibilityFocus); } mAccessibilityFocus = sourceId; mAccessibilityFocusedWindow = windowId; Loading core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java +6 −11 Original line number Diff line number Diff line Loading @@ -563,7 +563,7 @@ public class AccessibilityCacheTest { } @Test public void nodeWithA11yFocusWhenAnotherNodeGetsFocus_getsRefreshed() { public void nodeWithA11yFocusWhenAnotherNodeGetsFocus_getsRemoved() { AccessibilityNodeInfo nodeInfo = getNodeWithA11yAndWindowId(SINGLE_VIEW_ID, WINDOW_ID_1); nodeInfo.setAccessibilityFocused(true); mAccessibilityCache.add(nodeInfo); Loading @@ -573,7 +573,7 @@ public class AccessibilityCacheTest { mAccessibilityCache.onAccessibilityEvent(event); event.recycle(); try { verify(mAccessibilityNodeRefresher).refreshNode(nodeInfo, true); assertNull(mAccessibilityCache.getNode(WINDOW_ID_1, SINGLE_VIEW_ID)); } finally { nodeInfo.recycle(); } Loading Loading @@ -614,7 +614,7 @@ public class AccessibilityCacheTest { } @Test public void nodeWithInputFocusWhenAnotherNodeGetsFocus_getsRefreshed() { public void nodeWithInputFocusWhenAnotherNodeGetsFocus_getsRemoved() { AccessibilityNodeInfo nodeInfo = getNodeWithA11yAndWindowId(SINGLE_VIEW_ID, WINDOW_ID_1); nodeInfo.setFocused(true); mAccessibilityCache.add(nodeInfo); Loading @@ -624,7 +624,7 @@ public class AccessibilityCacheTest { mAccessibilityCache.onAccessibilityEvent(event); event.recycle(); try { verify(mAccessibilityNodeRefresher).refreshNode(nodeInfo, true); assertNull(mAccessibilityCache.getNode(WINDOW_ID_1, SINGLE_VIEW_ID)); } finally { nodeInfo.recycle(); } Loading Loading @@ -733,20 +733,15 @@ public class AccessibilityCacheTest { } @Test public void addA11yFocusNodeBeforeFocusClearedEvent_previousA11yFocusNodeGetsRefreshed() { public void addA11yFocusNodeBeforeFocusClearedEvent_previousA11yFocusNodeGetsRemoved() { AccessibilityNodeInfo nodeInfo1 = getNodeWithA11yAndWindowId(SINGLE_VIEW_ID, WINDOW_ID_1); nodeInfo1.setAccessibilityFocused(true); mAccessibilityCache.add(nodeInfo1); AccessibilityNodeInfo nodeInfo2 = getNodeWithA11yAndWindowId(OTHER_VIEW_ID, WINDOW_ID_1); nodeInfo2.setAccessibilityFocused(true); mAccessibilityCache.add(nodeInfo2); AccessibilityEvent event = AccessibilityEvent.obtain( AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); event.setSource(getMockViewWithA11yAndWindowIds(SINGLE_VIEW_ID, WINDOW_ID_1)); mAccessibilityCache.onAccessibilityEvent(event); event.recycle(); try { verify(mAccessibilityNodeRefresher).refreshNode(nodeInfo1, true); assertNull(mAccessibilityCache.getNode(WINDOW_ID_1, SINGLE_VIEW_ID)); } finally { nodeInfo1.recycle(); nodeInfo2.recycle(); Loading Loading
core/java/android/view/accessibility/AccessibilityCache.java +28 −49 Original line number Diff line number Diff line Loading @@ -158,6 +158,7 @@ public class AccessibilityCache { * @param event An event. */ public void onAccessibilityEvent(AccessibilityEvent event) { AccessibilityNodeInfo nodeToRefresh = null; synchronized (mLock) { if (DEBUG) { Log.i(LOG_TAG, "onAccessibilityEvent(" + event + ")"); Loading @@ -166,17 +167,19 @@ public class AccessibilityCache { switch (eventType) { case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: { if (mAccessibilityFocus != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { refreshCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); removeCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); } mAccessibilityFocus = event.getSourceNodeId(); mAccessibilityFocusedWindow = event.getWindowId(); refreshCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); nodeToRefresh = removeCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); } break; case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: { if (mAccessibilityFocus == event.getSourceNodeId() && mAccessibilityFocusedWindow == event.getWindowId()) { refreshCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); nodeToRefresh = removeCachedNodeLocked(mAccessibilityFocusedWindow, mAccessibilityFocus); mAccessibilityFocus = AccessibilityNodeInfo.UNDEFINED_ITEM_ID; mAccessibilityFocusedWindow = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID; } Loading @@ -184,17 +187,18 @@ public class AccessibilityCache { case AccessibilityEvent.TYPE_VIEW_FOCUSED: { if (mInputFocus != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { refreshCachedNodeLocked(event.getWindowId(), mInputFocus); removeCachedNodeLocked(event.getWindowId(), mInputFocus); } mInputFocus = event.getSourceNodeId(); refreshCachedNodeLocked(event.getWindowId(), mInputFocus); nodeToRefresh = removeCachedNodeLocked(event.getWindowId(), mInputFocus); } break; case AccessibilityEvent.TYPE_VIEW_SELECTED: case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: case AccessibilityEvent.TYPE_VIEW_CLICKED: case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: { refreshCachedNodeLocked(event.getWindowId(), event.getSourceNodeId()); nodeToRefresh = removeCachedNodeLocked(event.getWindowId(), event.getSourceNodeId()); } break; case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: { Loading @@ -205,7 +209,7 @@ public class AccessibilityCache { & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) != 0) { clearSubTreeLocked(windowId, sourceId); } else { refreshCachedNodeLocked(windowId, sourceId); nodeToRefresh = removeCachedNodeLocked(windowId, sourceId); } } } break; Loading @@ -218,8 +222,8 @@ public class AccessibilityCache { if (event.getWindowChanges() == AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED) { // Don't need to clear all cache. Unless the changes are related to // content, we won't clear all cache here. refreshCachedWindowLocked(event.getWindowId()); // content, we won't clear all cache here with clear(). clearWindowCacheLocked(); break; } case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: { Loading @@ -228,59 +232,34 @@ public class AccessibilityCache { } } if (nodeToRefresh != null) { if (DEBUG) { Log.i(LOG_TAG, "Refreshing and re-adding cached node."); } if (mAccessibilityNodeRefresher.refreshNode(nodeToRefresh, true)) { add(nodeToRefresh); } } if (CHECK_INTEGRITY) { checkIntegrity(); } } private void refreshCachedNodeLocked(int windowId, long sourceId) { private AccessibilityNodeInfo removeCachedNodeLocked(int windowId, long sourceId) { if (DEBUG) { Log.i(LOG_TAG, "Refreshing cached node."); Log.i(LOG_TAG, "Removing cached node."); } LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId); if (nodes == null) { return; return null; } AccessibilityNodeInfo cachedInfo = nodes.get(sourceId); // If the source is not in the cache - nothing to do. if (cachedInfo == null) { return; } // The node changed so we will just refresh it right now. if (mAccessibilityNodeRefresher.refreshNode(cachedInfo, true)) { return; } // Weird, we could not refresh. Just evict the entire sub-tree. clearSubTreeLocked(windowId, sourceId); } private void refreshCachedWindowLocked(int windowId) { if (DEBUG) { Log.i(LOG_TAG, "Refreshing cached window."); } if (windowId == AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) { return; } final int displayCounts = mWindowCacheByDisplay.size(); for (int i = 0; i < displayCounts; i++) { final SparseArray<AccessibilityWindowInfo> windowsOfDisplay = mWindowCacheByDisplay.valueAt(i); if (windowsOfDisplay == null) { continue; } final AccessibilityWindowInfo window = windowsOfDisplay.get(windowId); if (window == null) { continue; } if (!mAccessibilityNodeRefresher.refreshWindow(window)) { // If we fail to refresh the window, clear all windows. clearWindowCacheLocked(); } return; return null; } nodes.remove(sourceId); return cachedInfo; } /** Loading Loading @@ -450,7 +429,7 @@ public class AccessibilityCache { if (clone.isAccessibilityFocused()) { if (mAccessibilityFocus != AccessibilityNodeInfo.UNDEFINED_ITEM_ID && mAccessibilityFocus != sourceId) { refreshCachedNodeLocked(windowId, mAccessibilityFocus); removeCachedNodeLocked(windowId, mAccessibilityFocus); } mAccessibilityFocus = sourceId; mAccessibilityFocusedWindow = windowId; Loading
core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java +6 −11 Original line number Diff line number Diff line Loading @@ -563,7 +563,7 @@ public class AccessibilityCacheTest { } @Test public void nodeWithA11yFocusWhenAnotherNodeGetsFocus_getsRefreshed() { public void nodeWithA11yFocusWhenAnotherNodeGetsFocus_getsRemoved() { AccessibilityNodeInfo nodeInfo = getNodeWithA11yAndWindowId(SINGLE_VIEW_ID, WINDOW_ID_1); nodeInfo.setAccessibilityFocused(true); mAccessibilityCache.add(nodeInfo); Loading @@ -573,7 +573,7 @@ public class AccessibilityCacheTest { mAccessibilityCache.onAccessibilityEvent(event); event.recycle(); try { verify(mAccessibilityNodeRefresher).refreshNode(nodeInfo, true); assertNull(mAccessibilityCache.getNode(WINDOW_ID_1, SINGLE_VIEW_ID)); } finally { nodeInfo.recycle(); } Loading Loading @@ -614,7 +614,7 @@ public class AccessibilityCacheTest { } @Test public void nodeWithInputFocusWhenAnotherNodeGetsFocus_getsRefreshed() { public void nodeWithInputFocusWhenAnotherNodeGetsFocus_getsRemoved() { AccessibilityNodeInfo nodeInfo = getNodeWithA11yAndWindowId(SINGLE_VIEW_ID, WINDOW_ID_1); nodeInfo.setFocused(true); mAccessibilityCache.add(nodeInfo); Loading @@ -624,7 +624,7 @@ public class AccessibilityCacheTest { mAccessibilityCache.onAccessibilityEvent(event); event.recycle(); try { verify(mAccessibilityNodeRefresher).refreshNode(nodeInfo, true); assertNull(mAccessibilityCache.getNode(WINDOW_ID_1, SINGLE_VIEW_ID)); } finally { nodeInfo.recycle(); } Loading Loading @@ -733,20 +733,15 @@ public class AccessibilityCacheTest { } @Test public void addA11yFocusNodeBeforeFocusClearedEvent_previousA11yFocusNodeGetsRefreshed() { public void addA11yFocusNodeBeforeFocusClearedEvent_previousA11yFocusNodeGetsRemoved() { AccessibilityNodeInfo nodeInfo1 = getNodeWithA11yAndWindowId(SINGLE_VIEW_ID, WINDOW_ID_1); nodeInfo1.setAccessibilityFocused(true); mAccessibilityCache.add(nodeInfo1); AccessibilityNodeInfo nodeInfo2 = getNodeWithA11yAndWindowId(OTHER_VIEW_ID, WINDOW_ID_1); nodeInfo2.setAccessibilityFocused(true); mAccessibilityCache.add(nodeInfo2); AccessibilityEvent event = AccessibilityEvent.obtain( AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); event.setSource(getMockViewWithA11yAndWindowIds(SINGLE_VIEW_ID, WINDOW_ID_1)); mAccessibilityCache.onAccessibilityEvent(event); event.recycle(); try { verify(mAccessibilityNodeRefresher).refreshNode(nodeInfo1, true); assertNull(mAccessibilityCache.getNode(WINDOW_ID_1, SINGLE_VIEW_ID)); } finally { nodeInfo1.recycle(); nodeInfo2.recycle(); Loading