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

Commit c3281200 authored by Maxim Bogatov's avatar Maxim Bogatov
Browse files

Prevent AccessibilityInteractionClient.getWindows()

returns partially cached windows list.

It could happen that AccessibilityWindowInfo cache is
cleared. And after that calling
AccessibilityInteractionClient.getWindow(windowId)
would add that window to cache. And while cache is
not empty after that AccessibilityInteractionClient
returns its content on getWindows() request even
if it does not contain all windows.

Change-Id: I70dc96d50e3368285fd482a98769a93ae2c15f22
parent 5da678f7
Loading
Loading
Loading
Loading
+35 −6
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ final class AccessibilityCache {
    private long mAccessibilityFocus = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
    private long mInputFocus = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;

    private boolean mIsAllWindowsCached;

    private final SparseArray<AccessibilityWindowInfo> mWindowCache =
            new SparseArray<>();

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

    public void setWindows(List<AccessibilityWindowInfo> windows) {
        synchronized (mLock) {
            if (DEBUG) {
                Log.i(LOG_TAG, "Set windows");
            }
            clearWindowCache();
            if (windows == null) {
                return;
            }
            final int windowCount = windows.size();
            for (int i = 0; i < windowCount; i++) {
                final AccessibilityWindowInfo window = windows.get(i);
                addWindow(window);
            }
            mIsAllWindowsCached = true;
        }
    }

    public void addWindow(AccessibilityWindowInfo window) {
        synchronized (mLock) {
            if (DEBUG) {
@@ -186,6 +206,10 @@ final class AccessibilityCache {

    public List<AccessibilityWindowInfo> getWindows() {
        synchronized (mLock) {
            if (!mIsAllWindowsCached) {
                return null;
            }

            final int windowCount = mWindowCache.size();
            if (windowCount > 0) {
                // Careful to return the windows in a decreasing layer order.
@@ -280,12 +304,7 @@ final class AccessibilityCache {
            if (DEBUG) {
                Log.i(LOG_TAG, "clear()");
            }
            final int windowCount = mWindowCache.size();
            for (int i = windowCount - 1; i >= 0; i--) {
                AccessibilityWindowInfo window = mWindowCache.valueAt(i);
                window.recycle();
                mWindowCache.removeAt(i);
            }
            clearWindowCache();
            final int nodesForWindowCount = mNodeCache.size();
            for (int i = 0; i < nodesForWindowCount; i++) {
                final int windowId = mNodeCache.keyAt(i);
@@ -297,6 +316,16 @@ final class AccessibilityCache {
        }
    }

    private void clearWindowCache() {
        final int windowCount = mWindowCache.size();
        for (int i = windowCount - 1; i >= 0; i--) {
            AccessibilityWindowInfo window = mWindowCache.valueAt(i);
            window.recycle();
            mWindowCache.removeAt(i);
        }
        mIsAllWindowsCached = false;
    }

    private void clearNodesForWindowLocked(int windowId) {
        if (DEBUG) {
            Log.i(LOG_TAG, "clearNodesForWindowLocked(" + windowId + ")");
+1 −5
Original line number Diff line number Diff line
@@ -228,11 +228,7 @@ public final class AccessibilityInteractionClient
                windows = connection.getWindows();
                Binder.restoreCallingIdentity(identityToken);
                if (windows != null) {
                    final int windowCount = windows.size();
                    for (int i = 0; i < windowCount; i++) {
                        AccessibilityWindowInfo window = windows.get(i);
                        sAccessibilityCache.addWindow(window);
                    }
                    sAccessibilityCache.setWindows(windows);
                    return windows;
                }
            } else {