diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index ae913b07fd748..5ded2ccf86408 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -3061,6 +3061,12 @@ "group": "WM_DEBUG_STATES", "at": "com\/android\/server\/wm\/RootWindowContainer.java" }, + "898260097": { + "message": "Creating Pending Pip-Enter: %s", + "level": "VERBOSE", + "group": "WM_DEBUG_WINDOW_TRANSITIONS", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" + }, "898863925": { "message": "Attempted to add QS dialog window with unknown token %s. Aborting.", "level": "WARN", diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index 195923c40c5d6..dfd34f8b7bc64 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -145,6 +145,11 @@ public class PipTransition extends PipTransitionController { if (destinationBounds != null) { mExitDestinationBounds.set(destinationBounds); } + final PipAnimationController.PipTransitionAnimator animator = + mPipAnimationController.getCurrentAnimator(); + if (animator != null && animator.isRunning()) { + animator.cancel(); + } mExitTransition = mTransitions.startTransition(type, out, this); } 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 e4c94264be2c6..98eee7ba33a0e 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 @@ -377,6 +377,7 @@ public class Transitions implements RemoteCallable { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Invalid root leash (%s): %s", transitionToken, info); t.apply(); + finishT.apply(); onAbort(transitionToken); return; } @@ -400,6 +401,7 @@ public class Transitions implements RemoteCallable { } if (nonTaskChange && transferStartingWindow) { t.apply(); + finishT.apply(); // Treat this as an abort since we are bypassing any merge logic and effectively // finishing immediately. onAbort(transitionToken); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 206cee802f9e1..7524825a998ac 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -65,6 +65,7 @@ import static android.provider.Settings.System.FONT_SCALE; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT; +import static android.view.WindowManager.TRANSIT_PIP; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS; @@ -237,6 +238,7 @@ import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.TransferPipe; import com.android.internal.policy.AttributeCache; import com.android.internal.policy.KeyguardDismissCallback; +import com.android.internal.protolog.ProtoLogGroup; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastPrintWriter; @@ -3463,6 +3465,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return false; } + // Create a transition for this pip entry. We guarantee that this gets its own transition + // by queueing this transition on SyncEngine. This is shared by all the entry paths. + final Transition transition = getTransitionController().isShellTransitionsEnabled() + ? new Transition(TRANSIT_PIP, 0 /* flags */, + getTransitionController(), mWindowManager.mSyncEngine) + : null; + final Runnable enterPipRunnable = () -> { synchronized (mGlobalLock) { if (r.getParent() == null) { @@ -3471,7 +3480,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } r.setPictureInPictureParams(params); mRootWindowContainer.moveActivityToPinnedRootTask(r, - null /* launchIntoPipHostActivity */, "enterPictureInPictureMode"); + null /* launchIntoPipHostActivity */, "enterPictureInPictureMode", + transition); final Task task = r.getTask(); // Continue the pausing process after entering pip. if (task.getPausingActivity() == r) { @@ -3488,12 +3498,36 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mActivityClientController.dismissKeyguard(r.token, new KeyguardDismissCallback() { @Override public void onDismissSucceeded() { - mH.post(enterPipRunnable); + if (mWindowManager.mSyncEngine.hasActiveSync()) { + ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, + "Creating Pending Pip-Enter: %s", transition); + mWindowManager.mSyncEngine.queueSyncSet( + () -> getTransitionController().moveToCollecting(transition), + enterPipRunnable); + } else { + // Move to collecting immediately to "claim" the sync-engine for this + // transition. + if (transition != null) { + getTransitionController().moveToCollecting(transition); + } + mH.post(enterPipRunnable); + } } }, null /* message */); } else { // Enter picture in picture immediately otherwise - enterPipRunnable.run(); + if (mWindowManager.mSyncEngine.hasActiveSync()) { + ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, + "Creating Pending Pip-Enter: %s", transition); + mWindowManager.mSyncEngine.queueSyncSet( + () -> getTransitionController().moveToCollecting(transition), + enterPipRunnable); + } else { + if (transition != null) { + getTransitionController().moveToCollecting(transition); + } + enterPipRunnable.run(); + } } return true; } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index e79bb40709e81..ff18d681bee20 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -1977,16 +1977,21 @@ class RootWindowContainer extends WindowContainer void moveActivityToPinnedRootTask(@NonNull ActivityRecord r, @Nullable ActivityRecord launchIntoPipHostActivity, String reason) { + moveActivityToPinnedRootTask(r, launchIntoPipHostActivity, reason, null /* transition */); + } + void moveActivityToPinnedRootTask(@NonNull ActivityRecord r, + @Nullable ActivityRecord launchIntoPipHostActivity, String reason, + @Nullable Transition transition) { final TaskDisplayArea taskDisplayArea = r.getDisplayArea(); final Task task = r.getTask(); final Task rootTask; - Transition newTransition = null; - // Create a transition now to collect the current pinned Task dismiss. Only do the - // create here as the Task (trigger) to enter PIP is not ready yet. + Transition newTransition = transition; + // Create a transition now (if not provided) to collect the current pinned Task dismiss. + // Only do the create here as the Task (trigger) to enter PIP is not ready yet. final TransitionController transitionController = task.mTransitionController; - if (!transitionController.isCollecting() + if (newTransition == null && !transitionController.isCollecting() && transitionController.getTransitionPlayer() != null) { newTransition = transitionController.createTransition(TRANSIT_PIP); }