From 7567b9b595c710173703391c979152db70708b75 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Tue, 13 Jun 2023 10:27:40 -0700 Subject: [PATCH] Add mixed-handler for unfold and mix in pip state Add unfold to mixed-handler so that we can mix in updates for other components. In this case, we update pip state during unfold. Bug: 286084821 Test: Unfold with a PiP Change-Id: I872c8326dfa4662feecb45e2d2b4fd7b042a9123 --- .../wm/shell/dagger/WMShellModule.java | 3 +- .../shell/transition/DefaultMixedHandler.java | 53 ++++++++++++++++++- .../shell/unfold/UnfoldTransitionHandler.java | 10 +++- 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index ec40244188607..f663d4d758f70 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -547,10 +547,11 @@ public abstract class WMShellModule { KeyguardTransitionHandler keyguardTransitionHandler, Optional desktopModeController, Optional desktopTasksController, + Optional unfoldHandler, Transitions transitions) { return new DefaultMixedHandler(shellInit, transitions, splitScreenOptional, pipTouchHandlerOptional, recentsTransitionHandler, keyguardTransitionHandler, - desktopModeController, desktopTasksController); + desktopModeController, desktopTasksController, unfoldHandler); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java index bda25d5b3b82d..6013754b97d1a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java @@ -33,7 +33,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.PendingIntent; import android.os.IBinder; -import android.util.Log; import android.util.Pair; import android.view.SurfaceControl; import android.view.WindowManager; @@ -55,6 +54,7 @@ import com.android.wm.shell.recents.RecentsTransitionHandler; import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.splitscreen.StageCoordinator; import com.android.wm.shell.sysui.ShellInit; +import com.android.wm.shell.unfold.UnfoldTransitionHandler; import com.android.wm.shell.util.TransitionUtil; import java.util.ArrayList; @@ -74,6 +74,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, private final KeyguardTransitionHandler mKeyguardHandler; private DesktopModeController mDesktopModeController; private DesktopTasksController mDesktopTasksController; + private UnfoldTransitionHandler mUnfoldHandler; private static class MixedTransition { static final int TYPE_ENTER_PIP_FROM_SPLIT = 1; @@ -93,6 +94,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, /** Recents Transition while in desktop mode. */ static final int TYPE_RECENTS_DURING_DESKTOP = 6; + /** Fuld/Unfold transition. */ + static final int TYPE_UNFOLD = 7; + /** The default animation for this mixed transition. */ static final int ANIM_TYPE_DEFAULT = 0; @@ -146,7 +150,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, Optional recentsHandlerOptional, KeyguardTransitionHandler keyguardHandler, Optional desktopModeControllerOptional, - Optional desktopTasksControllerOptional) { + Optional desktopTasksControllerOptional, + Optional unfoldHandler) { mPlayer = player; mKeyguardHandler = keyguardHandler; if (Transitions.ENABLE_SHELL_TRANSITIONS && pipTouchHandlerOptional.isPresent() @@ -165,6 +170,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, } mDesktopModeController = desktopModeControllerOptional.orElse(null); mDesktopTasksController = desktopTasksControllerOptional.orElse(null); + mUnfoldHandler = unfoldHandler.orElse(null); }, this); } } @@ -230,6 +236,16 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, mixed.mLeftoversHandler = handler.first; mActiveTransitions.add(mixed); return handler.second; + } else if (mUnfoldHandler != null && mUnfoldHandler.hasUnfold(request)) { + final WindowContainerTransaction wct = + mUnfoldHandler.handleRequest(transition, request); + if (wct != null) { + final MixedTransition mixed = new MixedTransition( + MixedTransition.TYPE_UNFOLD, transition); + mixed.mLeftoversHandler = mUnfoldHandler; + mActiveTransitions.add(mixed); + } + return wct; } return null; } @@ -335,6 +351,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_DESKTOP) { return animateRecentsDuringDesktop(mixed, info, startTransaction, finishTransaction, finishCallback); + } else if (mixed.mType == MixedTransition.TYPE_UNFOLD) { + return animateUnfold(mixed, info, startTransaction, finishTransaction, finishCallback); } else { mActiveTransitions.remove(mixed); throw new IllegalStateException("Starting mixed animation without a known mixed type? " @@ -642,6 +660,33 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, return false; } + private boolean animateUnfold(@NonNull final MixedTransition mixed, + @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction startTransaction, + @NonNull SurfaceControl.Transaction finishTransaction, + @NonNull Transitions.TransitionFinishCallback finishCallback) { + final Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> { + mixed.mInFlightSubAnimations--; + if (mixed.mInFlightSubAnimations > 0) return; + mActiveTransitions.remove(mixed); + finishCallback.onTransitionFinished(wct, wctCB); + }; + mixed.mInFlightSubAnimations = 1; + if (!mUnfoldHandler.startAnimation( + mixed.mTransition, info, startTransaction, finishTransaction, finishCB)) { + return false; + } + // Sync pip state. + if (mPipHandler != null) { + // We don't know when to apply `startTransaction` so use a separate transaction here. + // This should be fine because these surface properties are independent. + final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + mPipHandler.syncPipSurfaceState(info, t, finishTransaction); + t.apply(); + } + return true; + } + /** Use to when split use intent to enter, check if this enter transition should be mixed or * not.*/ public boolean shouldSplitEnterMixed(PendingIntent intent) { @@ -699,6 +744,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_DESKTOP) { mixed.mLeftoversHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback); + } else if (mixed.mType == MixedTransition.TYPE_UNFOLD) { + mUnfoldHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback); } else { throw new IllegalStateException("Playing a mixed transition with unknown type? " + mixed.mType); @@ -726,6 +773,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, mKeyguardHandler.onTransitionConsumed(transition, aborted, finishT); } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_DESKTOP) { mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT); + } else if (mixed.mType == MixedTransition.TYPE_UNFOLD) { + mUnfoldHandler.onTransitionConsumed(transition, aborted, finishT); } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java index c504f57216f34..b565cb77324f5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java @@ -184,12 +184,18 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene } } + /** Whether `request` contains an unfold action. */ + public boolean hasUnfold(@NonNull TransitionRequestInfo request) { + return (request.getType() == TRANSIT_CHANGE + && request.getDisplayChange() != null + && request.getDisplayChange().isPhysicalDisplayChanged()); + } + @Nullable @Override public WindowContainerTransaction handleRequest(@NonNull IBinder transition, @NonNull TransitionRequestInfo request) { - if (request.getType() == TRANSIT_CHANGE && request.getDisplayChange() != null - && request.getDisplayChange().isPhysicalDisplayChanged()) { + if (hasUnfold(request)) { mTransition = transition; return new WindowContainerTransaction(); }