From 67959b765de0c6db2ed4aa26e68ce028753c64cb Mon Sep 17 00:00:00 2001 From: "jorgegil@google.com" Date: Mon, 9 Nov 2020 15:00:43 -0800 Subject: [PATCH] Rename PipBoundsHandler to PipBoundsAlgorithm Now that all state handling has been moved out of PipBoundsHandler, this CL renames it to PipBoundsAlgorithm and cleans up its public API so that it functions more like an utility to calculate several types of "bounds" related to PIP such as: - Default bounds - Normal bounds - Movemement bounds - Entry bounds - Bounds adjusted to aspect ratio - Inset bounds PipBoundsAlgorithm's is then only responsible for calculating such bounds based on the current state of PIP (owned by PipBoundsState) but it no longer owns or manages the state, as that would be the responsability of its users (e.g PipController). Bug: 169373982 Test: atest com.android.wm.shell.pip Change-Id: I67c3004b60069160f82d7c3d00d8c3995c0c5f80 --- ...dsHandler.java => PipBoundsAlgorithm.java} | 175 ++++-------------- .../wm/shell/pip/PipTaskOrganizer.java | 18 +- .../wm/shell/pip/phone/PipController.java | 130 +++++++++++-- .../pip/phone/PipResizeGestureHandler.java | 10 +- .../wm/shell/pip/phone/PipTouchHandler.java | 43 ++--- .../wm/shell/pip/tv/PipController.java | 17 +- ...rTest.java => PipBoundsAlgorithmTest.java} | 50 ++--- .../wm/shell/pip/PipTaskOrganizerTest.java | 8 +- .../wm/shell/pip/phone/PipControllerTest.java | 8 +- .../shell/pip/phone/PipTouchHandlerTest.java | 12 +- .../android/systemui/wmshell/TvPipModule.java | 14 +- .../systemui/wmshell/WMShellModule.java | 18 +- 12 files changed, 253 insertions(+), 250 deletions(-) rename libs/WindowManager/Shell/src/com/android/wm/shell/pip/{PipBoundsHandler.java => PipBoundsAlgorithm.java} (63%) rename libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/{PipBoundsHandlerTest.java => PipBoundsAlgorithmTest.java} (83%) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java similarity index 63% rename from libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java rename to libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java index ca16cfc5141bd..df6683ebb80b2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java @@ -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); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index a095fb525d24c..7cc2a419354ed 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -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 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(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 8e48229ca4bb5..1f67d2c748e0c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -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); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java index 124683e2ff375..4849e0ddb6f7d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java @@ -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 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, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index b8d6b3cab8839..d8cab8eeab138 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -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; @@ -162,7 +162,7 @@ public class PipTouchHandler { @SuppressLint("InflateParams") public PipTouchHandler(Context context, PipMenuActivityController menuController, - PipBoundsHandler pipBoundsHandler, + PipBoundsAlgorithm pipBoundsAlgorithm, @NonNull PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer, FloatingContentCoordinator floatingContentCoordinator, @@ -170,15 +170,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, @@ -194,7 +195,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; @@ -314,7 +315,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) { @@ -346,13 +347,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 */); } @@ -360,11 +361,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()); @@ -385,7 +386,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 @@ -396,7 +397,7 @@ public class PipTouchHandler { if (isExpanded) { curBounds.set(mExpandedBounds); - mPipBoundsHandler.getSnapAlgorithm().applySnapFraction(curBounds, + mPipBoundsAlgorithm.getSnapAlgorithm().applySnapFraction(curBounds, toMovementBounds, mSavedSnapFraction); } @@ -659,7 +660,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 */); @@ -719,7 +720,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 @@ -869,19 +870,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; } @@ -922,7 +923,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); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java index fd055d1a6685b..940438049f49a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java @@ -53,7 +53,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; @@ -110,7 +110,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; @@ -206,9 +206,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()); + } }); } @@ -225,7 +228,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac public PipController(Context context, PipBoundsState pipBoundsState, - PipBoundsHandler pipBoundsHandler, + PipBoundsAlgorithm pipBoundsAlgorithm, PipTaskOrganizer pipTaskOrganizer, PipMediaController pipMediaController, PipNotification pipNotification, @@ -234,7 +237,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 diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java similarity index 83% rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java index ba60d3d03f99f..7a6e0c1b41fc3 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java @@ -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); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java index 08841bd2b1b2e..8d3774cee1e0c 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java @@ -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); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java index 745d18804f0ba..88c8eb902a6f1 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java @@ -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)); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java index 94f30511ebbf8..ec02331d9870d 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java @@ -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); diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java index 694b4a03fa64e..86ba5f1f74a9d 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java @@ -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 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 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); } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java index 1cdec27af8703..e9c4b0b398c89 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java @@ -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 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 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); }