Loading core/java/android/view/AccessibilityInteractionController.java +16 −13 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.util.Poolable; import android.util.PoolableManager; import android.util.Pools; import android.util.SparseLongArray; import android.view.ViewGroup.ChildListForAccessibility; import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeProvider; Loading Loading @@ -623,6 +622,8 @@ final class AccessibilityInteractionController { private static final int MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE = 50; private final ArrayList<View> mTempViewList = new ArrayList<View>(); public void prefetchAccessibilityNodeInfos(View view, int virtualViewId, int prefetchFlags, List<AccessibilityNodeInfo> outInfos) { AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider(); Loading Loading @@ -663,8 +664,6 @@ final class AccessibilityInteractionController { while (parent instanceof View && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) { View parentView = (View) parent; final long parentNodeId = AccessibilityNodeInfo.makeNodeId( parentView.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED); AccessibilityNodeInfo info = parentView.createAccessibilityNodeInfo(); if (info != null) { outInfos.add(info); Loading @@ -678,19 +677,21 @@ final class AccessibilityInteractionController { ViewParent parent = current.getParentForAccessibility(); if (parent instanceof ViewGroup) { ViewGroup parentGroup = (ViewGroup) parent; ChildListForAccessibility children = ChildListForAccessibility.obtain(parentGroup, false); ArrayList<View> children = mTempViewList; children.clear(); try { final int childCount = children.getChildCount(); parentGroup.addChildrenForAccessibility(children); final int childCount = children.size(); for (int i = 0; i < childCount; i++) { if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) { return; } View child = children.getChildAt(i); View child = children.get(i); if (child.getAccessibilityViewId() != current.getAccessibilityViewId() && isShown(child)) { AccessibilityNodeInfo info = null; AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider(); AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider(); if (provider == null) { info = child.createAccessibilityNodeInfo(); } else { Loading @@ -703,7 +704,7 @@ final class AccessibilityInteractionController { } } } finally { children.recycle(); children.clear(); } } } Loading @@ -716,14 +717,16 @@ final class AccessibilityInteractionController { ViewGroup rootGroup = (ViewGroup) root; HashMap<View, AccessibilityNodeInfo> addedChildren = new HashMap<View, AccessibilityNodeInfo>(); ChildListForAccessibility children = ChildListForAccessibility.obtain(rootGroup, false); ArrayList<View> children = mTempViewList; children.clear(); try { final int childCount = children.getChildCount(); root.addChildrenForAccessibility(children); final int childCount = children.size(); for (int i = 0; i < childCount; i++) { if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) { return; } View child = children.getChildAt(i); View child = children.get(i); if (isShown(child)) { AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider(); if (provider == null) { Loading @@ -743,7 +746,7 @@ final class AccessibilityInteractionController { } } } finally { children.recycle(); children.clear(); } if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) { for (Map.Entry<View, AccessibilityNodeInfo> entry : addedChildren.entrySet()) { Loading core/java/android/view/accessibility/AccessibilityInteractionClient.java +62 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.view.accessibility; import android.accessibilityservice.IAccessibilityServiceConnection; import android.graphics.Rect; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Message; import android.os.Process; Loading @@ -27,10 +28,14 @@ import android.os.SystemClock; import android.util.Log; import android.util.LongSparseArray; import android.util.SparseArray; import android.util.SparseLongArray; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.concurrent.atomic.AtomicInteger; /** Loading Loading @@ -74,6 +79,8 @@ public final class AccessibilityInteractionClient private static final boolean DEBUG = false; private static final boolean CHECK_INTEGRITY = true; private static final long TIMEOUT_INTERACTION_MILLIS = 5000; private static final Object sStaticLock = new Object(); Loading Loading @@ -491,6 +498,9 @@ public final class AccessibilityInteractionClient result = Collections.emptyList(); } clearResultLocked(); if (Build.IS_DEBUGGABLE && CHECK_INTEGRITY) { checkFindAccessibilityNodeInfoResultIntegrity(result); } return result; } } Loading Loading @@ -696,4 +706,56 @@ public final class AccessibilityInteractionClient sConnectionCache.remove(connectionId); } } /** * Checks whether the infos are a fully connected tree with no duplicates. * * @param infos The result list to check. */ private void checkFindAccessibilityNodeInfoResultIntegrity(List<AccessibilityNodeInfo> infos) { if (infos.size() == 0) { return; } // Find the root node. AccessibilityNodeInfo root = infos.get(0); final int infoCount = infos.size(); for (int i = 1; i < infoCount; i++) { for (int j = i; j < infoCount; j++) { AccessibilityNodeInfo candidate = infos.get(j); if (root.getParentNodeId() == candidate.getSourceNodeId()) { root = candidate; break; } } } if (root == null) { Log.e(LOG_TAG, "No root."); } // Check for duplicates. HashSet<AccessibilityNodeInfo> seen = new HashSet<AccessibilityNodeInfo>(); Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>(); fringe.add(root); while (!fringe.isEmpty()) { AccessibilityNodeInfo current = fringe.poll(); if (!seen.add(current)) { Log.e(LOG_TAG, "Duplicate node."); return; } SparseLongArray childIds = current.getChildNodeIds(); final int childCount = childIds.size(); for (int i = 0; i < childCount; i++) { final long childId = childIds.valueAt(i); for (int j = 0; j < infoCount; j++) { AccessibilityNodeInfo child = infos.get(j); if (child.getSourceNodeId() == childId) { fringe.add(child); } } } } final int disconnectedCount = infos.size() - seen.size(); if (disconnectedCount > 0) { Log.e(LOG_TAG, disconnectedCount + " Disconnected nodes."); } } } core/java/android/view/accessibility/AccessibilityNodeInfoCache.java +1 −1 Original line number Diff line number Diff line Loading @@ -244,7 +244,7 @@ public class AccessibilityNodeInfoCache { /** * We are enforcing the invariant for a single accessibility focus. * * @param currentInputFocusId The current input focused node. * @param currentAccessibilityFocusId The current input focused node. */ private void clearSubtreeWithOldAccessibilityFocusLocked(long currentAccessibilityFocusId) { final int cacheSize = mCacheImpl.size(); Loading core/java/android/widget/NumberPicker.java +1 −1 Original line number Diff line number Diff line Loading @@ -2490,7 +2490,7 @@ public class NumberPicker extends LinearLayout { info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INCREMENT); } info.setParent((View) getParent()); info.setParent((View) getParentForAccessibility()); info.setEnabled(NumberPicker.this.isEnabled()); info.setScrollable(true); Rect boundsInParent = mTempRect; Loading Loading
core/java/android/view/AccessibilityInteractionController.java +16 −13 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.util.Poolable; import android.util.PoolableManager; import android.util.Pools; import android.util.SparseLongArray; import android.view.ViewGroup.ChildListForAccessibility; import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeProvider; Loading Loading @@ -623,6 +622,8 @@ final class AccessibilityInteractionController { private static final int MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE = 50; private final ArrayList<View> mTempViewList = new ArrayList<View>(); public void prefetchAccessibilityNodeInfos(View view, int virtualViewId, int prefetchFlags, List<AccessibilityNodeInfo> outInfos) { AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider(); Loading Loading @@ -663,8 +664,6 @@ final class AccessibilityInteractionController { while (parent instanceof View && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) { View parentView = (View) parent; final long parentNodeId = AccessibilityNodeInfo.makeNodeId( parentView.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED); AccessibilityNodeInfo info = parentView.createAccessibilityNodeInfo(); if (info != null) { outInfos.add(info); Loading @@ -678,19 +677,21 @@ final class AccessibilityInteractionController { ViewParent parent = current.getParentForAccessibility(); if (parent instanceof ViewGroup) { ViewGroup parentGroup = (ViewGroup) parent; ChildListForAccessibility children = ChildListForAccessibility.obtain(parentGroup, false); ArrayList<View> children = mTempViewList; children.clear(); try { final int childCount = children.getChildCount(); parentGroup.addChildrenForAccessibility(children); final int childCount = children.size(); for (int i = 0; i < childCount; i++) { if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) { return; } View child = children.getChildAt(i); View child = children.get(i); if (child.getAccessibilityViewId() != current.getAccessibilityViewId() && isShown(child)) { AccessibilityNodeInfo info = null; AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider(); AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider(); if (provider == null) { info = child.createAccessibilityNodeInfo(); } else { Loading @@ -703,7 +704,7 @@ final class AccessibilityInteractionController { } } } finally { children.recycle(); children.clear(); } } } Loading @@ -716,14 +717,16 @@ final class AccessibilityInteractionController { ViewGroup rootGroup = (ViewGroup) root; HashMap<View, AccessibilityNodeInfo> addedChildren = new HashMap<View, AccessibilityNodeInfo>(); ChildListForAccessibility children = ChildListForAccessibility.obtain(rootGroup, false); ArrayList<View> children = mTempViewList; children.clear(); try { final int childCount = children.getChildCount(); root.addChildrenForAccessibility(children); final int childCount = children.size(); for (int i = 0; i < childCount; i++) { if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) { return; } View child = children.getChildAt(i); View child = children.get(i); if (isShown(child)) { AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider(); if (provider == null) { Loading @@ -743,7 +746,7 @@ final class AccessibilityInteractionController { } } } finally { children.recycle(); children.clear(); } if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) { for (Map.Entry<View, AccessibilityNodeInfo> entry : addedChildren.entrySet()) { Loading
core/java/android/view/accessibility/AccessibilityInteractionClient.java +62 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.view.accessibility; import android.accessibilityservice.IAccessibilityServiceConnection; import android.graphics.Rect; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Message; import android.os.Process; Loading @@ -27,10 +28,14 @@ import android.os.SystemClock; import android.util.Log; import android.util.LongSparseArray; import android.util.SparseArray; import android.util.SparseLongArray; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.concurrent.atomic.AtomicInteger; /** Loading Loading @@ -74,6 +79,8 @@ public final class AccessibilityInteractionClient private static final boolean DEBUG = false; private static final boolean CHECK_INTEGRITY = true; private static final long TIMEOUT_INTERACTION_MILLIS = 5000; private static final Object sStaticLock = new Object(); Loading Loading @@ -491,6 +498,9 @@ public final class AccessibilityInteractionClient result = Collections.emptyList(); } clearResultLocked(); if (Build.IS_DEBUGGABLE && CHECK_INTEGRITY) { checkFindAccessibilityNodeInfoResultIntegrity(result); } return result; } } Loading Loading @@ -696,4 +706,56 @@ public final class AccessibilityInteractionClient sConnectionCache.remove(connectionId); } } /** * Checks whether the infos are a fully connected tree with no duplicates. * * @param infos The result list to check. */ private void checkFindAccessibilityNodeInfoResultIntegrity(List<AccessibilityNodeInfo> infos) { if (infos.size() == 0) { return; } // Find the root node. AccessibilityNodeInfo root = infos.get(0); final int infoCount = infos.size(); for (int i = 1; i < infoCount; i++) { for (int j = i; j < infoCount; j++) { AccessibilityNodeInfo candidate = infos.get(j); if (root.getParentNodeId() == candidate.getSourceNodeId()) { root = candidate; break; } } } if (root == null) { Log.e(LOG_TAG, "No root."); } // Check for duplicates. HashSet<AccessibilityNodeInfo> seen = new HashSet<AccessibilityNodeInfo>(); Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>(); fringe.add(root); while (!fringe.isEmpty()) { AccessibilityNodeInfo current = fringe.poll(); if (!seen.add(current)) { Log.e(LOG_TAG, "Duplicate node."); return; } SparseLongArray childIds = current.getChildNodeIds(); final int childCount = childIds.size(); for (int i = 0; i < childCount; i++) { final long childId = childIds.valueAt(i); for (int j = 0; j < infoCount; j++) { AccessibilityNodeInfo child = infos.get(j); if (child.getSourceNodeId() == childId) { fringe.add(child); } } } } final int disconnectedCount = infos.size() - seen.size(); if (disconnectedCount > 0) { Log.e(LOG_TAG, disconnectedCount + " Disconnected nodes."); } } }
core/java/android/view/accessibility/AccessibilityNodeInfoCache.java +1 −1 Original line number Diff line number Diff line Loading @@ -244,7 +244,7 @@ public class AccessibilityNodeInfoCache { /** * We are enforcing the invariant for a single accessibility focus. * * @param currentInputFocusId The current input focused node. * @param currentAccessibilityFocusId The current input focused node. */ private void clearSubtreeWithOldAccessibilityFocusLocked(long currentAccessibilityFocusId) { final int cacheSize = mCacheImpl.size(); Loading
core/java/android/widget/NumberPicker.java +1 −1 Original line number Diff line number Diff line Loading @@ -2490,7 +2490,7 @@ public class NumberPicker extends LinearLayout { info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INCREMENT); } info.setParent((View) getParent()); info.setParent((View) getParentForAccessibility()); info.setEnabled(NumberPicker.this.isEnabled()); info.setScrollable(true); Rect boundsInParent = mTempRect; Loading