Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f22a7c34 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android Git Automerger
Browse files

am a379e733: am 67d10a58: Merge "Prefetching of accessibility node infos...

am a379e733: am 67d10a58: Merge "Prefetching of accessibility node infos getting incorrect views." into jb-dev

* commit 'a379e733':
  Prefetching of accessibility node infos getting incorrect views.
parents 7dea5abd a379e733
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -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()) {
+62 −0
Original line number Diff line number Diff line
@@ -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.");
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -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();
+1 −1
Original line number Diff line number Diff line
@@ -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;