Merge "Persist PiP size to be restored on re-entry"
This commit is contained in:
committed by
Android (Google) Code Review
commit
b11f93129c
@@ -67,20 +67,20 @@ oneway interface IPinnedStackListener {
|
||||
void onActionsChanged(in ParceledListSlice actions);
|
||||
|
||||
/**
|
||||
* Called by the window manager to notify the listener to save the reentry fraction,
|
||||
* Called by the window manager to notify the listener to save the reentry fraction and size,
|
||||
* typically when an Activity leaves PiP (picture-in-picture) mode to fullscreen.
|
||||
* {@param componentName} represents the application component of PiP window
|
||||
* while {@param bounds} is the current PiP bounds used to calculate the
|
||||
* reentry snap fraction.
|
||||
* reentry snap fraction and size.
|
||||
*/
|
||||
void onSaveReentrySnapFraction(in ComponentName componentName, in Rect bounds);
|
||||
void onSaveReentryBounds(in ComponentName componentName, in Rect bounds);
|
||||
|
||||
/**
|
||||
* Called by the window manager to notify the listener to reset saved reentry fraction,
|
||||
* Called by the window manager to notify the listener to reset saved reentry fraction and size,
|
||||
* typically when an Activity enters PiP (picture-in-picture) mode from fullscreen.
|
||||
* {@param componentName} represents the application component of PiP window.
|
||||
*/
|
||||
void onResetReentrySnapFraction(in ComponentName componentName);
|
||||
void onResetReentryBounds(in ComponentName componentName);
|
||||
|
||||
/**
|
||||
* Called when the window manager has detected change on DisplayInfo, or
|
||||
|
||||
@@ -359,6 +359,28 @@ public class PipSnapAlgorithm {
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the adjusted size so that it conforms to the given aspectRatio, ensuring that the
|
||||
* minimum edge is at least minEdgeSize.
|
||||
*/
|
||||
public Size getSizeForAspectRatio(Size size, float aspectRatio, float minEdgeSize) {
|
||||
final int smallestSize = Math.min(size.getWidth(), size.getHeight());
|
||||
final int minSize = (int) Math.max(minEdgeSize, 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the closest point in {@param points} to the given {@param x} and {@param y}.
|
||||
*/
|
||||
|
||||
@@ -83,16 +83,16 @@ public class PinnedStackListenerForwarder extends IPinnedStackListener.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveReentrySnapFraction(ComponentName componentName, Rect bounds) {
|
||||
public void onSaveReentryBounds(ComponentName componentName, Rect bounds) {
|
||||
for (PinnedStackListener listener : mListeners) {
|
||||
listener.onSaveReentrySnapFraction(componentName, bounds);
|
||||
listener.onSaveReentryBounds(componentName, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResetReentrySnapFraction(ComponentName componentName) {
|
||||
public void onResetReentryBounds(ComponentName componentName) {
|
||||
for (PinnedStackListener listener : mListeners) {
|
||||
listener.onResetReentrySnapFraction(componentName);
|
||||
listener.onResetReentryBounds(componentName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,9 +140,9 @@ public class PinnedStackListenerForwarder extends IPinnedStackListener.Stub {
|
||||
|
||||
public void onActionsChanged(ParceledListSlice actions) {}
|
||||
|
||||
public void onSaveReentrySnapFraction(ComponentName componentName, Rect bounds) {}
|
||||
public void onSaveReentryBounds(ComponentName componentName, Rect bounds) {}
|
||||
|
||||
public void onResetReentrySnapFraction(ComponentName componentName) {}
|
||||
public void onResetReentryBounds(ComponentName componentName) {}
|
||||
|
||||
public void onDisplayInfoChanged(DisplayInfo displayInfo) {}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ public class PipBoundsHandler {
|
||||
private IPinnedStackController mPinnedStackController;
|
||||
private ComponentName mLastPipComponentName;
|
||||
private float mReentrySnapFraction = INVALID_SNAP_FRACTION;
|
||||
private Size mReentrySize = null;
|
||||
|
||||
private float mDefaultAspectRatio;
|
||||
private float mMinAspectRatio;
|
||||
@@ -162,7 +163,7 @@ public class PipBoundsHandler {
|
||||
public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
|
||||
Rect animatingBounds, DisplayInfo displayInfo) {
|
||||
getInsetBounds(insetBounds);
|
||||
final Rect defaultBounds = getDefaultBounds(INVALID_SNAP_FRACTION);
|
||||
final Rect defaultBounds = getDefaultBounds(INVALID_SNAP_FRACTION, null);
|
||||
normalBounds.set(defaultBounds);
|
||||
if (animatingBounds.isEmpty()) {
|
||||
animatingBounds.set(defaultBounds);
|
||||
@@ -175,26 +176,28 @@ public class PipBoundsHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to IPinnedStackListener on saving reentry snap fraction
|
||||
* Responds to IPinnedStackListener on saving reentry snap fraction and size
|
||||
* for a given {@link ComponentName}.
|
||||
*/
|
||||
public void onSaveReentrySnapFraction(ComponentName componentName, Rect bounds) {
|
||||
public void onSaveReentryBounds(ComponentName componentName, Rect bounds) {
|
||||
mReentrySnapFraction = getSnapFraction(bounds);
|
||||
mReentrySize = new Size(bounds.width(), bounds.height());
|
||||
mLastPipComponentName = componentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to IPinnedStackListener on resetting reentry snap fraction
|
||||
* Responds to IPinnedStackListener on resetting reentry snap fraction and size
|
||||
* for a given {@link ComponentName}.
|
||||
*/
|
||||
public void onResetReentrySnapFraction(ComponentName componentName) {
|
||||
public void onResetReentryBounds(ComponentName componentName) {
|
||||
if (componentName.equals(mLastPipComponentName)) {
|
||||
onResetReentrySnapFractionUnchecked();
|
||||
onResetReentryBoundsUnchecked();
|
||||
}
|
||||
}
|
||||
|
||||
private void onResetReentrySnapFractionUnchecked() {
|
||||
private void onResetReentryBoundsUnchecked() {
|
||||
mReentrySnapFraction = INVALID_SNAP_FRACTION;
|
||||
mReentrySize = null;
|
||||
mLastPipComponentName = null;
|
||||
}
|
||||
|
||||
@@ -233,7 +236,7 @@ public class PipBoundsHandler {
|
||||
public void onPrepareAnimation(Rect sourceRectHint, float aspectRatio, Rect bounds) {
|
||||
final Rect destinationBounds;
|
||||
if (bounds == null) {
|
||||
destinationBounds = getDefaultBounds(mReentrySnapFraction);
|
||||
destinationBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
|
||||
} else {
|
||||
destinationBounds = new Rect(bounds);
|
||||
}
|
||||
@@ -245,7 +248,7 @@ public class PipBoundsHandler {
|
||||
return;
|
||||
}
|
||||
mAspectRatio = aspectRatio;
|
||||
onResetReentrySnapFractionUnchecked();
|
||||
onResetReentryBoundsUnchecked();
|
||||
try {
|
||||
mPinnedStackController.startAnimation(destinationBounds, sourceRectHint,
|
||||
-1 /* animationDuration */);
|
||||
@@ -269,13 +272,14 @@ public class PipBoundsHandler {
|
||||
*/
|
||||
private void transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio,
|
||||
boolean useCurrentMinEdgeSize) {
|
||||
// Save the snap fraction, calculate the aspect ratio based on screen size
|
||||
|
||||
// Save the snap fraction and adjust the size based on the new aspect ratio.
|
||||
final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
|
||||
getMovementBounds(stackBounds));
|
||||
|
||||
final int minEdgeSize = useCurrentMinEdgeSize ? mCurrentMinSize : mDefaultMinSize;
|
||||
final Size size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, minEdgeSize,
|
||||
mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
|
||||
final Size size = mSnapAlgorithm.getSizeForAspectRatio(
|
||||
new Size(stackBounds.width(), stackBounds.height()), aspectRatio, minEdgeSize);
|
||||
|
||||
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());
|
||||
@@ -286,21 +290,20 @@ public class PipBoundsHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the default bounds to show the PIP, if a {@param snapFraction} is provided, then it
|
||||
* will apply the default bounds to the provided snap fraction.
|
||||
* @return the default bounds to show the PIP, if a {@param snapFraction} and {@param size} are
|
||||
* provided, then it will apply the default bounds to the provided snap fraction and size.
|
||||
*/
|
||||
private Rect getDefaultBounds(float snapFraction) {
|
||||
final Rect insetBounds = new Rect();
|
||||
getInsetBounds(insetBounds);
|
||||
|
||||
private Rect getDefaultBounds(float snapFraction, Size size) {
|
||||
final Rect defaultBounds = new Rect();
|
||||
final Size size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
|
||||
mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
|
||||
if (snapFraction != INVALID_SNAP_FRACTION) {
|
||||
if (snapFraction != INVALID_SNAP_FRACTION && size != null) {
|
||||
defaultBounds.set(0, 0, size.getWidth(), size.getHeight());
|
||||
final Rect movementBounds = getMovementBounds(defaultBounds);
|
||||
mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction);
|
||||
} else {
|
||||
final Rect insetBounds = new Rect();
|
||||
getInsetBounds(insetBounds);
|
||||
size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
|
||||
mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
|
||||
Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
|
||||
0, Math.max(mIsImeShowing ? mImeHeight : 0,
|
||||
mIsShelfShowing ? mShelfHeight : 0),
|
||||
@@ -364,10 +367,18 @@ public class PipBoundsHandler {
|
||||
* @return the default snap fraction to apply instead of the default gravity when calculating
|
||||
* the default stack bounds when first entering PiP.
|
||||
*/
|
||||
private float getSnapFraction(Rect stackBounds) {
|
||||
public float getSnapFraction(Rect stackBounds) {
|
||||
return mSnapAlgorithm.getSnapFraction(stackBounds, getMovementBounds(stackBounds));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given snap fraction to the given stack bounds.
|
||||
*/
|
||||
public void applySnapFraction(Rect stackBounds, float snapFraction) {
|
||||
final Rect movementBounds = getMovementBounds(stackBounds);
|
||||
mSnapAlgorithm.applySnapFraction(stackBounds, movementBounds, snapFraction);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pixels for a given dp value.
|
||||
*/
|
||||
|
||||
@@ -65,6 +65,7 @@ public class PipManager implements BasePipManager {
|
||||
private final DisplayInfo mTmpDisplayInfo = new DisplayInfo();
|
||||
private final Rect mTmpInsetBounds = new Rect();
|
||||
private final Rect mTmpNormalBounds = new Rect();
|
||||
private final Rect mReentryBounds = new Rect();
|
||||
|
||||
private PipBoundsHandler mPipBoundsHandler;
|
||||
private InputConsumerController mInputConsumerController;
|
||||
@@ -164,13 +165,25 @@ public class PipManager implements BasePipManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveReentrySnapFraction(ComponentName componentName, Rect bounds) {
|
||||
mHandler.post(() -> mPipBoundsHandler.onSaveReentrySnapFraction(componentName, bounds));
|
||||
public void onSaveReentryBounds(ComponentName componentName, Rect bounds) {
|
||||
mHandler.post(() -> {
|
||||
// On phones, the expansion animation that happens on pip tap before restoring
|
||||
// to fullscreen makes it so that the bounds received here are the expanded
|
||||
// bounds. We want to restore to the unexpanded bounds when re-entering pip,
|
||||
// so we save the bounds before expansion (normal) instead of the current
|
||||
// bounds.
|
||||
mReentryBounds.set(mTouchHandler.getNormalBounds());
|
||||
// Apply the snap fraction of the current bounds to the normal bounds.
|
||||
float snapFraction = mPipBoundsHandler.getSnapFraction(bounds);
|
||||
mPipBoundsHandler.applySnapFraction(mReentryBounds, snapFraction);
|
||||
// Save reentry bounds (normal non-expand bounds with current position applied).
|
||||
mPipBoundsHandler.onSaveReentryBounds(componentName, mReentryBounds);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResetReentrySnapFraction(ComponentName componentName) {
|
||||
mHandler.post(() -> mPipBoundsHandler.onResetReentrySnapFraction(componentName));
|
||||
public void onResetReentryBounds(ComponentName componentName) {
|
||||
mHandler.post(() -> mPipBoundsHandler.onResetReentryBounds(componentName));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -591,6 +591,13 @@ public class PipTouchHandler {
|
||||
return mMotionHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the unexpanded bounds.
|
||||
*/
|
||||
public Rect getNormalBounds() {
|
||||
return mNormalBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gesture controlling normal movement of the PIP.
|
||||
*/
|
||||
|
||||
@@ -3075,7 +3075,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
}
|
||||
|
||||
// Reset the last saved PiP snap fraction on removal.
|
||||
mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(mActivityComponent);
|
||||
mDisplayContent.mPinnedStackControllerLocked.resetReentryBounds(mActivityComponent);
|
||||
|
||||
mRemovingFromDisplay = false;
|
||||
}
|
||||
@@ -4329,7 +4329,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
ProtoLog.v(WM_DEBUG_ADD_REMOVE, "notifyAppStopped: %s", this);
|
||||
mAppStopped = true;
|
||||
// Reset the last saved PiP snap fraction on app stop.
|
||||
mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(mActivityComponent);
|
||||
mDisplayContent.mPinnedStackControllerLocked.resetReentryBounds(mActivityComponent);
|
||||
destroySurfaces();
|
||||
// Remove any starting window that was added for this app if they are still around.
|
||||
removeStartingWindow();
|
||||
@@ -6572,7 +6572,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
stackBounds = mTmpRect;
|
||||
pinnedStack.getBounds(stackBounds);
|
||||
}
|
||||
mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(
|
||||
mDisplayContent.mPinnedStackControllerLocked.saveReentryBounds(
|
||||
mActivityComponent, stackBounds);
|
||||
}
|
||||
|
||||
|
||||
@@ -236,10 +236,10 @@ class PinnedStackController {
|
||||
/**
|
||||
* Saves the current snap fraction for re-entry of the current activity into PiP.
|
||||
*/
|
||||
void saveReentrySnapFraction(final ComponentName componentName, final Rect stackBounds) {
|
||||
void saveReentryBounds(final ComponentName componentName, final Rect stackBounds) {
|
||||
if (mPinnedStackListener == null) return;
|
||||
try {
|
||||
mPinnedStackListener.onSaveReentrySnapFraction(componentName, stackBounds);
|
||||
mPinnedStackListener.onSaveReentryBounds(componentName, stackBounds);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG_WM, "Error delivering save reentry fraction event.", e);
|
||||
}
|
||||
@@ -248,10 +248,10 @@ class PinnedStackController {
|
||||
/**
|
||||
* Resets the last saved snap fraction so that the default bounds will be returned.
|
||||
*/
|
||||
void resetReentrySnapFraction(ComponentName componentName) {
|
||||
void resetReentryBounds(ComponentName componentName) {
|
||||
if (mPinnedStackListener == null) return;
|
||||
try {
|
||||
mPinnedStackListener.onResetReentrySnapFraction(componentName);
|
||||
mPinnedStackListener.onResetReentryBounds(componentName);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG_WM, "Error delivering reset reentry fraction event.", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user