Loading services/core/java/com/android/server/am/ActivityManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -10589,8 +10589,7 @@ public class ActivityManagerService extends IActivityManager.Stub mStackSupervisor.getStack(PINNED_STACK_ID); if (pinnedStack != null) { pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds, animationDuration, false /* schedulePipModeChangedOnAnimationEnd */); destBounds, animationDuration, false /* fromFullscreen */); } } else { throw new IllegalArgumentException("Stack: " + stackId services/core/java/com/android/server/am/ActivityStackSupervisor.java +11 −8 Original line number Diff line number Diff line Loading @@ -2986,18 +2986,21 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D mWindowManager.continueSurfaceLayout(); } // The task might have already been running and its visibility needs to be synchronized // with the visibility of the stack / windows. ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); resumeFocusedStackTopActivityLocked(); // Calculate the default bounds (don't use existing stack bounds as we may have just created // the stack // the stack, and schedule the start of the animation into PiP (the bounds animator that // is triggered by this is posted on another thread) final Rect destBounds = stack.getPictureInPictureBounds(aspectRatio, false /* useExistingStackBounds */); stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */, true /* schedulePipModeChangedOnAnimationEnd */); true /* fromFullscreen */); // Update the visibility of all activities after the they have been reparented to the new // stack. This MUST run after the animation above is scheduled to ensure that the windows // drawn signal is scheduled after the bounds animation start call on the bounds animator // thread. ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); resumeFocusedStackTopActivityLocked(); mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName, r.getTask().taskId); } Loading services/core/java/com/android/server/am/PinnedActivityStack.java +2 −2 Original line number Diff line number Diff line Loading @@ -50,12 +50,12 @@ class PinnedActivityStack extends ActivityStack<PinnedStackWindowController> } void animateResizePinnedStack(Rect sourceHintBounds, Rect toBounds, int animationDuration, boolean schedulePipModeChangedOnAnimationEnd) { boolean fromFullscreen) { if (skipResizeAnimation(toBounds == null /* toFullscreen */)) { mService.moveTasksToFullscreenStack(mStackId, true /* onTop */); } else { getWindowContainerController().animateResizePinnedStack(toBounds, sourceHintBounds, animationDuration, schedulePipModeChangedOnAnimationEnd); animationDuration, fromFullscreen); } } Loading services/core/java/com/android/server/wm/AppWindowToken.java +7 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; Loading Loading @@ -51,6 +52,7 @@ import static com.android.server.wm.WindowManagerService.logWithStack; import android.annotation.NonNull; import android.app.Activity; import android.app.ActivityManager; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Binder; Loading Loading @@ -1345,9 +1347,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget(); final TaskStack s = getStack(); if (s != null) { s.onAllWindowsDrawn(); // Notify the pinned stack upon all windows drawn. If there was an animation in // progress then this signal will resume that animation. final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID); if (pinnedStack != null) { pinnedStack.onAllWindowsDrawn(); } } } Loading services/core/java/com/android/server/wm/BoundsAnimationController.java +41 −18 Original line number Diff line number Diff line Loading @@ -139,8 +139,14 @@ public class BoundsAnimationController { private final boolean mSkipAnimationStart; // True if this animation was canceled by the user, not as a part of a replacing animation private boolean mSkipAnimationEnd; // True if the animation target is animating from the fullscreen. Only one of // {@link mMoveToFullscreen} or {@link mMoveFromFullscreen} can be true at any time in the // animation. private boolean mMoveFromFullscreen; // True if the animation target should be moved to the fullscreen stack at the end of this // animation // animation. Only one of {@link mMoveToFullscreen} or {@link mMoveFromFullscreen} can be // true at any time in the animation. private boolean mMoveToFullscreen; // Whether to schedule PiP mode changes on animation start/end Loading @@ -151,15 +157,21 @@ public class BoundsAnimationController { private final int mFrozenTaskWidth; private final int mFrozenTaskHeight; // Timeout callback to ensure we continue the animation if waiting for resuming or app // windows drawn fails private final Runnable mResumeRunnable = () -> resume(); BoundsAnimator(BoundsAnimationTarget target, Rect from, Rect to, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveToFullscreen, boolean replacingExistingAnimation) { boolean moveFromFullscreen, boolean moveToFullscreen, boolean replacingExistingAnimation) { super(); mTarget = target; mFrom.set(from); mTo.set(to); mSkipAnimationStart = replacingExistingAnimation; mSchedulePipModeChangedState = schedulePipModeChangedState; mMoveFromFullscreen = moveFromFullscreen; mMoveToFullscreen = moveToFullscreen; addUpdateListener(this); addListener(this); Loading @@ -177,13 +189,6 @@ public class BoundsAnimationController { } } final Runnable mResumeRunnable = new Runnable() { @Override public void run() { resume(); } }; @Override public void onAnimationStart(Animator animation) { if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget Loading @@ -199,6 +204,12 @@ public class BoundsAnimationController { if (!mSkipAnimationStart) { mTarget.onAnimationStart(mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START); // When starting an animation from fullscreen, pause here and wait for the // windows-drawn signal before we start the rest of the transition down into PiP. if (mMoveFromFullscreen) { pause(); } } // Immediately update the task bounds if they have to become larger, but preserve Loading @@ -213,13 +224,20 @@ public class BoundsAnimationController { // correct logic to make this resize seamless. if (mMoveToFullscreen) { pause(); mHandler.postDelayed(mResumeRunnable, WAIT_FOR_DRAW_TIMEOUT_MS); } } } @Override public void pause() { if (DEBUG) Slog.d(TAG, "pause: waiting for windows drawn"); super.pause(); mHandler.postDelayed(mResumeRunnable, WAIT_FOR_DRAW_TIMEOUT_MS); } @Override public void resume() { if (DEBUG) Slog.d(TAG, "resume:"); mHandler.removeCallbacks(mResumeRunnable); super.resume(); } Loading Loading @@ -336,15 +354,15 @@ public class BoundsAnimationController { public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to, int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveToFullscreen) { boolean moveFromFullscreen, boolean moveToFullscreen) { animateBoundsImpl(target, from, to, animationDuration, schedulePipModeChangedState, moveToFullscreen); moveFromFullscreen, moveToFullscreen); } @VisibleForTesting BoundsAnimator animateBoundsImpl(final BoundsAnimationTarget target, Rect from, Rect to, int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveToFullscreen) { boolean moveFromFullscreen, boolean moveToFullscreen) { final BoundsAnimator existing = mRunningAnimations.get(target); final boolean replacing = existing != null; Loading Loading @@ -387,7 +405,7 @@ public class BoundsAnimationController { existing.cancel(); } final BoundsAnimator animator = new BoundsAnimator(target, from, to, schedulePipModeChangedState, moveToFullscreen, replacing); schedulePipModeChangedState, moveFromFullscreen, moveToFullscreen, replacing); mRunningAnimations.put(target, animator); animator.setFloatValues(0f, 1f); animator.setDuration((animationDuration != -1 ? animationDuration Loading @@ -397,14 +415,19 @@ public class BoundsAnimationController { return animator; } public Handler getHandler() { return mHandler; } public void onAllWindowsDrawn() { if (DEBUG) Slog.d(TAG, "onAllWindowsDrawn:"); mHandler.post(this::resume); } private void resume() { for (int i = 0; i < mRunningAnimations.size(); i++) { final BoundsAnimator b = mRunningAnimations.valueAt(i); b.resume(); } } public void onAllWindowsDrawn() { mHandler.post(this::resume); } } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +1 −2 Original line number Diff line number Diff line Loading @@ -10589,8 +10589,7 @@ public class ActivityManagerService extends IActivityManager.Stub mStackSupervisor.getStack(PINNED_STACK_ID); if (pinnedStack != null) { pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds, animationDuration, false /* schedulePipModeChangedOnAnimationEnd */); destBounds, animationDuration, false /* fromFullscreen */); } } else { throw new IllegalArgumentException("Stack: " + stackId
services/core/java/com/android/server/am/ActivityStackSupervisor.java +11 −8 Original line number Diff line number Diff line Loading @@ -2986,18 +2986,21 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D mWindowManager.continueSurfaceLayout(); } // The task might have already been running and its visibility needs to be synchronized // with the visibility of the stack / windows. ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); resumeFocusedStackTopActivityLocked(); // Calculate the default bounds (don't use existing stack bounds as we may have just created // the stack // the stack, and schedule the start of the animation into PiP (the bounds animator that // is triggered by this is posted on another thread) final Rect destBounds = stack.getPictureInPictureBounds(aspectRatio, false /* useExistingStackBounds */); stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */, true /* schedulePipModeChangedOnAnimationEnd */); true /* fromFullscreen */); // Update the visibility of all activities after the they have been reparented to the new // stack. This MUST run after the animation above is scheduled to ensure that the windows // drawn signal is scheduled after the bounds animation start call on the bounds animator // thread. ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); resumeFocusedStackTopActivityLocked(); mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName, r.getTask().taskId); } Loading
services/core/java/com/android/server/am/PinnedActivityStack.java +2 −2 Original line number Diff line number Diff line Loading @@ -50,12 +50,12 @@ class PinnedActivityStack extends ActivityStack<PinnedStackWindowController> } void animateResizePinnedStack(Rect sourceHintBounds, Rect toBounds, int animationDuration, boolean schedulePipModeChangedOnAnimationEnd) { boolean fromFullscreen) { if (skipResizeAnimation(toBounds == null /* toFullscreen */)) { mService.moveTasksToFullscreenStack(mStackId, true /* onTop */); } else { getWindowContainerController().animateResizePinnedStack(toBounds, sourceHintBounds, animationDuration, schedulePipModeChangedOnAnimationEnd); animationDuration, fromFullscreen); } } Loading
services/core/java/com/android/server/wm/AppWindowToken.java +7 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; Loading Loading @@ -51,6 +52,7 @@ import static com.android.server.wm.WindowManagerService.logWithStack; import android.annotation.NonNull; import android.app.Activity; import android.app.ActivityManager; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Binder; Loading Loading @@ -1345,9 +1347,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget(); final TaskStack s = getStack(); if (s != null) { s.onAllWindowsDrawn(); // Notify the pinned stack upon all windows drawn. If there was an animation in // progress then this signal will resume that animation. final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID); if (pinnedStack != null) { pinnedStack.onAllWindowsDrawn(); } } } Loading
services/core/java/com/android/server/wm/BoundsAnimationController.java +41 −18 Original line number Diff line number Diff line Loading @@ -139,8 +139,14 @@ public class BoundsAnimationController { private final boolean mSkipAnimationStart; // True if this animation was canceled by the user, not as a part of a replacing animation private boolean mSkipAnimationEnd; // True if the animation target is animating from the fullscreen. Only one of // {@link mMoveToFullscreen} or {@link mMoveFromFullscreen} can be true at any time in the // animation. private boolean mMoveFromFullscreen; // True if the animation target should be moved to the fullscreen stack at the end of this // animation // animation. Only one of {@link mMoveToFullscreen} or {@link mMoveFromFullscreen} can be // true at any time in the animation. private boolean mMoveToFullscreen; // Whether to schedule PiP mode changes on animation start/end Loading @@ -151,15 +157,21 @@ public class BoundsAnimationController { private final int mFrozenTaskWidth; private final int mFrozenTaskHeight; // Timeout callback to ensure we continue the animation if waiting for resuming or app // windows drawn fails private final Runnable mResumeRunnable = () -> resume(); BoundsAnimator(BoundsAnimationTarget target, Rect from, Rect to, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveToFullscreen, boolean replacingExistingAnimation) { boolean moveFromFullscreen, boolean moveToFullscreen, boolean replacingExistingAnimation) { super(); mTarget = target; mFrom.set(from); mTo.set(to); mSkipAnimationStart = replacingExistingAnimation; mSchedulePipModeChangedState = schedulePipModeChangedState; mMoveFromFullscreen = moveFromFullscreen; mMoveToFullscreen = moveToFullscreen; addUpdateListener(this); addListener(this); Loading @@ -177,13 +189,6 @@ public class BoundsAnimationController { } } final Runnable mResumeRunnable = new Runnable() { @Override public void run() { resume(); } }; @Override public void onAnimationStart(Animator animation) { if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget Loading @@ -199,6 +204,12 @@ public class BoundsAnimationController { if (!mSkipAnimationStart) { mTarget.onAnimationStart(mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START); // When starting an animation from fullscreen, pause here and wait for the // windows-drawn signal before we start the rest of the transition down into PiP. if (mMoveFromFullscreen) { pause(); } } // Immediately update the task bounds if they have to become larger, but preserve Loading @@ -213,13 +224,20 @@ public class BoundsAnimationController { // correct logic to make this resize seamless. if (mMoveToFullscreen) { pause(); mHandler.postDelayed(mResumeRunnable, WAIT_FOR_DRAW_TIMEOUT_MS); } } } @Override public void pause() { if (DEBUG) Slog.d(TAG, "pause: waiting for windows drawn"); super.pause(); mHandler.postDelayed(mResumeRunnable, WAIT_FOR_DRAW_TIMEOUT_MS); } @Override public void resume() { if (DEBUG) Slog.d(TAG, "resume:"); mHandler.removeCallbacks(mResumeRunnable); super.resume(); } Loading Loading @@ -336,15 +354,15 @@ public class BoundsAnimationController { public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to, int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveToFullscreen) { boolean moveFromFullscreen, boolean moveToFullscreen) { animateBoundsImpl(target, from, to, animationDuration, schedulePipModeChangedState, moveToFullscreen); moveFromFullscreen, moveToFullscreen); } @VisibleForTesting BoundsAnimator animateBoundsImpl(final BoundsAnimationTarget target, Rect from, Rect to, int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveToFullscreen) { boolean moveFromFullscreen, boolean moveToFullscreen) { final BoundsAnimator existing = mRunningAnimations.get(target); final boolean replacing = existing != null; Loading Loading @@ -387,7 +405,7 @@ public class BoundsAnimationController { existing.cancel(); } final BoundsAnimator animator = new BoundsAnimator(target, from, to, schedulePipModeChangedState, moveToFullscreen, replacing); schedulePipModeChangedState, moveFromFullscreen, moveToFullscreen, replacing); mRunningAnimations.put(target, animator); animator.setFloatValues(0f, 1f); animator.setDuration((animationDuration != -1 ? animationDuration Loading @@ -397,14 +415,19 @@ public class BoundsAnimationController { return animator; } public Handler getHandler() { return mHandler; } public void onAllWindowsDrawn() { if (DEBUG) Slog.d(TAG, "onAllWindowsDrawn:"); mHandler.post(this::resume); } private void resume() { for (int i = 0; i < mRunningAnimations.size(); i++) { final BoundsAnimator b = mRunningAnimations.valueAt(i); b.resume(); } } public void onAllWindowsDrawn() { mHandler.post(this::resume); } }