Merge "Don't save the default size as reentry state"
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user