diff options
3 files changed, 83 insertions, 7 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/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 2bae59a93048..7ba656ba2819 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; |