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

Commit a50a0106 authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

Update PiP on display change

Dispatch OnDisplayChangingListeners upon
any display change in requestStartTransition().

Make sure any display changes with PiP present
also update the PiP bounds and cache relevant information
for future interactions (e.g. boundary conditions).

Bug: 359336365
Flag: com.android.wm.shell.enable_pip2_implementation
Test: fold/unfold while in PiP
Change-Id: I8970576cae758272687c56eb5c43065752006329
parent ddbbcaed
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -115,8 +115,11 @@ public final class TransitionRequestInfo implements Parcelable {
    @DataClass(genToString = true, genSetters = true, genBuilder = false, genConstructor = false)
    public static final class DisplayChange implements Parcelable {
        private final int mDisplayId;

        // If non-null, these bounds changes should ignore any potential rotation changes.
        @Nullable private Rect mStartAbsBounds = null;
        @Nullable private Rect mEndAbsBounds = null;

        private int mStartRotation = WindowConfiguration.ROTATION_UNDEFINED;
        private int mEndRotation = WindowConfiguration.ROTATION_UNDEFINED;
        private boolean mPhysicalDisplayChanged = false;
+10 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Size;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -193,8 +194,8 @@ public class DisplayController {


    /** Called when a display rotate requested. */
    public void onDisplayRotateRequested(WindowContainerTransaction wct, int displayId,
            int fromRotation, int toRotation) {
    public void onDisplayChangeRequested(WindowContainerTransaction wct, int displayId,
            Rect startAbsBounds, Rect endAbsBounds, int fromRotation, int toRotation) {
        synchronized (mDisplays) {
            final DisplayRecord dr = mDisplays.get(displayId);
            if (dr == null) {
@@ -203,6 +204,13 @@ public class DisplayController {
            }

            if (dr.mDisplayLayout != null) {
                if (endAbsBounds != null) {
                    // If there is a change in the display dimensions update the layout as well;
                    // note that endAbsBounds should ignore any potential rotation changes, so
                    // we still need to rotate the layout after if needed.
                    dr.mDisplayLayout.resizeTo(dr.mContext.getResources(),
                            new Size(endAbsBounds.width(), endAbsBounds.height()));
                }
                dr.mDisplayLayout.rotateTo(dr.mContext.getResources(), toRotation);
            }

+11 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.graphics.Rect;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Size;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
@@ -244,6 +245,16 @@ public class DisplayLayout {
        recalcInsets(res);
    }

    /**
     * Update the dimensions of this layout.
     */
    public void resizeTo(Resources res, Size displaySize) {
        mWidth = displaySize.getWidth();
        mHeight = displaySize.getHeight();

        recalcInsets(res);
    }

    /** Get this layout's non-decor insets. */
    public Rect nonDecorInsets() {
        return mNonDecorInsets;
+18 −25
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.InsetsState;
import android.view.SurfaceControl;
import android.window.DisplayAreaInfo;
import android.window.WindowContainerTransaction;
@@ -200,16 +199,7 @@ public class PipController implements ConfigurationChangeListener,
        DisplayLayout layout = new DisplayLayout(mContext, mContext.getDisplay());
        mPipDisplayLayoutState.setDisplayLayout(layout);

        mDisplayController.addDisplayWindowListener(this);
        mDisplayController.addDisplayChangingController(this);
        mDisplayInsetsController.addInsetsChangedListener(mPipDisplayLayoutState.getDisplayId(),
                new DisplayInsetsController.OnInsetsChangedListener() {
                    @Override
                    public void insetsChanged(InsetsState insetsState) {
                        setDisplayLayout(mDisplayController
                                        .getDisplayLayout(mPipDisplayLayoutState.getDisplayId()));
                    }
                });
        mDisplayInsetsController.addInsetsChangedListener(mPipDisplayLayoutState.getDisplayId(),
                new ImeListener(mDisplayController, mPipDisplayLayoutState.getDisplayId()) {
                    @Override
@@ -285,34 +275,37 @@ public class PipController implements ConfigurationChangeListener,
        setDisplayLayout(mDisplayController.getDisplayLayout(displayId));
    }

    @Override
    public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
        if (displayId != mPipDisplayLayoutState.getDisplayId()) {
            return;
        }
        setDisplayLayout(mDisplayController.getDisplayLayout(displayId));
    }

    /**
     * A callback for any observed transition that contains a display change in its
     * {@link android.window.TransitionRequestInfo} with a non-zero rotation delta.
     * {@link android.window.TransitionRequestInfo},
     */
    @Override
    public void onDisplayChange(int displayId, int fromRotation, int toRotation,
            @Nullable DisplayAreaInfo newDisplayAreaInfo, WindowContainerTransaction t) {
        if (displayId != mPipDisplayLayoutState.getDisplayId()) {
            return;
        }
        final float snapFraction = mPipBoundsAlgorithm.getSnapFraction(mPipBoundsState.getBounds());
        final float boundsScale = mPipBoundsState.getBoundsScale();

        // Update the display layout caches even if we are not in PiP.
        setDisplayLayout(mDisplayController.getDisplayLayout(displayId));

        if (!mPipTransitionState.isInPip()) {
            return;
        }

        // Calculate the snap fraction pre-rotation.
        float snapFraction = mPipBoundsAlgorithm.getSnapFraction(mPipBoundsState.getBounds());
        mPipTouchHandler.updateMinMaxSize(mPipBoundsState.getAspectRatio());

        // Update the caches to reflect the new display layout and movement bounds.
        mPipDisplayLayoutState.rotateTo(toRotation);
        // Update the caches to reflect the new display layout in the movement bounds;
        // temporarily update bounds to be at the top left for the movement bounds calculation.
        Rect toBounds = new Rect(0, 0,
                (int) Math.ceil(mPipBoundsState.getMaxSize().x * boundsScale),
                (int) Math.ceil(mPipBoundsState.getMaxSize().y * boundsScale));
        mPipBoundsState.setBounds(toBounds);
        mPipTouchHandler.updateMovementBounds();

        // The policy is to keep PiP width, height and snap fraction invariant.
        Rect toBounds = mPipBoundsState.getBounds();
        // The policy is to keep PiP snap fraction invariant.
        mPipBoundsAlgorithm.applySnapFraction(toBounds, snapFraction);
        mPipBoundsState.setBounds(toBounds);
        t.setBounds(mPipTransitionState.mPipTaskToken, toBounds);
+6 −3
Original line number Diff line number Diff line
@@ -1183,12 +1183,15 @@ public class Transitions implements RemoteCallable<Transitions>,
            }
            if (request.getDisplayChange() != null) {
                TransitionRequestInfo.DisplayChange change = request.getDisplayChange();
                if (change.getEndRotation() != change.getStartRotation()) {
                    // Is a rotation, so dispatch to all displayChange listeners
                if (change.getStartRotation() != change.getEndRotation()
                        || (change.getStartAbsBounds() != null
                        && !change.getStartAbsBounds().equals(change.getEndAbsBounds()))) {
                    // Is a display change, so dispatch to all displayChange listeners
                    if (wct == null) {
                        wct = new WindowContainerTransaction();
                    }
                    mDisplayController.onDisplayRotateRequested(wct, change.getDisplayId(),
                    mDisplayController.onDisplayChangeRequested(wct, change.getDisplayId(),
                            change.getStartAbsBounds(), change.getEndAbsBounds(),
                            change.getStartRotation(), change.getEndRotation());
                }
            }