diff options
4 files changed, 92 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 0a42aa9cce63..21085fa2f717 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -3116,6 +3116,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Need to make sure the pinned stack exist so we can resize it below... stack = display.getOrCreateStack(WINDOWING_MODE_PINNED, r.getActivityType(), ON_TOP); + // Calculate the target bounds here before the task is reparented back into pinned windowing + // mode (which will reset the saved bounds) + final Rect destBounds = stack.getDefaultPictureInPictureBounds(aspectRatio); + try { final TaskRecord task = r.getTask(); // Resize the pinned stack to match the current size of the task the activity we are @@ -3154,11 +3158,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D mWindowManager.continueSurfaceLayout(); } - // Calculate the default bounds (don't use existing stack bounds as we may have just created - // 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.getDefaultPictureInPictureBounds(aspectRatio); - stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */, true /* fromFullscreen */); diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 44d7948b12b6..9f9ca8f2643c 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -16,6 +16,9 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 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; @@ -53,6 +56,7 @@ import static com.android.server.wm.proto.AppWindowTokenProto.WINDOW_TOKEN; import android.annotation.CallSuper; import android.app.Activity; +import android.app.WindowConfiguration.WindowingMode; import android.content.res.Configuration; import android.graphics.GraphicBuffer; import android.graphics.Point; @@ -1211,6 +1215,30 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } @Override + public void onConfigurationChanged(Configuration newParentConfig) { + final int prevWinMode = getWindowingMode(); + super.onConfigurationChanged(newParentConfig); + final int winMode = getWindowingMode(); + + if (prevWinMode == winMode) { + return; + } + + if (prevWinMode != WINDOWING_MODE_UNDEFINED && winMode == WINDOWING_MODE_PINNED) { + // Entering PiP from fullscreen, reset the snap fraction + mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this); + } else if (prevWinMode == WINDOWING_MODE_PINNED && winMode != WINDOWING_MODE_UNDEFINED) { + // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds + // for the next re-entry into PiP (assuming the activity is not hidden or destroyed) + final TaskStack pinnedStack = mDisplayContent.getPinnedStack(); + if (pinnedStack != null) { + mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(this, + pinnedStack.mPreAnimationBounds); + } + } + } + + @Override void checkAppWindowsReadyToShow() { if (allDrawn == mLastAllDrawn) { return; @@ -1837,6 +1865,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree @Override void setHidden(boolean hidden) { super.setHidden(hidden); + + if (hidden) { + // Once the app window is hidden, reset the last saved PiP snap fraction + mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this); + } scheduleAnimation(); } diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java index d8726bfc2c20..69cbe4607cf1 100644 --- a/services/core/java/com/android/server/wm/PinnedStackController.java +++ b/services/core/java/com/android/server/wm/PinnedStackController.java @@ -48,6 +48,7 @@ import com.android.internal.policy.PipSnapAlgorithm; import com.android.server.UiThread; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; @@ -71,6 +72,7 @@ class PinnedStackController { private static final String TAG = TAG_WITH_CLASS_NAME ? "PinnedStackController" : TAG_WM; + public static final float INVALID_SNAP_FRACTION = -1f; private final WindowManagerService mService; private final DisplayContent mDisplayContent; private final Handler mHandler = UiThread.getHandler(); @@ -101,6 +103,8 @@ class PinnedStackController { private float mDefaultAspectRatio; private Point mScreenEdgeInsets; private int mCurrentMinSize; + private float mReentrySnapFraction = INVALID_SNAP_FRACTION; + private WeakReference<AppWindowToken> mLastPipActivity = null; // The aspect ratio bounds of the PIP. private float mMinAspectRatio; @@ -113,6 +117,7 @@ class PinnedStackController { private final Rect mTmpAnimatingBoundsRect = new Rect(); private final Point mTmpDisplaySize = new Point(); + /** * The callback object passed to listeners for them to notify the controller of state changes. */ @@ -250,9 +255,35 @@ class PinnedStackController { } /** + * Saves the current snap fraction for re-entry of the current activity into PiP. + */ + void saveReentrySnapFraction(final AppWindowToken token, final Rect stackBounds) { + mReentrySnapFraction = getSnapFraction(stackBounds); + mLastPipActivity = new WeakReference<>(token); + } + + /** + * Resets the last saved snap fraction so that the default bounds will be returned. + */ + void resetReentrySnapFraction(AppWindowToken token) { + if (mLastPipActivity != null && mLastPipActivity.get() == token) { + mReentrySnapFraction = INVALID_SNAP_FRACTION; + mLastPipActivity = null; + } + } + + /** * @return the default bounds to show the PIP when there is no active PIP. */ - Rect getDefaultBounds() { + Rect getDefaultOrLastSavedBounds() { + return getDefaultBounds(mReentrySnapFraction); + } + + /** + * @return the default bounds to show the PIP, if a {@param snapFraction} is provided, then it + * will apply the default bounds to the provided snap fraction. + */ + Rect getDefaultBounds(float snapFraction) { synchronized (mService.mWindowMap) { final Rect insetBounds = new Rect(); getInsetBounds(insetBounds); @@ -260,8 +291,14 @@ class PinnedStackController { final Rect defaultBounds = new Rect(); final Size size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio, mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); - Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds, - 0, mIsImeShowing ? mImeHeight : 0, defaultBounds); + if (snapFraction != INVALID_SNAP_FRACTION) { + defaultBounds.set(0, 0, size.getWidth(), size.getHeight()); + final Rect movementBounds = getMovementBounds(defaultBounds); + mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction); + } else { + Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds, + 0, mIsImeShowing ? mImeHeight : 0, defaultBounds); + } return defaultBounds; } } @@ -299,9 +336,7 @@ class PinnedStackController { final Rect postChangeStackBounds = mTmpRect; // Calculate the snap fraction of the current stack along the old movement bounds - final Rect preChangeMovementBounds = getMovementBounds(postChangeStackBounds); - final float snapFraction = mSnapAlgorithm.getSnapFraction(postChangeStackBounds, - preChangeMovementBounds); + final float snapFraction = getSnapFraction(postChangeStackBounds); mDisplayInfo.copyFrom(displayInfo); // Calculate the stack bounds in the new orientation to the same same fraction along the @@ -414,7 +449,7 @@ class PinnedStackController { try { final Rect insetBounds = new Rect(); getInsetBounds(insetBounds); - final Rect normalBounds = getDefaultBounds(); + final Rect normalBounds = getDefaultBounds(INVALID_SNAP_FRACTION); if (isValidPictureInPictureAspectRatio(mAspectRatio)) { transformBoundsToAspectRatio(normalBounds, mAspectRatio, false /* useCurrentMinEdgeSize */); @@ -486,6 +521,14 @@ class PinnedStackController { } /** + * @return the default snap fraction to apply instead of the default gravity when calculating + * the default stack bounds when first entering PiP. + */ + private float getSnapFraction(Rect stackBounds) { + return mSnapAlgorithm.getSnapFraction(stackBounds, getMovementBounds(stackBounds)); + } + + /** * @return the pixels for a given dp value. */ private int dpToPx(float dpValue, DisplayMetrics dm) { @@ -494,7 +537,8 @@ class PinnedStackController { void dump(String prefix, PrintWriter pw) { pw.println(prefix + "PinnedStackController"); - pw.print(prefix + " defaultBounds="); getDefaultBounds().printShortString(pw); + pw.print(prefix + " defaultBounds="); + getDefaultBounds(INVALID_SNAP_FRACTION).printShortString(pw); pw.println(); mService.getStackBounds(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mTmpRect); pw.print(prefix + " movementBounds="); getMovementBounds(mTmpRect).printShortString(pw); @@ -516,7 +560,7 @@ class PinnedStackController { void writeToProto(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); - getDefaultBounds().writeToProto(proto, DEFAULT_BOUNDS); + getDefaultBounds(INVALID_SNAP_FRACTION).writeToProto(proto, DEFAULT_BOUNDS); mService.getStackBounds(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mTmpRect); getMovementBounds(mTmpRect).writeToProto(proto, MOVEMENT_BOUNDS); proto.end(token); diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowController.java b/services/core/java/com/android/server/wm/PinnedStackWindowController.java index b021a7223e2e..02fbfba9d332 100644 --- a/services/core/java/com/android/server/wm/PinnedStackWindowController.java +++ b/services/core/java/com/android/server/wm/PinnedStackWindowController.java @@ -61,7 +61,7 @@ public class PinnedStackWindowController extends StackWindowController { displayContent.getPinnedStackController(); if (stackBounds == null) { // Calculate the aspect ratio bounds from the default bounds - stackBounds = pinnedStackController.getDefaultBounds(); + stackBounds = pinnedStackController.getDefaultOrLastSavedBounds(); } if (pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)) { @@ -173,7 +173,7 @@ public class PinnedStackWindowController extends StackWindowController { * from fullscreen to non-fullscreen bounds. */ public boolean deferScheduleMultiWindowModeChanged() { - synchronized(mWindowMap) { + synchronized (mWindowMap) { return mContainer.deferScheduleMultiWindowModeChanged(); } } |