Loading data/etc/services.core.protolog.json +6 −0 Original line number Diff line number Diff line Loading @@ -1141,6 +1141,12 @@ "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-863438038": { "message": "Aborting Transition: %d", "level": "VERBOSE", "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, "-861859917": { "message": "Attempted to add window to a display that does not exist: %d. Aborting.", "level": "WARN", Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +8 −0 Original line number Diff line number Diff line Loading @@ -282,6 +282,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mMainExecutor.execute(() -> { mTaskOrganizer.addListenerForType(this, TASK_LISTENER_TYPE_PIP); }); mPipTransitionController.setPipOrganizer(this); displayController.addDisplayWindowListener(this); } Loading Loading @@ -349,6 +350,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } } public ActivityManager.RunningTaskInfo getTaskInfo() { return mTaskInfo; } public SurfaceControl getSurfaceControl() { return mLeash; } Loading Loading @@ -716,6 +721,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mOnDisplayIdChangeCallback.accept(Display.DEFAULT_DISPLAY); } if (Transitions.ENABLE_SHELL_TRANSITIONS) { mPipTransitionController.forceFinishTransition(); } final PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController.getCurrentAnimator(); if (animator != null) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +62 −22 Original line number Diff line number Diff line Loading @@ -32,17 +32,18 @@ import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection; import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP; import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP; import android.app.ActivityManager; import android.app.TaskInfo; import android.content.Context; import android.graphics.Matrix; import android.graphics.Rect; import android.os.IBinder; import android.util.Log; import android.view.Surface; import android.view.SurfaceControl; import android.window.TransitionInfo; import android.window.TransitionRequestInfo; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransactionCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -57,11 +58,14 @@ import com.android.wm.shell.transition.Transitions; */ public class PipTransition extends PipTransitionController { private static final String TAG = PipTransition.class.getSimpleName(); private final PipTransitionState mPipTransitionState; private final int mEnterExitAnimationDuration; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private Transitions.TransitionFinishCallback mFinishCallback; private Rect mExitDestinationBounds = new Rect(); private IBinder mExitTransition = null; public PipTransition(Context context, PipBoundsState pipBoundsState, Loading Loading @@ -96,7 +100,7 @@ public class PipTransition extends PipTransitionController { public void startTransition(Rect destinationBounds, WindowContainerTransaction out) { if (destinationBounds != null) { mExitDestinationBounds.set(destinationBounds); mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this); mExitTransition = mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this); } else { mTransitions.startTransition(TRANSIT_REMOVE_PIP, out, this); } Loading @@ -109,7 +113,9 @@ public class PipTransition extends PipTransitionController { @android.annotation.NonNull SurfaceControl.Transaction finishTransaction, @android.annotation.NonNull Transitions.TransitionFinishCallback finishCallback) { if (info.getType() == TRANSIT_EXIT_PIP && info.getChanges().size() == 1) { if (mExitTransition == transition || info.getType() == TRANSIT_EXIT_PIP) { mExitTransition = null; if (info.getChanges().size() == 1) { final TransitionInfo.Change change = info.getChanges().get(0); mFinishCallback = finishCallback; startTransaction.apply(); Loading @@ -117,6 +123,9 @@ public class PipTransition extends PipTransitionController { new Rect(mExitDestinationBounds)); mExitDestinationBounds.setEmpty(); return success; } else { Log.e(TAG, "Got an exit-pip transition with unexpected change-list"); } } if (info.getType() == TRANSIT_REMOVE_PIP) { Loading Loading @@ -182,27 +191,59 @@ public class PipTransition extends PipTransitionController { } } @Override public void onTransitionMerged(@NonNull IBinder transition) { if (transition != mExitTransition) { return; } // This means an expand happened before enter-pip finished and we are now "merging" a // no-op transition that happens to match our exit-pip. boolean cancelled = false; if (mPipAnimationController.getCurrentAnimator() != null) { mPipAnimationController.getCurrentAnimator().cancel(); cancelled = true; } // Unset exitTransition AFTER cancel so that finishResize knows we are merging. mExitTransition = null; if (!cancelled) return; final ActivityManager.RunningTaskInfo taskInfo = mPipOrganizer.getTaskInfo(); if (taskInfo != null) { startExpandAnimation(taskInfo, mPipOrganizer.getSurfaceControl(), new Rect(mExitDestinationBounds)); } mExitDestinationBounds.setEmpty(); } @Override public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, SurfaceControl.Transaction tx) { @Nullable SurfaceControl.Transaction tx) { if (isInPipDirection(direction)) { mPipTransitionState.setTransitionState(PipTransitionState.ENTERED_PIP); } // If there is an expected exit transition, then the exit will be "merged" into this // transition so don't fire the finish-callback in that case. if (mExitTransition == null && mFinishCallback != null) { WindowContainerTransaction wct = new WindowContainerTransaction(); prepareFinishResizeTransaction(taskInfo, destinationBounds, direction, tx, wct); mFinishCallback.onTransitionFinished(wct, new WindowContainerTransactionCallback() { @Override public void onTransactionReady(int id, @NonNull SurfaceControl.Transaction t) { t.merge(tx); t.apply(); direction, wct); if (tx != null) { wct.setBoundsChangeTransaction(taskInfo.token, tx); } mFinishCallback.onTransitionFinished(wct, null /* wctCallback */); mFinishCallback = null; } }); finishResizeForMenu(destinationBounds); } @Override public void forceFinishTransition() { if (mFinishCallback == null) return; mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCallback */); mFinishCallback = null; } private boolean startExpandAnimation(final TaskInfo taskInfo, final SurfaceControl leash, final Rect destinationBounds) { PipAnimationController.PipTransitionAnimator animator = Loading Loading @@ -243,7 +284,7 @@ public class PipTransition extends PipTransitionController { startTransaction.merge(tx); startTransaction.apply(); mPipBoundsState.setBounds(destinationBounds); onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, tx); onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, null /* tx */); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); mFinishCallback = null; mPipTransitionState.setInSwipePipToHomeTransition(false); Loading Loading @@ -292,7 +333,6 @@ public class PipTransition extends PipTransitionController { private void prepareFinishResizeTransaction(TaskInfo taskInfo, Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, SurfaceControl.Transaction tx, WindowContainerTransaction wct) { Rect taskBounds = null; if (isInPipDirection(direction)) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +12 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ public abstract class PipTransitionController implements Transitions.TransitionH protected final Transitions mTransitions; private final Handler mMainHandler; private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>(); protected PipTaskOrganizer mPipOrganizer; protected final PipAnimationController.PipAnimationCallback mPipAnimationCallback = new PipAnimationController.PipAnimationCallback() { Loading Loading @@ -103,6 +104,13 @@ public abstract class PipTransitionController implements Transitions.TransitionH // Default implementation does nothing. } /** * Called when the transition animation can't continue (eg. task is removed during * animation) */ public void forceFinishTransition() { } public PipTransitionController(PipBoundsState pipBoundsState, PipMenuController pipMenuController, PipBoundsAlgorithm pipBoundsAlgorithm, PipAnimationController pipAnimationController, Transitions transitions, Loading @@ -119,6 +127,10 @@ public abstract class PipTransitionController implements Transitions.TransitionH } } void setPipOrganizer(PipTaskOrganizer pto) { mPipOrganizer = pto; } /** * Registers {@link PipTransitionCallback} to receive transition callbacks. */ Loading services/core/java/com/android/server/wm/ActivityStarter.java +5 −1 Original line number Diff line number Diff line Loading @@ -1565,7 +1565,7 @@ class ActivityStarter { // transition based on a sub-action. // Only do the create here (and defer requestStart) since startActivityInner might abort. final TransitionController transitionController = r.mTransitionController; final Transition newTransition = (!transitionController.isCollecting() Transition newTransition = (!transitionController.isCollecting() && transitionController.getTransitionPlayer() != null) ? transitionController.createTransition(TRANSIT_OPEN) : null; RemoteTransition remoteTransition = r.takeRemoteTransition(); Loading Loading @@ -1620,6 +1620,10 @@ class ActivityStarter { // The activity is started new rather than just brought forward, so record // it as an existence change. transitionController.collectExistenceChange(r); } else if (result == START_DELIVERED_TO_TOP && newTransition != null) { // We just delivered to top, so there isn't an actual transition here newTransition.abort(); newTransition = null; } if (isTransient) { // `r` isn't guaranteed to be the actual relevant activity, so we must wait Loading Loading
data/etc/services.core.protolog.json +6 −0 Original line number Diff line number Diff line Loading @@ -1141,6 +1141,12 @@ "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "-863438038": { "message": "Aborting Transition: %d", "level": "VERBOSE", "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, "-861859917": { "message": "Attempted to add window to a display that does not exist: %d. Aborting.", "level": "WARN", Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +8 −0 Original line number Diff line number Diff line Loading @@ -282,6 +282,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mMainExecutor.execute(() -> { mTaskOrganizer.addListenerForType(this, TASK_LISTENER_TYPE_PIP); }); mPipTransitionController.setPipOrganizer(this); displayController.addDisplayWindowListener(this); } Loading Loading @@ -349,6 +350,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } } public ActivityManager.RunningTaskInfo getTaskInfo() { return mTaskInfo; } public SurfaceControl getSurfaceControl() { return mLeash; } Loading Loading @@ -716,6 +721,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mOnDisplayIdChangeCallback.accept(Display.DEFAULT_DISPLAY); } if (Transitions.ENABLE_SHELL_TRANSITIONS) { mPipTransitionController.forceFinishTransition(); } final PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController.getCurrentAnimator(); if (animator != null) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +62 −22 Original line number Diff line number Diff line Loading @@ -32,17 +32,18 @@ import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection; import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP; import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP; import android.app.ActivityManager; import android.app.TaskInfo; import android.content.Context; import android.graphics.Matrix; import android.graphics.Rect; import android.os.IBinder; import android.util.Log; import android.view.Surface; import android.view.SurfaceControl; import android.window.TransitionInfo; import android.window.TransitionRequestInfo; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransactionCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -57,11 +58,14 @@ import com.android.wm.shell.transition.Transitions; */ public class PipTransition extends PipTransitionController { private static final String TAG = PipTransition.class.getSimpleName(); private final PipTransitionState mPipTransitionState; private final int mEnterExitAnimationDuration; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private Transitions.TransitionFinishCallback mFinishCallback; private Rect mExitDestinationBounds = new Rect(); private IBinder mExitTransition = null; public PipTransition(Context context, PipBoundsState pipBoundsState, Loading Loading @@ -96,7 +100,7 @@ public class PipTransition extends PipTransitionController { public void startTransition(Rect destinationBounds, WindowContainerTransaction out) { if (destinationBounds != null) { mExitDestinationBounds.set(destinationBounds); mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this); mExitTransition = mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this); } else { mTransitions.startTransition(TRANSIT_REMOVE_PIP, out, this); } Loading @@ -109,7 +113,9 @@ public class PipTransition extends PipTransitionController { @android.annotation.NonNull SurfaceControl.Transaction finishTransaction, @android.annotation.NonNull Transitions.TransitionFinishCallback finishCallback) { if (info.getType() == TRANSIT_EXIT_PIP && info.getChanges().size() == 1) { if (mExitTransition == transition || info.getType() == TRANSIT_EXIT_PIP) { mExitTransition = null; if (info.getChanges().size() == 1) { final TransitionInfo.Change change = info.getChanges().get(0); mFinishCallback = finishCallback; startTransaction.apply(); Loading @@ -117,6 +123,9 @@ public class PipTransition extends PipTransitionController { new Rect(mExitDestinationBounds)); mExitDestinationBounds.setEmpty(); return success; } else { Log.e(TAG, "Got an exit-pip transition with unexpected change-list"); } } if (info.getType() == TRANSIT_REMOVE_PIP) { Loading Loading @@ -182,27 +191,59 @@ public class PipTransition extends PipTransitionController { } } @Override public void onTransitionMerged(@NonNull IBinder transition) { if (transition != mExitTransition) { return; } // This means an expand happened before enter-pip finished and we are now "merging" a // no-op transition that happens to match our exit-pip. boolean cancelled = false; if (mPipAnimationController.getCurrentAnimator() != null) { mPipAnimationController.getCurrentAnimator().cancel(); cancelled = true; } // Unset exitTransition AFTER cancel so that finishResize knows we are merging. mExitTransition = null; if (!cancelled) return; final ActivityManager.RunningTaskInfo taskInfo = mPipOrganizer.getTaskInfo(); if (taskInfo != null) { startExpandAnimation(taskInfo, mPipOrganizer.getSurfaceControl(), new Rect(mExitDestinationBounds)); } mExitDestinationBounds.setEmpty(); } @Override public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, SurfaceControl.Transaction tx) { @Nullable SurfaceControl.Transaction tx) { if (isInPipDirection(direction)) { mPipTransitionState.setTransitionState(PipTransitionState.ENTERED_PIP); } // If there is an expected exit transition, then the exit will be "merged" into this // transition so don't fire the finish-callback in that case. if (mExitTransition == null && mFinishCallback != null) { WindowContainerTransaction wct = new WindowContainerTransaction(); prepareFinishResizeTransaction(taskInfo, destinationBounds, direction, tx, wct); mFinishCallback.onTransitionFinished(wct, new WindowContainerTransactionCallback() { @Override public void onTransactionReady(int id, @NonNull SurfaceControl.Transaction t) { t.merge(tx); t.apply(); direction, wct); if (tx != null) { wct.setBoundsChangeTransaction(taskInfo.token, tx); } mFinishCallback.onTransitionFinished(wct, null /* wctCallback */); mFinishCallback = null; } }); finishResizeForMenu(destinationBounds); } @Override public void forceFinishTransition() { if (mFinishCallback == null) return; mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCallback */); mFinishCallback = null; } private boolean startExpandAnimation(final TaskInfo taskInfo, final SurfaceControl leash, final Rect destinationBounds) { PipAnimationController.PipTransitionAnimator animator = Loading Loading @@ -243,7 +284,7 @@ public class PipTransition extends PipTransitionController { startTransaction.merge(tx); startTransaction.apply(); mPipBoundsState.setBounds(destinationBounds); onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, tx); onFinishResize(taskInfo, destinationBounds, TRANSITION_DIRECTION_TO_PIP, null /* tx */); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); mFinishCallback = null; mPipTransitionState.setInSwipePipToHomeTransition(false); Loading Loading @@ -292,7 +333,6 @@ public class PipTransition extends PipTransitionController { private void prepareFinishResizeTransaction(TaskInfo taskInfo, Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, SurfaceControl.Transaction tx, WindowContainerTransaction wct) { Rect taskBounds = null; if (isInPipDirection(direction)) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +12 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ public abstract class PipTransitionController implements Transitions.TransitionH protected final Transitions mTransitions; private final Handler mMainHandler; private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>(); protected PipTaskOrganizer mPipOrganizer; protected final PipAnimationController.PipAnimationCallback mPipAnimationCallback = new PipAnimationController.PipAnimationCallback() { Loading Loading @@ -103,6 +104,13 @@ public abstract class PipTransitionController implements Transitions.TransitionH // Default implementation does nothing. } /** * Called when the transition animation can't continue (eg. task is removed during * animation) */ public void forceFinishTransition() { } public PipTransitionController(PipBoundsState pipBoundsState, PipMenuController pipMenuController, PipBoundsAlgorithm pipBoundsAlgorithm, PipAnimationController pipAnimationController, Transitions transitions, Loading @@ -119,6 +127,10 @@ public abstract class PipTransitionController implements Transitions.TransitionH } } void setPipOrganizer(PipTaskOrganizer pto) { mPipOrganizer = pto; } /** * Registers {@link PipTransitionCallback} to receive transition callbacks. */ Loading
services/core/java/com/android/server/wm/ActivityStarter.java +5 −1 Original line number Diff line number Diff line Loading @@ -1565,7 +1565,7 @@ class ActivityStarter { // transition based on a sub-action. // Only do the create here (and defer requestStart) since startActivityInner might abort. final TransitionController transitionController = r.mTransitionController; final Transition newTransition = (!transitionController.isCollecting() Transition newTransition = (!transitionController.isCollecting() && transitionController.getTransitionPlayer() != null) ? transitionController.createTransition(TRANSIT_OPEN) : null; RemoteTransition remoteTransition = r.takeRemoteTransition(); Loading Loading @@ -1620,6 +1620,10 @@ class ActivityStarter { // The activity is started new rather than just brought forward, so record // it as an existence change. transitionController.collectExistenceChange(r); } else if (result == START_DELIVERED_TO_TOP && newTransition != null) { // We just delivered to top, so there isn't an actual transition here newTransition.abort(); newTransition = null; } if (isTransient) { // `r` isn't guaranteed to be the actual relevant activity, so we must wait Loading