diff options
Diffstat (limited to 'core/java')
4 files changed, 80 insertions, 15 deletions
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index 16f9a18..6dc31dd 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -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; @@ -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(); @@ -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); @@ -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 { @@ -703,7 +704,7 @@ final class AccessibilityInteractionController { } } } finally { - children.recycle(); + children.clear(); } } } @@ -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) { @@ -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()) { diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index bd341d0..20b5f17 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -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; @@ -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; /** @@ -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(); @@ -491,6 +498,9 @@ public final class AccessibilityInteractionClient result = Collections.emptyList(); } clearResultLocked(); + if (Build.IS_DEBUGGABLE && CHECK_INTEGRITY) { + checkFindAccessibilityNodeInfoResultIntegrity(result); + } return result; } } @@ -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."); + } + } } diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java index 52b7772..14954be 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java @@ -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(); diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index b825e1b..515f0c4 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -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; |
