Ensure recents input consumer can be focused in Overview

- Previously, when a fix for b/138622418 was introduced, it also changed
  the behavior to make the windows being animated by recents
  not-touchable, which caused additional checks on the input monitor
  side to handle this case.  But because we already have the recents
  input consumer in place to intercept input, we can leave the window
  touchability as is (as we do in other cases like PIP where we also
  intercept all input), and rely on the existing behavior in input
  monitor to focus the consumer if one of its animating windows is
  focused.

  To not regress on b/138622418, we push the check up to where the
  window is considered for affecting the exclusion rects instead.
  This enabled the followup CL of routing the back gesture to the
  consumer with the new back flow.

Bug: 223750399
Test: Verify b/138622418 - swipe up from home and quickly swipe to
      -1 and ensure back doesn't show
Test: Verify b/191058092 - receive a HUN while in overview and ensure
      input focus switches from recents input consumer -> notif shade
      and IME shows, and then back to the input consumer when finished
Test: Verify b/177923822 - recents input consumer is always focused
      in overview in all nav modes and volume works and is routed to
      launcher to handle


Change-Id: I79160004afc7d6759563ef68a9e2a480ef3d900a
This commit is contained in:
Winson Chung
2022-05-12 23:53:52 +00:00
parent 5815b8820e
commit 34a280bc45
4 changed files with 12 additions and 31 deletions

View File

@@ -5440,13 +5440,18 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
final Region local = Region.obtain();
final int[] remainingLeftRight =
{mSystemGestureExclusionLimit, mSystemGestureExclusionLimit};
final RecentsAnimationController recentsAnimationController =
mWmService.getRecentsAnimationController();
// Traverse all windows top down to assemble the gesture exclusion rects.
// For each window, we only take the rects that fall within its touchable region.
forAllWindows(w -> {
final boolean ignoreRecentsAnimationTarget = recentsAnimationController != null
&& recentsAnimationController.shouldApplyInputConsumer(w.getActivityRecord());
if (!w.canReceiveTouchInput() || !w.isVisible()
|| (w.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0
|| unhandled.isEmpty()) {
|| unhandled.isEmpty()
|| ignoreRecentsAnimationTarget) {
return;
}

View File

@@ -545,12 +545,7 @@ final class InputMonitor {
@Override
public void accept(WindowState w) {
final InputWindowHandleWrapper inputWindowHandle = w.mInputWindowHandle;
final RecentsAnimationController recentsAnimationController =
mService.getRecentsAnimationController();
final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null
&& recentsAnimationController.shouldApplyInputConsumer(w.mActivityRecord);
if (w.mInputChannelToken == null || w.mRemoved
|| (!w.canReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) {
if (w.mInputChannelToken == null || w.mRemoved || !w.canReceiveTouchInput()) {
if (w.mWinAnimator.hasSurface()) {
// Make sure the input info can't receive input event. It may be omitted from
// occlusion detection depending on the type or if it's a trusted overlay.
@@ -566,6 +561,10 @@ final class InputMonitor {
final int privateFlags = w.mAttrs.privateFlags;
// This only works for legacy transitions.
final RecentsAnimationController recentsAnimationController =
mService.getRecentsAnimationController();
final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null
&& recentsAnimationController.shouldApplyInputConsumer(w.mActivityRecord);
if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) {
if (recentsAnimationController.updateInputConsumerForApp(
mRecentsAnimationInputConsumer.mWindowHandle)) {

View File

@@ -3220,19 +3220,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
return !mActivityRecord.getTask().getRootTask().shouldIgnoreInput()
&& mActivityRecord.mVisibleRequested
&& !isRecentsAnimationConsumingAppInput();
}
/**
* Returns {@code true} if the window is animating to home as part of the recents animation and
* it is consuming input from the app.
*/
private boolean isRecentsAnimationConsumingAppInput() {
final RecentsAnimationController recentsAnimationController =
mWmService.getRecentsAnimationController();
return recentsAnimationController != null
&& recentsAnimationController.shouldApplyInputConsumer(mActivityRecord);
&& mActivityRecord.mVisibleRequested;
}
/**

View File

@@ -730,17 +730,6 @@ public class WindowStateTests extends WindowTestsBase {
assertThat(mWm.mResizingWindows).doesNotContain(win);
}
@Test
public void testCantReceiveTouchDuringRecentsAnimation() {
final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
// Mock active recents animation
RecentsAnimationController recentsController = mock(RecentsAnimationController.class);
when(recentsController.shouldApplyInputConsumer(win0.mActivityRecord)).thenReturn(true);
mWm.setRecentsAnimationController(recentsController);
assertFalse(win0.canReceiveTouchInput());
}
@Test
public void testCantReceiveTouchWhenAppTokenHiddenRequested() {
final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");