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

Commit f6859429 authored by Sally Yuen's avatar Sally Yuen Committed by Android (Google) Code Review
Browse files

Merge "Add and implement cache API"

parents 2e4df87b 70243103
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -3014,6 +3014,8 @@ package android.accessibilityservice {
  public abstract class AccessibilityService extends android.app.Service {
  public abstract class AccessibilityService extends android.app.Service {
    ctor public AccessibilityService();
    ctor public AccessibilityService();
    method public boolean clearCache();
    method public boolean clearCachedSubtree(@NonNull android.view.accessibility.AccessibilityNodeInfo);
    method public final void disableSelf();
    method public final void disableSelf();
    method public final boolean dispatchGesture(@NonNull android.accessibilityservice.GestureDescription, @Nullable android.accessibilityservice.AccessibilityService.GestureResultCallback, @Nullable android.os.Handler);
    method public final boolean dispatchGesture(@NonNull android.accessibilityservice.GestureDescription, @Nullable android.accessibilityservice.AccessibilityService.GestureResultCallback, @Nullable android.os.Handler);
    method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
    method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
@@ -3028,6 +3030,8 @@ package android.accessibilityservice {
    method @NonNull public final android.accessibilityservice.TouchInteractionController getTouchInteractionController(int);
    method @NonNull public final android.accessibilityservice.TouchInteractionController getTouchInteractionController(int);
    method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
    method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
    method @NonNull public final android.util.SparseArray<java.util.List<android.view.accessibility.AccessibilityWindowInfo>> getWindowsOnAllDisplays();
    method @NonNull public final android.util.SparseArray<java.util.List<android.view.accessibility.AccessibilityWindowInfo>> getWindowsOnAllDisplays();
    method public boolean isCacheEnabled();
    method public boolean isNodeInCache(@NonNull android.view.accessibility.AccessibilityNodeInfo);
    method public abstract void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
    method public abstract void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
    method public final android.os.IBinder onBind(android.content.Intent);
    method public final android.os.IBinder onBind(android.content.Intent);
    method @Deprecated protected boolean onGesture(int);
    method @Deprecated protected boolean onGesture(int);
@@ -3038,6 +3042,7 @@ package android.accessibilityservice {
    method public void onSystemActionsChanged();
    method public void onSystemActionsChanged();
    method public final boolean performGlobalAction(int);
    method public final boolean performGlobalAction(int);
    method public void setAccessibilityFocusAppearance(int, @ColorInt int);
    method public void setAccessibilityFocusAppearance(int, @ColorInt int);
    method public boolean setCacheEnabled(boolean);
    method public void setGestureDetectionPassthroughRegion(int, @NonNull android.graphics.Region);
    method public void setGestureDetectionPassthroughRegion(int, @NonNull android.graphics.Region);
    method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
    method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
    method public void setTouchExplorationPassthroughRegion(int, @NonNull android.graphics.Region);
    method public void setTouchExplorationPassthroughRegion(int, @NonNull android.graphics.Region);
+82 −3
Original line number Original line Diff line number Diff line
@@ -59,6 +59,7 @@ import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityCache;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -748,7 +749,6 @@ public abstract class AccessibilityService extends Service {


    private FingerprintGestureController mFingerprintGestureController;
    private FingerprintGestureController mFingerprintGestureController;



    /**
    /**
     * Callback for {@link android.view.accessibility.AccessibilityEvent}s.
     * Callback for {@link android.view.accessibility.AccessibilityEvent}s.
     *
     *
@@ -2076,6 +2076,85 @@ public abstract class AccessibilityService extends Service {
                available);
                available);
    }
    }


    /** Sets the cache status.
     *
     * <p>If {@code enabled}, enable the cache and prefetching. Otherwise, disable the cache
     * and prefetching.
     * Note: By default the cache is enabled.
     * @param enabled whether to enable or disable the cache.
     * @return {@code true} if the cache and connection are not null, so the cache status is set.
     */
    public boolean setCacheEnabled(boolean enabled) {
        AccessibilityCache cache =
                AccessibilityInteractionClient.getCache(mConnectionId);
        if (cache == null) {
            return false;
        }
        final IAccessibilityServiceConnection connection =
                AccessibilityInteractionClient.getConnection(mConnectionId);
        if (connection == null) {
            return false;
        }
        try {
            connection.setCacheEnabled(enabled);
            cache.setEnabled(enabled);
            return true;
        } catch (RemoteException re) {
            Log.w(LOG_TAG, "Error while setting status of cache", re);
            re.rethrowFromSystemServer();
        }
        return false;
    }

    /** Invalidates {@code node} and its subtree in the cache.
     * @param node the node to invalidate.
     * @return {@code true} if the subtree rooted at {@code node} was invalidated.
     */
    public boolean clearCachedSubtree(@NonNull AccessibilityNodeInfo node) {
        AccessibilityCache cache =
                AccessibilityInteractionClient.getCache(mConnectionId);
        if (cache == null) {
            return false;
        }
        return cache.clearSubTree(node);
    }

    /** Clears the cache.
     * @return {@code true} if the cache was cleared
     */
    public boolean clearCache() {
        AccessibilityCache cache =
                AccessibilityInteractionClient.getCache(mConnectionId);
        if (cache == null) {
            return false;
        }
        cache.clear();
        return true;
    }

    /** Checks if {@code node} is in the cache.
     * @param node the node to check.
     * @return {@code true} if {@code node} is in the cache.
     */
    public boolean isNodeInCache(@NonNull AccessibilityNodeInfo node) {
        AccessibilityCache cache =
                AccessibilityInteractionClient.getCache(mConnectionId);
        if (cache == null) {
            return false;
        }
        return cache.isNodeInCache(node);
    }

    /** Returns {@code true} if the cache is enabled. */
    public boolean isCacheEnabled() {
        AccessibilityCache cache =
                AccessibilityInteractionClient.getCache(mConnectionId);
        if (cache == null) {
            return false;
        }
        return cache.isEnabled();
    }

    /** This is called when the system action list is changed. */
    /** This is called when the system action list is changed. */
    public void onSystemActionsChanged() {
    public void onSystemActionsChanged() {
    }
    }
@@ -2613,11 +2692,11 @@ public abstract class AccessibilityService extends Service {
                        mCallback.init(mConnectionId, windowToken);
                        mCallback.init(mConnectionId, windowToken);
                        mCallback.onServiceConnected();
                        mCallback.onServiceConnected();
                    } else {
                    } else {
                        AccessibilityInteractionClient.getInstance(mContext)
                                .clearCache(mConnectionId);
                        AccessibilityInteractionClient.getInstance(mContext).removeConnection(
                        AccessibilityInteractionClient.getInstance(mContext).removeConnection(
                                mConnectionId);
                                mConnectionId);
                        mConnectionId = AccessibilityInteractionClient.NO_ID;
                        mConnectionId = AccessibilityInteractionClient.NO_ID;
                        AccessibilityInteractionClient.getInstance(mContext)
                                .clearCache(mConnectionId);
                        mCallback.init(AccessibilityInteractionClient.NO_ID, null);
                        mCallback.init(AccessibilityInteractionClient.NO_ID, null);
                    }
                    }
                    return;
                    return;
+2 −0
Original line number Original line Diff line number Diff line
@@ -124,6 +124,8 @@ interface IAccessibilityServiceConnection {


    void setFocusAppearance(int strokeWidth, int color);
    void setFocusAppearance(int strokeWidth, int color);


    void setCacheEnabled(boolean enabled);

    oneway void logTrace(long timestamp, String where, long loggingTypes, String callingParams,
    oneway void logTrace(long timestamp, String where, long loggingTypes, String callingParams,
        int processId, long threadId, int callingUid, in Bundle serializedCallingStackInBundle);
        int processId, long threadId, int callingUid, in Bundle serializedCallingStackInBundle);


+104 −0
Original line number Original line Diff line number Diff line
@@ -46,6 +46,8 @@ public class AccessibilityCache {


    private static final boolean CHECK_INTEGRITY = Build.IS_ENG;
    private static final boolean CHECK_INTEGRITY = Build.IS_ENG;


    private boolean mEnabled = true;

    /**
    /**
     * {@link AccessibilityEvent} types that are critical for the cache to stay up to date
     * {@link AccessibilityEvent} types that are critical for the cache to stay up to date
     *
     *
@@ -98,6 +100,21 @@ public class AccessibilityCache {
        mAccessibilityNodeRefresher = nodeRefresher;
        mAccessibilityNodeRefresher = nodeRefresher;
    }
    }


    /** Returns if the cache is enabled. */
    public boolean isEnabled() {
        synchronized (mLock) {
            return mEnabled;
        }
    }

    /** Sets enabled status. */
    public void setEnabled(boolean enabled) {
        synchronized (mLock) {
            mEnabled = enabled;
            clear();
        }
    }

    /**
    /**
     * Sets all {@link AccessibilityWindowInfo}s of all displays into the cache.
     * Sets all {@link AccessibilityWindowInfo}s of all displays into the cache.
     * The key of SparseArray is display ID.
     * The key of SparseArray is display ID.
@@ -110,6 +127,12 @@ public class AccessibilityCache {
            SparseArray<List<AccessibilityWindowInfo>> windowsOnAllDisplays,
            SparseArray<List<AccessibilityWindowInfo>> windowsOnAllDisplays,
            long populationTimeStamp) {
            long populationTimeStamp) {
        synchronized (mLock) {
        synchronized (mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return;
            }
            if (DEBUG) {
            if (DEBUG) {
                Log.i(LOG_TAG, "Set windows");
                Log.i(LOG_TAG, "Set windows");
            }
            }
@@ -148,6 +171,12 @@ public class AccessibilityCache {
     */
     */
    public void addWindow(AccessibilityWindowInfo window) {
    public void addWindow(AccessibilityWindowInfo window) {
        synchronized (mLock) {
        synchronized (mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return;
            }
            if (DEBUG) {
            if (DEBUG) {
                Log.i(LOG_TAG, "Caching window: " + window.getId() + " at display Id [ "
                Log.i(LOG_TAG, "Caching window: " + window.getId() + " at display Id [ "
                        + window.getDisplayId() + " ]");
                        + window.getDisplayId() + " ]");
@@ -177,6 +206,12 @@ public class AccessibilityCache {
    public void onAccessibilityEvent(AccessibilityEvent event) {
    public void onAccessibilityEvent(AccessibilityEvent event) {
        AccessibilityNodeInfo nodeToRefresh = null;
        AccessibilityNodeInfo nodeToRefresh = null;
        synchronized (mLock) {
        synchronized (mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return;
            }
            if (DEBUG) {
            if (DEBUG) {
                Log.i(LOG_TAG, "onAccessibilityEvent(" + event + ")");
                Log.i(LOG_TAG, "onAccessibilityEvent(" + event + ")");
            }
            }
@@ -292,6 +327,12 @@ public class AccessibilityCache {
     */
     */
    public AccessibilityNodeInfo getNode(int windowId, long accessibilityNodeId) {
    public AccessibilityNodeInfo getNode(int windowId, long accessibilityNodeId) {
        synchronized(mLock) {
        synchronized(mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return null;
            }
            LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId);
            LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId);
            if (nodes == null) {
            if (nodes == null) {
                return null;
                return null;
@@ -309,6 +350,28 @@ public class AccessibilityCache {
        }
        }
    }
    }


    /** Returns {@code true} if {@code info} is in the cache. */
    public boolean isNodeInCache(AccessibilityNodeInfo info) {
        if (info == null) {
            return false;
        }
        int windowId = info.getWindowId();
        long accessibilityNodeId = info.getSourceNodeId();
        synchronized (mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return false;
            }
            LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId);
            if (nodes == null) {
                return false;
            }
            return nodes.get(accessibilityNodeId) != null;
        }
    }

    /**
    /**
     * Gets all {@link AccessibilityWindowInfo}s of all displays from the cache.
     * Gets all {@link AccessibilityWindowInfo}s of all displays from the cache.
     *
     *
@@ -317,6 +380,12 @@ public class AccessibilityCache {
     */
     */
    public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
    public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
        synchronized (mLock) {
        synchronized (mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return null;
            }
            if (!mIsAllWindowsCached) {
            if (!mIsAllWindowsCached) {
                return null;
                return null;
            }
            }
@@ -373,6 +442,12 @@ public class AccessibilityCache {
     */
     */
    public AccessibilityWindowInfo getWindow(int windowId) {
    public AccessibilityWindowInfo getWindow(int windowId) {
        synchronized (mLock) {
        synchronized (mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return null;
            }
            final int displayCounts = mWindowCacheByDisplay.size();
            final int displayCounts = mWindowCacheByDisplay.size();
            for (int i = 0; i < displayCounts; i++) {
            for (int i = 0; i < displayCounts; i++) {
                final SparseArray<AccessibilityWindowInfo> windowsOfDisplay =
                final SparseArray<AccessibilityWindowInfo> windowsOfDisplay =
@@ -397,6 +472,12 @@ public class AccessibilityCache {
     */
     */
    public void add(AccessibilityNodeInfo info) {
    public void add(AccessibilityNodeInfo info) {
        synchronized(mLock) {
        synchronized(mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return;
            }
            if (VERBOSE) {
            if (VERBOSE) {
                Log.i(LOG_TAG, "add(" + info + ")");
                Log.i(LOG_TAG, "add(" + info + ")");
            }
            }
@@ -522,6 +603,12 @@ public class AccessibilityCache {
     */
     */
    public AccessibilityNodeInfo getFocus(int focusType, long initialNodeId, int windowId) {
    public AccessibilityNodeInfo getFocus(int focusType, long initialNodeId, int windowId) {
        synchronized (mLock) {
        synchronized (mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return null;
            }
            int currentFocusWindowId;
            int currentFocusWindowId;
            long currentFocusId;
            long currentFocusId;
            if (focusType == FOCUS_ACCESSIBILITY) {
            if (focusType == FOCUS_ACCESSIBILITY) {
@@ -602,6 +689,23 @@ public class AccessibilityCache {
        mNodeCache.remove(windowId);
        mNodeCache.remove(windowId);
    }
    }


    /** Clears a subtree rooted at {@code info}. */
    public boolean clearSubTree(AccessibilityNodeInfo info) {
        if (info == null) {
            return false;
        }
        synchronized (mLock) {
            if (!mEnabled) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Cache is disabled");
                }
                return false;
            }
            clearSubTreeLocked(info.getWindowId(), info.getSourceNodeId());
            return true;
        }
    }

    /**
    /**
     * Clears a subtree rooted at the node with the given id that is
     * Clears a subtree rooted at the node with the given id that is
     * hosted in a given window.
     * hosted in a given window.
+10 −2
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view.accessibility;


import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_INTERACTION_CLIENT;
import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_INTERACTION_CLIENT;
import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION_CALLBACK;
import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION_CALLBACK;
import static android.os.Build.VERSION_CODES.S;


import android.accessibilityservice.IAccessibilityServiceConnection;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.annotation.NonNull;
import android.annotation.NonNull;
@@ -225,6 +226,9 @@ public final class AccessibilityInteractionClient
     */
     */
    public static void addConnection(int connectionId, IAccessibilityServiceConnection connection,
    public static void addConnection(int connectionId, IAccessibilityServiceConnection connection,
            boolean initializeCache) {
            boolean initializeCache) {
        if (connectionId == NO_ID) {
            return;
        }
        synchronized (sConnectionCache) {
        synchronized (sConnectionCache) {
            sConnectionCache.put(connectionId, connection);
            sConnectionCache.put(connectionId, connection);
            if (!initializeCache) {
            if (!initializeCache) {
@@ -554,6 +558,10 @@ public final class AccessibilityInteractionClient
                            }
                            }
                            return cachedInfo;
                            return cachedInfo;
                        }
                        }
                        if (!cache.isEnabled()) {
                            // Skip prefetching if cache is disabled.
                            prefetchFlags &= ~AccessibilityNodeInfo.FLAG_PREFETCH_MASK;
                        }
                        if (DEBUG) {
                        if (DEBUG) {
                            Log.i(LOG_TAG, "Node cache miss for "
                            Log.i(LOG_TAG, "Node cache miss for "
                                    + idToString(accessibilityWindowId, accessibilityNodeId));
                                    + idToString(accessibilityWindowId, accessibilityNodeId));
@@ -970,9 +978,9 @@ public final class AccessibilityInteractionClient
    /**
    /**
     * Clears the cache associated with {@code connectionId}
     * Clears the cache associated with {@code connectionId}
     * @param connectionId the connection id
     * @param connectionId the connection id
     * TODO(207417185): Modify UnsupportedAppUsage
     */
     */
    @UnsupportedAppUsage()
    @UnsupportedAppUsage(maxTargetSdk = S, publicAlternatives =
            "{@link android.accessibilityservice.AccessibilityService#clearCache()}")
    public void clearCache(int connectionId) {
    public void clearCache(int connectionId) {
        AccessibilityCache cache = getCache(connectionId);
        AccessibilityCache cache = getCache(connectionId);
        if (cache == null) {
        if (cache == null) {
Loading