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
This commit is contained in:
Daniel Norman
2022-09-20 13:25:35 -07:00
parent a73cc8946d
commit 35280c1dc4
2 changed files with 31 additions and 69 deletions

View File

@@ -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);

View File

@@ -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;
}
}
}