summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Winson Chung <winsonc@google.com> 2022-05-18 17:23:38 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-05-18 17:23:38 +0000
commit35640f948e248324401defb4e39a62928509bc28 (patch)
tree224aace7fb7cd4d4fb18c5c60acb4d856236ec8e
parentc3b917ad972f7a0417022e5201fe3a9ab9c332dd (diff)
parent03df66775f830c42899b8b599d03fafe6a8bbceb (diff)
Merge changes I1978ce3a,I79160004 into tm-dev
* changes: Add workaround for new back flow with legacy recents animation Ensure recents input consumer can be focused in Overview
-rw-r--r--data/etc/services.core.protolog.json12
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java25
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java7
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java11
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java53
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java11
7 files changed, 95 insertions, 38 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 12d3d642a862..51ed8567063e 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1657,6 +1657,12 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/Task.java"
},
+ "-451552570": {
+ "message": "Current focused window being animated by recents. Overriding back callback to recents controller callback.",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_BACK_PREVIEW",
+ "at": "com\/android\/server\/wm\/BackNavigationController.java"
+ },
"-449118559": {
"message": "Trying to update display configuration for invalid process, pid=%d",
"level": "WARN",
@@ -2917,12 +2923,6 @@
"group": "WM_DEBUG_LOCKTASK",
"at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
},
- "716528224": {
- "message": "Focused window found using wmService.getFocusedWindowLocked()",
- "level": "DEBUG",
- "group": "WM_DEBUG_BACK_PREVIEW",
- "at": "com\/android\/server\/wm\/BackNavigationController.java"
- },
"726205185": {
"message": "Moving to DESTROYED: %s (destroy skipped)",
"level": "VERBOSE",
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 247117e707c8..dac72d820251 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -145,6 +145,27 @@ class BackNavigationController {
"Focused window found using getFocusedWindowToken");
}
+ OnBackInvokedCallbackInfo overrideCallbackInfo = null;
+ if (window != null) {
+ // This is needed to bridge the old and new back behavior with recents. While in
+ // Overview with live tile enabled, the previous app is technically focused but we
+ // add an input consumer to capture all input that would otherwise go to the apps
+ // being controlled by the animation. This means that the window resolved is not
+ // the right window to consume back while in overview, so we need to route it to
+ // launcher and use the legacy behavior of injecting KEYCODE_BACK since the existing
+ // compat callback in VRI only works when the window is focused.
+ final RecentsAnimationController recentsAnimationController =
+ wmService.getRecentsAnimationController();
+ if (recentsAnimationController != null
+ && recentsAnimationController.shouldApplyInputConsumer(
+ window.getActivityRecord())) {
+ window = recentsAnimationController.getTargetAppMainWindow();
+ overrideCallbackInfo = recentsAnimationController.getBackInvokedInfo();
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Current focused window being animated by "
+ + "recents. Overriding back callback to recents controller callback.");
+ }
+ }
+
if (window == null) {
// We don't have any focused window, fallback ont the top currentTask of the focused
// display.
@@ -159,7 +180,9 @@ class BackNavigationController {
if (window != null) {
currentActivity = window.mActivityRecord;
currentTask = window.getTask();
- callbackInfo = window.getOnBackInvokedCallbackInfo();
+ callbackInfo = overrideCallbackInfo != null
+ ? overrideCallbackInfo
+ : window.getOnBackInvokedCallbackInfo();
if (callbackInfo == null) {
Slog.e(TAG, "No callback registered, returning null.");
return null;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 66eca990b14f..c60dfa1ed8ba 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -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;
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index ce416ad89c95..7e06b8823260 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -559,12 +559,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.
@@ -580,6 +575,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)) {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index b61af2f9febe..fe0ab2b39909 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -19,10 +19,12 @@ package com.android.server.wm;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.hardware.input.InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.window.OnBackInvokedDispatcher.PRIORITY_DEFAULT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -39,6 +41,7 @@ import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
+import android.hardware.input.InputManager;
import android.os.Binder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
@@ -51,12 +54,18 @@ import android.util.SparseBooleanArray;
import android.util.proto.ProtoOutputStream;
import android.view.IRecentsAnimationController;
import android.view.IRecentsAnimationRunner;
+import android.view.InputDevice;
import android.view.InputWindowHandle;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
import android.view.WindowInsets.Type;
+import android.window.BackEvent;
+import android.window.IOnBackInvokedCallback;
+import android.window.OnBackInvokedCallbackInfo;
import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot;
@@ -194,6 +203,46 @@ public class RecentsAnimationController implements DeathRecipient {
}
};
+ /**
+ * Back invoked callback for legacy recents transition with the new back dispatch system.
+ */
+ final IOnBackInvokedCallback mBackCallback = new IOnBackInvokedCallback.Stub() {
+ @Override
+ public void onBackStarted() {
+ // Do nothing
+ }
+
+ @Override
+ public void onBackProgressed(BackEvent backEvent) {
+ // Do nothing
+ }
+
+ @Override
+ public void onBackCancelled() {
+ // Do nothing
+ }
+
+ @Override
+ public void onBackInvoked() {
+ sendBackEvent(KeyEvent.ACTION_DOWN);
+ sendBackEvent(KeyEvent.ACTION_UP);
+ }
+
+ private void sendBackEvent(int action) {
+ if (mTargetActivityRecord == null) {
+ return;
+ }
+ long when = SystemClock.uptimeMillis();
+ final KeyEvent ev = new KeyEvent(when, when, action,
+ KeyEvent.KEYCODE_BACK, 0 /* repeat */, 0 /* metaState */,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
+ KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+ InputDevice.SOURCE_KEYBOARD);
+ ev.setDisplayId(mTargetActivityRecord.getDisplayId());
+ InputManager.getInstance().injectInputEvent(ev, INJECT_INPUT_EVENT_MODE_ASYNC);
+ }
+ };
+
public interface RecentsAnimationCallbacks {
/** Callback when recents animation is finished. */
void onAnimationFinished(@ReorderMode int reorderMode, boolean sendUserLeaveHint);
@@ -1104,6 +1153,10 @@ public class RecentsAnimationController implements DeathRecipient {
return mTargetActivityRecord.findMainWindow();
}
+ OnBackInvokedCallbackInfo getBackInvokedInfo() {
+ return new OnBackInvokedCallbackInfo(mBackCallback, PRIORITY_DEFAULT);
+ }
+
DisplayArea getTargetAppDisplayArea() {
if (mTargetActivityRecord == null) {
return null;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 3b282aada7ae..1abe24e926fe 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -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;
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index b6998d84afa3..724204f79eab 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -731,17 +731,6 @@ public class WindowStateTests extends WindowTestsBase {
}
@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");
win0.mActivityRecord.mVisibleRequested = false;