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

Commit 35280c1d authored by Daniel Norman's avatar Daniel Norman
Browse files

Remove special case handling for letterboxBounds.

InputWindowHandles for the letterboxes are already provided by the
WindowInfosListener callback, so we can directly use those in the various
calculations in these files. However, those handles have no IWindow
token so we instead look for non-empty frame & non-empty touch region
to decide which windows to include in calculations.

Windows without an IWindow token are still excluded from being passed
back to accessibility services.

Fix: 199358388
Test: open app in letterbox mode, use logging to check that
      AccessibilityController stops iterating once the letterbox
      windows fill up the remaining screen bounds
Test: atest CtsAccessibilityServiceTestCases
Change-Id: I625afa17711fcd52bbb7fe9a9ba51500eb1bef5c
parent a73cc894
Loading
Loading
Loading
Loading
+5 −27
Original line number Diff line number Diff line
@@ -965,13 +965,6 @@ final class AccessibilityController {
                        availableBounds.op(navBarInsets, Region.Op.DIFFERENCE);
                    }

                    // Count letterbox into nonMagnifiedBounds
                    if (windowState.areAppWindowBoundsLetterboxed()) {
                        Region letterboxBounds = getLetterboxBounds(windowState);
                        nonMagnifiedBounds.op(letterboxBounds, Region.Op.UNION);
                        availableBounds.op(letterboxBounds, Region.Op.DIFFERENCE);
                    }

                    // Update accounted bounds
                    Region accountedBounds = mTempRegion2;
                    accountedBounds.set(mMagnificationRegion);
@@ -1411,20 +1404,6 @@ final class AccessibilityController {
        return source != null ? source.getFrame() : EMPTY_RECT;
    }

    static Region getLetterboxBounds(WindowState windowState) {
        final ActivityRecord appToken = windowState.mActivityRecord;
        if (appToken == null) {
            return new Region();
        }
        final Rect letterboxInsets = appToken.getLetterboxInsets();
        final Rect nonLetterboxRect = windowState.getBounds();
        nonLetterboxRect.inset(letterboxInsets);
        final Region letterboxBounds = new Region();
        letterboxBounds.set(windowState.getBounds());
        letterboxBounds.op(nonLetterboxRect, Region.Op.DIFFERENCE);
        return letterboxBounds;
    }

    /**
     * This class encapsulates the functionality related to computing the windows
     * reported for accessibility purposes. These windows are all windows a sighted
@@ -1678,18 +1657,17 @@ final class AccessibilityController {
                a11yWindow.getTouchableRegionInScreen(touchableRegion);
                unaccountedSpace.op(touchableRegion, unaccountedSpace,
                        Region.Op.REVERSE_DIFFERENCE);
                // Account for the space of letterbox.
                final Region letterboxBounds = mTempRegion1;
                if (a11yWindow.setLetterBoxBoundsIfNeeded(letterboxBounds)) {
                    unaccountedSpace.op(letterboxBounds,
                            unaccountedSpace, Region.Op.REVERSE_DIFFERENCE);
                }
            }
        }

        private static void addPopulatedWindowInfo(AccessibilityWindow a11yWindow,
                Region regionInScreen, List<WindowInfo> out, Set<IBinder> tokenOut) {
            final WindowInfo window = a11yWindow.getWindowInfo();
            if (window.token == null) {
                // The window was used in calculating visible windows but does not have an
                // associated IWindow token, so exclude it from the list returned to accessibility.
                return;
            }
            window.regionInScreen.set(regionInScreen);
            window.layer = tokenOut.size();
            out.add(window);
+26 −42
Original line number Diff line number Diff line
@@ -153,7 +153,11 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
        for (InputWindowHandle window : windowHandles) {
            final boolean visible = (window.inputConfig & InputConfig.NOT_VISIBLE) == 0;
            final boolean isNotClone = (window.inputConfig & InputConfig.CLONE) == 0;
            if (visible && window.getWindow() != null && isNotClone) {
            final boolean hasTouchableRegion = !window.touchableRegion.isEmpty();
            final boolean hasNonEmptyFrame =
                    (window.frameBottom != window.frameTop) && (window.frameLeft
                            != window.frameRight);
            if (visible && isNotClone && hasTouchableRegion && hasNonEmptyFrame) {
                tempVisibleWindows.add(window);
            }
        }
@@ -321,10 +325,20 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
        // the old and new windows at the same index should be the
        // same, otherwise something changed.
        for (int i = 0; i < windowsCount; i++) {
            final InputWindowHandle newWindow = newWindows.get(i);
            final InputWindowHandle oldWindow = oldWindows.get(i);
            final IWindow newWindowToken = newWindows.get(i).getWindow();
            final IWindow oldWindowToken = oldWindows.get(i).getWindow();
            final boolean hasNewWindowToken = newWindowToken != null;
            final boolean hasOldWindowToken = oldWindowToken != null;

            if (!newWindow.getWindow().asBinder().equals(oldWindow.getWindow().asBinder())) {
            // If window token presence has changed then the windows have changed.
            if (hasNewWindowToken != hasOldWindowToken) {
                return true;
            }

            // If both old and new windows had window tokens, but those tokens differ,
            // then the windows have changed.
            if (hasNewWindowToken && hasOldWindowToken
                    && !newWindowToken.asBinder().equals(oldWindowToken.asBinder())) {
                return true;
            }
        }
@@ -374,7 +388,8 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
        for (int index = inputWindowHandles.size() - 1; index >= 0; index--) {
            final Matrix windowTransformMatrix = mTempMatrix2;
            final InputWindowHandle windowHandle = inputWindowHandles.get(index);
            final IBinder iBinder = windowHandle.getWindow().asBinder();
            final IBinder iBinder =
                    windowHandle.getWindow() != null ? windowHandle.getWindow().asBinder() : null;

            if (getWindowTransformMatrix(iBinder, windowTransformMatrix)) {
                generateMagnificationSpecInverseMatrix(windowHandle, currentMagnificationSpec,
@@ -609,7 +624,6 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
        private boolean mIgnoreDuetoRecentsAnimation;
        private final Region mTouchableRegionInScreen = new Region();
        private final Region mTouchableRegionInWindow = new Region();
        private final Region mLetterBoxBounds = new Region();
        private WindowInfo mWindowInfo;


@@ -628,11 +642,11 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {

            final AccessibilityWindow instance = new AccessibilityWindow();

            instance.mWindow = inputWindowHandle.getWindow();
            instance.mWindow = window;
            instance.mDisplayId = inputWindowHandle.displayId;
            instance.mInputConfig = inputWindowHandle.inputConfig;
            instance.mType = inputWindowHandle.layoutParamsType;
            instance.mIsPIPMenu = inputWindowHandle.getWindow().asBinder().equals(pipIBinder);
            instance.mIsPIPMenu = window != null && window.asBinder().equals(pipIBinder);

            // TODO (b/199357848): gets the private flag of the window from other way.
            instance.mPrivateFlags = windowState != null ? windowState.mAttrs.privateFlags : 0;
@@ -644,11 +658,6 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            instance.mIgnoreDuetoRecentsAnimation = windowState != null && controller != null
                    && controller.shouldIgnoreForAccessibility(windowState);

            // TODO (b/199358388) : gets the letterbox bounds of the window from other way.
            if (windowState != null && windowState.areAppWindowBoundsLetterboxed()) {
                getLetterBoxBounds(windowState, instance.mLetterBoxBounds);
            }

            final Rect windowFrame = new Rect(inputWindowHandle.frameLeft,
                    inputWindowHandle.frameTop, inputWindowHandle.frameRight,
                    inputWindowHandle.frameBottom);
@@ -723,21 +732,6 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            return mWindowInfo;
        }

        /**
         * Gets the letter box bounds if activity bounds are letterboxed
         * or letterboxed for display cutout.
         *
         * @return {@code true} there's a letter box bounds.
         */
        public Boolean setLetterBoxBoundsIfNeeded(Region outBounds) {
            if (mLetterBoxBounds.isEmpty()) {
                return false;
            }

            outBounds.set(mLetterBoxBounds);
            return true;
        }

        /**
         * @return true if this window should be magnified.
         */
@@ -841,7 +835,7 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            WindowInfo windowInfo = WindowInfo.obtain();
            windowInfo.displayId = window.mDisplayId;
            windowInfo.type = window.mType;
            windowInfo.token = window.mWindow.asBinder();
            windowInfo.token = window.mWindow != null ? window.mWindow.asBinder() : null;
            windowInfo.hasFlagWatchOutsideTouch = (window.mInputConfig
                    & InputConfig.WATCH_OUTSIDE_TOUCH) != 0;
            // Set it to true to be consistent with the legacy implementation.
@@ -849,18 +843,11 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            return windowInfo;
        }

        private static void getLetterBoxBounds(WindowState windowState, Region outRegion) {
            final Rect letterboxInsets = windowState.mActivityRecord.getLetterboxInsets();
            final Rect nonLetterboxRect = windowState.getBounds();

            nonLetterboxRect.inset(letterboxInsets);
            outRegion.set(windowState.getBounds());
            outRegion.op(nonLetterboxRect, Region.Op.DIFFERENCE);
        }

        @Override
        public String toString() {
            String builder = "A11yWindow=[" + mWindow.asBinder()
            String windowToken =
                    mWindow != null ? mWindow.asBinder().toString() : "(no window token)";
            return "A11yWindow=[" + windowToken
                    + ", displayId=" + mDisplayId
                    + ", inputConfig=0x" + Integer.toHexString(mInputConfig)
                    + ", type=" + mType
@@ -871,12 +858,9 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
                    + ", isTrustedOverlay=" + isTrustedOverlay()
                    + ", regionInScreen=" + mTouchableRegionInScreen
                    + ", touchableRegion=" + mTouchableRegionInWindow
                    + ", letterBoxBounds=" + mLetterBoxBounds
                    + ", isPIPMenu=" + mIsPIPMenu
                    + ", windowInfo=" + mWindowInfo
                    + "]";

            return builder;
        }
    }
}