Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 448e8d4c authored by jorgegil@google.com's avatar jorgegil@google.com
Browse files

Move display state into PipBoundsState

Migrates more state out of PipBoundsHandler as an effort
to split it into a state holder (PipBoundsState) and a
bounds calculating util.

Bug: 169373982
Test: atest com.android.wm.shell.pip
Change-Id: I37ab29c988be519a074ec260163632df3060efc4
parent 51b7fea9
Loading
Loading
Loading
Loading
+22 −62
Original line number Diff line number Diff line
@@ -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);
+42 −0
Original line number Diff line number Diff line
@@ -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 {
+3 −4
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.pip.phone.PipMenuActivityController;
import com.android.wm.shell.pip.phone.PipMotionHelper;
import com.android.wm.shell.pip.phone.PipUpdateThread;
import com.android.wm.shell.pip.phone.PipUtils;
import com.android.wm.shell.splitscreen.SplitScreen;

import java.io.PrintWriter;
@@ -378,7 +377,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)
@@ -488,7 +487,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);
        }
@@ -802,7 +801,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;
        }
+8 −6
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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,
Loading