Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +5 −4 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.util.ArraySet; import android.util.Pair; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.DisplayAreaInfo; Loading Loading @@ -363,10 +364,10 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll } ProtoLog.d(WM_SHELL_DESKTOP_MODE, "handle shell transition request: %s", request); WindowContainerTransaction wct = mTransitions.dispatchRequest(transition, request, this); if (wct == null) { wct = new WindowContainerTransaction(); } Pair<Transitions.TransitionHandler, WindowContainerTransaction> subHandler = mTransitions.dispatchRequest(transition, request, this); WindowContainerTransaction wct = subHandler != null ? subHandler.second : new WindowContainerTransaction(); bringDesktopAppsToFront(wct); wct.reorder(request.getTriggerTask().token, true /* onTop */); Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +102 −14 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.transition; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; Loading @@ -28,11 +29,13 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON import android.annotation.NonNull; import android.annotation.Nullable; import android.os.IBinder; import android.util.Pair; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.TransitionInfo; import android.window.TransitionRequestInfo; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransactionCallback; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.pip.PipTransitionController; Loading Loading @@ -61,6 +64,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { /** Both the display and split-state (enter/exit) is changing */ static final int TYPE_DISPLAY_AND_SPLIT_CHANGE = 2; /** Pip was entered while handling an intent with its own remoteTransition. */ static final int TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE = 3; /** The default animation for this mixed transition. */ static final int ANIM_TYPE_DEFAULT = 0; Loading @@ -85,6 +91,23 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { mType = type; mTransition = transition; } void joinFinishArgs(WindowContainerTransaction wct, WindowContainerTransactionCallback wctCB) { if (wctCB != null) { // Technically can probably support 1, but don't want to encourage CB usage since // it creates instabliity, so just throw. throw new IllegalArgumentException("Can't mix transitions that require finish" + " sync callback"); } if (wct != null) { if (mFinishWCT == null) { mFinishWCT = wct; } else { mFinishWCT.merge(wct, true /* transfer */); } } } } private final ArrayList<MixedTransition> mActiveTransitions = new ArrayList<>(); Loading Loading @@ -125,6 +148,25 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { mPipHandler.augmentRequest(transition, request, out); mSplitHandler.addEnterOrExitIfNeeded(request, out); return out; } else if (request.getRemoteTransition() != null && Transitions.isOpeningType(request.getType()) && (request.getTriggerTask() == null || (request.getTriggerTask().topActivityType != ACTIVITY_TYPE_HOME && request.getTriggerTask().topActivityType != ACTIVITY_TYPE_RECENTS))) { // Only select transitions with an intent-provided remote-animation because that will // usually grab priority and often won't handle PiP. If there isn't an intent-provided // remote, then the transition will be dispatched normally and the PipHandler will // pick it up. Pair<Transitions.TransitionHandler, WindowContainerTransaction> handler = mPlayer.dispatchRequest(transition, request, this); if (handler == null) { return null; } final MixedTransition mixed = new MixedTransition( MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE, transition); mixed.mLeftoversHandler = handler.first; mActiveTransitions.add(mixed); return handler.second; } return null; } Loading Loading @@ -169,6 +211,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { finishCallback); } else if (mixed.mType == MixedTransition.TYPE_DISPLAY_AND_SPLIT_CHANGE) { return false; } else if (mixed.mType == MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE) { return animateOpenIntentWithRemoteAndPip(mixed, info, startTransaction, finishTransaction, finishCallback); } else { mActiveTransitions.remove(mixed); throw new IllegalStateException("Starting mixed animation without a known mixed type? " Loading @@ -176,6 +221,59 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { } } private boolean animateOpenIntentWithRemoteAndPip(@NonNull MixedTransition mixed, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { TransitionInfo.Change pipChange = null; for (int i = info.getChanges().size() - 1; i >= 0; --i) { TransitionInfo.Change change = info.getChanges().get(i); if (mPipHandler.isEnteringPip(change, info.getType())) { if (pipChange != null) { throw new IllegalStateException("More than 1 pip-entering changes in one" + " transition? " + info); } pipChange = change; info.getChanges().remove(i); } } if (pipChange == null) { if (mixed.mLeftoversHandler != null) { return mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info, startTransaction, finishTransaction, finishCallback); } return false; } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Splitting PIP into a separate" + " animation because remote-animation likely doesn't support it"); mixed.mFinishCallback = finishCallback; Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> { --mixed.mInFlightSubAnimations; mixed.joinFinishArgs(wct, wctCB); if (mixed.mInFlightSubAnimations > 0) return; mActiveTransitions.remove(mixed); mixed.mFinishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB); }; // Split the transition into 2 parts: the pip part and the rest. mixed.mInFlightSubAnimations = 2; // make a new startTransaction because pip's startEnterAnimation "consumes" it so // we need a separate one to send over to launcher. SurfaceControl.Transaction otherStartT = new SurfaceControl.Transaction(); mPipHandler.startEnterAnimation(pipChange, otherStartT, finishTransaction, finishCB); // Dispatch the rest of the transition normally. if (mixed.mLeftoversHandler != null && mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info, startTransaction, finishTransaction, finishCB)) { return true; } mixed.mLeftoversHandler = mPlayer.dispatchTransition(mixed.mTransition, info, startTransaction, finishTransaction, finishCB, this); return true; } private boolean animateEnterPipFromSplit(@NonNull final MixedTransition mixed, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, Loading Loading @@ -211,12 +309,13 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { mixed.mFinishCallback = finishCallback; Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> { --mixed.mInFlightSubAnimations; mixed.joinFinishArgs(wct, wctCB); if (mixed.mInFlightSubAnimations > 0) return; mActiveTransitions.remove(mixed); if (isGoingHome) { mSplitHandler.onTransitionAnimationComplete(); } mixed.mFinishCallback.onTransitionFinished(wct, wctCB); mixed.mFinishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB); }; if (isGoingHome) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animation is actually mixed " Loading Loading @@ -317,17 +416,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> { --mixed.mInFlightSubAnimations; if (wctCB != null) { throw new IllegalArgumentException("Can't mix transitions that require finish" + " sync callback"); } if (wct != null) { if (mixed.mFinishWCT == null) { mixed.mFinishWCT = wct; } else { mixed.mFinishWCT.merge(wct, true /* transfer */); } } mixed.joinFinishArgs(wct, wctCB); if (mixed.mInFlightSubAnimations > 0) return; mActiveTransitions.remove(mixed); mixed.mFinishCallback.onTransitionFinished(mixed.mFinishWCT, null /* wctCB */); Loading @@ -342,8 +431,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { // Note: at this point, startT has probably already been applied, so we are basically // giving splitHandler an empty startT. This is currently OK because display-change will // grab a screenshot and paste it on top anyways. mSplitHandler.startPendingAnimation( transition, everythingElse, startT, finishT, finishCB); mSplitHandler.startPendingAnimation(transition, everythingElse, startT, finishT, finishCB); return true; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +8 −6 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.os.RemoteException; import android.os.SystemProperties; import android.provider.Settings; import android.util.Log; import android.util.Pair; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.ITransitionPlayer; Loading Loading @@ -627,13 +628,14 @@ public class Transitions implements RemoteCallable<Transitions> { * Gives every handler (in order) a chance to handle request until one consumes the transition. * @return the WindowContainerTransaction given by the handler which consumed the transition. */ public WindowContainerTransaction dispatchRequest(@NonNull IBinder transition, @NonNull TransitionRequestInfo request, @Nullable TransitionHandler skip) { public Pair<TransitionHandler, WindowContainerTransaction> dispatchRequest( @NonNull IBinder transition, @NonNull TransitionRequestInfo request, @Nullable TransitionHandler skip) { for (int i = mHandlers.size() - 1; i >= 0; --i) { if (mHandlers.get(i) == skip) continue; WindowContainerTransaction wct = mHandlers.get(i).handleRequest(transition, request); if (wct != null) { return wct; return new Pair<>(mHandlers.get(i), wct); } } return null; Loading Loading @@ -698,9 +700,9 @@ public class Transitions implements RemoteCallable<Transitions> { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition animation finished (abort=%b), notifying core %s", abort, transition); if (active.mStartT != null) { // Applied by now, so close immediately. Do not set to null yet, though, since nullness // is used later to disambiguate malformed transitions. active.mStartT.close(); // Applied by now, so clear immediately to remove any references. Do not set to null // yet, though, since nullness is used later to disambiguate malformed transitions. active.mStartT.clear(); } // Merge all relevant transactions together SurfaceControl.Transaction fullFinish = active.mFinishT; Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +5 −4 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.util.ArraySet; import android.util.Pair; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.DisplayAreaInfo; Loading Loading @@ -363,10 +364,10 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll } ProtoLog.d(WM_SHELL_DESKTOP_MODE, "handle shell transition request: %s", request); WindowContainerTransaction wct = mTransitions.dispatchRequest(transition, request, this); if (wct == null) { wct = new WindowContainerTransaction(); } Pair<Transitions.TransitionHandler, WindowContainerTransaction> subHandler = mTransitions.dispatchRequest(transition, request, this); WindowContainerTransaction wct = subHandler != null ? subHandler.second : new WindowContainerTransaction(); bringDesktopAppsToFront(wct); wct.reorder(request.getTriggerTask().token, true /* onTop */); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +102 −14 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.transition; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; Loading @@ -28,11 +29,13 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON import android.annotation.NonNull; import android.annotation.Nullable; import android.os.IBinder; import android.util.Pair; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.TransitionInfo; import android.window.TransitionRequestInfo; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransactionCallback; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.pip.PipTransitionController; Loading Loading @@ -61,6 +64,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { /** Both the display and split-state (enter/exit) is changing */ static final int TYPE_DISPLAY_AND_SPLIT_CHANGE = 2; /** Pip was entered while handling an intent with its own remoteTransition. */ static final int TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE = 3; /** The default animation for this mixed transition. */ static final int ANIM_TYPE_DEFAULT = 0; Loading @@ -85,6 +91,23 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { mType = type; mTransition = transition; } void joinFinishArgs(WindowContainerTransaction wct, WindowContainerTransactionCallback wctCB) { if (wctCB != null) { // Technically can probably support 1, but don't want to encourage CB usage since // it creates instabliity, so just throw. throw new IllegalArgumentException("Can't mix transitions that require finish" + " sync callback"); } if (wct != null) { if (mFinishWCT == null) { mFinishWCT = wct; } else { mFinishWCT.merge(wct, true /* transfer */); } } } } private final ArrayList<MixedTransition> mActiveTransitions = new ArrayList<>(); Loading Loading @@ -125,6 +148,25 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { mPipHandler.augmentRequest(transition, request, out); mSplitHandler.addEnterOrExitIfNeeded(request, out); return out; } else if (request.getRemoteTransition() != null && Transitions.isOpeningType(request.getType()) && (request.getTriggerTask() == null || (request.getTriggerTask().topActivityType != ACTIVITY_TYPE_HOME && request.getTriggerTask().topActivityType != ACTIVITY_TYPE_RECENTS))) { // Only select transitions with an intent-provided remote-animation because that will // usually grab priority and often won't handle PiP. If there isn't an intent-provided // remote, then the transition will be dispatched normally and the PipHandler will // pick it up. Pair<Transitions.TransitionHandler, WindowContainerTransaction> handler = mPlayer.dispatchRequest(transition, request, this); if (handler == null) { return null; } final MixedTransition mixed = new MixedTransition( MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE, transition); mixed.mLeftoversHandler = handler.first; mActiveTransitions.add(mixed); return handler.second; } return null; } Loading Loading @@ -169,6 +211,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { finishCallback); } else if (mixed.mType == MixedTransition.TYPE_DISPLAY_AND_SPLIT_CHANGE) { return false; } else if (mixed.mType == MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE) { return animateOpenIntentWithRemoteAndPip(mixed, info, startTransaction, finishTransaction, finishCallback); } else { mActiveTransitions.remove(mixed); throw new IllegalStateException("Starting mixed animation without a known mixed type? " Loading @@ -176,6 +221,59 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { } } private boolean animateOpenIntentWithRemoteAndPip(@NonNull MixedTransition mixed, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { TransitionInfo.Change pipChange = null; for (int i = info.getChanges().size() - 1; i >= 0; --i) { TransitionInfo.Change change = info.getChanges().get(i); if (mPipHandler.isEnteringPip(change, info.getType())) { if (pipChange != null) { throw new IllegalStateException("More than 1 pip-entering changes in one" + " transition? " + info); } pipChange = change; info.getChanges().remove(i); } } if (pipChange == null) { if (mixed.mLeftoversHandler != null) { return mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info, startTransaction, finishTransaction, finishCallback); } return false; } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Splitting PIP into a separate" + " animation because remote-animation likely doesn't support it"); mixed.mFinishCallback = finishCallback; Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> { --mixed.mInFlightSubAnimations; mixed.joinFinishArgs(wct, wctCB); if (mixed.mInFlightSubAnimations > 0) return; mActiveTransitions.remove(mixed); mixed.mFinishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB); }; // Split the transition into 2 parts: the pip part and the rest. mixed.mInFlightSubAnimations = 2; // make a new startTransaction because pip's startEnterAnimation "consumes" it so // we need a separate one to send over to launcher. SurfaceControl.Transaction otherStartT = new SurfaceControl.Transaction(); mPipHandler.startEnterAnimation(pipChange, otherStartT, finishTransaction, finishCB); // Dispatch the rest of the transition normally. if (mixed.mLeftoversHandler != null && mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info, startTransaction, finishTransaction, finishCB)) { return true; } mixed.mLeftoversHandler = mPlayer.dispatchTransition(mixed.mTransition, info, startTransaction, finishTransaction, finishCB, this); return true; } private boolean animateEnterPipFromSplit(@NonNull final MixedTransition mixed, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, Loading Loading @@ -211,12 +309,13 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { mixed.mFinishCallback = finishCallback; Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> { --mixed.mInFlightSubAnimations; mixed.joinFinishArgs(wct, wctCB); if (mixed.mInFlightSubAnimations > 0) return; mActiveTransitions.remove(mixed); if (isGoingHome) { mSplitHandler.onTransitionAnimationComplete(); } mixed.mFinishCallback.onTransitionFinished(wct, wctCB); mixed.mFinishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB); }; if (isGoingHome) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animation is actually mixed " Loading Loading @@ -317,17 +416,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> { --mixed.mInFlightSubAnimations; if (wctCB != null) { throw new IllegalArgumentException("Can't mix transitions that require finish" + " sync callback"); } if (wct != null) { if (mixed.mFinishWCT == null) { mixed.mFinishWCT = wct; } else { mixed.mFinishWCT.merge(wct, true /* transfer */); } } mixed.joinFinishArgs(wct, wctCB); if (mixed.mInFlightSubAnimations > 0) return; mActiveTransitions.remove(mixed); mixed.mFinishCallback.onTransitionFinished(mixed.mFinishWCT, null /* wctCB */); Loading @@ -342,8 +431,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { // Note: at this point, startT has probably already been applied, so we are basically // giving splitHandler an empty startT. This is currently OK because display-change will // grab a screenshot and paste it on top anyways. mSplitHandler.startPendingAnimation( transition, everythingElse, startT, finishT, finishCB); mSplitHandler.startPendingAnimation(transition, everythingElse, startT, finishT, finishCB); return true; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +8 −6 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.os.RemoteException; import android.os.SystemProperties; import android.provider.Settings; import android.util.Log; import android.util.Pair; import android.view.SurfaceControl; import android.view.WindowManager; import android.window.ITransitionPlayer; Loading Loading @@ -627,13 +628,14 @@ public class Transitions implements RemoteCallable<Transitions> { * Gives every handler (in order) a chance to handle request until one consumes the transition. * @return the WindowContainerTransaction given by the handler which consumed the transition. */ public WindowContainerTransaction dispatchRequest(@NonNull IBinder transition, @NonNull TransitionRequestInfo request, @Nullable TransitionHandler skip) { public Pair<TransitionHandler, WindowContainerTransaction> dispatchRequest( @NonNull IBinder transition, @NonNull TransitionRequestInfo request, @Nullable TransitionHandler skip) { for (int i = mHandlers.size() - 1; i >= 0; --i) { if (mHandlers.get(i) == skip) continue; WindowContainerTransaction wct = mHandlers.get(i).handleRequest(transition, request); if (wct != null) { return wct; return new Pair<>(mHandlers.get(i), wct); } } return null; Loading Loading @@ -698,9 +700,9 @@ public class Transitions implements RemoteCallable<Transitions> { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition animation finished (abort=%b), notifying core %s", abort, transition); if (active.mStartT != null) { // Applied by now, so close immediately. Do not set to null yet, though, since nullness // is used later to disambiguate malformed transitions. active.mStartT.close(); // Applied by now, so clear immediately to remove any references. Do not set to null // yet, though, since nullness is used later to disambiguate malformed transitions. active.mStartT.clear(); } // Merge all relevant transactions together SurfaceControl.Transaction fullFinish = active.mFinishT; Loading