Merge "Move display state into PipBoundsState"

This commit is contained in:
Jorge Gil
2020-10-23 21:43:01 +00:00
committed by Android (Google) Code Review
8 changed files with 88 additions and 77 deletions

View File

@@ -34,13 +34,10 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.util.TypedValue;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.window.WindowContainerTransaction;
import com.android.wm.shell.common.DisplayLayout;
import java.io.PrintWriter;
/**
@@ -54,8 +51,6 @@ public class PipBoundsHandler {
private final @NonNull PipBoundsState mPipBoundsState;
private final PipSnapAlgorithm mSnapAlgorithm;
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private DisplayLayout mDisplayLayout;
private float mDefaultAspectRatio;
private float mMinAspectRatio;
@@ -74,7 +69,6 @@ public class PipBoundsHandler {
public PipBoundsHandler(Context context, @NonNull PipBoundsState pipBoundsState) {
mPipBoundsState = pipBoundsState;
mSnapAlgorithm = new PipSnapAlgorithm(context);
mDisplayLayout = new DisplayLayout();
reloadResources(context);
// Initialize the aspect ratio to the default aspect ratio. Don't do this in reload
// resources as it would clobber mAspectRatio when entering PiP from fullscreen which
@@ -108,22 +102,6 @@ public class PipBoundsHandler {
com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
}
/**
* Sets or update latest {@link DisplayLayout} when new display added or rotation callbacks
* from {@link DisplayController.OnDisplaysChangedListener}
* @param newDisplayLayout latest {@link DisplayLayout}
*/
public void setDisplayLayout(DisplayLayout newDisplayLayout) {
mDisplayLayout.set(newDisplayLayout);
}
/**
* Get the current saved display info.
*/
public DisplayInfo getDisplayInfo() {
return mDisplayInfo;
}
/**
* Update the Min edge size for {@link PipSnapAlgorithm} to calculate corresponding bounds
* @param minEdgeSize
@@ -160,7 +138,7 @@ public class PipBoundsHandler {
* 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, DisplayInfo displayInfo) {
Rect animatingBounds) {
getInsetBounds(insetBounds);
final Rect defaultBounds = getDefaultBounds(INVALID_SNAP_FRACTION, null);
normalBounds.set(defaultBounds);
@@ -171,7 +149,6 @@ public class PipBoundsHandler {
transformBoundsToAspectRatio(normalBounds, mPipBoundsState.getAspectRatio(),
false /* useCurrentMinEdgeSize */, false /* useCurrentSize */);
}
displayInfo.copyFrom(mDisplayInfo);
}
/**
@@ -182,23 +159,6 @@ public class PipBoundsHandler {
return mSnapAlgorithm;
}
public Rect getDisplayBounds() {
return new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
}
public int getDisplayRotation() {
return mDisplayInfo.rotation;
}
/**
* Responds to IPinnedStackListener on {@link DisplayInfo} change.
* It will normally follow up with a
* {@link #onMovementBoundsChanged(Rect, Rect, Rect, DisplayInfo)} callback.
*/
public void onDisplayInfoChanged(DisplayInfo displayInfo) {
mDisplayInfo.copyFrom(displayInfo);
}
/**
* Responds to IPinnedStackListener on configuration change.
*/
@@ -250,10 +210,6 @@ public class PipBoundsHandler {
return mDefaultAspectRatio;
}
public void onOverlayChanged(Context context, Display display) {
mDisplayLayout = new DisplayLayout(context, display);
}
/**
* 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
@@ -262,13 +218,13 @@ public class PipBoundsHandler {
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
mDisplayLayout.rotateTo(context.getResources(), toRotation);
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.
mDisplayInfo.rotation = toRotation;
mPipBoundsState.setDisplayRotation(toRotation);
updateDisplayInfoIfNeeded();
}
@@ -282,7 +238,8 @@ public class PipBoundsHandler {
Rect outInsetBounds,
int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) {
// Bail early if the event is not sent to current {@link #mDisplayInfo}
if ((displayId != mDisplayInfo.displayId) || (fromRotation == toRotation)) {
if ((displayId != mPipBoundsState.getDisplayInfo().displayId)
|| (fromRotation == toRotation)) {
return false;
}
@@ -302,13 +259,13 @@ public class PipBoundsHandler {
final float snapFraction = getSnapFraction(postChangeStackBounds);
// Update the display layout
mDisplayLayout.rotateTo(context.getResources(), toRotation);
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.
mDisplayInfo.rotation = toRotation;
mPipBoundsState.getDisplayInfo().rotation = toRotation;
updateDisplayInfoIfNeeded();
// Calculate the stack bounds in the new orientation based on same fraction along the
@@ -325,16 +282,17 @@ public class PipBoundsHandler {
}
private void updateDisplayInfoIfNeeded() {
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
final boolean updateNeeded;
if ((mDisplayInfo.rotation == ROTATION_0) || (mDisplayInfo.rotation == ROTATION_180)) {
updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight);
if ((displayInfo.rotation == ROTATION_0) || (displayInfo.rotation == ROTATION_180)) {
updateNeeded = (displayInfo.logicalWidth > displayInfo.logicalHeight);
} else {
updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight);
updateNeeded = (displayInfo.logicalWidth < displayInfo.logicalHeight);
}
if (updateNeeded) {
final int newLogicalHeight = mDisplayInfo.logicalWidth;
mDisplayInfo.logicalWidth = mDisplayInfo.logicalHeight;
mDisplayInfo.logicalHeight = newLogicalHeight;
final int newLogicalHeight = displayInfo.logicalWidth;
displayInfo.logicalWidth = displayInfo.logicalHeight;
displayInfo.logicalHeight = newLogicalHeight;
}
}
@@ -370,8 +328,9 @@ public class PipBoundsHandler {
size = mSnapAlgorithm.getSizeForAspectRatio(
new Size(stackBounds.width(), stackBounds.height()), aspectRatio, minEdgeSize);
} else {
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, minEdgeSize,
mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
displayInfo.logicalWidth, displayInfo.logicalHeight);
}
final int left = (int) (stackBounds.centerX() - size.getWidth() / 2f);
@@ -421,8 +380,9 @@ public class PipBoundsHandler {
} else {
final Rect insetBounds = new Rect();
getInsetBounds(insetBounds);
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
mDefaultMinSize, displayInfo.logicalWidth, displayInfo.logicalHeight);
Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
0, Math.max(mIsImeShowing ? mImeHeight : 0,
mIsShelfShowing ? mShelfHeight : 0),
@@ -435,11 +395,12 @@ public class PipBoundsHandler {
* Populates the bounds on the screen that the PIP can be visible in.
*/
protected void getInsetBounds(Rect outRect) {
Rect insets = mDisplayLayout.stableInsets();
final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
Rect insets = mPipBoundsState.getDisplayLayout().stableInsets();
outRect.set(insets.left + mScreenEdgeInsets.x,
insets.top + mScreenEdgeInsets.y,
mDisplayInfo.logicalWidth - insets.right - mScreenEdgeInsets.x,
mDisplayInfo.logicalHeight - insets.bottom - mScreenEdgeInsets.y);
displayInfo.logicalWidth - insets.right - mScreenEdgeInsets.x,
displayInfo.logicalHeight - insets.bottom - mScreenEdgeInsets.y);
}
/**
@@ -493,7 +454,6 @@ public class PipBoundsHandler {
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + TAG);
pw.println(innerPrefix + "mDisplayInfo=" + mDisplayInfo);
pw.println(innerPrefix + "mDefaultAspectRatio=" + mDefaultAspectRatio);
pw.println(innerPrefix + "mMinAspectRatio=" + mMinAspectRatio);
pw.println(innerPrefix + "mMaxAspectRatio=" + mMaxAspectRatio);

View File

@@ -21,8 +21,10 @@ import android.annotation.Nullable;
import android.content.ComponentName;
import android.graphics.Rect;
import android.util.Size;
import android.view.DisplayInfo;
import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.common.DisplayLayout;
import java.io.PrintWriter;
import java.util.Objects;
@@ -37,6 +39,8 @@ public final class PipBoundsState {
private float mAspectRatio;
private PipReentryState mPipReentryState;
private ComponentName mLastPipComponentName;
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private final DisplayLayout mDisplayLayout = new DisplayLayout();
void setBounds(@NonNull Rect bounds) {
mBounds.set(bounds);
@@ -88,6 +92,42 @@ public final class PipBoundsState {
return mLastPipComponentName;
}
@NonNull
public DisplayInfo getDisplayInfo() {
return mDisplayInfo;
}
/**
* Update the display info.
*/
public void setDisplayInfo(@NonNull DisplayInfo displayInfo) {
mDisplayInfo.copyFrom(displayInfo);
}
public void setDisplayRotation(int rotation) {
mDisplayInfo.rotation = rotation;
}
/**
* Returns the display's bound.
*/
@NonNull
public Rect getDisplayBounds() {
return new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
}
/**
* Update the display layout.
*/
public void setDisplayLayout(@NonNull DisplayLayout displayLayout) {
mDisplayLayout.set(displayLayout);
}
@NonNull
public DisplayLayout getDisplayLayout() {
return mDisplayLayout;
}
@VisibleForTesting
void clearReentryState() {
mPipReentryState = null;
@@ -130,6 +170,8 @@ public final class PipBoundsState {
pw.println(innerPrefix + "mBounds=" + mBounds);
pw.println(innerPrefix + "mLastPipComponentName=" + mLastPipComponentName);
pw.println(innerPrefix + "mAspectRatio=" + mAspectRatio);
pw.println(innerPrefix + "mDisplayInfo=" + mDisplayInfo);
pw.println(innerPrefix + "mDisplayLayout=" + mDisplayLayout);
if (mPipReentryState == null) {
pw.println(innerPrefix + "mPipReentryState=null");
} else {

View File

@@ -380,7 +380,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mPipUiEventLoggerLogger.log(
PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN);
final boolean orientationDiffers = initialConfig.windowConfiguration.getRotation()
!= mPipBoundsHandler.getDisplayRotation();
!= mPipBoundsState.getDisplayInfo().rotation;
final WindowContainerTransaction wct = new WindowContainerTransaction();
final Rect destinationBounds = initialConfig.windowConfiguration.getBounds();
final int direction = syncWithSplitScreenBounds(destinationBounds)
@@ -490,7 +490,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
// If the displayId of the task is different than what PipBoundsHandler has, then update
// it. This is possible if we entered PiP on an external display.
if (info.displayId != mPipBoundsHandler.getDisplayInfo().displayId
if (info.displayId != mPipBoundsState.getDisplayInfo().displayId
&& mOnDisplayIdChangeCallback != null) {
mOnDisplayIdChangeCallback.accept(info.displayId);
}
@@ -811,7 +811,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
final Rect currentDestinationBounds = animator.getDestinationBounds();
destinationBoundsOut.set(currentDestinationBounds);
if (!fromImeAdjustment && !fromShelfAdjustment
&& mPipBoundsHandler.getDisplayBounds().contains(currentDestinationBounds)) {
&& mPipBoundsState.getDisplayBounds().contains(currentDestinationBounds)) {
// no need to update the destination bounds, bail early
return;
}

View File

@@ -44,6 +44,7 @@ import androidx.annotation.Nullable;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayChangeController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipBoundsHandler;
@@ -136,7 +137,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
@Override
public void onDisplayAdded(int displayId) {
mPipBoundsHandler.setDisplayLayout(
mPipBoundsState.setDisplayLayout(
mDisplayController.getDisplayLayout(displayId));
}
};
@@ -184,7 +185,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
@Override
public void onDisplayInfoChanged(DisplayInfo displayInfo) {
mHandler.post(() -> mPipBoundsHandler.onDisplayInfoChanged(displayInfo));
mHandler.post(() -> mPipBoundsState.setDisplayInfo(displayInfo));
}
@Override
@@ -233,7 +234,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
mPipTaskOrganizer.registerOnDisplayIdChangeCallback((int displayId) -> {
final DisplayInfo newDisplayInfo = new DisplayInfo();
displayController.getDisplay(displayId).getDisplayInfo(newDisplayInfo);
mPipBoundsHandler.onDisplayInfoChanged(newDisplayInfo);
mPipBoundsState.setDisplayInfo(newDisplayInfo);
updateMovementBounds(null /* toBounds */, false /* fromRotation */,
false /* fromImeAdjustment */, false /* fromShelfAdustment */,
null /* wct */);
@@ -249,7 +250,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
// listener calls back
final DisplayInfo displayInfo = new DisplayInfo();
context.getDisplay().getDisplayInfo(displayInfo);
mPipBoundsHandler.onDisplayInfoChanged(displayInfo);
mPipBoundsState.setDisplayInfo(displayInfo);
try {
mWindowManagerShellWrapper.addPinnedStackListener(
@@ -298,7 +299,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
@Override
public void onOverlayChanged() {
mHandler.post(() -> {
mPipBoundsHandler.onOverlayChanged(mContext, mContext.getDisplay());
mPipBoundsState.setDisplayLayout(new DisplayLayout(mContext, mContext.getDisplay()));
updateMovementBounds(null /* toBounds */,
false /* fromRotation */, false /* fromImeAdjustment */,
false /* fromShelfAdjustment */,
@@ -443,8 +444,9 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
// Populate inset / normal bounds and DisplayInfo from mPipBoundsHandler before
// passing to mTouchHandler/mPipTaskOrganizer
final Rect outBounds = new Rect(toBounds);
mTmpDisplayInfo.copyFrom(mPipBoundsState.getDisplayInfo());
mPipBoundsHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds,
outBounds, mTmpDisplayInfo);
outBounds);
// mTouchHandler would rely on the bounds populated from mPipTaskOrganizer
mPipTaskOrganizer.onMovementBoundsChanged(outBounds, fromRotation, fromImeAdjustment,
fromShelfAdjustment, wct);

View File

@@ -783,8 +783,8 @@ public class PipTouchHandler {
// If User releases the PIP window while it's out of the display bounds, put
// PIP into stashed mode.
if (mEnableStash
&& (animatingBounds.right > mPipBoundsHandler.getDisplayBounds().right
|| animatingBounds.left < mPipBoundsHandler.getDisplayBounds().left)) {
&& (animatingBounds.right > mPipBoundsState.getDisplayBounds().right
|| animatingBounds.left < mPipBoundsState.getDisplayBounds().left)) {
mMotionHelper.stashToEdge(vel.x, vel.y, this::flingEndAction /* endAction */);
} else {
mMotionHelper.flingToSnapTarget(vel.x, vel.y,

View File

@@ -54,6 +54,7 @@ import com.android.wm.shell.WindowManagerShellWrapper;
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.PipBoundsState;
import com.android.wm.shell.pip.PipTaskOrganizer;
import java.util.ArrayList;
@@ -106,6 +107,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
private int mSuspendPipResizingReason;
private Context mContext;
private PipBoundsState mPipBoundsState;
private PipBoundsHandler mPipBoundsHandler;
private PipTaskOrganizer mPipTaskOrganizer;
private IActivityTaskManager mActivityTaskManager;
@@ -208,9 +210,10 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
@Override
public void onMovementBoundsChanged(boolean fromImeAdjustment) {
mHandler.post(() -> {
// Populate the inset / normal bounds and DisplayInfo from mPipBoundsHandler first.
mTmpDisplayInfo.copyFrom(mPipBoundsState.getDisplayInfo());
// Populate the inset / normal bounds from mPipBoundsHandler first.
mPipBoundsHandler.onMovementBoundsChanged(mTmpInsetBounds, mPipBounds,
mDefaultPipBounds, mTmpDisplayInfo);
mDefaultPipBounds);
});
}
@@ -226,6 +229,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
}
public PipController(Context context,
PipBoundsState pipBoundsState,
PipBoundsHandler pipBoundsHandler,
PipTaskOrganizer pipTaskOrganizer,
WindowManagerShellWrapper windowManagerShellWrapper
@@ -233,13 +237,14 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
if (!mInitialized) {
mInitialized = true;
mContext = context;
mPipBoundsState = pipBoundsState;
mPipNotification = new PipNotification(context, this);
mPipBoundsHandler = pipBoundsHandler;
// Ensure that we have the display info in case we get calls to update the bounds
// before the listener calls back
final DisplayInfo displayInfo = new DisplayInfo();
context.getDisplay().getDisplayInfo(displayInfo);
mPipBoundsHandler.onDisplayInfoChanged(displayInfo);
mPipBoundsState.setDisplayInfo(displayInfo);
mResizeAnimationDuration = context.getResources()
.getInteger(R.integer.config_pipResizeAnimationDuration);

View File

@@ -65,7 +65,7 @@ public class PipBoundsHandlerTest extends PipTestCase {
mPipBoundsState = new PipBoundsState();
mPipBoundsHandler = new PipBoundsHandler(mContext, mPipBoundsState);
mPipBoundsHandler.onDisplayInfoChanged(mDefaultDisplayInfo);
mPipBoundsState.setDisplayInfo(mDefaultDisplayInfo);
}
private void initializeMockResources() {

View File

@@ -50,12 +50,14 @@ public abstract class TvPipModule {
@Provides
static Optional<Pip> providePip(
Context context,
PipBoundsState pipBoundsState,
PipBoundsHandler pipBoundsHandler,
PipTaskOrganizer pipTaskOrganizer,
WindowManagerShellWrapper windowManagerShellWrapper) {
return Optional.of(
new PipController(
context,
pipBoundsState,
pipBoundsHandler,
pipTaskOrganizer,
windowManagerShellWrapper));