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 4980e49a6fc3d..dda430a24c4de 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 @@ -536,9 +536,11 @@ public abstract class WMShellModule { Optional pipTouchHandlerOptional, Optional recentsTransitionHandler, KeyguardTransitionHandler keyguardTransitionHandler, + Optional unfoldHandler, Transitions transitions) { return new DefaultMixedHandler(shellInit, transitions, splitScreenOptional, - pipTouchHandlerOptional, recentsTransitionHandler, keyguardTransitionHandler); + pipTouchHandlerOptional, recentsTransitionHandler, keyguardTransitionHandler, + 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 2aa9f20df7468..35165fbc85e2f 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; @@ -52,6 +51,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; @@ -69,6 +69,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, private RecentsTransitionHandler mRecentsHandler; private StageCoordinator mSplitHandler; private final KeyguardTransitionHandler mKeyguardHandler; + private UnfoldTransitionHandler mUnfoldHandler; private static class MixedTransition { static final int TYPE_ENTER_PIP_FROM_SPLIT = 1; @@ -85,6 +86,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, /** Keyguard exit/occlude/unocclude transition. */ static final int TYPE_KEYGUARD = 5; + /** Fuld/Unfold transition. */ + static final int TYPE_UNFOLD = 6; + /** The default animation for this mixed transition. */ static final int ANIM_TYPE_DEFAULT = 0; @@ -136,7 +140,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, Optional splitScreenControllerOptional, Optional pipTouchHandlerOptional, Optional recentsHandlerOptional, - KeyguardTransitionHandler keyguardHandler) { + KeyguardTransitionHandler keyguardHandler, + Optional unfoldHandler) { mPlayer = player; mKeyguardHandler = keyguardHandler; if (Transitions.ENABLE_SHELL_TRANSITIONS && pipTouchHandlerOptional.isPresent() @@ -153,6 +158,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, if (mRecentsHandler != null) { mRecentsHandler.addMixer(this); } + mUnfoldHandler = unfoldHandler.orElse(null); }, this); } } @@ -218,6 +224,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; } @@ -312,6 +328,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, } else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) { return animateKeyguard(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? " @@ -595,6 +613,33 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, return true; } + 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) { @@ -649,6 +694,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, finishCallback); } else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) { mKeyguardHandler.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); @@ -674,6 +721,8 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT); } else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) { mKeyguardHandler.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 e1d58a4c29e1c..f148412205bff 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 @@ -197,12 +197,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(); }