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

Commit 6734276b authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Do not prefetching accessibility nodes while a view is scrolling" into...

Merge "Do not prefetching accessibility nodes while a view is scrolling" into rvc-dev am: 7fc16f7c am: e71b948b

Change-Id: Icbf06741339df4ad4318e5591b076152965ab3b9
parents 2b0bd95d e71b948b
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
@@ -31,7 +31,9 @@ import android.os.SystemClock;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseArray;
import android.util.SparseLongArray;
import android.view.Display;
import android.view.ViewConfiguration;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -89,6 +91,9 @@ public final class AccessibilityInteractionClient

    private static final long TIMEOUT_INTERACTION_MILLIS = 5000;

    private static final long DISABLE_PREFETCHING_FOR_SCROLLING_MILLIS =
            (long) (ViewConfiguration.getSendRecurringAccessibilityEventsInterval() * 1.5);

    private static final Object sStaticLock = new Object();

    private static final LongSparseArray<AccessibilityInteractionClient> sClients =
@@ -97,6 +102,10 @@ public final class AccessibilityInteractionClient
    private static final SparseArray<IAccessibilityServiceConnection> sConnectionCache =
            new SparseArray<>();

    /** List of timestamps which indicate the latest time an a11y service receives a scroll event
        from a window, mapping from windowId -> timestamp. */
    private static final SparseLongArray sScrollingWindows = new SparseLongArray();

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

@@ -422,6 +431,14 @@ public final class AccessibilityInteractionClient
                        Log.i(LOG_TAG, "Node cache miss for "
                                + idToString(accessibilityWindowId, accessibilityNodeId));
                    }
                } else {
                    // No need to prefech nodes in bypass cache case.
                    prefetchFlags &= ~AccessibilityNodeInfo.FLAG_PREFETCH_MASK;
                }
                // Skip prefetching if window is scrolling.
                if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_MASK) != 0
                        && isWindowScrolling(accessibilityWindowId)) {
                    prefetchFlags &= ~AccessibilityNodeInfo.FLAG_PREFETCH_MASK;
                }
                final int interactionId = mInteractionIdCounter.getAndIncrement();
                final long identityToken = Binder.clearCallingIdentity();
@@ -718,6 +735,18 @@ public final class AccessibilityInteractionClient
    }

    public void onAccessibilityEvent(AccessibilityEvent event) {
        switch (event.getEventType()) {
            case AccessibilityEvent.TYPE_VIEW_SCROLLED:
                updateScrollingWindow(event.getWindowId(), SystemClock.uptimeMillis());
                break;
            case AccessibilityEvent.TYPE_WINDOWS_CHANGED:
                if (event.getWindowChanges() == AccessibilityEvent.WINDOWS_CHANGE_REMOVED) {
                    deleteScrollingWindow(event.getWindowId());
                }
                break;
            default:
                break;
        }
        sAccessibilityCache.onAccessibilityEvent(event);
    }

@@ -986,4 +1015,48 @@ public final class AccessibilityInteractionClient
            Log.e(LOG_TAG, disconnectedCount + " Disconnected nodes.");
        }
    }

    /**
     * Update scroll event timestamp of a given window.
     *
     * @param windowId The window id.
     * @param uptimeMillis Device uptime millis.
     */
    private void updateScrollingWindow(int windowId, long uptimeMillis) {
        synchronized (sScrollingWindows) {
            sScrollingWindows.put(windowId, uptimeMillis);
        }
    }

    /**
     * Remove a window from the scrolling windows list.
     *
     * @param windowId The window id.
     */
    private void deleteScrollingWindow(int windowId) {
        synchronized (sScrollingWindows) {
            sScrollingWindows.delete(windowId);
        }
    }

    /**
     * Whether or not the window is scrolling.
     *
     * @param windowId
     * @return true if it's scrolling.
     */
    private boolean isWindowScrolling(int windowId) {
        synchronized (sScrollingWindows) {
            final long latestScrollingTime = sScrollingWindows.get(windowId);
            if (latestScrollingTime == 0) {
                return false;
            }
            final long currentUptime = SystemClock.uptimeMillis();
            if (currentUptime > (latestScrollingTime + DISABLE_PREFETCHING_FOR_SCROLLING_MILLIS)) {
                sScrollingWindows.delete(windowId);
                return false;
            }
        }
        return true;
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -137,6 +137,9 @@ public class AccessibilityNodeInfo implements Parcelable {
    /** @hide */
    public static final int FLAG_PREFETCH_DESCENDANTS = 0x00000004;

    /** @hide */
    public static final int FLAG_PREFETCH_MASK = 0x00000007;

    /** @hide */
    public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x00000008;