Merge "Rename PipBoundsHandler to PipBoundsAlgorithm"

This commit is contained in:
Jorge Gil
2020-11-12 16:53:00 +00:00
committed by Android (Google) Code Review
12 changed files with 253 additions and 250 deletions

View File

@@ -16,37 +16,27 @@
package com.android.wm.shell.pip;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import android.annotation.NonNull;
import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager.RootTaskInfo;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.util.TypedValue;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.window.WindowContainerTransaction;
import java.io.PrintWriter;
/**
* Handles bounds calculation for PIP on Phone and other form factors, it keeps tracking variant
* state changes originated from Window Manager and is the source of truth for PiP window bounds.
* Calculates the default, normal, entry, inset and movement bounds of the PIP.
*/
public class PipBoundsHandler {
public class PipBoundsAlgorithm {
private static final String TAG = PipBoundsHandler.class.getSimpleName();
private static final String TAG = PipBoundsAlgorithm.class.getSimpleName();
private static final float INVALID_SNAP_FRACTION = -1f;
private final @NonNull PipBoundsState mPipBoundsState;
@@ -59,7 +49,7 @@ public class PipBoundsHandler {
private int mDefaultMinSize;
private Point mScreenEdgeInsets;
public PipBoundsHandler(Context context, @NonNull PipBoundsState pipBoundsState) {
public PipBoundsAlgorithm(Context context, @NonNull PipBoundsState pipBoundsState) {
mPipBoundsState = pipBoundsState;
mSnapAlgorithm = new PipSnapAlgorithm(context);
reloadResources(context);
@@ -95,24 +85,6 @@ public class PipBoundsHandler {
com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
}
/**
* Responds to IPinnedStackListener on movement bounds change.
* Note that both inset and normal bounds will be calculated here rather than in the caller.
*/
public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
Rect animatingBounds) {
getInsetBounds(insetBounds);
final Rect defaultBounds = getDefaultBounds(INVALID_SNAP_FRACTION, null);
normalBounds.set(defaultBounds);
if (animatingBounds.isEmpty()) {
animatingBounds.set(defaultBounds);
}
if (isValidPictureInPictureAspectRatio(mPipBoundsState.getAspectRatio())) {
transformBoundsToAspectRatio(normalBounds, mPipBoundsState.getAspectRatio(),
false /* useCurrentMinEdgeSize */, false /* useCurrentSize */);
}
}
/**
* The {@link PipSnapAlgorithm} is couple on display bounds
* @return {@link PipSnapAlgorithm}.
@@ -128,6 +100,19 @@ public class PipBoundsHandler {
reloadResources(context);
}
/** Returns the normal bounds (i.e. the default entry bounds). */
public Rect getNormalBounds() {
// The normal bounds are the default bounds adjusted to the current aspect ratio.
return transformBoundsToAspectRatioIfValid(getDefaultBounds(),
mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */,
false /* useCurrentSize */);
}
/** Returns the default bounds. */
public Rect getDefaultBounds() {
return getDefaultBounds(INVALID_SNAP_FRACTION, null /* size */);
}
/** Returns the destination bounds to place the PIP window on entry. */
public Rect getEntryDestinationBounds() {
final PipBoundsState.PipReentryState reentryState = mPipBoundsState.getReentryState();
@@ -135,117 +120,23 @@ public class PipBoundsHandler {
final Rect destinationBounds = shouldRestoreReentryBounds
? getDefaultBounds(reentryState.getSnapFraction(), reentryState.getSize())
: getDefaultBounds(INVALID_SNAP_FRACTION, null /* size */);
: getDefaultBounds();
if (isValidPictureInPictureAspectRatio(mPipBoundsState.getAspectRatio())) {
transformBoundsToAspectRatio(destinationBounds, mPipBoundsState.getAspectRatio(),
false /* useCurrentMinEdgeSize */, shouldRestoreReentryBounds);
}
return destinationBounds;
return transformBoundsToAspectRatioIfValid(destinationBounds,
mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */,
shouldRestoreReentryBounds);
}
/** Returns the current bounds adjusted to the new aspect ratio, if valid. */
public Rect getAdjustedDestinationBounds(Rect currentBounds, float newAspectRatio) {
final Rect destinationBounds = new Rect(currentBounds);
if (isValidPictureInPictureAspectRatio(newAspectRatio)) {
transformBoundsToAspectRatio(destinationBounds, newAspectRatio,
true /* useCurrentMinEdgeSize */, false /* isReentryBounds */);
}
return destinationBounds;
return transformBoundsToAspectRatioIfValid(currentBounds, newAspectRatio,
true /* useCurrentMinEdgeSize */, false /* useCurrentSize */);
}
public float getDefaultAspectRatio() {
return mDefaultAspectRatio;
}
/**
* Updatest the display info and display layout on rotation change. This is needed even when we
* aren't in PIP because the rotation layout is used to calculate the proper insets for the
* next enter animation into PIP.
*/
public void onDisplayRotationChangedNotInPip(Context context, int toRotation) {
// Update the display layout, note that we have to do this on every rotation even if we
// aren't in PIP since we need to update the display layout to get the right resources
mPipBoundsState.getDisplayLayout().rotateTo(context.getResources(), toRotation);
// Populate the new {@link #mDisplayInfo}.
// The {@link DisplayInfo} queried from DisplayManager would be the one before rotation,
// therefore, the width/height may require a swap first.
// Moving forward, we should get the new dimensions after rotation from DisplayLayout.
mPipBoundsState.setDisplayRotation(toRotation);
updateDisplayInfoIfNeeded();
}
/**
* Updates the display info, calculating and returning the new stack and movement bounds in the
* new orientation of the device if necessary.
*
* @return {@code true} if internal {@link DisplayInfo} is rotated, {@code false} otherwise.
*/
public boolean onDisplayRotationChanged(Context context, Rect outBounds, Rect oldBounds,
Rect outInsetBounds,
int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) {
// Bail early if the event is not sent to current {@link #mDisplayInfo}
if ((displayId != mPipBoundsState.getDisplayInfo().displayId)
|| (fromRotation == toRotation)) {
return false;
}
// Bail early if the pinned task is staled.
final RootTaskInfo pinnedTaskInfo;
try {
pinnedTaskInfo = ActivityTaskManager.getService()
.getRootTaskInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
if (pinnedTaskInfo == null) return false;
} catch (RemoteException e) {
Log.e(TAG, "Failed to get RootTaskInfo for pinned task", e);
return false;
}
// Calculate the snap fraction of the current stack along the old movement bounds
final Rect postChangeStackBounds = new Rect(oldBounds);
final float snapFraction = mSnapAlgorithm.getSnapFraction(postChangeStackBounds,
getMovementBounds(postChangeStackBounds), mPipBoundsState.getStashedState());
// Update the display layout
mPipBoundsState.getDisplayLayout().rotateTo(context.getResources(), toRotation);
// Populate the new {@link #mDisplayInfo}.
// The {@link DisplayInfo} queried from DisplayManager would be the one before rotation,
// therefore, the width/height may require a swap first.
// Moving forward, we should get the new dimensions after rotation from DisplayLayout.
mPipBoundsState.getDisplayInfo().rotation = toRotation;
updateDisplayInfoIfNeeded();
// Calculate the stack bounds in the new orientation based on same fraction along the
// rotated movement bounds.
final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
false /* adjustForIme */);
mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
snapFraction, mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(),
mPipBoundsState.getDisplayBounds());
getInsetBounds(outInsetBounds);
outBounds.set(postChangeStackBounds);
t.setBounds(pinnedTaskInfo.token, outBounds);
return true;
}
private void updateDisplayInfoIfNeeded() {
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
final boolean updateNeeded;
if ((displayInfo.rotation == ROTATION_0) || (displayInfo.rotation == ROTATION_180)) {
updateNeeded = (displayInfo.logicalWidth > displayInfo.logicalHeight);
} else {
updateNeeded = (displayInfo.logicalWidth < displayInfo.logicalHeight);
}
if (updateNeeded) {
final int newLogicalHeight = displayInfo.logicalWidth;
displayInfo.logicalWidth = displayInfo.logicalHeight;
displayInfo.logicalHeight = newLogicalHeight;
}
}
/**
* @return whether the given {@param aspectRatio} is valid.
*/
@@ -254,6 +145,16 @@ public class PipBoundsHandler {
&& Float.compare(aspectRatio, mMaxAspectRatio) <= 0;
}
private Rect transformBoundsToAspectRatioIfValid(Rect bounds, float aspectRatio,
boolean useCurrentMinEdgeSize, boolean useCurrentSize) {
final Rect destinationBounds = new Rect(bounds);
if (isValidPictureInPictureAspectRatio(aspectRatio)) {
transformBoundsToAspectRatio(destinationBounds, aspectRatio,
useCurrentMinEdgeSize, useCurrentSize);
}
return destinationBounds;
}
/**
* Set the current bounds (or the default bounds if there are no current bounds) with the
* specified aspect ratio.
@@ -343,7 +244,7 @@ public class PipBoundsHandler {
/**
* Populates the bounds on the screen that the PIP can be visible in.
*/
protected void getInsetBounds(Rect outRect) {
public void getInsetBounds(Rect outRect) {
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
Rect insets = mPipBoundsState.getDisplayLayout().stableInsets();
outRect.set(insets.left + mScreenEdgeInsets.x,
@@ -353,18 +254,18 @@ public class PipBoundsHandler {
}
/**
* @return the movement bounds for the given {@param stackBounds} and the current state of the
* @return the movement bounds for the given stackBounds and the current state of the
* controller.
*/
private Rect getMovementBounds(Rect stackBounds) {
public Rect getMovementBounds(Rect stackBounds) {
return getMovementBounds(stackBounds, true /* adjustForIme */);
}
/**
* @return the movement bounds for the given {@param stackBounds} and the current state of the
* @return the movement bounds for the given stackBounds and the current state of the
* controller.
*/
private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
public Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
final Rect movementBounds = new Rect();
getInsetBounds(movementBounds);

View File

@@ -134,7 +134,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private final Handler mMainHandler;
private final Handler mUpdateHandler;
private final PipBoundsState mPipBoundsState;
private final PipBoundsHandler mPipBoundsHandler;
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
// TODO(b/172286265): Remove dependency on .pip.PHONE.PipMenuActivityController
private final PipMenuActivityController mMenuActivityController;
private final PipAnimationController mPipAnimationController;
@@ -263,7 +263,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private boolean mShouldIgnoreEnteringPipTransition;
public PipTaskOrganizer(Context context, @NonNull PipBoundsState pipBoundsState,
@NonNull PipBoundsHandler boundsHandler,
@NonNull PipBoundsAlgorithm boundsHandler,
PipMenuActivityController menuActivityController,
@NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
Optional<SplitScreen> splitScreenOptional,
@@ -273,7 +273,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mMainHandler = new Handler(Looper.getMainLooper());
mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
mPipBoundsState = pipBoundsState;
mPipBoundsHandler = boundsHandler;
mPipBoundsAlgorithm = boundsHandler;
mMenuActivityController = menuActivityController;
mEnterExitAnimationDuration = context.getResources()
.getInteger(R.integer.config_pipResizeAnimationDuration);
@@ -340,7 +340,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mShouldIgnoreEnteringPipTransition = true;
sendOnPipTransitionStarted(componentName, TRANSITION_DIRECTION_TO_PIP);
setBoundsStateForEntry(componentName, pictureInPictureParams, activityInfo);
return mPipBoundsHandler.getEntryDestinationBounds();
return mPipBoundsAlgorithm.getEntryDestinationBounds();
}
/**
@@ -528,7 +528,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
return;
}
final Rect destinationBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
Objects.requireNonNull(destinationBounds, "Missing destination bounds");
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
@@ -690,7 +690,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
return;
}
// Aspect ratio changed, re-calculate bounds if valid.
final Rect destinationBounds = mPipBoundsHandler.getAdjustedDestinationBounds(
final Rect destinationBounds = mPipBoundsAlgorithm.getAdjustedDestinationBounds(
mPipBoundsState.getBounds(), mPipBoundsState.getAspectRatio());
Objects.requireNonNull(destinationBounds, "Missing destination bounds");
scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration,
@@ -705,7 +705,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
@Override
public void onFixedRotationFinished(int displayId) {
if (mShouldDeferEnteringPip && mState.isInPip()) {
final Rect destinationBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
// schedule a regular animation to ensure all the callbacks are still being sent
enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */);
}
@@ -780,7 +780,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
return;
}
final Rect newDestinationBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect newDestinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
if (newDestinationBounds.equals(currentDestinationBounds)) return;
if (animator.getAnimationType() == ANIM_TYPE_BOUNDS) {
animator.updateEndValue(newDestinationBounds);
@@ -1106,7 +1106,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private float getAspectRatioOrDefault(@Nullable PictureInPictureParams params) {
return params == null || !params.hasSetAspectRatio()
? mPipBoundsHandler.getDefaultAspectRatio()
? mPipBoundsAlgorithm.getDefaultAspectRatio()
: params.getAspectRatio();
}

View File

@@ -19,6 +19,8 @@ package com.android.wm.shell.pip.phone;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import static android.view.WindowManager.INPUT_CONSUMER_PIP;
import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection;
@@ -56,9 +58,10 @@ import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipBoundsHandler;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipUtils;
@@ -78,7 +81,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
private WindowManagerShellWrapper mWindowManagerShellWrapper;
private PipAppOpsListener mAppOpsListener;
private PipMediaController mMediaController;
private PipBoundsHandler mPipBoundsHandler;
private PipBoundsAlgorithm mPipBoundsAlgorithm;
private PipBoundsState mPipBoundsState;
private PipTouchHandler mTouchHandler;
@@ -103,14 +106,14 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
if (!mPipTaskOrganizer.isInPip() || mPipTaskOrganizer.isDeferringEnterPipAnimation()) {
// Skip if we aren't in PIP or haven't actually entered PIP yet. We still need to update
// the display layout in the bounds handler in this case.
mPipBoundsHandler.onDisplayRotationChangedNotInPip(mContext, toRotation);
onDisplayRotationChangedNotInPip(mContext, toRotation);
return;
}
// If there is an animation running (ie. from a shelf offset), then ensure that we calculate
// the bounds for the next orientation using the destination bounds of the animation
// TODO: Technically this should account for movement animation bounds as well
Rect currentBounds = mPipTaskOrganizer.getCurrentOrAnimatingBounds();
final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mContext,
final boolean changed = onDisplayRotationChanged(mContext,
mTmpNormalBounds, currentBounds, mTmpInsetBounds, displayId, fromRotation,
toRotation, t);
if (changed) {
@@ -204,7 +207,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
@Override
public void onConfigurationChanged() {
mMainExecutor.execute(() -> {
mPipBoundsHandler.onConfigurationChanged(mContext);
mPipBoundsAlgorithm.onConfigurationChanged(mContext);
mTouchHandler.onConfigurationChanged();
mPipBoundsState.onConfigurationChanged();
});
@@ -224,7 +227,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
protected PipController(Context context,
DisplayController displayController,
PipAppOpsListener pipAppOpsListener,
PipBoundsHandler pipBoundsHandler,
PipBoundsAlgorithm pipBoundsAlgorithm,
@NonNull PipBoundsState pipBoundsState,
PipMediaController pipMediaController,
PipMenuActivityController pipMenuActivityController,
@@ -243,7 +246,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
mContext = context;
mWindowManagerShellWrapper = windowManagerShellWrapper;
mDisplayController = displayController;
mPipBoundsHandler = pipBoundsHandler;
mPipBoundsAlgorithm = pipBoundsAlgorithm;
mPipBoundsState = pipBoundsState;
mPipTaskOrganizer = pipTaskOrganizer;
mMainExecutor = mainExecutor;
@@ -437,7 +440,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
PictureInPictureParams pictureInPictureParams,
int launcherRotation, int shelfHeight) {
setShelfHeightLocked(shelfHeight > 0 /* visible */, shelfHeight);
mPipBoundsHandler.onDisplayRotationChangedNotInPip(mContext, launcherRotation);
onDisplayRotationChangedNotInPip(mContext, launcherRotation);
return mPipTaskOrganizer.startSwipePipToHome(componentName, activityInfo,
pictureInPictureParams);
}
@@ -452,7 +455,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
if (isOutPipDirection(direction)) {
// Exiting PIP, save the reentry bounds to restore to when re-entering.
updateReentryBounds(pipBounds);
final float snapFraction = mPipBoundsHandler.getSnapFraction(mReentryBounds);
final float snapFraction = mPipBoundsAlgorithm.getSnapFraction(mReentryBounds);
mPipBoundsState.saveReentryState(mReentryBounds, snapFraction);
}
// Disable touches while the animation is running
@@ -467,8 +470,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
*/
public void updateReentryBounds(Rect bounds) {
final Rect reentryBounds = mTouchHandler.getUserResizeBounds();
float snapFraction = mPipBoundsHandler.getSnapFraction(bounds);
mPipBoundsHandler.applySnapFraction(reentryBounds, snapFraction);
float snapFraction = mPipBoundsAlgorithm.getSnapFraction(bounds);
mPipBoundsAlgorithm.applySnapFraction(reentryBounds, snapFraction);
mReentryBounds.set(reentryBounds);
}
@@ -506,8 +509,13 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
// passing to mTouchHandler/mPipTaskOrganizer
final Rect outBounds = new Rect(toBounds);
mTmpDisplayInfo.copyFrom(mPipBoundsState.getDisplayInfo());
mPipBoundsHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds,
outBounds);
mPipBoundsAlgorithm.getInsetBounds(mTmpInsetBounds);
mTmpNormalBounds.set(mPipBoundsAlgorithm.getNormalBounds());
if (outBounds.isEmpty()) {
outBounds.set(mPipBoundsAlgorithm.getDefaultBounds());
}
// mTouchHandler would rely on the bounds populated from mPipTaskOrganizer
mPipTaskOrganizer.onMovementBoundsChanged(outBounds, fromRotation, fromImeAdjustment,
fromShelfAdjustment, wct);
@@ -516,13 +524,103 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
mTmpDisplayInfo.rotation);
}
/**
* Updates the display info and display layout on rotation change. This is needed even when we
* aren't in PIP because the rotation layout is used to calculate the proper insets for the
* next enter animation into PIP.
*/
private void onDisplayRotationChangedNotInPip(Context context, int toRotation) {
// Update the display layout, note that we have to do this on every rotation even if we
// aren't in PIP since we need to update the display layout to get the right resources
mPipBoundsState.getDisplayLayout().rotateTo(context.getResources(), toRotation);
// Populate the new {@link #mDisplayInfo}.
// The {@link DisplayInfo} queried from DisplayManager would be the one before rotation,
// therefore, the width/height may require a swap first.
// Moving forward, we should get the new dimensions after rotation from DisplayLayout.
mPipBoundsState.setDisplayRotation(toRotation);
updateDisplayInfoIfNeeded();
}
/**
* Updates the display info, calculating and returning the new stack and movement bounds in the
* new orientation of the device if necessary.
*
* @return {@code true} if internal {@link DisplayInfo} is rotated, {@code false} otherwise.
*/
public boolean onDisplayRotationChanged(Context context, Rect outBounds, Rect oldBounds,
Rect outInsetBounds,
int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) {
// Bail early if the event is not sent to current {@link #mDisplayInfo}
if ((displayId != mPipBoundsState.getDisplayInfo().displayId)
|| (fromRotation == toRotation)) {
return false;
}
// Bail early if the pinned task is staled.
final ActivityTaskManager.RootTaskInfo pinnedTaskInfo;
try {
pinnedTaskInfo = ActivityTaskManager.getService()
.getRootTaskInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
if (pinnedTaskInfo == null) return false;
} catch (RemoteException e) {
Log.e(TAG, "Failed to get RootTaskInfo for pinned task", e);
return false;
}
final PipSnapAlgorithm pipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm();
// Calculate the snap fraction of the current stack along the old movement bounds
final Rect postChangeStackBounds = new Rect(oldBounds);
final float snapFraction = pipSnapAlgorithm.getSnapFraction(postChangeStackBounds,
mPipBoundsAlgorithm.getMovementBounds(postChangeStackBounds),
mPipBoundsState.getStashedState());
// Update the display layout
mPipBoundsState.getDisplayLayout().rotateTo(context.getResources(), toRotation);
// Populate the new {@link #mDisplayInfo}.
// The {@link DisplayInfo} queried from DisplayManager would be the one before rotation,
// therefore, the width/height may require a swap first.
// Moving forward, we should get the new dimensions after rotation from DisplayLayout.
mPipBoundsState.getDisplayInfo().rotation = toRotation;
updateDisplayInfoIfNeeded();
// Calculate the stack bounds in the new orientation based on same fraction along the
// rotated movement bounds.
final Rect postChangeMovementBounds = mPipBoundsAlgorithm.getMovementBounds(
postChangeStackBounds, false /* adjustForIme */);
pipSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
snapFraction, mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(),
mPipBoundsState.getDisplayBounds());
mPipBoundsAlgorithm.getInsetBounds(outInsetBounds);
outBounds.set(postChangeStackBounds);
t.setBounds(pinnedTaskInfo.token, outBounds);
return true;
}
private void updateDisplayInfoIfNeeded() {
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
final boolean updateNeeded;
if ((displayInfo.rotation == ROTATION_0) || (displayInfo.rotation == ROTATION_180)) {
updateNeeded = (displayInfo.logicalWidth > displayInfo.logicalHeight);
} else {
updateNeeded = (displayInfo.logicalWidth < displayInfo.logicalHeight);
}
if (updateNeeded) {
final int newLogicalHeight = displayInfo.logicalWidth;
displayInfo.logicalWidth = displayInfo.logicalHeight;
displayInfo.logicalHeight = newLogicalHeight;
}
}
@Override
public void dump(PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG);
mMenuController.dump(pw, innerPrefix);
mTouchHandler.dump(pw, innerPrefix);
mPipBoundsHandler.dump(pw, innerPrefix);
mPipBoundsAlgorithm.dump(pw, innerPrefix);
mPipTaskOrganizer.dump(pw, innerPrefix);
mPipBoundsState.dump(pw, innerPrefix);
mPipInputConsumer.dump(pw, innerPrefix);
@@ -533,7 +631,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
*/
@Nullable
public static PipController create(Context context, DisplayController displayController,
PipAppOpsListener pipAppOpsListener, PipBoundsHandler pipBoundsHandler,
PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
PipBoundsState pipBoundsState, PipMediaController pipMediaController,
PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer,
PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper,
@@ -543,7 +641,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
return null;
}
return new PipController(context, displayController, pipAppOpsListener, pipBoundsHandler,
return new PipController(context, displayController, pipAppOpsListener, pipBoundsAlgorithm,
pipBoundsState, pipMediaController, pipMenuActivityController, pipTaskOrganizer,
pipTouchHandler, windowManagerShellWrapper, taskStackListener, mainExecutor);
}

View File

@@ -46,7 +46,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.internal.policy.TaskResizingAlgorithm;
import com.android.wm.shell.R;
import com.android.wm.shell.pip.PipBoundsHandler;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipUiEventLogger;
@@ -66,7 +66,7 @@ public class PipResizeGestureHandler {
private static final float STARTING_SCALE_FACTOR = 1.0f;
private final Context mContext;
private final PipBoundsHandler mPipBoundsHandler;
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
private final PipMotionHelper mMotionHelper;
private final PipBoundsState mPipBoundsState;
private final int mDisplayId;
@@ -108,7 +108,7 @@ public class PipResizeGestureHandler {
private int mCtrlType;
public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler,
public PipResizeGestureHandler(Context context, PipBoundsAlgorithm pipBoundsAlgorithm,
PipBoundsState pipBoundsState, PipMotionHelper motionHelper,
PipTaskOrganizer pipTaskOrganizer, Function<Rect, Rect> movementBoundsSupplier,
Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger,
@@ -116,7 +116,7 @@ public class PipResizeGestureHandler {
mContext = context;
mDisplayId = context.getDisplayId();
mMainExecutor = context.getMainExecutor();
mPipBoundsHandler = pipBoundsHandler;
mPipBoundsAlgorithm = pipBoundsAlgorithm;
mPipBoundsState = pipBoundsState;
mMotionHelper = motionHelper;
mPipTaskOrganizer = pipTaskOrganizer;
@@ -451,7 +451,7 @@ public class PipResizeGestureHandler {
mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x,
mMinSize.y, mMaxSize, true,
mLastDownBounds.width() > mLastDownBounds.height()));
mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds,
mPipBoundsAlgorithm.transformBoundsToAspectRatio(mLastResizeBounds,
mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */,
true /* useCurrentSize */);
mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,

View File

@@ -48,7 +48,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.R;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipBoundsHandler;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipUiEventLogger;
@@ -69,7 +69,7 @@ public class PipTouchHandler {
// Allow PIP to resize to a slightly bigger state upon touch
private final boolean mEnableResize;
private final Context mContext;
private final PipBoundsHandler mPipBoundsHandler;
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
private final @NonNull PipBoundsState mPipBoundsState;
private final PipUiEventLogger mPipUiEventLogger;
private final PipDismissTargetHandler mPipDismissTargetHandler;
@@ -161,7 +161,7 @@ public class PipTouchHandler {
@SuppressLint("InflateParams")
public PipTouchHandler(Context context,
PipMenuActivityController menuController,
PipBoundsHandler pipBoundsHandler,
PipBoundsAlgorithm pipBoundsAlgorithm,
@NonNull PipBoundsState pipBoundsState,
PipTaskOrganizer pipTaskOrganizer,
FloatingContentCoordinator floatingContentCoordinator,
@@ -169,15 +169,16 @@ public class PipTouchHandler {
// Initialize the Pip input consumer
mContext = context;
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
mPipBoundsHandler = pipBoundsHandler;
mPipBoundsAlgorithm = pipBoundsAlgorithm;
mPipBoundsState = pipBoundsState;
mMenuController = menuController;
mMenuController.addListener(new PipMenuListener());
mGesture = new DefaultPipTouchGesture();
mMotionHelper = new PipMotionHelper(mContext, pipBoundsState, pipTaskOrganizer,
mMenuController, mPipBoundsHandler.getSnapAlgorithm(), floatingContentCoordinator);
mMenuController, mPipBoundsAlgorithm.getSnapAlgorithm(),
floatingContentCoordinator);
mPipResizeGestureHandler =
new PipResizeGestureHandler(context, pipBoundsHandler, pipBoundsState,
new PipResizeGestureHandler(context, pipBoundsAlgorithm, pipBoundsState,
mMotionHelper, pipTaskOrganizer, this::getMovementBounds,
this::updateMovementBounds, pipUiEventLogger, menuController);
mPipDismissTargetHandler = new PipDismissTargetHandler(context, pipUiEventLogger,
@@ -193,7 +194,7 @@ public class PipTouchHandler {
mFloatingContentCoordinator = floatingContentCoordinator;
mConnection = new PipAccessibilityInteractionConnection(mContext, pipBoundsState,
mMotionHelper, pipTaskOrganizer, mPipBoundsHandler.getSnapAlgorithm(),
mMotionHelper, pipTaskOrganizer, mPipBoundsAlgorithm.getSnapAlgorithm(),
this::onAccessibilityShowMenu, this::updateMovementBounds, mHandler);
mPipUiEventLogger = pipUiEventLogger;
@@ -313,7 +314,7 @@ public class PipTouchHandler {
public void adjustBoundsForRotation(Rect outBounds, Rect curBounds, Rect insetBounds) {
final Rect toMovementBounds = new Rect();
mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(outBounds, insetBounds,
mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(outBounds, insetBounds,
toMovementBounds, 0);
final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets;
if ((prevBottom - mBottomOffsetBufferPx) <= curBounds.top) {
@@ -345,13 +346,13 @@ public class PipTouchHandler {
// Re-calculate the expanded bounds
mNormalBounds.set(normalBounds);
Rect normalMovementBounds = new Rect();
mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(mNormalBounds, insetBounds,
mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(mNormalBounds, insetBounds,
normalMovementBounds, bottomOffset);
if (mMovementBounds.isEmpty()) {
// mMovementBounds is not initialized yet and a clean movement bounds without
// bottom offset shall be used later in this function.
mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds,
mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds,
mMovementBounds, 0 /* bottomOffset */);
}
@@ -359,11 +360,11 @@ public class PipTouchHandler {
float aspectRatio = (float) normalBounds.width() / normalBounds.height();
Point displaySize = new Point();
mContext.getDisplay().getRealSize(displaySize);
Size expandedSize = mPipBoundsHandler.getSnapAlgorithm().getSizeForAspectRatio(aspectRatio,
mExpandedShortestEdgeSize, displaySize.x, displaySize.y);
Size expandedSize = mPipBoundsAlgorithm.getSnapAlgorithm().getSizeForAspectRatio(
aspectRatio, mExpandedShortestEdgeSize, displaySize.x, displaySize.y);
mExpandedBounds.set(0, 0, expandedSize.getWidth(), expandedSize.getHeight());
Rect expandedMovementBounds = new Rect();
mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(mExpandedBounds, insetBounds,
mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(mExpandedBounds, insetBounds,
expandedMovementBounds, bottomOffset);
mPipResizeGestureHandler.updateMinSize(mNormalBounds.width(), mNormalBounds.height());
@@ -384,7 +385,7 @@ public class PipTouchHandler {
} else {
final boolean isExpanded = mMenuState == MENU_STATE_FULL && willResizeMenu();
final Rect toMovementBounds = new Rect();
mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds,
mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds,
toMovementBounds, mIsImeShowing ? mImeHeight : 0);
final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets;
// This is to handle landscape fullscreen IMEs, don't apply the extra offset in this
@@ -395,7 +396,7 @@ public class PipTouchHandler {
if (isExpanded) {
curBounds.set(mExpandedBounds);
mPipBoundsHandler.getSnapAlgorithm().applySnapFraction(curBounds,
mPipBoundsAlgorithm.getSnapAlgorithm().applySnapFraction(curBounds,
toMovementBounds, mSavedSnapFraction);
}
@@ -658,7 +659,7 @@ public class PipTouchHandler {
private void animateToUnexpandedState(Rect restoreBounds) {
Rect restoredMovementBounds = new Rect();
mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(restoreBounds,
mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(restoreBounds,
mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
mMotionHelper.animateToUnexpandedState(restoreBounds, mSavedSnapFraction,
restoredMovementBounds, mMovementBounds, false /* immediate */);
@@ -718,7 +719,7 @@ public class PipTouchHandler {
mStartPosition.set(bounds.left, bounds.top);
mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
mMotionHelper.setSpringingToTouch(false);
mDownSavedFraction = mPipBoundsHandler.getSnapFraction(mPipBoundsState.getBounds());
mDownSavedFraction = mPipBoundsAlgorithm.getSnapFraction(mPipBoundsState.getBounds());
// If the menu is still visible then just poke the menu
// so that it will timeout after the user stops touching it
@@ -868,19 +869,19 @@ public class PipTouchHandler {
* resized.
*/
private void updateMovementBounds() {
mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(mMotionHelper.getBounds(),
mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(mMotionHelper.getBounds(),
mInsetBounds, mMovementBounds, mIsImeShowing ? mImeHeight : 0);
mMotionHelper.setCurrentMovementBounds(mMovementBounds);
boolean isMenuExpanded = mMenuState == MENU_STATE_FULL;
mPipBoundsState.setMinEdgeSize(
isMenuExpanded && willResizeMenu() ? mExpandedShortestEdgeSize
: mPipBoundsHandler.getDefaultMinSize());
: mPipBoundsAlgorithm.getDefaultMinSize());
}
private Rect getMovementBounds(Rect curBounds) {
Rect movementBounds = new Rect();
mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(curBounds, mInsetBounds,
mPipBoundsAlgorithm.getSnapAlgorithm().getMovementBounds(curBounds, mInsetBounds,
movementBounds, mIsImeShowing ? mImeHeight : 0);
return movementBounds;
}
@@ -921,7 +922,7 @@ public class PipTouchHandler {
pw.println(innerPrefix + "mShelfHeight=" + mShelfHeight);
pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction);
pw.println(innerPrefix + "mMovementBoundsExtraOffsets=" + mMovementBoundsExtraOffsets);
mPipBoundsHandler.dump(pw, innerPrefix);
mPipBoundsAlgorithm.dump(pw, innerPrefix);
mTouchState.dump(pw, innerPrefix);
if (mPipResizeGestureHandler != null) {
mPipResizeGestureHandler.dump(pw, innerPrefix);

View File

@@ -52,7 +52,7 @@ import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipBoundsHandler;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipTaskOrganizer;
@@ -108,7 +108,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
private final Context mContext;
private final PipBoundsState mPipBoundsState;
private final PipBoundsHandler mPipBoundsHandler;
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
private final PipTaskOrganizer mPipTaskOrganizer;
private final PipMediaController mPipMediaController;
@@ -204,9 +204,12 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
public void onMovementBoundsChanged(boolean fromImeAdjustment) {
mHandler.post(() -> {
mTmpDisplayInfo.copyFrom(mPipBoundsState.getDisplayInfo());
// Populate the inset / normal bounds from mPipBoundsHandler first.
mPipBoundsHandler.onMovementBoundsChanged(mTmpInsetBounds, mPipBounds,
mDefaultPipBounds);
mPipBoundsAlgorithm.getInsetBounds(mTmpInsetBounds);
mPipBounds.set(mPipBoundsAlgorithm.getNormalBounds());
if (mDefaultPipBounds.isEmpty()) {
mDefaultPipBounds.set(mPipBoundsAlgorithm.getDefaultBounds());
}
});
}
@@ -223,7 +226,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
public PipController(Context context,
PipBoundsState pipBoundsState,
PipBoundsHandler pipBoundsHandler,
PipBoundsAlgorithm pipBoundsAlgorithm,
PipTaskOrganizer pipTaskOrganizer,
PipMediaController pipMediaController,
PipNotification pipNotification,
@@ -232,7 +235,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
mContext = context;
mPipBoundsState = pipBoundsState;
mPipNotification = pipNotification;
mPipBoundsHandler = pipBoundsHandler;
mPipBoundsAlgorithm = pipBoundsAlgorithm;
mPipMediaController = pipMediaController;
// Ensure that we have the display info in case we get calls to update the bounds
// before the listener calls back

View File

@@ -36,7 +36,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Unit tests against {@link PipBoundsHandler}, including but not limited to:
* Unit tests against {@link PipBoundsAlgorithm}, including but not limited to:
* - default/movement bounds
* - save/restore PiP position on application lifecycle
* - save/restore PiP position on screen rotation
@@ -44,14 +44,14 @@ import org.junit.runner.RunWith;
@RunWith(AndroidTestingRunner.class)
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class PipBoundsHandlerTest extends ShellTestCase {
public class PipBoundsAlgorithmTest extends ShellTestCase {
private static final int ROUNDING_ERROR_MARGIN = 16;
private static final float ASPECT_RATIO_ERROR_MARGIN = 0.01f;
private static final float DEFAULT_ASPECT_RATIO = 1f;
private static final float MIN_ASPECT_RATIO = 0.5f;
private static final float MAX_ASPECT_RATIO = 2f;
private PipBoundsHandler mPipBoundsHandler;
private PipBoundsAlgorithm mPipBoundsAlgorithm;
private DisplayInfo mDefaultDisplayInfo;
private PipBoundsState mPipBoundsState;
@@ -59,7 +59,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
public void setUp() throws Exception {
initializeMockResources();
mPipBoundsState = new PipBoundsState(mContext);
mPipBoundsHandler = new PipBoundsHandler(mContext, mPipBoundsState);
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState);
mPipBoundsState.setDisplayInfo(mDefaultDisplayInfo);
}
@@ -93,7 +93,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
@Test
public void getDefaultAspectRatio() {
assertEquals("Default aspect ratio matches resources",
DEFAULT_ASPECT_RATIO, mPipBoundsHandler.getDefaultAspectRatio(),
DEFAULT_ASPECT_RATIO, mPipBoundsAlgorithm.getDefaultAspectRatio(),
ASPECT_RATIO_ERROR_MARGIN);
}
@@ -104,10 +104,10 @@ public class PipBoundsHandlerTest extends ShellTestCase {
res.addOverride(com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio,
newDefaultAspectRatio);
mPipBoundsHandler.onConfigurationChanged(mContext);
mPipBoundsAlgorithm.onConfigurationChanged(mContext);
assertEquals("Default aspect ratio should be reloaded",
mPipBoundsHandler.getDefaultAspectRatio(), newDefaultAspectRatio,
mPipBoundsAlgorithm.getDefaultAspectRatio(), newDefaultAspectRatio,
ASPECT_RATIO_ERROR_MARGIN);
}
@@ -120,7 +120,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
};
for (float aspectRatio : aspectRatios) {
mPipBoundsState.setAspectRatio(aspectRatio);
final Rect destinationBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
final float actualAspectRatio =
destinationBounds.width() / (destinationBounds.height() * 1f);
assertEquals("Destination bounds matches the given aspect ratio",
@@ -136,11 +136,11 @@ public class PipBoundsHandlerTest extends ShellTestCase {
};
for (float aspectRatio : invalidAspectRatios) {
mPipBoundsState.setAspectRatio(aspectRatio);
final Rect destinationBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
final float actualAspectRatio =
destinationBounds.width() / (destinationBounds.height() * 1f);
assertEquals("Destination bounds fallbacks to default aspect ratio",
mPipBoundsHandler.getDefaultAspectRatio(), actualAspectRatio,
mPipBoundsAlgorithm.getDefaultAspectRatio(), actualAspectRatio,
ASPECT_RATIO_ERROR_MARGIN);
}
}
@@ -152,7 +152,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left;
mPipBoundsState.setAspectRatio(aspectRatio);
final Rect destinationBounds = mPipBoundsHandler.getAdjustedDestinationBounds(
final Rect destinationBounds = mPipBoundsAlgorithm.getAdjustedDestinationBounds(
currentBounds, aspectRatio);
final float actualAspectRatio =
@@ -178,7 +178,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
final Size minimalSize = minimalSizes[i];
mPipBoundsState.setAspectRatio(aspectRatio);
mPipBoundsState.setOverrideMinSize(minimalSize);
final Rect destinationBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
assertTrue("Destination bounds is no smaller than minimal requirement",
(destinationBounds.width() == minimalSize.getWidth()
&& destinationBounds.height() >= minimalSize.getHeight())
@@ -200,7 +200,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
mPipBoundsState.setAspectRatio(aspectRatio);
mPipBoundsState.setOverrideMinSize(minSize);
final Rect destinationBounds = mPipBoundsHandler.getAdjustedDestinationBounds(
final Rect destinationBounds = mPipBoundsAlgorithm.getAdjustedDestinationBounds(
currentBounds, aspectRatio);
assertTrue("Destination bounds ignores minimal size",
@@ -211,12 +211,12 @@ public class PipBoundsHandlerTest extends ShellTestCase {
@Test
public void getEntryDestinationBounds_reentryStateExists_restoreLastSize() {
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
final Rect reentryBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect reentryBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
reentryBounds.scale(1.25f);
final float reentrySnapFraction = mPipBoundsHandler.getSnapFraction(reentryBounds);
final float reentrySnapFraction = mPipBoundsAlgorithm.getSnapFraction(reentryBounds);
mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction);
final Rect destinationBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
assertEquals(reentryBounds.width(), destinationBounds.width());
assertEquals(reentryBounds.height(), destinationBounds.height());
@@ -225,13 +225,13 @@ public class PipBoundsHandlerTest extends ShellTestCase {
@Test
public void getEntryDestinationBounds_reentryStateExists_restoreLastPosition() {
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
final Rect reentryBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect reentryBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
reentryBounds.offset(0, -100);
final float reentrySnapFraction = mPipBoundsHandler.getSnapFraction(reentryBounds);
final float reentrySnapFraction = mPipBoundsAlgorithm.getSnapFraction(reentryBounds);
mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction);
final Rect destinationBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
assertBoundsInclusionWithMargin("restoreLastPosition", reentryBounds, destinationBounds);
}
@@ -240,10 +240,10 @@ public class PipBoundsHandlerTest extends ShellTestCase {
public void setShelfHeight_offsetBounds() {
final int shelfHeight = 100;
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
final Rect oldPosition = mPipBoundsHandler.getEntryDestinationBounds();
final Rect oldPosition = mPipBoundsAlgorithm.getEntryDestinationBounds();
mPipBoundsState.setShelfVisibility(true, shelfHeight);
final Rect newPosition = mPipBoundsHandler.getEntryDestinationBounds();
final Rect newPosition = mPipBoundsAlgorithm.getEntryDestinationBounds();
oldPosition.offset(0, -shelfHeight);
assertBoundsInclusionWithMargin("offsetBounds by shelf", oldPosition, newPosition);
@@ -253,10 +253,10 @@ public class PipBoundsHandlerTest extends ShellTestCase {
public void onImeVisibilityChanged_offsetBounds() {
final int imeHeight = 100;
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
final Rect oldPosition = mPipBoundsHandler.getEntryDestinationBounds();
final Rect oldPosition = mPipBoundsAlgorithm.getEntryDestinationBounds();
mPipBoundsState.setImeVisibility(true, imeHeight);
final Rect newPosition = mPipBoundsHandler.getEntryDestinationBounds();
final Rect newPosition = mPipBoundsAlgorithm.getEntryDestinationBounds();
oldPosition.offset(0, -imeHeight);
assertBoundsInclusionWithMargin("offsetBounds by IME", oldPosition, newPosition);
@@ -265,11 +265,11 @@ public class PipBoundsHandlerTest extends ShellTestCase {
@Test
public void getEntryDestinationBounds_noReentryState_useDefaultBounds() {
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
final Rect defaultBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect defaultBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
mPipBoundsState.clearReentryState();
final Rect actualBounds = mPipBoundsHandler.getEntryDestinationBounds();
final Rect actualBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
assertBoundsInclusionWithMargin("useDefaultBounds", defaultBounds, actualBounds);
}

View File

@@ -65,7 +65,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
private PipTaskOrganizer mSpiedPipTaskOrganizer;
@Mock private DisplayController mMockdDisplayController;
@Mock private PipBoundsHandler mMockPipBoundsHandler;
@Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
@Mock private PipMenuActivityController mMenuActivityController;
@Mock private PipSurfaceTransactionHelper mMockPipSurfaceTransactionHelper;
@Mock private PipUiEventLogger mMockPipUiEventLogger;
@@ -83,7 +83,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
mComponent2 = new ComponentName(mContext, "component2");
mPipBoundsState = new PipBoundsState(mContext);
mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipBoundsState,
mMockPipBoundsHandler, mMenuActivityController, mMockPipSurfaceTransactionHelper,
mMockPipBoundsAlgorithm, mMenuActivityController, mMockPipSurfaceTransactionHelper,
mMockOptionalSplitScreen, mMockdDisplayController, mMockPipUiEventLogger,
mMockShellTaskOrganizer));
preparePipTaskOrg();
@@ -192,8 +192,8 @@ public class PipTaskOrganizerTest extends ShellTestCase {
private void preparePipTaskOrg() {
final DisplayInfo info = new DisplayInfo();
mPipBoundsState.setDisplayInfo(info);
when(mMockPipBoundsHandler.getEntryDestinationBounds()).thenReturn(new Rect());
when(mMockPipBoundsHandler.getAdjustedDestinationBounds(any(), anyFloat()))
when(mMockPipBoundsAlgorithm.getEntryDestinationBounds()).thenReturn(new Rect());
when(mMockPipBoundsAlgorithm.getAdjustedDestinationBounds(any(), anyFloat()))
.thenReturn(new Rect());
mPipBoundsState.setDisplayInfo(info);
mSpiedPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA);

View File

@@ -40,7 +40,7 @@ import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.pip.PipBoundsHandler;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipTaskOrganizer;
@@ -63,7 +63,7 @@ public class PipControllerTest extends ShellTestCase {
@Mock private DisplayController mMockDisplayController;
@Mock private PipMenuActivityController mMockPipMenuActivityController;
@Mock private PipAppOpsListener mMockPipAppOpsListener;
@Mock private PipBoundsHandler mMockPipBoundsHandler;
@Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
@Mock private PipMediaController mMockPipMediaController;
@Mock private PipTaskOrganizer mMockPipTaskOrganizer;
@Mock private PipTouchHandler mMockPipTouchHandler;
@@ -76,7 +76,7 @@ public class PipControllerTest extends ShellTestCase {
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
mPipController = new PipController(mContext, mMockDisplayController,
mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState,
mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipBoundsState,
mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer,
mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockTaskStackListener,
mMockExecutor);
@@ -109,7 +109,7 @@ public class PipControllerTest extends ShellTestCase {
when(spyContext.getPackageManager()).thenReturn(mockPackageManager);
assertNull(PipController.create(spyContext, mMockDisplayController,
mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipBoundsState,
mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipBoundsState,
mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer,
mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockTaskStackListener,
mMockExecutor));

View File

@@ -33,7 +33,7 @@ import androidx.test.filters.SmallTest;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.pip.PipBoundsHandler;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
@@ -72,7 +72,7 @@ public class PipTouchHandlerTest extends ShellTestCase {
private PipUiEventLogger mPipUiEventLogger;
private PipBoundsState mPipBoundsState;
private PipBoundsHandler mPipBoundsHandler;
private PipBoundsAlgorithm mPipBoundsAlgorithm;
private PipSnapAlgorithm mPipSnapAlgorithm;
private PipMotionHelper mMotionHelper;
private PipResizeGestureHandler mPipResizeGestureHandler;
@@ -89,12 +89,12 @@ public class PipTouchHandlerTest extends ShellTestCase {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mPipBoundsState = new PipBoundsState(mContext);
mPipBoundsHandler = new PipBoundsHandler(mContext, mPipBoundsState);
mPipSnapAlgorithm = mPipBoundsHandler.getSnapAlgorithm();
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState);
mPipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm();
mPipSnapAlgorithm = new PipSnapAlgorithm(mContext);
mPipTouchHandler = new PipTouchHandler(mContext, mPipMenuActivityController,
mPipBoundsHandler, mPipBoundsState, mPipTaskOrganizer, mFloatingContentCoordinator,
mPipUiEventLogger);
mPipBoundsAlgorithm, mPipBoundsState, mPipTaskOrganizer,
mFloatingContentCoordinator, mPipUiEventLogger);
mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper());
mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler());
mPipTouchHandler.setPipMotionHelper(mMotionHelper);

View File

@@ -24,7 +24,7 @@ import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipBoundsHandler;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
@@ -51,7 +51,7 @@ public abstract class TvPipModule {
static Optional<Pip> providePip(
Context context,
PipBoundsState pipBoundsState,
PipBoundsHandler pipBoundsHandler,
PipBoundsAlgorithm pipBoundsAlgorithm,
PipTaskOrganizer pipTaskOrganizer,
PipMediaController pipMediaController,
PipNotification pipNotification,
@@ -61,7 +61,7 @@ public abstract class TvPipModule {
new PipController(
context,
pipBoundsState,
pipBoundsHandler,
pipBoundsAlgorithm,
pipTaskOrganizer,
pipMediaController,
pipNotification,
@@ -91,9 +91,9 @@ public abstract class TvPipModule {
@WMSingleton
@Provides
static PipBoundsHandler providePipBoundsHandler(Context context,
static PipBoundsAlgorithm providePipBoundsHandler(Context context,
PipBoundsState pipBoundsState) {
return new PipBoundsHandler(context, pipBoundsState);
return new PipBoundsAlgorithm(context, pipBoundsState);
}
@WMSingleton
@@ -106,11 +106,11 @@ public abstract class TvPipModule {
@Provides
static PipTaskOrganizer providePipTaskOrganizer(Context context,
PipBoundsState pipBoundsState,
PipBoundsHandler pipBoundsHandler,
PipBoundsAlgorithm pipBoundsAlgorithm,
PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
Optional<SplitScreen> splitScreenOptional, DisplayController displayController,
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer) {
return new PipTaskOrganizer(context, pipBoundsState, pipBoundsHandler,
return new PipTaskOrganizer(context, pipBoundsState, pipBoundsAlgorithm,
null /* menuActivityController */, pipSurfaceTransactionHelper, splitScreenOptional,
displayController, pipUiEventLogger, shellTaskOrganizer);
}

View File

@@ -33,7 +33,7 @@ import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipBoundsHandler;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
@@ -82,13 +82,13 @@ public class WMShellModule {
@WMSingleton
@Provides
static Optional<Pip> providePip(Context context, DisplayController displayController,
PipAppOpsListener pipAppOpsListener, PipBoundsHandler pipBoundsHandler,
PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
PipBoundsState pipBoundsState, PipMediaController pipMediaController,
PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer,
PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper,
TaskStackListenerImpl taskStackListener, ShellExecutor mainExecutor) {
return Optional.ofNullable(PipController.create(context, displayController,
pipAppOpsListener, pipBoundsHandler, pipBoundsState, pipMediaController,
pipAppOpsListener, pipBoundsAlgorithm, pipBoundsState, pipMediaController,
pipMenuActivityController, pipTaskOrganizer, pipTouchHandler,
windowManagerShellWrapper, taskStackListener, mainExecutor));
}
@@ -101,9 +101,9 @@ public class WMShellModule {
@WMSingleton
@Provides
static PipBoundsHandler providesPipBoundsHandler(Context context,
static PipBoundsAlgorithm providesPipBoundsHandler(Context context,
PipBoundsState pipBoundsState) {
return new PipBoundsHandler(context, pipBoundsState);
return new PipBoundsAlgorithm(context, pipBoundsState);
}
@WMSingleton
@@ -116,12 +116,12 @@ public class WMShellModule {
@WMSingleton
@Provides
static PipTouchHandler providePipTouchHandler(Context context,
PipMenuActivityController menuActivityController, PipBoundsHandler pipBoundsHandler,
PipMenuActivityController menuActivityController, PipBoundsAlgorithm pipBoundsAlgorithm,
PipBoundsState pipBoundsState,
PipTaskOrganizer pipTaskOrganizer,
FloatingContentCoordinator floatingContentCoordinator,
PipUiEventLogger pipUiEventLogger) {
return new PipTouchHandler(context, menuActivityController, pipBoundsHandler,
return new PipTouchHandler(context, menuActivityController, pipBoundsAlgorithm,
pipBoundsState, pipTaskOrganizer, floatingContentCoordinator, pipUiEventLogger);
}
@@ -129,12 +129,12 @@ public class WMShellModule {
@Provides
static PipTaskOrganizer providePipTaskOrganizer(Context context,
PipBoundsState pipBoundsState,
PipBoundsHandler pipBoundsHandler,
PipBoundsAlgorithm pipBoundsAlgorithm,
PipMenuActivityController menuActivityController,
PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
Optional<SplitScreen> splitScreenOptional, DisplayController displayController,
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer) {
return new PipTaskOrganizer(context, pipBoundsState, pipBoundsHandler,
return new PipTaskOrganizer(context, pipBoundsState, pipBoundsAlgorithm,
menuActivityController, pipSurfaceTransactionHelper, splitScreenOptional,
displayController, pipUiEventLogger, shellTaskOrganizer);
}