Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java +31 −18 Original line number Diff line number Diff line Loading @@ -123,15 +123,16 @@ public class PipBoundsAlgorithm { /** Returns the destination bounds to place the PIP window on entry. */ public Rect getEntryDestinationBounds() { final PipBoundsState.PipReentryState reentryState = mPipBoundsState.getReentryState(); final boolean shouldRestoreReentryBounds = reentryState != null; final Rect destinationBounds = shouldRestoreReentryBounds final Rect destinationBounds = reentryState != null ? getDefaultBounds(reentryState.getSnapFraction(), reentryState.getSize()) : getDefaultBounds(); return transformBoundsToAspectRatioIfValid(destinationBounds, final boolean useCurrentSize = reentryState != null && reentryState.getSize() != null; final Rect r = transformBoundsToAspectRatioIfValid(destinationBounds, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, shouldRestoreReentryBounds); useCurrentSize); return r; } /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ Loading Loading @@ -221,14 +222,18 @@ public class PipBoundsAlgorithm { private Rect getDefaultBounds(float snapFraction, Size size) { final Rect defaultBounds = new Rect(); if (snapFraction != INVALID_SNAP_FRACTION && size != null) { // The default bounds are the given size positioned at the given snap fraction. defaultBounds.set(0, 0, size.getWidth(), size.getHeight()); final Rect movementBounds = getMovementBounds(defaultBounds); mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction); } else { return defaultBounds; } // Calculate the default size. final Size defaultSize; final Rect insetBounds = new Rect(); getInsetBounds(insetBounds); final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo(); final Size defaultSize; final Size overrideMinSize = mPipBoundsState.getOverrideMinSize(); if (overrideMinSize != null) { // The override minimal size is set, use that as the default size making sure it's Loading @@ -239,6 +244,14 @@ public class PipBoundsAlgorithm { defaultSize = getSizeForAspectRatio(mDefaultAspectRatio, mDefaultMinSize, displayInfo.logicalWidth, displayInfo.logicalHeight); } // Now that we have the default size, apply the snap fraction if valid or position the // bounds using the default gravity. if (snapFraction != INVALID_SNAP_FRACTION) { defaultBounds.set(0, 0, defaultSize.getWidth(), defaultSize.getHeight()); final Rect movementBounds = getMovementBounds(defaultBounds); mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction); } else { Gravity.apply(mDefaultStackGravity, defaultSize.getWidth(), defaultSize.getHeight(), insetBounds, 0, Math.max( mPipBoundsState.isImeShowing() ? mPipBoundsState.getImeHeight() : 0, Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +18 −5 Original line number Diff line number Diff line Loading @@ -76,6 +76,8 @@ public final class PipBoundsState { private int mImeHeight; private boolean mIsShelfShowing; private int mShelfHeight; /** Whether the user has resized the PIP manually. */ private boolean mHasUserResizedPip; private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable BiConsumer<Boolean, Integer> mOnShelfVisibilityChangeCallback; Loading Loading @@ -189,8 +191,8 @@ public final class PipBoundsState { } /** Save the reentry state to restore to when re-entering PIP mode. */ public void saveReentryState(@NonNull Rect bounds, float fraction) { mPipReentryState = new PipReentryState(new Size(bounds.width(), bounds.height()), fraction); public void saveReentryState(Size size, float fraction) { mPipReentryState = new PipReentryState(size, fraction); } /** Returns the saved reentry state. */ Loading @@ -205,6 +207,7 @@ public final class PipBoundsState { mLastPipComponentName = lastPipComponentName; if (changed) { clearReentryState(); setHasUserResizedPip(false); } } Loading Loading @@ -329,6 +332,16 @@ public final class PipBoundsState { return mShelfHeight; } /** Returns whether the user has resized the PIP. */ public boolean hasUserResizedPip() { return mHasUserResizedPip; } /** Set whether the user has resized the PIP. */ public void setHasUserResizedPip(boolean hasUserResizedPip) { mHasUserResizedPip = hasUserResizedPip; } /** * Registers a callback when the minimal size of PIP that is set by the app changes. */ Loading Loading @@ -397,15 +410,15 @@ public final class PipBoundsState { static final class PipReentryState { private static final String TAG = PipReentryState.class.getSimpleName(); private final @NonNull Size mSize; private final @Nullable Size mSize; private final float mSnapFraction; PipReentryState(@NonNull Size size, float snapFraction) { PipReentryState(@Nullable Size size, float snapFraction) { mSize = size; mSnapFraction = snapFraction; } @NonNull @Nullable Size getSize() { return mSize; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +13 −13 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.Log; import android.util.Pair; import android.util.Size; import android.util.Slog; import android.view.DisplayInfo; import android.view.WindowManagerGlobal; Loading Loading @@ -86,7 +87,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private final DisplayInfo mTmpDisplayInfo = new DisplayInfo(); private final Rect mTmpInsetBounds = new Rect(); protected final Rect mReentryBounds = new Rect(); private boolean mIsInFixedRotation; private Consumer<Boolean> mPinnedStackAnimationRecentsCallback; Loading Loading @@ -438,10 +438,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds) { if (isOutPipDirection(direction)) { // Exiting PIP, save the reentry bounds to restore to when re-entering. updateReentryBounds(pipBounds); final float snapFraction = mPipBoundsAlgorithm.getSnapFraction(mReentryBounds); mPipBoundsState.saveReentryState(mReentryBounds, snapFraction); // Exiting PIP, save the reentry state to restore to when re-entering. saveReentryState(pipBounds); } // Disable touches while the animation is running mTouchHandler.setTouchEnabled(false); Loading @@ -450,14 +448,16 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } } /** * Update the bounds used to save the re-entry size and snap fraction when exiting PIP. */ public void updateReentryBounds(Rect bounds) { /** Save the state to restore to on re-entry. */ public void saveReentryState(Rect pipBounds) { float snapFraction = mPipBoundsAlgorithm.getSnapFraction(pipBounds); if (mPipBoundsState.hasUserResizedPip()) { final Rect reentryBounds = mTouchHandler.getUserResizeBounds(); float snapFraction = mPipBoundsAlgorithm.getSnapFraction(bounds); mPipBoundsAlgorithm.applySnapFraction(reentryBounds, snapFraction); mReentryBounds.set(reentryBounds); final Size reentrySize = new Size(reentryBounds.width(), reentryBounds.height()); mPipBoundsState.saveReentryState(reentrySize, snapFraction); } else { mPipBoundsState.saveReentryState(null /* bounds */, snapFraction); } } /** Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java +2 −0 Original line number Diff line number Diff line Loading @@ -410,6 +410,7 @@ public class PipResizeGestureHandler { mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds, null); mPipBoundsState.setHasUserResizedPip(true); } } } Loading Loading @@ -462,6 +463,7 @@ public class PipResizeGestureHandler { true /* useCurrentSize */); mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds, null); mPipBoundsState.setHasUserResizedPip(true); } break; case MotionEvent.ACTION_UP: Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java +4 −2 Original line number Diff line number Diff line Loading @@ -337,7 +337,8 @@ public class PipBoundsAlgorithmTest extends ShellTestCase { reentryBounds.scale(1.25f); final float reentrySnapFraction = mPipBoundsAlgorithm.getSnapFraction(reentryBounds); mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction); mPipBoundsState.saveReentryState( new Size(reentryBounds.width(), reentryBounds.height()), reentrySnapFraction); final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); assertEquals(reentryBounds.width(), destinationBounds.width()); Loading @@ -351,7 +352,8 @@ public class PipBoundsAlgorithmTest extends ShellTestCase { reentryBounds.offset(0, -100); final float reentrySnapFraction = mPipBoundsAlgorithm.getSnapFraction(reentryBounds); mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction); mPipBoundsState.saveReentryState( new Size(reentryBounds.width(), reentryBounds.height()), reentrySnapFraction); final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java +31 −18 Original line number Diff line number Diff line Loading @@ -123,15 +123,16 @@ public class PipBoundsAlgorithm { /** Returns the destination bounds to place the PIP window on entry. */ public Rect getEntryDestinationBounds() { final PipBoundsState.PipReentryState reentryState = mPipBoundsState.getReentryState(); final boolean shouldRestoreReentryBounds = reentryState != null; final Rect destinationBounds = shouldRestoreReentryBounds final Rect destinationBounds = reentryState != null ? getDefaultBounds(reentryState.getSnapFraction(), reentryState.getSize()) : getDefaultBounds(); return transformBoundsToAspectRatioIfValid(destinationBounds, final boolean useCurrentSize = reentryState != null && reentryState.getSize() != null; final Rect r = transformBoundsToAspectRatioIfValid(destinationBounds, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, shouldRestoreReentryBounds); useCurrentSize); return r; } /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ Loading Loading @@ -221,14 +222,18 @@ public class PipBoundsAlgorithm { private Rect getDefaultBounds(float snapFraction, Size size) { final Rect defaultBounds = new Rect(); if (snapFraction != INVALID_SNAP_FRACTION && size != null) { // The default bounds are the given size positioned at the given snap fraction. defaultBounds.set(0, 0, size.getWidth(), size.getHeight()); final Rect movementBounds = getMovementBounds(defaultBounds); mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction); } else { return defaultBounds; } // Calculate the default size. final Size defaultSize; final Rect insetBounds = new Rect(); getInsetBounds(insetBounds); final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo(); final Size defaultSize; final Size overrideMinSize = mPipBoundsState.getOverrideMinSize(); if (overrideMinSize != null) { // The override minimal size is set, use that as the default size making sure it's Loading @@ -239,6 +244,14 @@ public class PipBoundsAlgorithm { defaultSize = getSizeForAspectRatio(mDefaultAspectRatio, mDefaultMinSize, displayInfo.logicalWidth, displayInfo.logicalHeight); } // Now that we have the default size, apply the snap fraction if valid or position the // bounds using the default gravity. if (snapFraction != INVALID_SNAP_FRACTION) { defaultBounds.set(0, 0, defaultSize.getWidth(), defaultSize.getHeight()); final Rect movementBounds = getMovementBounds(defaultBounds); mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction); } else { Gravity.apply(mDefaultStackGravity, defaultSize.getWidth(), defaultSize.getHeight(), insetBounds, 0, Math.max( mPipBoundsState.isImeShowing() ? mPipBoundsState.getImeHeight() : 0, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +18 −5 Original line number Diff line number Diff line Loading @@ -76,6 +76,8 @@ public final class PipBoundsState { private int mImeHeight; private boolean mIsShelfShowing; private int mShelfHeight; /** Whether the user has resized the PIP manually. */ private boolean mHasUserResizedPip; private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable BiConsumer<Boolean, Integer> mOnShelfVisibilityChangeCallback; Loading Loading @@ -189,8 +191,8 @@ public final class PipBoundsState { } /** Save the reentry state to restore to when re-entering PIP mode. */ public void saveReentryState(@NonNull Rect bounds, float fraction) { mPipReentryState = new PipReentryState(new Size(bounds.width(), bounds.height()), fraction); public void saveReentryState(Size size, float fraction) { mPipReentryState = new PipReentryState(size, fraction); } /** Returns the saved reentry state. */ Loading @@ -205,6 +207,7 @@ public final class PipBoundsState { mLastPipComponentName = lastPipComponentName; if (changed) { clearReentryState(); setHasUserResizedPip(false); } } Loading Loading @@ -329,6 +332,16 @@ public final class PipBoundsState { return mShelfHeight; } /** Returns whether the user has resized the PIP. */ public boolean hasUserResizedPip() { return mHasUserResizedPip; } /** Set whether the user has resized the PIP. */ public void setHasUserResizedPip(boolean hasUserResizedPip) { mHasUserResizedPip = hasUserResizedPip; } /** * Registers a callback when the minimal size of PIP that is set by the app changes. */ Loading Loading @@ -397,15 +410,15 @@ public final class PipBoundsState { static final class PipReentryState { private static final String TAG = PipReentryState.class.getSimpleName(); private final @NonNull Size mSize; private final @Nullable Size mSize; private final float mSnapFraction; PipReentryState(@NonNull Size size, float snapFraction) { PipReentryState(@Nullable Size size, float snapFraction) { mSize = size; mSnapFraction = snapFraction; } @NonNull @Nullable Size getSize() { return mSize; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +13 −13 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.Log; import android.util.Pair; import android.util.Size; import android.util.Slog; import android.view.DisplayInfo; import android.view.WindowManagerGlobal; Loading Loading @@ -86,7 +87,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac private final DisplayInfo mTmpDisplayInfo = new DisplayInfo(); private final Rect mTmpInsetBounds = new Rect(); protected final Rect mReentryBounds = new Rect(); private boolean mIsInFixedRotation; private Consumer<Boolean> mPinnedStackAnimationRecentsCallback; Loading Loading @@ -438,10 +438,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac @Override public void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds) { if (isOutPipDirection(direction)) { // Exiting PIP, save the reentry bounds to restore to when re-entering. updateReentryBounds(pipBounds); final float snapFraction = mPipBoundsAlgorithm.getSnapFraction(mReentryBounds); mPipBoundsState.saveReentryState(mReentryBounds, snapFraction); // Exiting PIP, save the reentry state to restore to when re-entering. saveReentryState(pipBounds); } // Disable touches while the animation is running mTouchHandler.setTouchEnabled(false); Loading @@ -450,14 +448,16 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac } } /** * Update the bounds used to save the re-entry size and snap fraction when exiting PIP. */ public void updateReentryBounds(Rect bounds) { /** Save the state to restore to on re-entry. */ public void saveReentryState(Rect pipBounds) { float snapFraction = mPipBoundsAlgorithm.getSnapFraction(pipBounds); if (mPipBoundsState.hasUserResizedPip()) { final Rect reentryBounds = mTouchHandler.getUserResizeBounds(); float snapFraction = mPipBoundsAlgorithm.getSnapFraction(bounds); mPipBoundsAlgorithm.applySnapFraction(reentryBounds, snapFraction); mReentryBounds.set(reentryBounds); final Size reentrySize = new Size(reentryBounds.width(), reentryBounds.height()); mPipBoundsState.saveReentryState(reentrySize, snapFraction); } else { mPipBoundsState.saveReentryState(null /* bounds */, snapFraction); } } /** Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java +2 −0 Original line number Diff line number Diff line Loading @@ -410,6 +410,7 @@ public class PipResizeGestureHandler { mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds, null); mPipBoundsState.setHasUserResizedPip(true); } } } Loading Loading @@ -462,6 +463,7 @@ public class PipResizeGestureHandler { true /* useCurrentSize */); mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds, null); mPipBoundsState.setHasUserResizedPip(true); } break; case MotionEvent.ACTION_UP: Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java +4 −2 Original line number Diff line number Diff line Loading @@ -337,7 +337,8 @@ public class PipBoundsAlgorithmTest extends ShellTestCase { reentryBounds.scale(1.25f); final float reentrySnapFraction = mPipBoundsAlgorithm.getSnapFraction(reentryBounds); mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction); mPipBoundsState.saveReentryState( new Size(reentryBounds.width(), reentryBounds.height()), reentrySnapFraction); final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); assertEquals(reentryBounds.width(), destinationBounds.width()); Loading @@ -351,7 +352,8 @@ public class PipBoundsAlgorithmTest extends ShellTestCase { reentryBounds.offset(0, -100); final float reentrySnapFraction = mPipBoundsAlgorithm.getSnapFraction(reentryBounds); mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction); mPipBoundsState.saveReentryState( new Size(reentryBounds.width(), reentryBounds.height()), reentrySnapFraction); final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); Loading