From c5533eb5cadb3b897f6c4f5c7634ff0cb8f32bfc Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 2 Feb 2023 14:11:13 +0000 Subject: [PATCH] Disable handling display change transition for remote If display space is changed, a transaction will be passed to DisplayManagerService#performTraversalInternal, and the transaction may contain setDisplayProjection if display size/orientation is changed. With shell transition, the transaction can be the sync transaction. And the sync transaction may be applied by the remote animator. But since [1], the command setDisplayProjection requires a signature permission ACCESS_SURFACE_FLINGER. Then if the remote is launcher, the display coordinate will not be updated because without the permission. So simply use the default transition handler (SystemUI has the permission) if the transition contains a display change (the appearance will be the same as legacy transition). Also shell rotation is not fully implemented yet, it may be still flickering even if launcher has the permission. [1]: Id9d9012d4ede9c8330f0ce1096bcb78e51b7c5df Bug: 267118962 Test: Open an activity which calls setRequestedOrientation in onResume, it will have a normal rotation animation. Change-Id: If2f3885007ed5b1c69eaa31e4a9c8be7eb54a017 --- .../wm/shell/splitscreen/StageCoordinator.java | 11 +---------- .../wm/shell/transition/RemoteTransitionHandler.java | 5 +++++ .../com/android/wm/shell/transition/Transitions.java | 12 ++++++++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 39cf5f1b95bd4..9624ae9b741b4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -2108,7 +2108,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Use normal animations. return false; - } else if (mMixedHandler != null && hasDisplayChange(info)) { + } else if (mMixedHandler != null && Transitions.hasDisplayChange(info)) { // A display-change has been un-expectedly inserted into the transition. Redirect // handling to the mixed-handler to deal with splitting it up. if (mMixedHandler.animatePendingSplitWithDisplayChange(transition, info, @@ -2151,15 +2151,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return true; } - private boolean hasDisplayChange(TransitionInfo info) { - boolean has = false; - for (int iC = 0; iC < info.getChanges().size() && !has; ++iC) { - final TransitionInfo.Change change = info.getChanges().get(iC); - has = change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0; - } - return has; - } - /** Called to clean-up state and do house-keeping after the animation is done. */ public void onTransitionAnimationComplete() { // If still playing, let it finish. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java index b4e05848882cc..02f19ebdb7580 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java @@ -93,6 +93,11 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { + if (!Transitions.SHELL_TRANSITIONS_ROTATION && Transitions.hasDisplayChange(info)) { + // Note that if the remote doesn't have permission ACCESS_SURFACE_FLINGER, some + // operations of the start transaction may be ignored. + return false; + } RemoteTransition pendingRemote = mRequestedRemotes.get(transition); if (pendingRemote == null) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition %s doesn't have " diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index 44d6a0de13668..b2f61c2319117 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -24,6 +24,7 @@ import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManager.fixScale; +import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.TransitionInfo.FLAG_IS_OCCLUDED; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_NO_ANIMATION; @@ -328,6 +329,17 @@ public class Transitions implements RemoteCallable { return type == TRANSIT_CLOSE || type == TRANSIT_TO_BACK; } + /** Returns {@code true} if the transition has a display change. */ + public static boolean hasDisplayChange(@NonNull TransitionInfo info) { + for (int i = info.getChanges().size() - 1; i >= 0; --i) { + final TransitionInfo.Change change = info.getChanges().get(i); + if (change.getMode() == TRANSIT_CHANGE && change.hasFlags(FLAG_IS_DISPLAY)) { + return true; + } + } + return false; + } + /** * Sets up visibility/alpha/transforms to resemble the starting state of an animation. */