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

Commit 5ef2e14b authored by Phil Weaver's avatar Phil Weaver Committed by Android (Google) Code Review
Browse files

Merge "Add tests for accessibility cache."

parents acf09424 b010b127
Loading
Loading
Loading
Loading
+29 −3
Original line number Diff line number Diff line
@@ -23,14 +23,18 @@ import android.util.LongArray;
import android.util.LongSparseArray;
import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.List;

/**
 * Cache for AccessibilityWindowInfos and AccessibilityNodeInfos.
 * It is updated when windows change or nodes change.
 * @hide
 */
final class AccessibilityCache {
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public final class AccessibilityCache {

    private static final String LOG_TAG = "AccessibilityCache";

@@ -40,6 +44,8 @@ final class AccessibilityCache {

    private final Object mLock = new Object();

    private final AccessibilityNodeRefresher mAccessibilityNodeRefresher;

    private long mAccessibilityFocus = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
    private long mInputFocus = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;

@@ -54,6 +60,10 @@ final class AccessibilityCache {
    private final SparseArray<AccessibilityWindowInfo> mTempWindowArray =
            new SparseArray<>();

    public AccessibilityCache(AccessibilityNodeRefresher nodeRefresher) {
        mAccessibilityNodeRefresher = nodeRefresher;
    }

    public void setWindows(List<AccessibilityWindowInfo> windows) {
        synchronized (mLock) {
            if (DEBUG) {
@@ -170,7 +180,7 @@ final class AccessibilityCache {
            return;
        }
        // The node changed so we will just refresh it right now.
        if (cachedInfo.refresh(true)) {
        if (mAccessibilityNodeRefresher.refreshNode(cachedInfo, true)) {
            return;
        }
        // Weird, we could not refresh. Just evict the entire sub-tree.
@@ -285,10 +295,12 @@ final class AccessibilityCache {

                // Also be careful if the parent has changed since the new
                // parent may be a predecessor of the old parent which will
                // add cyclse to the cache.
                // add cycles to the cache.
                final long oldParentId = oldInfo.getParentNodeId();
                if (info.getParentNodeId() != oldParentId) {
                    clearSubTreeLocked(windowId, oldParentId);
                } else {
                    oldInfo.recycle();
                }
           }

@@ -296,6 +308,12 @@ final class AccessibilityCache {
            // will wipe the data of the cached info.
            AccessibilityNodeInfo clone = AccessibilityNodeInfo.obtain(info);
            nodes.put(sourceId, clone);
            if (clone.isAccessibilityFocused()) {
                mAccessibilityFocus = sourceId;
            }
            if (clone.isFocused()) {
                mInputFocus = sourceId;
            }
        }
    }

@@ -383,6 +401,7 @@ final class AccessibilityCache {
            final long childNodeId = current.getChildId(i);
            clearSubTreeRecursiveLocked(nodes, childNodeId);
        }
        current.recycle();
    }

    /**
@@ -505,4 +524,11 @@ final class AccessibilityCache {
            }
        }
    }

    // Layer of indirection included to break dependency chain for testing
    public static class AccessibilityNodeRefresher {
        public boolean refreshNode(AccessibilityNodeInfo info, boolean bypassCache) {
            return info.refresh(bypassCache);
        }
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ public final class AccessibilityInteractionClient
        new SparseArray<>();

    private static final AccessibilityCache sAccessibilityCache =
        new AccessibilityCache();
        new AccessibilityCache(new AccessibilityCache.AccessibilityNodeRefresher());

    /**
     * @return The client for the current thread.
@@ -293,6 +293,9 @@ public final class AccessibilityInteractionClient
                            interactionId);
                    finalizeAndCacheAccessibilityNodeInfos(infos, connectionId);
                    if (infos != null && !infos.isEmpty()) {
                        for (int i = 1; i < infos.size(); i++) {
                            infos.get(i).recycle();
                        }
                        return infos.get(0);
                    }
                }
+14 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.internal.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * This class represents a node of the window content as well as actions that
@@ -553,6 +554,8 @@ public class AccessibilityNodeInfo implements Parcelable {
     */
    private static final int VIRTUAL_DESCENDANT_ID_SHIFT = 32;

    private static final AtomicInteger sNumInstancesInUse = new AtomicInteger();

    /**
     * Gets the accessibility view id which identifies a View in the view three.
     *
@@ -2688,6 +2691,7 @@ public class AccessibilityNodeInfo implements Parcelable {
     */
    public static AccessibilityNodeInfo obtain() {
        AccessibilityNodeInfo info = sPool.acquire();
        sNumInstancesInUse.incrementAndGet();
        return (info != null) ? info : new AccessibilityNodeInfo();
    }

@@ -2715,6 +2719,16 @@ public class AccessibilityNodeInfo implements Parcelable {
    public void recycle() {
        clear();
        sPool.release(this);
        sNumInstancesInUse.decrementAndGet();
    }

    /**
     * @return The number of instances of this class that have been obtained but not recycled.
     *
     * @hide
     */
    public static int getNumInstancesInUse() {
        return sNumInstancesInUse.get();
    }

    /**
+14 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.os.Parcelable;
import android.util.LongArray;
import android.util.Pools.SynchronizedPool;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * This class represents a state snapshot of a window for accessibility
 * purposes. The screen content contains one or more windows where some
@@ -81,6 +83,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
    private static final int MAX_POOL_SIZE = 10;
    private static final SynchronizedPool<AccessibilityWindowInfo> sPool =
            new SynchronizedPool<AccessibilityWindowInfo>(MAX_POOL_SIZE);
    private static final AtomicInteger sNumInstancesInUse = new AtomicInteger();

    // Data.
    private int mType = UNDEFINED;
@@ -400,6 +403,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
        if (info == null) {
            info = new AccessibilityWindowInfo();
        }
        sNumInstancesInUse.incrementAndGet();
        return info;
    }

@@ -436,6 +440,15 @@ public final class AccessibilityWindowInfo implements Parcelable {
        return infoClone;
    }

    /**
     * @return The number of instances of this class that have been obtained but not recycled.
     *
     * @hide
     */
    public static int getNumInstancesInUse() {
        return sNumInstancesInUse.get();
    }

    /**
     * Return an instance back to be reused.
     * <p>
@@ -447,6 +460,7 @@ public final class AccessibilityWindowInfo implements Parcelable {
    public void recycle() {
        clear();
        sPool.release(this);
        sNumInstancesInUse.decrementAndGet();
    }

    @Override
+568 −0

File added.

Preview size limit exceeded, changes collapsed.