summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java49
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java18
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java26
7 files changed, 103 insertions, 47 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
index 22d8ed50c10e..484592e87a20 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java
@@ -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. */
@@ -221,24 +222,36 @@ 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);
+ return defaultBounds;
+ }
+
+ // Calculate the default size.
+ final Size defaultSize;
+ final Rect insetBounds = new Rect();
+ getInsetBounds(insetBounds);
+ final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
+ 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 = 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 {
- 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
- // adjusted to the aspect ratio.
- defaultSize = adjustSizeToAspectRatio(overrideMinSize, mDefaultAspectRatio);
- } else {
- // Calculate the default size using the display size and default min edge size.
- defaultSize = getSizeForAspectRatio(mDefaultAspectRatio,
- mDefaultMinSize, displayInfo.logicalWidth, displayInfo.logicalHeight);
- }
Gravity.apply(mDefaultStackGravity, defaultSize.getWidth(), defaultSize.getHeight(),
insetBounds, 0, Math.max(
mPipBoundsState.isImeShowing() ? mPipBoundsState.getImeHeight() : 0,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
index 53aa61477483..4493d38d2144 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
@@ -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;
@@ -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. */
@@ -205,6 +207,7 @@ public final class PipBoundsState {
mLastPipComponentName = lastPipComponentName;
if (changed) {
clearReentryState();
+ setHasUserResizedPip(false);
}
}
@@ -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.
*/
@@ -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;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 46fff85ca58d..4d2760259521 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -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;
@@ -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;
@@ -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);
@@ -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) {
- final Rect reentryBounds = mTouchHandler.getUserResizeBounds();
- float snapFraction = mPipBoundsAlgorithm.getSnapFraction(bounds);
- mPipBoundsAlgorithm.applySnapFraction(reentryBounds, snapFraction);
- mReentryBounds.set(reentryBounds);
+ /** 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();
+ final Size reentrySize = new Size(reentryBounds.width(), reentryBounds.height());
+ mPipBoundsState.saveReentryState(reentrySize, snapFraction);
+ } else {
+ mPipBoundsState.saveReentryState(null /* bounds */, snapFraction);
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index 2f5219c59bf2..02f6231c6ecf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -410,6 +410,7 @@ public class PipResizeGestureHandler {
mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,
null);
+ mPipBoundsState.setHasUserResizedPip(true);
}
}
}
@@ -462,6 +463,7 @@ public class PipResizeGestureHandler {
true /* useCurrentSize */);
mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,
null);
+ mPipBoundsState.setHasUserResizedPip(true);
}
break;
case MotionEvent.ACTION_UP:
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 a65d832359d2..ef9923550fc5 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
@@ -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());
@@ -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();
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 4bcca06b592f..8ba301a9ebfa 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
@@ -47,7 +47,7 @@ import java.util.function.BiConsumer;
@SmallTest
public class PipBoundsStateTest extends ShellTestCase {
- private static final Rect DEFAULT_BOUNDS = new Rect(0, 0, 10, 10);
+ private static final Size DEFAULT_SIZE = new Size(10, 10);
private static final float DEFAULT_SNAP_FRACTION = 1.0f;
private PipBoundsState mPipBoundsState;
@@ -71,22 +71,22 @@ public class PipBoundsStateTest extends ShellTestCase {
@Test
public void testSetReentryState() {
- final Rect bounds = new Rect(0, 0, 100, 100);
+ final Size size = new Size(100, 100);
final float snapFraction = 0.5f;
- mPipBoundsState.saveReentryState(bounds, snapFraction);
+ mPipBoundsState.saveReentryState(size, snapFraction);
final PipBoundsState.PipReentryState state = mPipBoundsState.getReentryState();
- assertEquals(new Size(100, 100), state.getSize());
+ assertEquals(size, state.getSize());
assertEquals(snapFraction, state.getSnapFraction(), 0.01);
}
@Test
public void testClearReentryState() {
- final Rect bounds = new Rect(0, 0, 100, 100);
+ final Size size = new Size(100, 100);
final float snapFraction = 0.5f;
- mPipBoundsState.saveReentryState(bounds, snapFraction);
+ mPipBoundsState.saveReentryState(size, snapFraction);
mPipBoundsState.clearReentryState();
assertNull(mPipBoundsState.getReentryState());
@@ -95,20 +95,20 @@ public class PipBoundsStateTest extends ShellTestCase {
@Test
public void testSetLastPipComponentName_notChanged_doesNotClearReentryState() {
mPipBoundsState.setLastPipComponentName(mTestComponentName1);
- mPipBoundsState.saveReentryState(DEFAULT_BOUNDS, DEFAULT_SNAP_FRACTION);
+ mPipBoundsState.saveReentryState(DEFAULT_SIZE, DEFAULT_SNAP_FRACTION);
mPipBoundsState.setLastPipComponentName(mTestComponentName1);
final PipBoundsState.PipReentryState state = mPipBoundsState.getReentryState();
assertNotNull(state);
- assertEquals(new Size(DEFAULT_BOUNDS.width(), DEFAULT_BOUNDS.height()), state.getSize());
+ assertEquals(DEFAULT_SIZE, state.getSize());
assertEquals(DEFAULT_SNAP_FRACTION, state.getSnapFraction(), 0.01);
}
@Test
public void testSetLastPipComponentName_changed_clearReentryState() {
mPipBoundsState.setLastPipComponentName(mTestComponentName1);
- mPipBoundsState.saveReentryState(DEFAULT_BOUNDS, DEFAULT_SNAP_FRACTION);
+ mPipBoundsState.saveReentryState(DEFAULT_SIZE, DEFAULT_SNAP_FRACTION);
mPipBoundsState.setLastPipComponentName(mTestComponentName2);
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 4687d2d9667c..62ffac4fbd3f 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
@@ -30,10 +30,12 @@ import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
+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.Size;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.WindowManagerShellWrapper;
@@ -135,4 +137,28 @@ public class PipControllerTest extends ShellTestCase {
verify(mMockPipBoundsState, never()).setLastPipComponentName(null);
}
+
+ @Test
+ public void saveReentryState_noUserResize_doesNotSaveSize() {
+ final Rect bounds = new Rect(0, 0, 10, 10);
+ when(mMockPipBoundsAlgorithm.getSnapFraction(bounds)).thenReturn(1.0f);
+ when(mMockPipBoundsState.hasUserResizedPip()).thenReturn(false);
+
+ mPipController.saveReentryState(bounds);
+
+ verify(mMockPipBoundsState).saveReentryState(null, 1.0f);
+ }
+
+ @Test
+ public void saveReentryState_userHasResized_savesSize() {
+ final Rect bounds = new Rect(0, 0, 10, 10);
+ final Rect resizedBounds = new Rect(0, 0, 30, 30);
+ when(mMockPipBoundsAlgorithm.getSnapFraction(bounds)).thenReturn(1.0f);
+ when(mMockPipTouchHandler.getUserResizeBounds()).thenReturn(resizedBounds);
+ when(mMockPipBoundsState.hasUserResizedPip()).thenReturn(true);
+
+ mPipController.saveReentryState(bounds);
+
+ verify(mMockPipBoundsState).saveReentryState(new Size(30, 30), 1.0f);
+ }
}