Loading data/etc/services.core.protolog.json +6 −6 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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", Loading services/core/java/com/android/server/wm/BackNavigationController.java +24 −1 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; Loading services/core/java/com/android/server/wm/DisplayContent.java +6 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading services/core/java/com/android/server/wm/InputMonitor.java +5 −6 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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)) { Loading services/core/java/com/android/server/wm/RecentsAnimationController.java +53 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading
data/etc/services.core.protolog.json +6 −6 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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", Loading
services/core/java/com/android/server/wm/BackNavigationController.java +24 −1 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; Loading
services/core/java/com/android/server/wm/DisplayContent.java +6 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading
services/core/java/com/android/server/wm/InputMonitor.java +5 −6 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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)) { Loading
services/core/java/com/android/server/wm/RecentsAnimationController.java +53 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading