Merge "Fix resizability in apps using the override min size"
This commit is contained in:
committed by
Android (Google) Code Review
commit
489b97ba52
@@ -58,8 +58,6 @@ public class PipBoundsHandler {
|
||||
private int mDefaultStackGravity;
|
||||
private int mDefaultMinSize;
|
||||
private Point mScreenEdgeInsets;
|
||||
private int mCurrentMinSize;
|
||||
private Size mOverrideMinimalSize;
|
||||
|
||||
private boolean mIsImeShowing;
|
||||
private int mImeHeight;
|
||||
@@ -74,6 +72,7 @@ public class PipBoundsHandler {
|
||||
// resources as it would clobber mAspectRatio when entering PiP from fullscreen which
|
||||
// triggers a configuration change and the resources to be reloaded.
|
||||
mPipBoundsState.setAspectRatio(mDefaultAspectRatio);
|
||||
mPipBoundsState.setMinEdgeSize(mDefaultMinSize);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +86,6 @@ public class PipBoundsHandler {
|
||||
com.android.internal.R.integer.config_defaultPictureInPictureGravity);
|
||||
mDefaultMinSize = res.getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.default_minimal_size_pip_resizable_task);
|
||||
mCurrentMinSize = mDefaultMinSize;
|
||||
final String screenEdgeInsetsDpString = res.getString(
|
||||
com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets);
|
||||
final Size screenEdgeInsetsDp = !screenEdgeInsetsDpString.isEmpty()
|
||||
@@ -102,14 +100,6 @@ public class PipBoundsHandler {
|
||||
com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Min edge size for {@link PipSnapAlgorithm} to calculate corresponding bounds
|
||||
* @param minEdgeSize
|
||||
*/
|
||||
public void setMinEdgeSize(int minEdgeSize) {
|
||||
mCurrentMinSize = minEdgeSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets both shelf visibility and its height if applicable.
|
||||
* @return {@code true} if the internal shelf state is changed, {@code false} otherwise.
|
||||
@@ -167,16 +157,16 @@ public class PipBoundsHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #getDestinationBounds(Rect, Size, boolean)}
|
||||
* See {@link #getDestinationBounds(Rect, boolean)}
|
||||
*/
|
||||
public Rect getDestinationBounds(Rect bounds, Size minimalSize) {
|
||||
return getDestinationBounds(bounds, minimalSize, false /* useCurrentMinEdgeSize */);
|
||||
public Rect getDestinationBounds(Rect bounds) {
|
||||
return getDestinationBounds(bounds, false /* useCurrentMinEdgeSize */);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link Rect} of the destination PiP window bounds.
|
||||
*/
|
||||
public Rect getDestinationBounds(Rect bounds, Size minimalSize, boolean useCurrentMinEdgeSize) {
|
||||
public Rect getDestinationBounds(Rect bounds, boolean useCurrentMinEdgeSize) {
|
||||
boolean isReentryBounds = false;
|
||||
final Rect destinationBounds;
|
||||
if (bounds == null) {
|
||||
@@ -191,7 +181,6 @@ public class PipBoundsHandler {
|
||||
} else {
|
||||
// Get actual default bounds.
|
||||
defaultBounds = getDefaultBounds(INVALID_SNAP_FRACTION, null /* size */);
|
||||
mOverrideMinimalSize = minimalSize;
|
||||
}
|
||||
|
||||
destinationBounds = new Rect(defaultBounds);
|
||||
@@ -306,67 +295,56 @@ public class PipBoundsHandler {
|
||||
&& Float.compare(aspectRatio, mMaxAspectRatio) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current bound with the currently store aspect ratio.
|
||||
* @param stackBounds
|
||||
*/
|
||||
public void transformBoundsToAspectRatio(Rect stackBounds) {
|
||||
transformBoundsToAspectRatio(stackBounds, mPipBoundsState.getAspectRatio(),
|
||||
true /* useCurrentMinEdgeSize */, true /* useCurrentSize */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current bounds (or the default bounds if there are no current bounds) with the
|
||||
* specified aspect ratio.
|
||||
*/
|
||||
private void transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio,
|
||||
public void transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio,
|
||||
boolean useCurrentMinEdgeSize, boolean useCurrentSize) {
|
||||
// Save the snap fraction and adjust the size based on the new aspect ratio.
|
||||
final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
|
||||
getMovementBounds(stackBounds), mPipBoundsState.getStashedState());
|
||||
final int minEdgeSize = useCurrentMinEdgeSize ? mCurrentMinSize : mDefaultMinSize;
|
||||
|
||||
final Size overrideMinSize = mPipBoundsState.getOverrideMinSize();
|
||||
final Size size;
|
||||
if (useCurrentMinEdgeSize || useCurrentSize) {
|
||||
// The default minimum edge size, or the override min edge size if set.
|
||||
final int defaultMinEdgeSize = overrideMinSize == null ? mDefaultMinSize
|
||||
: mPipBoundsState.getOverrideMinEdgeSize();
|
||||
final int minEdgeSize = useCurrentMinEdgeSize ? mPipBoundsState.getMinEdgeSize()
|
||||
: defaultMinEdgeSize;
|
||||
// Use the existing size but adjusted to the aspect ratio and min edge size.
|
||||
size = mSnapAlgorithm.getSizeForAspectRatio(
|
||||
new Size(stackBounds.width(), stackBounds.height()), aspectRatio, minEdgeSize);
|
||||
} else {
|
||||
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
|
||||
size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, minEdgeSize,
|
||||
displayInfo.logicalWidth, displayInfo.logicalHeight);
|
||||
if (overrideMinSize != null) {
|
||||
// The override minimal size is set, use that as the default size making sure it's
|
||||
// adjusted to the aspect ratio.
|
||||
size = adjustSizeToAspectRatio(overrideMinSize, aspectRatio);
|
||||
} else {
|
||||
// Calculate the default size using the display size and default min edge size.
|
||||
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
|
||||
size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, mDefaultMinSize,
|
||||
displayInfo.logicalWidth, displayInfo.logicalHeight);
|
||||
}
|
||||
}
|
||||
|
||||
final int left = (int) (stackBounds.centerX() - size.getWidth() / 2f);
|
||||
final int top = (int) (stackBounds.centerY() - size.getHeight() / 2f);
|
||||
stackBounds.set(left, top, left + size.getWidth(), top + size.getHeight());
|
||||
// apply the override minimal size if applicable, this minimal size is specified by app
|
||||
if (mOverrideMinimalSize != null) {
|
||||
transformBoundsToMinimalSize(stackBounds, aspectRatio, mOverrideMinimalSize);
|
||||
}
|
||||
mSnapAlgorithm.applySnapFraction(stackBounds, getMovementBounds(stackBounds), snapFraction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a given bounds to meet the minimal size constraints.
|
||||
* This function assumes the given {@param stackBounds} qualifies {@param aspectRatio}.
|
||||
*/
|
||||
private void transformBoundsToMinimalSize(Rect stackBounds, float aspectRatio,
|
||||
Size minimalSize) {
|
||||
if (minimalSize == null) return;
|
||||
final Size adjustedMinimalSize;
|
||||
final float minimalSizeAspectRatio =
|
||||
minimalSize.getWidth() / (float) minimalSize.getHeight();
|
||||
if (minimalSizeAspectRatio > aspectRatio) {
|
||||
// minimal size is wider, fixed the width and increase the height
|
||||
adjustedMinimalSize = new Size(
|
||||
minimalSize.getWidth(), (int) (minimalSize.getWidth() / aspectRatio));
|
||||
/** Adjusts the given size to conform to the given aspect ratio. */
|
||||
private Size adjustSizeToAspectRatio(@NonNull Size size, float aspectRatio) {
|
||||
final float sizeAspectRatio = size.getWidth() / (float) size.getHeight();
|
||||
if (sizeAspectRatio > aspectRatio) {
|
||||
// Size is wider, fix the width and increase the height
|
||||
return new Size(size.getWidth(), (int) (size.getWidth() / aspectRatio));
|
||||
} else {
|
||||
adjustedMinimalSize = new Size(
|
||||
(int) (minimalSize.getHeight() * aspectRatio), minimalSize.getHeight());
|
||||
// Size is taller, fix the height and adjust the width.
|
||||
return new Size((int) (size.getHeight() * aspectRatio), size.getHeight());
|
||||
}
|
||||
final Rect containerBounds = new Rect(stackBounds);
|
||||
Gravity.apply(mDefaultStackGravity,
|
||||
adjustedMinimalSize.getWidth(), adjustedMinimalSize.getHeight(),
|
||||
containerBounds, stackBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,12 +361,20 @@ public class PipBoundsHandler {
|
||||
final Rect insetBounds = new Rect();
|
||||
getInsetBounds(insetBounds);
|
||||
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
|
||||
size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
|
||||
mDefaultMinSize, displayInfo.logicalWidth, displayInfo.logicalHeight);
|
||||
Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
|
||||
0, Math.max(mIsImeShowing ? mImeHeight : 0,
|
||||
mIsShelfShowing ? mShelfHeight : 0),
|
||||
defaultBounds);
|
||||
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
|
||||
// adjusted to the aspect ratio.
|
||||
defaultSize = adjustSizeToAspectRatio(overrideMinSize, mDefaultAspectRatio);
|
||||
} else {
|
||||
// Calculate the default size using the display size and default min edge size.
|
||||
defaultSize = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
|
||||
mDefaultMinSize, displayInfo.logicalWidth, displayInfo.logicalHeight);
|
||||
}
|
||||
Gravity.apply(mDefaultStackGravity, defaultSize.getWidth(), defaultSize.getHeight(),
|
||||
insetBounds, 0, Math.max(mIsImeShowing ? mImeHeight : 0,
|
||||
mIsShelfShowing ? mShelfHeight : 0), defaultBounds);
|
||||
}
|
||||
return defaultBounds;
|
||||
}
|
||||
@@ -443,6 +429,10 @@ public class PipBoundsHandler {
|
||||
mSnapAlgorithm.applySnapFraction(stackBounds, movementBounds, snapFraction);
|
||||
}
|
||||
|
||||
public int getDefaultMinSize() {
|
||||
return mDefaultMinSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pixels for a given dp value.
|
||||
*/
|
||||
|
||||
@@ -61,8 +61,14 @@ public final class PipBoundsState {
|
||||
private ComponentName mLastPipComponentName;
|
||||
private final DisplayInfo mDisplayInfo = new DisplayInfo();
|
||||
private final DisplayLayout mDisplayLayout = new DisplayLayout();
|
||||
/** The current minimum edge size of PIP. */
|
||||
private int mMinEdgeSize;
|
||||
/** The preferred minimum (and default) size specified by apps. */
|
||||
private Size mOverrideMinSize;
|
||||
private final @NonNull AnimatingBoundsState mAnimatingBoundsState = new AnimatingBoundsState();
|
||||
|
||||
private Runnable mOnMinimalSizeChangeCallback;
|
||||
|
||||
public PipBoundsState(Context context) {
|
||||
mContext = context;
|
||||
reloadResources();
|
||||
@@ -203,10 +209,49 @@ public final class PipBoundsState {
|
||||
mPipReentryState = null;
|
||||
}
|
||||
|
||||
/** Set the PIP minimum edge size. */
|
||||
public void setMinEdgeSize(int minEdgeSize) {
|
||||
mMinEdgeSize = minEdgeSize;
|
||||
}
|
||||
|
||||
/** Returns the PIP's current minimum edge size. */
|
||||
public int getMinEdgeSize() {
|
||||
return mMinEdgeSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preferred size of PIP as specified by the activity in PIP mode.
|
||||
*/
|
||||
public void setOverrideMinSize(Size overrideMinSize) {
|
||||
final boolean changed = !Objects.equals(overrideMinSize, mOverrideMinSize);
|
||||
mOverrideMinSize = overrideMinSize;
|
||||
if (changed && mOnMinimalSizeChangeCallback != null) {
|
||||
mOnMinimalSizeChangeCallback.run();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the preferred minimal size specified by the activity in PIP. */
|
||||
public Size getOverrideMinSize() {
|
||||
return mOverrideMinSize;
|
||||
}
|
||||
|
||||
/** Returns the minimum edge size of the override minimum size, or 0 if not set. */
|
||||
public int getOverrideMinEdgeSize() {
|
||||
if (mOverrideMinSize == null) return 0;
|
||||
return Math.min(mOverrideMinSize.getWidth(), mOverrideMinSize.getHeight());
|
||||
}
|
||||
|
||||
public AnimatingBoundsState getAnimatingBoundsState() {
|
||||
return mAnimatingBoundsState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback when the minimal size of PIP that is set by the app changes.
|
||||
*/
|
||||
public void setOnMinimalSizeChangeCallback(Runnable onMinimalSizeChangeCallback) {
|
||||
mOnMinimalSizeChangeCallback = onMinimalSizeChangeCallback;
|
||||
}
|
||||
|
||||
/** Source of truth for the current animation bounds of PIP. */
|
||||
public static class AnimatingBoundsState {
|
||||
/** The bounds used when PIP is being dragged or animated. */
|
||||
@@ -298,6 +343,8 @@ public final class PipBoundsState {
|
||||
pw.println(innerPrefix + "mDisplayLayout=" + mDisplayLayout);
|
||||
pw.println(innerPrefix + "mStashedState=" + mStashedState);
|
||||
pw.println(innerPrefix + "mStashOffset=" + mStashOffset);
|
||||
pw.println(innerPrefix + "mMinEdgeSize=" + mMinEdgeSize);
|
||||
pw.println(innerPrefix + "mOverrideMinSize=" + mOverrideMinSize);
|
||||
if (mPipReentryState == null) {
|
||||
pw.println(innerPrefix + "mPipReentryState=null");
|
||||
} else {
|
||||
|
||||
@@ -339,10 +339,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
PictureInPictureParams pictureInPictureParams) {
|
||||
mShouldIgnoreEnteringPipTransition = true;
|
||||
sendOnPipTransitionStarted(componentName, TRANSITION_DIRECTION_TO_PIP);
|
||||
mPipBoundsState.setLastPipComponentName(componentName);
|
||||
mPipBoundsState.setAspectRatio(getAspectRatioOrDefault(pictureInPictureParams));
|
||||
return mPipBoundsHandler.getDestinationBounds(null /* bounds */,
|
||||
getMinimalSize(activityInfo));
|
||||
setBoundsStateForEntry(componentName, pictureInPictureParams, activityInfo);
|
||||
return mPipBoundsHandler.getDestinationBounds(null /* bounds */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,6 +354,13 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
}
|
||||
}
|
||||
|
||||
private void setBoundsStateForEntry(ComponentName componentName, PictureInPictureParams params,
|
||||
ActivityInfo activityInfo) {
|
||||
mPipBoundsState.setLastPipComponentName(componentName);
|
||||
mPipBoundsState.setAspectRatio(getAspectRatioOrDefault(params));
|
||||
mPipBoundsState.setOverrideMinSize(getMinimalSize(activityInfo));
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands PiP to the previous bounds, this is done in two phases using
|
||||
* {@link WindowContainerTransaction}
|
||||
@@ -483,7 +488,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
mLeash = leash;
|
||||
mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
|
||||
mPictureInPictureParams = mTaskInfo.pictureInPictureParams;
|
||||
mPipBoundsState.setLastPipComponentName(mTaskInfo.topActivity);
|
||||
setBoundsStateForEntry(mTaskInfo.topActivity, mPictureInPictureParams,
|
||||
mTaskInfo.topActivityInfo);
|
||||
|
||||
mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo);
|
||||
mPipUiEventLoggerLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER);
|
||||
@@ -520,9 +526,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
return;
|
||||
}
|
||||
|
||||
mPipBoundsState.setAspectRatio(getAspectRatioOrDefault(mPictureInPictureParams));
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(null /* bounds */,
|
||||
getMinimalSize(mTaskInfo.topActivityInfo));
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(null /* bounds */);
|
||||
Objects.requireNonNull(destinationBounds, "Missing destination bounds");
|
||||
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
|
||||
|
||||
@@ -675,6 +679,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
|
||||
Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken");
|
||||
mPipBoundsState.setLastPipComponentName(info.topActivity);
|
||||
mPipBoundsState.setOverrideMinSize(getMinimalSize(info.topActivityInfo));
|
||||
final PictureInPictureParams newParams = info.pictureInPictureParams;
|
||||
if (newParams == null || !applyPictureInPictureParams(newParams)) {
|
||||
Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams);
|
||||
@@ -682,8 +687,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
}
|
||||
// Aspect ratio changed, re-calculate destination bounds.
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
mPipBoundsState.getBounds(), getMinimalSize(info.topActivityInfo),
|
||||
true /* userCurrentMinEdgeSize */);
|
||||
mPipBoundsState.getBounds(), true /* useCurrentMinEdgeSize */);
|
||||
Objects.requireNonNull(destinationBounds, "Missing destination bounds");
|
||||
scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration,
|
||||
null /* updateBoundsCallback */);
|
||||
@@ -698,7 +702,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
public void onFixedRotationFinished(int displayId) {
|
||||
if (mShouldDeferEnteringPip && mState.isInPip()) {
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
|
||||
null /* bounds */);
|
||||
// schedule a regular animation to ensure all the callbacks are still being sent
|
||||
enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */);
|
||||
}
|
||||
@@ -773,8 +777,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
return;
|
||||
}
|
||||
|
||||
final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds(null /* bounds */,
|
||||
getMinimalSize(mTaskInfo.topActivityInfo));
|
||||
final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds(null /* bounds */);
|
||||
if (newDestinationBounds.equals(currentDestinationBounds)) return;
|
||||
if (animator.getAnimationType() == ANIM_TYPE_BOUNDS) {
|
||||
animator.updateEndValue(newDestinationBounds);
|
||||
|
||||
@@ -242,9 +242,16 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
displayController.getDisplay(displayId).getDisplayInfo(newDisplayInfo);
|
||||
mPipBoundsState.setDisplayInfo(newDisplayInfo);
|
||||
updateMovementBounds(null /* toBounds */, false /* fromRotation */,
|
||||
false /* fromImeAdjustment */, false /* fromShelfAdustment */,
|
||||
false /* fromImeAdjustment */, false /* fromShelfAdjustment */,
|
||||
null /* wct */);
|
||||
});
|
||||
mPipBoundsState.setOnMinimalSizeChangeCallback(
|
||||
() -> {
|
||||
// The minimal size drives the normal bounds, so they need to be recalculated.
|
||||
updateMovementBounds(null /* toBounds */, false /* fromRotation */,
|
||||
false /* fromImeAdjustment */, false /* fromShelfAdjustment */,
|
||||
null /* wct */);
|
||||
});
|
||||
mMediaController = pipMediaController;
|
||||
mMenuController = pipMenuActivityController;
|
||||
mTouchHandler = pipTouchHandler;
|
||||
|
||||
@@ -451,7 +451,9 @@ public class PipResizeGestureHandler {
|
||||
mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x,
|
||||
mMinSize.y, mMaxSize, true,
|
||||
mLastDownBounds.width() > mLastDownBounds.height()));
|
||||
mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds);
|
||||
mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds,
|
||||
mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */,
|
||||
true /* useCurrentSize */);
|
||||
mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,
|
||||
null);
|
||||
}
|
||||
|
||||
@@ -848,8 +848,9 @@ public class PipTouchHandler {
|
||||
mMotionHelper.setCurrentMovementBounds(mMovementBounds);
|
||||
|
||||
boolean isMenuExpanded = mMenuState == MENU_STATE_FULL;
|
||||
mPipBoundsHandler.setMinEdgeSize(
|
||||
isMenuExpanded && willResizeMenu() ? mExpandedShortestEdgeSize : 0);
|
||||
mPipBoundsState.setMinEdgeSize(
|
||||
isMenuExpanded && willResizeMenu() ? mExpandedShortestEdgeSize
|
||||
: mPipBoundsHandler.getDefaultMinSize());
|
||||
}
|
||||
|
||||
private Rect getMovementBounds(Rect curBounds) {
|
||||
|
||||
@@ -124,7 +124,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
for (float aspectRatio : aspectRatios) {
|
||||
mPipBoundsState.setAspectRatio(aspectRatio);
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
final float actualAspectRatio =
|
||||
destinationBounds.width() / (destinationBounds.height() * 1f);
|
||||
assertEquals("Destination bounds matches the given aspect ratio",
|
||||
@@ -141,7 +141,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
for (float aspectRatio : invalidAspectRatios) {
|
||||
mPipBoundsState.setAspectRatio(aspectRatio);
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
final float actualAspectRatio =
|
||||
destinationBounds.width() / (destinationBounds.height() * 1f);
|
||||
assertEquals("Destination bounds fallbacks to default aspect ratio",
|
||||
@@ -157,8 +157,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left;
|
||||
|
||||
mPipBoundsState.setAspectRatio(aspectRatio);
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(currentBounds,
|
||||
EMPTY_MINIMAL_SIZE);
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(currentBounds);
|
||||
|
||||
final float actualAspectRatio =
|
||||
destinationBounds.width() / (destinationBounds.height() * 1f);
|
||||
@@ -182,8 +181,9 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
final float aspectRatio = aspectRatios[i];
|
||||
final Size minimalSize = minimalSizes[i];
|
||||
mPipBoundsState.setAspectRatio(aspectRatio);
|
||||
mPipBoundsState.setOverrideMinSize(minimalSize);
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, minimalSize);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
assertTrue("Destination bounds is no smaller than minimal requirement",
|
||||
(destinationBounds.width() == minimalSize.getWidth()
|
||||
&& destinationBounds.height() >= minimalSize.getHeight())
|
||||
@@ -204,8 +204,9 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
final Size minSize = new Size(currentBounds.width() / 2, currentBounds.height() / 2);
|
||||
|
||||
mPipBoundsState.setAspectRatio(aspectRatio);
|
||||
mPipBoundsState.setOverrideMinSize(minSize);
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
currentBounds, minSize);
|
||||
currentBounds, true /* useCurrentMinEdgeSize */);
|
||||
|
||||
assertTrue("Destination bounds ignores minimal size",
|
||||
destinationBounds.width() > minSize.getWidth()
|
||||
@@ -216,13 +217,13 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
public void getDestinationBounds_reentryStateExists_restoreLastSize() {
|
||||
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
|
||||
final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
reentryBounds.scale(1.25f);
|
||||
final float reentrySnapFraction = mPipBoundsHandler.getSnapFraction(reentryBounds);
|
||||
|
||||
mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction);
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
|
||||
assertEquals(reentryBounds.width(), destinationBounds.width());
|
||||
assertEquals(reentryBounds.height(), destinationBounds.height());
|
||||
@@ -232,14 +233,14 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
public void getDestinationBounds_reentryStateExists_restoreLastPosition() {
|
||||
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
|
||||
final Rect reentryBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
reentryBounds.offset(0, -100);
|
||||
final float reentrySnapFraction = mPipBoundsHandler.getSnapFraction(reentryBounds);
|
||||
|
||||
mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction);
|
||||
|
||||
final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
|
||||
assertBoundsInclusionWithMargin("restoreLastPosition", reentryBounds, destinationBounds);
|
||||
}
|
||||
@@ -249,11 +250,11 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
final int shelfHeight = 100;
|
||||
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
|
||||
final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
|
||||
mPipBoundsHandler.setShelfHeight(true, shelfHeight);
|
||||
final Rect newPosition = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
|
||||
oldPosition.offset(0, -shelfHeight);
|
||||
assertBoundsInclusionWithMargin("offsetBounds by shelf", oldPosition, newPosition);
|
||||
@@ -264,11 +265,11 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
final int imeHeight = 100;
|
||||
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
|
||||
final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
|
||||
mPipBoundsHandler.onImeVisibilityChanged(true, imeHeight);
|
||||
final Rect newPosition = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
|
||||
oldPosition.offset(0, -imeHeight);
|
||||
assertBoundsInclusionWithMargin("offsetBounds by IME", oldPosition, newPosition);
|
||||
@@ -278,12 +279,12 @@ public class PipBoundsHandlerTest extends ShellTestCase {
|
||||
public void getDestinationBounds_noReentryState_useDefaultBounds() {
|
||||
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
|
||||
final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
|
||||
mPipBoundsState.clearReentryState();
|
||||
|
||||
final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(
|
||||
EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
|
||||
EMPTY_CURRENT_BOUNDS);
|
||||
|
||||
assertBoundsInclusionWithMargin("useDefaultBounds", defaultBounds, actualBounds);
|
||||
}
|
||||
|
||||
@@ -30,12 +30,14 @@ import static org.mockito.Mockito.when;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.PictureInPictureParams;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.os.RemoteException;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.util.Rational;
|
||||
import android.util.Size;
|
||||
import android.view.DisplayInfo;
|
||||
import android.window.WindowContainerToken;
|
||||
|
||||
@@ -113,6 +115,15 @@ public class PipTaskOrganizerTest extends ShellTestCase {
|
||||
assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startSwipePipToHome_updatesOverrideMinSize() {
|
||||
final Size minSize = new Size(100, 80);
|
||||
|
||||
mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, createActivityInfo(minSize), null);
|
||||
|
||||
assertEquals(minSize, mPipBoundsState.getOverrideMinSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onTaskAppeared_updatesAspectRatio() {
|
||||
final Rational aspectRatio = new Rational(2, 1);
|
||||
@@ -131,6 +142,17 @@ public class PipTaskOrganizerTest extends ShellTestCase {
|
||||
assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onTaskAppeared_updatesOverrideMinSize() {
|
||||
final Size minSize = new Size(100, 80);
|
||||
|
||||
mSpiedPipTaskOrganizer.onTaskAppeared(
|
||||
createTaskInfo(mComponent1, createPipParams(null), minSize),
|
||||
null /* leash */);
|
||||
|
||||
assertEquals(minSize, mPipBoundsState.getOverrideMinSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onTaskInfoChanged_updatesAspectRatioIfChanged() {
|
||||
final Rational startAspectRatio = new Rational(2, 1);
|
||||
@@ -155,11 +177,23 @@ public class PipTaskOrganizerTest extends ShellTestCase {
|
||||
assertEquals(mComponent2, mPipBoundsState.getLastPipComponentName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onTaskInfoChanged_updatesOverrideMinSize() {
|
||||
mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1,
|
||||
createPipParams(null)), null /* leash */);
|
||||
|
||||
final Size minSize = new Size(100, 80);
|
||||
mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2,
|
||||
createPipParams(null), minSize));
|
||||
|
||||
assertEquals(minSize, mPipBoundsState.getOverrideMinSize());
|
||||
}
|
||||
|
||||
private void preparePipTaskOrg() {
|
||||
final DisplayInfo info = new DisplayInfo();
|
||||
mPipBoundsState.setDisplayInfo(info);
|
||||
when(mMockPipBoundsHandler.getDestinationBounds(any(), any())).thenReturn(new Rect());
|
||||
when(mMockPipBoundsHandler.getDestinationBounds(any(), any(), anyBoolean()))
|
||||
when(mMockPipBoundsHandler.getDestinationBounds(any())).thenReturn(new Rect());
|
||||
when(mMockPipBoundsHandler.getDestinationBounds(any(), anyBoolean()))
|
||||
.thenReturn(new Rect());
|
||||
mPipBoundsState.setDisplayInfo(info);
|
||||
mSpiedPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA);
|
||||
@@ -169,13 +203,28 @@ public class PipTaskOrganizerTest extends ShellTestCase {
|
||||
|
||||
private static ActivityManager.RunningTaskInfo createTaskInfo(
|
||||
ComponentName componentName, PictureInPictureParams params) {
|
||||
return createTaskInfo(componentName, params, null /* minSize */);
|
||||
}
|
||||
|
||||
private static ActivityManager.RunningTaskInfo createTaskInfo(
|
||||
ComponentName componentName, PictureInPictureParams params, Size minSize) {
|
||||
final ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
|
||||
info.token = mock(WindowContainerToken.class);
|
||||
info.pictureInPictureParams = params;
|
||||
info.topActivity = componentName;
|
||||
if (minSize != null) {
|
||||
info.topActivityInfo = createActivityInfo(minSize);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
private static ActivityInfo createActivityInfo(Size minSize) {
|
||||
final ActivityInfo activityInfo = new ActivityInfo();
|
||||
activityInfo.windowLayout = new ActivityInfo.WindowLayout(
|
||||
0, 0, 0, 0, 0, minSize.getWidth(), minSize.getHeight());
|
||||
return activityInfo;
|
||||
}
|
||||
|
||||
private static PictureInPictureParams createPipParams(Rational aspectRatio) {
|
||||
return new PictureInPictureParams.Builder()
|
||||
.setAspectRatio(aspectRatio)
|
||||
|
||||
Reference in New Issue
Block a user