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

Commit 38a0b536 authored by Jacky Kao's avatar Jacky Kao Committed by Android (Google) Code Review
Browse files

Merge "Modifying the mechanism of A11y window cache"

parents ca0faeb5 35b8966e
Loading
Loading
Loading
Loading
+150 −54
Original line number Diff line number Diff line
@@ -71,7 +71,9 @@ public class AccessibilityCache {

    private boolean mIsAllWindowsCached;

    private final SparseArray<AccessibilityWindowInfo> mWindowCache =
    // The SparseArray of all {@link AccessibilityWindowInfo}s on all displays.
    // The key of outer SparseArray is display ID and the key of inner SparseArray is window ID.
    private final SparseArray<SparseArray<AccessibilityWindowInfo>> mWindowCacheByDisplay =
            new SparseArray<>();

    private final SparseArray<LongSparseArray<AccessibilityNodeInfo>> mNodeCache =
@@ -84,34 +86,66 @@ public class AccessibilityCache {
        mAccessibilityNodeRefresher = nodeRefresher;
    }

    public void setWindows(List<AccessibilityWindowInfo> windows) {
    /**
     * Sets all {@link AccessibilityWindowInfo}s of all displays into the cache.
     * The key of SparseArray is display ID.
     *
     * @param windowsOnAllDisplays The accessibility windows of all displays.
     */
    public void setWindowsOnAllDisplays(
            SparseArray<List<AccessibilityWindowInfo>> windowsOnAllDisplays) {
        synchronized (mLock) {
            if (DEBUG) {
                Log.i(LOG_TAG, "Set windows");
            }
            clearWindowCache();
            if (windows == null) {
            clearWindowCacheLocked();
            if (windowsOnAllDisplays == null) {
                return;
            }
            final int windowCount = windows.size();
            for (int i = 0; i < windowCount; i++) {
                final AccessibilityWindowInfo window = windows.get(i);
                addWindow(window);

            final int displayCounts = windowsOnAllDisplays.size();
            for (int i = 0; i < displayCounts; i++) {
                final List<AccessibilityWindowInfo> windowsOfDisplay =
                        windowsOnAllDisplays.valueAt(i);

                if (windowsOfDisplay == null) {
                    continue;
                }

                final int displayId = windowsOnAllDisplays.keyAt(i);
                final int windowCount = windowsOfDisplay.size();
                for (int j = 0; j < windowCount; j++) {
                    addWindowByDisplayLocked(displayId, windowsOfDisplay.get(j));
                }
            }
            mIsAllWindowsCached = true;
        }
    }

    /**
     * Sets an {@link AccessibilityWindowInfo} into the cache.
     *
     * @param window The accessibility window.
     */
    public void addWindow(AccessibilityWindowInfo window) {
        synchronized (mLock) {
            if (DEBUG) {
                Log.i(LOG_TAG, "Caching window: " + window.getId());
                Log.i(LOG_TAG, "Caching window: " + window.getId() + " at display Id [ "
                        + window.getDisplayId() + " ]");
            }
            final int windowId = window.getId();
            mWindowCache.put(windowId, new AccessibilityWindowInfo(window));
            addWindowByDisplayLocked(window.getDisplayId(), window);
        }
    }

    private void addWindowByDisplayLocked(int displayId, AccessibilityWindowInfo window) {
        SparseArray<AccessibilityWindowInfo> windows = mWindowCacheByDisplay.get(displayId);
        if (windows == null) {
            windows = new SparseArray<>();
            mWindowCacheByDisplay.put(displayId, windows);
        }
        final int windowId = window.getId();
        windows.put(windowId, new AccessibilityWindowInfo(window));
    }
    /**
     * Notifies the cache that the something in the UI changed. As a result
     * the cache will either refresh some nodes or evict some nodes.
@@ -236,45 +270,83 @@ public class AccessibilityCache {
        }
    }

    public List<AccessibilityWindowInfo> getWindows() {
    /**
     * Gets all {@link AccessibilityWindowInfo}s of all displays from the cache.
     *
     * @return All cached {@link AccessibilityWindowInfo}s of all displays
     *         or null if such not found. The key of SparseArray is display ID.
     */
    public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
        synchronized (mLock) {
            if (!mIsAllWindowsCached) {
                return null;
            }
            final SparseArray<List<AccessibilityWindowInfo>> returnWindows = new SparseArray<>();
            final int displayCounts = mWindowCacheByDisplay.size();

            if (displayCounts > 0) {
                for (int i = 0; i < displayCounts; i++) {
                    final int displayId = mWindowCacheByDisplay.keyAt(i);
                    final SparseArray<AccessibilityWindowInfo> windowsOfDisplay =
                            mWindowCacheByDisplay.valueAt(i);

                    if (windowsOfDisplay == null) {
                        continue;
                    }

            final int windowCount = mWindowCache.size();
                    final int windowCount = windowsOfDisplay.size();
                    if (windowCount > 0) {
                        // Careful to return the windows in a decreasing layer order.
                        SparseArray<AccessibilityWindowInfo> sortedWindows = mTempWindowArray;
                        sortedWindows.clear();

                for (int i = 0; i < windowCount; i++) {
                    AccessibilityWindowInfo window = mWindowCache.valueAt(i);
                        for (int j = 0; j < windowCount; j++) {
                            AccessibilityWindowInfo window = windowsOfDisplay.valueAt(j);
                            sortedWindows.put(window.getLayer(), window);
                        }

                        // It's possible in transient conditions for two windows to share the same
                // layer, which results in sortedWindows being smaller than mWindowCache
                        // layer, which results in sortedWindows being smaller than
                        // mWindowCacheByDisplay
                        final int sortedWindowCount = sortedWindows.size();
                List<AccessibilityWindowInfo> windows = new ArrayList<>(sortedWindowCount);
                for (int i = sortedWindowCount - 1; i >= 0; i--) {
                    AccessibilityWindowInfo window = sortedWindows.valueAt(i);
                        List<AccessibilityWindowInfo> windows =
                                new ArrayList<>(sortedWindowCount);
                        for (int j = sortedWindowCount - 1; j >= 0; j--) {
                            AccessibilityWindowInfo window = sortedWindows.valueAt(j);
                            windows.add(new AccessibilityWindowInfo(window));
                    sortedWindows.removeAt(i);
                            sortedWindows.removeAt(j);
                        }
                        returnWindows.put(displayId, windows);
                    }

                return windows;
                }
                return returnWindows;
            }
            return null;
        }
    }

    /**
     * Gets an {@link AccessibilityWindowInfo} by windowId.
     *
     * @param windowId The id of the window.
     *
     * @return The {@link AccessibilityWindowInfo} or null if such not found.
     */
    public AccessibilityWindowInfo getWindow(int windowId) {
        synchronized (mLock) {
            AccessibilityWindowInfo window = mWindowCache.get(windowId);
            final int displayCounts = mWindowCacheByDisplay.size();
            for (int i = 0; i < displayCounts; i++) {
                final SparseArray<AccessibilityWindowInfo> windowsOfDisplay =
                        mWindowCacheByDisplay.valueAt(i);
                if (windowsOfDisplay == null) {
                    continue;
                }

                AccessibilityWindowInfo window = windowsOfDisplay.get(windowId);
                if (window != null) {
                    return new AccessibilityWindowInfo(window);
                }
            }
            return null;
        }
    }
@@ -358,7 +430,7 @@ public class AccessibilityCache {
            if (DEBUG) {
                Log.i(LOG_TAG, "clear()");
            }
            clearWindowCache();
            clearWindowCacheLocked();
            final int nodesForWindowCount = mNodeCache.size();
            for (int i = nodesForWindowCount - 1; i >= 0; i--) {
                final int windowId = mNodeCache.keyAt(i);
@@ -370,8 +442,23 @@ public class AccessibilityCache {
        }
    }

    private void clearWindowCache() {
        mWindowCache.clear();
    private void clearWindowCacheLocked() {
        if (DEBUG) {
            Log.i(LOG_TAG, "clearWindowCacheLocked");
        }
        final int displayCounts = mWindowCacheByDisplay.size();

        if (displayCounts > 0) {
            for (int i = displayCounts - 1; i >= 0; i--) {
                final int displayId = mWindowCacheByDisplay.keyAt(i);
                final SparseArray<AccessibilityWindowInfo> windows =
                        mWindowCacheByDisplay.get(displayId);
                if (windows != null) {
                    windows.clear();
                }
                mWindowCacheByDisplay.remove(displayId);
            }
        }
        mIsAllWindowsCached = false;
    }

@@ -444,16 +531,25 @@ public class AccessibilityCache {
    public void checkIntegrity() {
        synchronized (mLock) {
            // Get the root.
            if (mWindowCache.size() <= 0 && mNodeCache.size() == 0) {
            if (mWindowCacheByDisplay.size() <= 0 && mNodeCache.size() == 0) {
                return;
            }

            AccessibilityWindowInfo focusedWindow = null;
            AccessibilityWindowInfo activeWindow = null;

            final int windowCount = mWindowCache.size();
            for (int i = 0; i < windowCount; i++) {
                AccessibilityWindowInfo window = mWindowCache.valueAt(i);
            final int displayCounts = mWindowCacheByDisplay.size();
            for (int i = 0; i < displayCounts; i++) {
                final SparseArray<AccessibilityWindowInfo> windowsOfDisplay =
                        mWindowCacheByDisplay.valueAt(i);

                if (windowsOfDisplay == null) {
                    continue;
                }

                final int windowCount = windowsOfDisplay.size();
                for (int j = 0; j < windowCount; j++) {
                    final AccessibilityWindowInfo window = windowsOfDisplay.valueAt(j);

                    // Check for one active window.
                    if (window.isActive()) {
@@ -463,7 +559,6 @@ public class AccessibilityCache {
                            activeWindow = window;
                        }
                    }

                    // Check for one focused window.
                    if (window.isFocused()) {
                        if (focusedWindow != null) {
@@ -473,6 +568,7 @@ public class AccessibilityCache {
                        }
                    }
                }
            }

            // Traverse the tree and do some checks.
            AccessibilityNodeInfo accessFocus = null;
+9 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.SystemClock;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseArray;
import android.view.Display;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -267,12 +268,14 @@ public final class AccessibilityInteractionClient
        try {
            IAccessibilityServiceConnection connection = getConnection(connectionId);
            if (connection != null) {
                List<AccessibilityWindowInfo> windows = sAccessibilityCache.getWindows();
                if (windows != null) {
                SparseArray<List<AccessibilityWindowInfo>> allWindows =
                        sAccessibilityCache.getWindowsOnAllDisplays();
                List<AccessibilityWindowInfo> windows;
                if (allWindows != null) {
                    if (DEBUG) {
                        Log.i(LOG_TAG, "Windows cache hit");
                    }
                    return windows;
                    return allWindows.valueAt(Display.DEFAULT_DISPLAY);
                }
                if (DEBUG) {
                    Log.i(LOG_TAG, "Windows cache miss");
@@ -284,7 +287,9 @@ public final class AccessibilityInteractionClient
                    Binder.restoreCallingIdentity(identityToken);
                }
                if (windows != null) {
                    sAccessibilityCache.setWindows(windows);
                    allWindows = new SparseArray<>();
                    allWindows.put(Display.DEFAULT_DISPLAY, windows);
                    sAccessibilityCache.setWindowsOnAllDisplays(allWindows);
                    return windows;
                }
            } else {
+197 −21

File changed.

Preview size limit exceeded, changes collapsed.