Recalculates the dimensions such that the target aspect ratio is achieved, while + * maintaining the same maximum size to current size ratio. + * + * @param size current size + * @param aspectRatio target aspect ratio + */ + @Override + public Size getSizeForAspectRatio(Size size, float aspectRatio) { + // getting the percentage of the max size that current size takes + float currAspectRatio = (float) size.getWidth() / size.getHeight(); + Size currentMaxSize = getMaxSize(currAspectRatio); + float currentPercent = (float) size.getWidth() / currentMaxSize.getWidth(); + + // getting the max size for the target aspect ratio + Size updatedMaxSize = getMaxSize(aspectRatio); + + int width = (int) (updatedMaxSize.getWidth() * currentPercent); + int height = (int) (updatedMaxSize.getHeight() * currentPercent); + + // adjust the dimensions if below allowed min edge size + if (width < getMinEdgeSize() && aspectRatio <= 1) { + width = getMinEdgeSize(); + height = (int) (width / aspectRatio); + } else if (height < getMinEdgeSize() && aspectRatio > 1) { + height = getMinEdgeSize(); + width = (int) (height * aspectRatio); + } + + // reduce the dimensions of the updated size to the calculated percentage + return new Size(width, height); + } + } + + private class SizeSpecDefaultImpl implements SizeSpecSource { + private float mDefaultSizePercent; + private float mMinimumSizePercent; + + @Override + public void reloadResources() { + final Resources res = mContext.getResources(); + + mMaxAspectRatioForMinSize = res.getFloat( + R.dimen.config_pictureInPictureAspectRatioLimitForMinSize); + mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize; + + mDefaultSizePercent = res.getFloat(R.dimen.config_pictureInPictureDefaultSizePercent); + mMinimumSizePercent = res.getFraction(R.fraction.config_pipShortestEdgePercent, 1, 1); + } + + @Override + public Size getMaxSize(float aspectRatio) { + final int shorterLength = Math.min(getDisplayBounds().width(), + getDisplayBounds().height()); + + final int totalHorizontalPadding = getInsetBounds().left + + (getDisplayBounds().width() - getInsetBounds().right); + final int totalVerticalPadding = getInsetBounds().top + + (getDisplayBounds().height() - getInsetBounds().bottom); + + final int maxWidth, maxHeight; + + if (aspectRatio > 1f) { + maxWidth = (int) Math.max(getDefaultSize(aspectRatio).getWidth(), + shorterLength - totalHorizontalPadding); + maxHeight = (int) (maxWidth / aspectRatio); + } else { + maxHeight = (int) Math.max(getDefaultSize(aspectRatio).getHeight(), + shorterLength - totalVerticalPadding); + maxWidth = (int) (maxHeight * aspectRatio); + } + + return new Size(maxWidth, maxHeight); + } + + @Override + public Size getDefaultSize(float aspectRatio) { + if (mOverrideMinSize != null) { + return this.getMinSize(aspectRatio); + } + + final int smallestDisplaySize = Math.min(getDisplayBounds().width(), + getDisplayBounds().height()); + final int minSize = (int) Math.max(getMinEdgeSize(), + smallestDisplaySize * mDefaultSizePercent); + + final int width; + final int height; + + if (aspectRatio <= mMinAspectRatioForMinSize + || aspectRatio > mMaxAspectRatioForMinSize) { + // Beyond these points, we can just use the min size as the shorter edge + if (aspectRatio <= 1) { + // Portrait, width is the minimum size + width = minSize; + height = Math.round(width / aspectRatio); + } else { + // Landscape, height is the minimum size + height = minSize; + width = Math.round(height * aspectRatio); + } + } else { + // Within these points, ensure that the bounds fit within the radius of the limits + // at the points + final float widthAtMaxAspectRatioForMinSize = mMaxAspectRatioForMinSize * minSize; + final float radius = PointF.length(widthAtMaxAspectRatioForMinSize, minSize); + height = (int) Math.round(Math.sqrt((radius * radius) + / (aspectRatio * aspectRatio + 1))); + width = Math.round(height * aspectRatio); + } + + return new Size(width, height); + } + + @Override + public Size getMinSize(float aspectRatio) { + if (mOverrideMinSize != null) { + return adjustOverrideMinSizeToAspectRatio(aspectRatio); + } + + final int shorterLength = Math.min(getDisplayBounds().width(), + getDisplayBounds().height()); + final int minWidth, minHeight; + + if (aspectRatio > 1f) { + minWidth = (int) Math.min(getDefaultSize(aspectRatio).getWidth(), + shorterLength * mMinimumSizePercent); + minHeight = (int) (minWidth / aspectRatio); + } else { + minHeight = (int) Math.min(getDefaultSize(aspectRatio).getHeight(), + shorterLength * mMinimumSizePercent); + minWidth = (int) (minHeight * aspectRatio); + } + + return new Size(minWidth, minHeight); + } + + @Override + public Size getSizeForAspectRatio(Size size, float aspectRatio) { + final int smallestSize = Math.min(size.getWidth(), size.getHeight()); + final int minSize = Math.max(getMinEdgeSize(), smallestSize); + + final int width; + final int height; + if (aspectRatio <= 1) { + // Portrait, width is the minimum size. + width = minSize; + height = Math.round(width / aspectRatio); + } else { + // Landscape, height is the minimum size + height = minSize; + width = Math.round(height * aspectRatio); + } + + return new Size(width, height); + } + } + + public PipSizeSpecHandler(Context context) { + mContext = context; + + boolean enablePipSizeLargeScreen = SystemProperties + .getBoolean("persist.wm.debug.enable_pip_size_large_screen", false); + + // choose between two implementations of size spec logic + if (enablePipSizeLargeScreen) { + mSizeSpecSourceImpl = new SizeSpecLargeScreenOptimizedImpl(); + } else { + mSizeSpecSourceImpl = new SizeSpecDefaultImpl(); + } + + reloadResources(); + } + + /** Reloads the resources */ + public void onConfigurationChanged() { + reloadResources(); + } + + private void reloadResources() { + final Resources res = mContext.getResources(); + + mDefaultMinSize = res.getDimensionPixelSize( + R.dimen.default_minimal_size_pip_resizable_task); + + final String screenEdgeInsetsDpString = res.getString( + R.string.config_defaultPictureInPictureScreenEdgeInsets); + final Size screenEdgeInsetsDp = !screenEdgeInsetsDpString.isEmpty() + ? Size.parseSize(screenEdgeInsetsDpString) + : null; + mScreenEdgeInsets = screenEdgeInsetsDp == null ? new Point() + : new Point(dpToPx(screenEdgeInsetsDp.getWidth(), res.getDisplayMetrics()), + dpToPx(screenEdgeInsetsDp.getHeight(), res.getDisplayMetrics())); + + // update the internal resources of the size spec source's stub + mSizeSpecSourceImpl.reloadResources(); + } + + /** Returns the display's bounds. */ + @NonNull + public Rect getDisplayBounds() { + return new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height()); + } + + /** Get the display layout. */ + @NonNull + public DisplayLayout getDisplayLayout() { + return mDisplayLayout; + } + + /** Update the display layout. */ + public void setDisplayLayout(@NonNull DisplayLayout displayLayout) { + mDisplayLayout.set(displayLayout); + } + + public Point getScreenEdgeInsets() { + return mScreenEdgeInsets; + } + + /** + * Returns the inset bounds the PIP window can be visible in. + */ + public Rect getInsetBounds() { + Rect insetBounds = new Rect(); + final DisplayLayout displayLayout = getDisplayLayout(); + Rect insets = getDisplayLayout().stableInsets(); + insetBounds.set(insets.left + mScreenEdgeInsets.x, + insets.top + mScreenEdgeInsets.y, + displayLayout.width() - insets.right - mScreenEdgeInsets.x, + displayLayout.height() - insets.bottom - mScreenEdgeInsets.y); + return insetBounds; + } + + /** Sets the preferred size of PIP as specified by the activity in PIP mode. */ + public void setOverrideMinSize(@Nullable Size overrideMinSize) { + mOverrideMinSize = overrideMinSize; + } + + /** Returns the preferred minimal size specified by the activity in PIP. */ + @Nullable + 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 int getMinEdgeSize() { + return mOverrideMinSize == null ? mDefaultMinSize : getOverrideMinEdgeSize(); + } + + /** + * Returns the size for the max size spec. + */ + public Size getMaxSize(float aspectRatio) { + return mSizeSpecSourceImpl.getMaxSize(aspectRatio); + } + + /** + * Returns the size for the default size spec. + */ + public Size getDefaultSize(float aspectRatio) { + return mSizeSpecSourceImpl.getDefaultSize(aspectRatio); + } + + /** + * Returns the size for the min size spec. + */ + public Size getMinSize(float aspectRatio) { + return mSizeSpecSourceImpl.getMinSize(aspectRatio); + } + + /** + * Returns the adjusted size so that it conforms to the given aspectRatio. + * + * @param size current size + * @param aspectRatio target aspect ratio + */ + public Size getSizeForAspectRatio(@NonNull Size size, float aspectRatio) { + if (size.equals(mOverrideMinSize)) { + return adjustOverrideMinSizeToAspectRatio(aspectRatio); + } + + return mSizeSpecSourceImpl.getSizeForAspectRatio(size, aspectRatio); + } + + /** + * Returns the adjusted overridden min size if it is set; otherwise, returns null. + * + *
Overridden min size needs to be adjusted in its own way while making sure that the target
+ * aspect ratio is maintained
+ *
+ * @param aspectRatio target aspect ratio
+ */
+ @Nullable
+ @VisibleForTesting
+ Size adjustOverrideMinSizeToAspectRatio(float aspectRatio) {
+ if (mOverrideMinSize == null) {
+ return null;
+ }
+ final Size size = mOverrideMinSize;
+ 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 {
+ // Size is taller, fix the height and adjust the width.
+ return new Size((int) (size.getHeight() * aspectRatio), size.getHeight());
+ }
+ }
+
+ /** Dumps internal state. */
+ public void dump(PrintWriter pw, String prefix) {
+ final String innerPrefix = prefix + " ";
+ pw.println(prefix + TAG);
+ pw.println(innerPrefix + "mSizeSpecSourceImpl=" + mSizeSpecSourceImpl.toString());
+ pw.println(innerPrefix + "mDisplayLayout=" + mDisplayLayout);
+ pw.println(innerPrefix + "mOverrideMinSize=" + mOverrideMinSize);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 850c561c891fe..0e8d13d9979d4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -78,7 +78,8 @@ public class PipTouchHandler {
private boolean mEnableResize;
private final Context mContext;
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
- private final @NonNull PipBoundsState mPipBoundsState;
+ @NonNull private final PipBoundsState mPipBoundsState;
+ @NonNull private final PipSizeSpecHandler mPipSizeSpecHandler;
private final PipUiEventLogger mPipUiEventLogger;
private final PipDismissTargetHandler mPipDismissTargetHandler;
private final PipTaskOrganizer mPipTaskOrganizer;
@@ -99,7 +100,6 @@ public class PipTouchHandler {
// The reference inset bounds, used to determine the dismiss fraction
private final Rect mInsetBounds = new Rect();
- private int mExpandedShortestEdgeSize;
// Used to workaround an issue where the WM rotation happens before we are notified, allowing
// us to send stale bounds
@@ -120,7 +120,6 @@ public class PipTouchHandler {
private float mSavedSnapFraction = -1f;
private boolean mSendingHoverAccessibilityEvents;
private boolean mMovementWithinDismiss;
- private float mMinimumSizePercent;
// Touch state
private final PipTouchState mTouchState;
@@ -174,6 +173,7 @@ public class PipTouchHandler {
PhonePipMenuController menuController,
PipBoundsAlgorithm pipBoundsAlgorithm,
@NonNull PipBoundsState pipBoundsState,
+ @NonNull PipSizeSpecHandler pipSizeSpecHandler,
PipTaskOrganizer pipTaskOrganizer,
PipMotionHelper pipMotionHelper,
FloatingContentCoordinator floatingContentCoordinator,
@@ -184,6 +184,7 @@ public class PipTouchHandler {
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
mPipBoundsAlgorithm = pipBoundsAlgorithm;
mPipBoundsState = pipBoundsState;
+ mPipSizeSpecHandler = pipSizeSpecHandler;
mPipTaskOrganizer = pipTaskOrganizer;
mMenuController = menuController;
mPipUiEventLogger = pipUiEventLogger;
@@ -271,10 +272,7 @@ public class PipTouchHandler {
private void reloadResources() {
final Resources res = mContext.getResources();
mBottomOffsetBufferPx = res.getDimensionPixelSize(R.dimen.pip_bottom_offset_buffer);
- mExpandedShortestEdgeSize = res.getDimensionPixelSize(
- R.dimen.pip_expanded_shortest_edge_size);
mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset);
- mMinimumSizePercent = res.getFraction(R.fraction.config_pipShortestEdgePercent, 1, 1);
mPipDismissTargetHandler.updateMagneticTargetSize();
}
@@ -407,10 +405,7 @@ public class PipTouchHandler {
// Calculate the expanded size
float aspectRatio = (float) normalBounds.width() / normalBounds.height();
- Point displaySize = new Point();
- mContext.getDisplay().getRealSize(displaySize);
- Size expandedSize = mPipBoundsAlgorithm.getSizeForAspectRatio(
- aspectRatio, mExpandedShortestEdgeSize, displaySize.x, displaySize.y);
+ Size expandedSize = mPipSizeSpecHandler.getDefaultSize(aspectRatio);
mPipBoundsState.setExpandedBounds(
new Rect(0, 0, expandedSize.getWidth(), expandedSize.getHeight()));
Rect expandedMovementBounds = new Rect();
@@ -418,7 +413,7 @@ public class PipTouchHandler {
mPipBoundsState.getExpandedBounds(), insetBounds, expandedMovementBounds,
bottomOffset);
- updatePipSizeConstraints(insetBounds, normalBounds, aspectRatio);
+ updatePipSizeConstraints(normalBounds, aspectRatio);
// The extra offset does not really affect the movement bounds, but are applied based on the
// current state (ime showing, or shelf offset) when we need to actually shift
@@ -496,14 +491,14 @@ public class PipTouchHandler {
* @param aspectRatio aspect ratio to use for the calculation of min/max size
*/
public void updateMinMaxSize(float aspectRatio) {
- updatePipSizeConstraints(mInsetBounds, mPipBoundsState.getNormalBounds(),
+ updatePipSizeConstraints(mPipBoundsState.getNormalBounds(),
aspectRatio);
}
- private void updatePipSizeConstraints(Rect insetBounds, Rect normalBounds,
+ private void updatePipSizeConstraints(Rect normalBounds,
float aspectRatio) {
if (mPipResizeGestureHandler.isUsingPinchToZoom()) {
- updatePinchResizeSizeConstraints(insetBounds, normalBounds, aspectRatio);
+ updatePinchResizeSizeConstraints(aspectRatio);
} else {
mPipResizeGestureHandler.updateMinSize(normalBounds.width(), normalBounds.height());
mPipResizeGestureHandler.updateMaxSize(mPipBoundsState.getExpandedBounds().width(),
@@ -511,26 +506,13 @@ public class PipTouchHandler {
}
}
- private void updatePinchResizeSizeConstraints(Rect insetBounds, Rect normalBounds,
- float aspectRatio) {
- final int shorterLength = Math.min(mPipBoundsState.getDisplayBounds().width(),
- mPipBoundsState.getDisplayBounds().height());
- final int totalHorizontalPadding = insetBounds.left
- + (mPipBoundsState.getDisplayBounds().width() - insetBounds.right);
- final int totalVerticalPadding = insetBounds.top
- + (mPipBoundsState.getDisplayBounds().height() - insetBounds.bottom);
+ private void updatePinchResizeSizeConstraints(float aspectRatio) {
final int minWidth, minHeight, maxWidth, maxHeight;
- if (aspectRatio > 1f) {
- minWidth = (int) Math.min(normalBounds.width(), shorterLength * mMinimumSizePercent);
- minHeight = (int) (minWidth / aspectRatio);
- maxWidth = (int) Math.max(normalBounds.width(), shorterLength - totalHorizontalPadding);
- maxHeight = (int) (maxWidth / aspectRatio);
- } else {
- minHeight = (int) Math.min(normalBounds.height(), shorterLength * mMinimumSizePercent);
- minWidth = (int) (minHeight * aspectRatio);
- maxHeight = (int) Math.max(normalBounds.height(), shorterLength - totalVerticalPadding);
- maxWidth = (int) (maxHeight * aspectRatio);
- }
+
+ minWidth = mPipSizeSpecHandler.getMinSize(aspectRatio).getWidth();
+ minHeight = mPipSizeSpecHandler.getMinSize(aspectRatio).getHeight();
+ maxWidth = mPipSizeSpecHandler.getMaxSize(aspectRatio).getWidth();
+ maxHeight = mPipSizeSpecHandler.getMaxSize(aspectRatio).getHeight();
mPipResizeGestureHandler.updateMinSize(minWidth, minHeight);
mPipResizeGestureHandler.updateMaxSize(maxWidth, maxHeight);
@@ -1064,11 +1046,6 @@ public class PipTouchHandler {
mPipBoundsAlgorithm.getMovementBounds(mPipBoundsState.getBounds(),
mInsetBounds, mPipBoundsState.getMovementBounds(), mIsImeShowing ? mImeHeight : 0);
mMotionHelper.onMovementBoundsChanged();
-
- boolean isMenuExpanded = mMenuState == MENU_STATE_FULL;
- mPipBoundsState.setMinEdgeSize(
- isMenuExpanded && willResizeMenu() ? mExpandedShortestEdgeSize
- : mPipBoundsAlgorithm.getDefaultMinSize());
}
private Rect getMovementBounds(Rect curBounds) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
index b042063c23c92..825b96921a22c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
@@ -39,6 +39,7 @@ import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipKeepClearAlgorithmInterface;
import com.android.wm.shell.pip.PipSnapAlgorithm;
+import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -60,10 +61,10 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm {
public TvPipBoundsAlgorithm(Context context,
@NonNull TvPipBoundsState tvPipBoundsState,
- @NonNull PipSnapAlgorithm pipSnapAlgorithm) {
+ @NonNull PipSnapAlgorithm pipSnapAlgorithm,
+ @NonNull PipSizeSpecHandler pipSizeSpecHandler) {
super(context, tvPipBoundsState, pipSnapAlgorithm,
- new PipKeepClearAlgorithmInterface() {
- });
+ new PipKeepClearAlgorithmInterface() {}, pipSizeSpecHandler);
this.mTvPipBoundsState = tvPipBoundsState;
this.mKeepClearAlgorithm = new TvPipKeepClearAlgorithm();
reloadResources(context);
@@ -289,7 +290,8 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm {
if (mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_HORIZONTAL) {
expandedSize = mTvPipBoundsState.getTvExpandedSize();
} else {
- int maxHeight = displayLayout.height() - (2 * mScreenEdgeInsets.y)
+ int maxHeight = displayLayout.height()
+ - (2 * mPipSizeSpecHandler.getScreenEdgeInsets().y)
- pipDecorations.top - pipDecorations.bottom;
float aspectRatioHeight = mFixedExpandedWidthInPx / expandedRatio;
@@ -308,7 +310,8 @@ public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm {
if (mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_VERTICAL) {
expandedSize = mTvPipBoundsState.getTvExpandedSize();
} else {
- int maxWidth = displayLayout.width() - (2 * mScreenEdgeInsets.x)
+ int maxWidth = displayLayout.width()
+ - (2 * mPipSizeSpecHandler.getScreenEdgeInsets().x)
- pipDecorations.left - pipDecorations.right;
float aspectRatioWidth = mFixedExpandedHeightInPx * expandedRatio;
if (maxWidth > aspectRatioWidth) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
index 9c7c0aef636d3..22b3f4987e82e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java
@@ -31,6 +31,7 @@ import android.view.View;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
+import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -73,8 +74,9 @@ public class TvPipBoundsState extends PipBoundsState {
@NonNull
private Insets mPipMenuTemporaryDecorInsets = Insets.NONE;
- public TvPipBoundsState(@NonNull Context context) {
- super(context);
+ public TvPipBoundsState(@NonNull Context context,
+ @NonNull PipSizeSpecHandler pipSizeSpecHandler) {
+ super(context, pipSizeSpecHandler);
mContext = context;
updateDefaultGravity();
mPreviousCollapsedGravity = mDefaultGravity;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index 442642348b076..02b919777f0f6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -55,6 +55,7 @@ import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.ShellController;
@@ -118,6 +119,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
private final ShellController mShellController;
private final TvPipBoundsState mTvPipBoundsState;
+ private final PipSizeSpecHandler mPipSizeSpecHandler;
private final TvPipBoundsAlgorithm mTvPipBoundsAlgorithm;
private final TvPipBoundsController mTvPipBoundsController;
private final PipAppOpsListener mAppOpsListener;
@@ -152,6 +154,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
ShellInit shellInit,
ShellController shellController,
TvPipBoundsState tvPipBoundsState,
+ PipSizeSpecHandler pipSizeSpecHandler,
TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
TvPipBoundsController tvPipBoundsController,
PipAppOpsListener pipAppOpsListener,
@@ -171,6 +174,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
shellInit,
shellController,
tvPipBoundsState,
+ pipSizeSpecHandler,
tvPipBoundsAlgorithm,
tvPipBoundsController,
pipAppOpsListener,
@@ -192,6 +196,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
ShellInit shellInit,
ShellController shellController,
TvPipBoundsState tvPipBoundsState,
+ PipSizeSpecHandler pipSizeSpecHandler,
TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
TvPipBoundsController tvPipBoundsController,
PipAppOpsListener pipAppOpsListener,
@@ -212,10 +217,13 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
mShellController = shellController;
mDisplayController = displayController;
- mTvPipBoundsState = tvPipBoundsState;
- mTvPipBoundsState.setDisplayId(context.getDisplayId());
- mTvPipBoundsState.setDisplayLayout(new DisplayLayout(context, context.getDisplay()));
+ DisplayLayout layout = new DisplayLayout(context, context.getDisplay());
+ mTvPipBoundsState = tvPipBoundsState;
+ mTvPipBoundsState.setDisplayLayout(layout);
+ mTvPipBoundsState.setDisplayId(context.getDisplayId());
+ mPipSizeSpecHandler = pipSizeSpecHandler;
+ mPipSizeSpecHandler.setDisplayLayout(layout);
mTvPipBoundsAlgorithm = tvPipBoundsAlgorithm;
mTvPipBoundsController = tvPipBoundsController;
mTvPipBoundsController.setListener(this);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
index 298d0a6248693..3d8cd2e4776d5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
@@ -32,6 +32,7 @@ import androidx.test.filters.SmallTest;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
import org.junit.Before;
import org.junit.Test;
@@ -57,17 +58,22 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
private PipBoundsAlgorithm mPipBoundsAlgorithm;
private DisplayInfo mDefaultDisplayInfo;
private PipBoundsState mPipBoundsState;
+ private PipSizeSpecHandler mPipSizeSpecHandler;
@Before
public void setUp() throws Exception {
initializeMockResources();
- mPipBoundsState = new PipBoundsState(mContext);
+ mPipSizeSpecHandler = new PipSizeSpecHandler(mContext);
+ mPipBoundsState = new PipBoundsState(mContext, mPipSizeSpecHandler);
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState,
- new PipSnapAlgorithm(), new PipKeepClearAlgorithmInterface() {});
+ new PipSnapAlgorithm(), new PipKeepClearAlgorithmInterface() {},
+ mPipSizeSpecHandler);
- mPipBoundsState.setDisplayLayout(
- new DisplayLayout(mDefaultDisplayInfo, mContext.getResources(), true, true));
+ DisplayLayout layout =
+ new DisplayLayout(mDefaultDisplayInfo, mContext.getResources(), true, true);
+ mPipBoundsState.setDisplayLayout(layout);
+ mPipSizeSpecHandler.setDisplayLayout(layout);
}
private void initializeMockResources() {
@@ -120,9 +126,7 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
@Test
public void getDefaultBounds_noOverrideMinSize_matchesDefaultSizeAndAspectRatio() {
- final Size defaultSize = mPipBoundsAlgorithm.getSizeForAspectRatio(DEFAULT_ASPECT_RATIO,
- DEFAULT_MIN_EDGE_SIZE, mDefaultDisplayInfo.logicalWidth,
- mDefaultDisplayInfo.logicalHeight);
+ final Size defaultSize = mPipSizeSpecHandler.getDefaultSize(DEFAULT_ASPECT_RATIO);
mPipBoundsState.setOverrideMinSize(null);
final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
index 8e30f65cee782..ede5bde9c92c5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
@@ -33,6 +33,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.function.TriConsumer;
import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
import org.junit.Before;
import org.junit.Test;
@@ -57,7 +58,7 @@ public class PipBoundsStateTest extends ShellTestCase {
@Before
public void setUp() {
- mPipBoundsState = new PipBoundsState(mContext);
+ mPipBoundsState = new PipBoundsState(mContext, new PipSizeSpecHandler(mContext));
mTestComponentName1 = new ComponentName(mContext, "component1");
mTestComponentName2 = new ComponentName(mContext, "component2");
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 17e7d74c57e08..2da4af80fd182 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -53,6 +53,7 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.pip.phone.PhonePipMenuController;
+import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
import com.android.wm.shell.splitscreen.SplitScreenController;
import org.junit.Before;
@@ -86,6 +87,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
private PipBoundsState mPipBoundsState;
private PipTransitionState mPipTransitionState;
private PipBoundsAlgorithm mPipBoundsAlgorithm;
+ private PipSizeSpecHandler mPipSizeSpecHandler;
private ComponentName mComponent1;
private ComponentName mComponent2;
@@ -95,10 +97,12 @@ public class PipTaskOrganizerTest extends ShellTestCase {
MockitoAnnotations.initMocks(this);
mComponent1 = new ComponentName(mContext, "component1");
mComponent2 = new ComponentName(mContext, "component2");
- mPipBoundsState = new PipBoundsState(mContext);
+ mPipSizeSpecHandler = new PipSizeSpecHandler(mContext);
+ mPipBoundsState = new PipBoundsState(mContext, mPipSizeSpecHandler);
mPipTransitionState = new PipTransitionState();
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState,
- new PipSnapAlgorithm(), new PipKeepClearAlgorithmInterface() {});
+ new PipSnapAlgorithm(), new PipKeepClearAlgorithmInterface() {},
+ mPipSizeSpecHandler);
mMainExecutor = new TestShellExecutor();
mPipTaskOrganizer = new PipTaskOrganizer(mContext,
mMockSyncTransactionQueue, mPipTransitionState, mPipBoundsState,
@@ -253,8 +257,10 @@ public class PipTaskOrganizerTest extends ShellTestCase {
private void preparePipTaskOrg() {
final DisplayInfo info = new DisplayInfo();
- mPipBoundsState.setDisplayLayout(new DisplayLayout(info,
- mContext.getResources(), true, true));
+ DisplayLayout layout = new DisplayLayout(info,
+ mContext.getResources(), true, true);
+ mPipBoundsState.setDisplayLayout(layout);
+ mPipSizeSpecHandler.setDisplayLayout(layout);
mPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA);
mPipTaskOrganizer.setSurfaceControlTransactionFactory(
MockSurfaceControlHelper::createMockSurfaceControlTransaction);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 35c09a121a1ca..4a68287a4486e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -65,7 +65,6 @@ import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.PipTransitionState;
-import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
@@ -108,6 +107,7 @@ public class PipControllerTest extends ShellTestCase {
@Mock private PipMotionHelper mMockPipMotionHelper;
@Mock private WindowManagerShellWrapper mMockWindowManagerShellWrapper;
@Mock private PipBoundsState mMockPipBoundsState;
+ @Mock private PipSizeSpecHandler mMockPipSizeSpecHandler;
@Mock private TaskStackListenerImpl mMockTaskStackListener;
@Mock private ShellExecutor mMockExecutor;
@Mock private Optional