Loading services/core/java/com/android/server/am/ActivityStackSupervisor.java +4 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */); Loading services/core/java/com/android/server/wm/AppWindowToken.java +33 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -1210,6 +1214,30 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return mOrientation; } @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) { Loading Loading @@ -1836,6 +1864,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(); } Loading services/core/java/com/android/server/wm/PinnedStackController.java +53 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -249,10 +254,36 @@ class PinnedStackController { return stackBounds; } /** * 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); Loading @@ -260,8 +291,14 @@ class PinnedStackController { final Rect defaultBounds = new Rect(); final Size size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio, mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); 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; } } Loading Loading @@ -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 Loading Loading @@ -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 */); Loading Loading @@ -485,6 +520,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. */ Loading @@ -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); Loading @@ -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); Loading services/core/java/com/android/server/wm/PinnedStackWindowController.java +2 −2 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading
services/core/java/com/android/server/am/ActivityStackSupervisor.java +4 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */); Loading
services/core/java/com/android/server/wm/AppWindowToken.java +33 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -1210,6 +1214,30 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return mOrientation; } @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) { Loading Loading @@ -1836,6 +1864,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(); } Loading
services/core/java/com/android/server/wm/PinnedStackController.java +53 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -249,10 +254,36 @@ class PinnedStackController { return stackBounds; } /** * 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); Loading @@ -260,8 +291,14 @@ class PinnedStackController { final Rect defaultBounds = new Rect(); final Size size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio, mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); 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; } } Loading Loading @@ -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 Loading Loading @@ -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 */); Loading Loading @@ -485,6 +520,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. */ Loading @@ -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); Loading @@ -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); Loading
services/core/java/com/android/server/wm/PinnedStackWindowController.java +2 −2 Original line number Diff line number Diff line Loading @@ -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)) { Loading