diff options
| author | 2024-12-23 20:50:47 -0800 | |
|---|---|---|
| committer | 2024-12-23 20:50:47 -0800 | |
| commit | 33b821c22d95b1007e40a668894ecf4480de1c99 (patch) | |
| tree | 6ed3cc0b2fb75d1a38110f0e22c56aed791509e5 | |
| parent | 8a5f1e186c70c97e93f7c3d6d56464aea6c4e8b0 (diff) | |
| parent | 440881550bca524db0934649cea920ac9be60f4f (diff) | |
Merge "[1/2][PiP2] Move removePip animation to transition" into main
7 files changed, 43 insertions, 41 deletions
| diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java index fd387d1811fb..37296531ee34 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java @@ -350,7 +350,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,          }          cancelPhysicsAnimation();          mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */); -        mPipScheduler.removePipAfterAnimation(); +        mPipScheduler.scheduleRemovePip();      }      /** Sets the movement bounds to use to constrain PIP position animations. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java index 4461a5c6a70c..7f673d2efc68 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java @@ -122,34 +122,26 @@ public class PipScheduler {       * Schedules exit PiP via expand transition.       */      public void scheduleExitPipViaExpand() { -        WindowContainerTransaction wct = getExitPipViaExpandTransaction(); -        if (wct != null) { -            mMainExecutor.execute(() -> { +        mMainExecutor.execute(() -> { +            if (!mPipTransitionState.isInPip()) return; +            WindowContainerTransaction wct = getExitPipViaExpandTransaction(); +            if (wct != null) {                  mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct,                          null /* destinationBounds */); -            }); -        } -    } - -    // TODO: Optimize this by running the animation as part of the transition -    /** Runs remove PiP animation and schedules remove PiP transition after the animation ends. */ -    public void removePipAfterAnimation() { -        SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); -        PipAlphaAnimator animator = mPipAlphaAnimatorSupplier.get(mContext, -                mPipTransitionState.getPinnedTaskLeash(), tx, PipAlphaAnimator.FADE_OUT); -        animator.setAnimationEndCallback(this::scheduleRemovePipImmediately); -        animator.start(); +            } +        });      }      /** Schedules remove PiP transition. */ -    private void scheduleRemovePipImmediately() { -        WindowContainerTransaction wct = getRemovePipTransaction(); -        if (wct != null) { -            mMainExecutor.execute(() -> { +    public void scheduleRemovePip() { +        mMainExecutor.execute(() -> { +            if (!mPipTransitionState.isInPip()) return; +            WindowContainerTransaction wct = getRemovePipTransaction(); +            if (wct != null) {                  mPipTransitionController.startExitTransition(TRANSIT_REMOVE_PIP, wct,                          null /* destinationBounds */); -            }); -        } +            } +        });      }      /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java index acb5622b041c..2e38449d4584 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java @@ -278,7 +278,8 @@ public class PipTransition extends PipTransitionController implements          }          if (isRemovePipTransition(info)) { -            return removePipImmediately(info, startTransaction, finishTransaction, finishCallback); +            mPipTransitionState.setState(PipTransitionState.EXITING_PIP); +            return startRemoveAnimation(info, startTransaction, finishTransaction, finishCallback);          }          return false;      } @@ -668,13 +669,18 @@ public class PipTransition extends PipTransitionController implements          return true;      } -    private boolean removePipImmediately(@NonNull TransitionInfo info, +    private boolean startRemoveAnimation(@NonNull TransitionInfo info,              @NonNull SurfaceControl.Transaction startTransaction,              @NonNull SurfaceControl.Transaction finishTransaction,              @NonNull Transitions.TransitionFinishCallback finishCallback) { -        startTransaction.apply(); -        finishCallback.onTransitionFinished(null); -        mPipTransitionState.setState(PipTransitionState.EXITED_PIP); +        TransitionInfo.Change pipChange = getChangeByToken(info, +                mPipTransitionState.getPipTaskToken()); +        mFinishCallback = finishCallback; +        PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipChange.getLeash(), +                startTransaction, PipAlphaAnimator.FADE_OUT); +        finishTransaction.setAlpha(pipChange.getLeash(), 0f); +        animator.setAnimationEndCallback(this::finishTransition); +        animator.start();          return true;      } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java index 3fe8c109807a..a8aa25700c7e 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java @@ -120,15 +120,22 @@ public class PipSchedulerTest {      @Test      public void scheduleExitPipViaExpand_nullTaskToken_noop() {          setNullPipTaskToken(); +        when(mMockPipTransitionState.isInPip()).thenReturn(true);          mPipScheduler.scheduleExitPipViaExpand(); -        verify(mMockMainExecutor, never()).execute(any()); +        verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture()); +        assertNotNull(mRunnableArgumentCaptor.getValue()); +        mRunnableArgumentCaptor.getValue().run(); + +        verify(mMockPipTransitionController, never()) +                .startExitTransition(eq(TRANSIT_EXIT_PIP), any(), isNull());      }      @Test      public void scheduleExitPipViaExpand_exitTransitionCalled() {          setMockPipTaskToken(); +        when(mMockPipTransitionState.isInPip()).thenReturn(true);          mPipScheduler.scheduleExitPipViaExpand(); @@ -142,20 +149,13 @@ public class PipSchedulerTest {      @Test      public void removePipAfterAnimation() { -        //TODO: Update once this is changed to run animation as part of transition          setMockPipTaskToken(); +        when(mMockPipTransitionState.isInPip()).thenReturn(true); -        mPipScheduler.removePipAfterAnimation(); -        verify(mMockAlphaAnimator, times(1)) -                .setAnimationEndCallback(mRunnableArgumentCaptor.capture()); -        assertNotNull(mRunnableArgumentCaptor.getValue()); -        verify(mMockAlphaAnimator, times(1)).start(); - -        mRunnableArgumentCaptor.getValue().run(); +        mPipScheduler.scheduleRemovePip();          verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture());          assertNotNull(mRunnableArgumentCaptor.getValue()); -          mRunnableArgumentCaptor.getValue().run();          verify(mMockPipTransitionController, times(1)) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index b71256d27a14..e4ad56fdc074 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -225,6 +225,7 @@ import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_F  import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;  import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;  import static com.android.server.wm.ActivityTaskManagerService.getInputDispatchingTimeoutMillisLocked; +import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled;  import static com.android.server.wm.IdentifierProto.HASH_CODE;  import static com.android.server.wm.IdentifierProto.TITLE;  import static com.android.server.wm.IdentifierProto.USER_ID; @@ -1495,7 +1496,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A              // precede the configuration change from the resize.)              mLastReportedPictureInPictureMode = inPictureInPictureMode;              mLastReportedMultiWindowMode = inPictureInPictureMode; -            ensureActivityConfiguration(true /* ignoreVisibility */); +            if (!isPip2ExperimentEnabled()) { +                // PiP2 should handle sending out the configuration as a part of Shell Transitions. +                ensureActivityConfiguration(true /* ignoreVisibility */); +            }              if (inPictureInPictureMode && findMainWindow() == null                      && task.topRunningActivity() == this) {                  // Prevent malicious app entering PiP without valid WindowState, which can in turn diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 0aff1de72cb1..ef6f92317b2c 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -2526,9 +2526,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {          task.forAllActivities(r -> {              if (!r.attachedToProcess()) return;              mPipModeChangedActivities.add(r); -            // If we are scheduling pip change, then remove this activity from multi-window -            // change list as the processing of pip change will make sure multi-window changed -            // message is processed in the right order relative to pip changed.              mMultiWindowModeChangedActivities.remove(r);          }); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index fb197c566b7d..e45ada9438ae 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -80,6 +80,7 @@ import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_WINDOW_ORG  import static com.android.server.wm.ActivityRecord.State.PAUSING;  import static com.android.server.wm.ActivityRecord.State.RESUMED;  import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission; +import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled;  import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS;  import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;  import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG; @@ -716,6 +717,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub                  }                  if (forceHiddenForPip) {                      wc.asTask().setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */); +                } +                if (forceHiddenForPip && !isPip2ExperimentEnabled()) {                      // When removing pip, make sure that onStop is sent to the app ahead of                      // onPictureInPictureModeChanged.                      // See also PinnedStackTests#testStopBeforeMultiWindowCallbacksOnDismiss |