From 35280c1dc4e9777d41d56f8a2cd991a577d3b7c8 Mon Sep 17 00:00:00 2001 From: Daniel Norman Date: Tue, 20 Sep 2022 13:25:35 -0700 Subject: [PATCH] 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 --- .../server/wm/AccessibilityController.java | 32 ++------- .../wm/AccessibilityWindowsPopulator.java | 68 +++++++------------ 2 files changed, 31 insertions(+), 69 deletions(-) diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 804689a219b48..f1b011f170709 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -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 out, Set 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); diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java index 79ae66250a636..d0c381e9debca 100644 --- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java +++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java @@ -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; } } }