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

Commit 39b6f235 authored by Evan Rosky's avatar Evan Rosky
Browse files

Move some display logic into hierarchy [1/2]

Starting to decouple WM-side computation logic from specific
hierarchy levels in WM hierarchy. This means trying to make
helper functions in pinned/docked controllers and in TaskStack
more "static" by using parameters instead of mDisplayContent
references. The short-term purpose of this is to make it
easier to use this logic from the ATM hierarchy. Longer-term
the purpose is to make it possible to use the controller
logic at any level of the hierarchy.

Bug: 113900640
Test: go/wm-smoke + relevant am/wm servicestests
Change-Id: I7054a0d4d75862bb152bae9bc179a418a2dadffc
parent 67dd91e6
Loading
Loading
Loading
Loading
+30 −26
Original line number Diff line number Diff line
@@ -157,8 +157,8 @@ import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
import android.view.WindowManager;
import android.view.WindowManagerPolicyConstants.PointerEventListener;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ToBooleanFunction;
@@ -1525,7 +1525,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
        config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
        config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, config.uiMode, dw,
                dh, mDisplayId);
                dh, displayInfo.displayCutout, mDisplayId);
        config.densityDpi = displayInfo.logicalDensityDpi;

        config.colorMode =
@@ -1602,7 +1602,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    }

    private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh,
            int displayId) {
            DisplayCutout displayCutout, int displayId) {
        mTmpDisplayMetrics.setTo(mDisplayMetrics);
        final DisplayMetrics tmpDm = mTmpDisplayMetrics;
        final int unrotDw, unrotDh;
@@ -1614,22 +1614,22 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            unrotDh = dh;
        }
        int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh,
                displayId);
                displayCutout, displayId);
        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw,
                displayId);
                displayCutout, displayId);
        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh,
                displayId);
                displayCutout, displayId);
        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw,
                displayId);
                displayCutout, displayId);
        return sw;
    }

    private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
            DisplayMetrics dm, int dw, int dh, int displayId) {
            DisplayMetrics dm, int dw, int dh, DisplayCutout displayCutout, int displayId) {
        dm.noncompatWidthPixels = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
                displayId, mDisplayInfo.displayCutout);
                displayId, displayCutout);
        dm.noncompatHeightPixels = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation,
                uiMode, displayId, mDisplayInfo.displayCutout);
                uiMode, displayId, displayCutout);
        float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
        int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
        if (curSize == 0 || size < curSize) {
@@ -1667,24 +1667,24 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                unrotDw);
        int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode,
                displayId);
                displayInfo.displayCutout, displayId);
        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode,
                displayId);
                displayInfo.displayCutout, displayId);
        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode,
                displayId);
                displayInfo.displayCutout, displayId);
        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode,
                displayId);
                displayInfo.displayCutout, displayId);
        outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
        outConfig.screenLayout = sl;
    }

    private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh,
            int uiMode, int displayId) {
            int uiMode, DisplayCutout displayCutout, int displayId) {
        // Get the app screen size at this rotation.
        int w = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayId,
                mDisplayInfo.displayCutout);
                displayCutout);
        int h = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayId,
                mDisplayInfo.displayCutout);
                displayCutout);

        // Compute the screen layout size class for this rotation.
        int longSize = w;
@@ -1892,7 +1892,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        // update as a result of the config change.  We do this here to consolidate the flow between
        // changes when there is and is not a stack.
        if (!hasPinnedStack()) {
            mPinnedStackControllerLocked.onDisplayInfoChanged();
            mPinnedStackControllerLocked.onDisplayInfoChanged(getDisplayInfo());
        }
    }

@@ -2494,11 +2494,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo

    void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
        getBounds(mTmpRect, newRotation);
        rotateBounds(mTmpRect, oldRotation, newRotation, bounds);
    }

    void rotateBounds(Rect parentBounds, int oldRotation, int newRotation, Rect bounds) {
        // Compute a transform matrix to undo the coordinate space transformation,
        // and present the window at the same physical position it previously occupied.
        final int deltaRotation = deltaRotation(newRotation, oldRotation);
        createRotationMatrix(deltaRotation, mTmpRect.width(), mTmpRect.height(), mTmpMatrix);
        createRotationMatrix(
                deltaRotation, parentBounds.width(), parentBounds.height(), mTmpMatrix);

        mTmpRectF.set(bounds);
        mTmpMatrix.mapRect(mTmpRectF);
@@ -3426,27 +3430,27 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    }

    private void updateBounds() {
        calculateBounds(mTmpBounds);
        calculateBounds(mDisplayInfo, mTmpBounds);
        setBounds(mTmpBounds);
    }

    // Determines the current display bounds based on the current state
    private void calculateBounds(Rect out) {
    private void calculateBounds(DisplayInfo displayInfo, Rect out) {
        // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
        final int orientation = mDisplayInfo.rotation;
        boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
        final int rotation = displayInfo.rotation;
        boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
        final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
        final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
        int width = mDisplayInfo.logicalWidth;
        int width = displayInfo.logicalWidth;
        int left = (physWidth - width) / 2;
        int height = mDisplayInfo.logicalHeight;
        int height = displayInfo.logicalHeight;
        int top = (physHeight - height) / 2;
        out.set(left, top, left + width, top + height);
    }

    @Override
    public void getBounds(Rect out) {
        calculateBounds(out);
        calculateBounds(mDisplayInfo, out);
    }

    private void getBounds(Rect out, int orientation) {
+9 −8
Original line number Diff line number Diff line
@@ -171,7 +171,7 @@ public class DockedStackDividerController {
            final int orientation = mTmpRect2.width() <= mTmpRect2.height()
                    ? ORIENTATION_PORTRAIT
                    : ORIENTATION_LANDSCAPE;
            final int dockSide = getDockSide(mTmpRect, mTmpRect2, orientation);
            final int dockSide = getDockSide(mTmpRect, mTmpRect2, orientation, rotation);
            final int position = DockedDividerUtils.calculatePositionForBounds(mTmpRect, dockSide,
                    getContentWidth());

@@ -202,7 +202,7 @@ public class DockedStackDividerController {
     * @param orientation the origination of device
     * @return current docked side
     */
    int getDockSide(Rect bounds, Rect displayRect, int orientation) {
    int getDockSide(Rect bounds, Rect displayRect, int orientation, int rotation) {
        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            // Portrait mode, docked either at the top or the bottom.
            final int diff = (displayRect.bottom - bounds.bottom) - (bounds.top - displayRect.top);
@@ -211,7 +211,8 @@ public class DockedStackDividerController {
            } else if (diff < 0) {
                return DOCKED_BOTTOM;
            }
            return canPrimaryStackDockTo(DOCKED_TOP) ? DOCKED_TOP : DOCKED_BOTTOM;
            return canPrimaryStackDockTo(DOCKED_TOP, displayRect, rotation)
                    ? DOCKED_TOP : DOCKED_BOTTOM;
        } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // Landscape mode, docked either on the left or on the right.
            final int diff = (displayRect.right - bounds.right) - (bounds.left - displayRect.left);
@@ -220,7 +221,8 @@ public class DockedStackDividerController {
            } else if (diff < 0) {
                return DOCKED_RIGHT;
            }
            return canPrimaryStackDockTo(DOCKED_LEFT) ? DOCKED_LEFT : DOCKED_RIGHT;
            return canPrimaryStackDockTo(DOCKED_LEFT, displayRect, rotation)
                    ? DOCKED_LEFT : DOCKED_RIGHT;
        }
        return DOCKED_INVALID;
    }
@@ -463,10 +465,9 @@ public class DockedStackDividerController {
     * @param dockSide the side to see if it is valid
     * @return true if the side provided is valid
     */
    boolean canPrimaryStackDockTo(int dockSide) {
        final DisplayInfo di = mDisplayContent.getDisplayInfo();
        return mService.mPolicy.isDockSideAllowed(dockSide, mOriginalDockedSide, di.logicalWidth,
                di.logicalHeight, di.rotation);
    boolean canPrimaryStackDockTo(int dockSide, Rect parentRect, int rotation) {
        return mService.mPolicy.isDockSideAllowed(dockSide, mOriginalDockedSide,
                parentRect.width(), parentRect.height(), rotation);
    }

    void notifyDockedStackExistsChanged(boolean exists) {
+2 −2
Original line number Diff line number Diff line
@@ -314,8 +314,8 @@ class PinnedStackController {
     * onTaskStackBoundsChanged() to be called.  But we still should update our known display info
     * with the new state so that we can update SystemUI.
     */
    synchronized void onDisplayInfoChanged() {
        mDisplayInfo.copyFrom(mDisplayContent.getDisplayInfo());
    synchronized void onDisplayInfoChanged(DisplayInfo displayInfo) {
        mDisplayInfo.copyFrom(displayInfo);
        notifyMovementBoundsChanged(false /* fromImeAdjustment */, false /* fromShelfAdjustment */);
    }

+39 −29
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import android.util.EventLog;
import android.util.Slog;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -486,9 +487,11 @@ public class TaskStack extends WindowContainer<Task> implements
        mTmpRect2.set(getRawBounds());
        mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
        if (inSplitScreenPrimaryWindowingMode()) {
            repositionPrimarySplitScreenStackAfterRotation(mTmpRect2);
            snapDockedStackAfterRotation(mTmpRect2);
            final int newDockSide = getDockSide(mTmpRect2);
            final Configuration parentConfig = getParent().getConfiguration();
            repositionSplitScreenStackAfterRotation(parentConfig, true /* primary */, mTmpRect2);
            final DisplayCutout cutout = mDisplayContent.getDisplayInfo().displayCutout;
            snapDockedStackAfterRotation(parentConfig, cutout, mTmpRect2);
            final int newDockSide = getDockSide(mDisplayContent, parentConfig, mTmpRect2);

            // Update the dock create mode and clear the dock create bounds, these
            // might change after a rotation and the original values will be invalid.
@@ -513,23 +516,30 @@ public class TaskStack extends WindowContainer<Task> implements
     * Some primary split screen sides are not allowed by the policy. This method queries the policy
     * and moves the primary stack around if needed.
     *
     * @param inOutBounds the bounds of the primary stack to adjust
     * @param parentConfig the configuration of the stack's parent.
     * @param primary true if adjusting the primary docked stack, false for secondary.
     * @param inOutBounds the bounds of the stack to adjust.
     */
    private void repositionPrimarySplitScreenStackAfterRotation(Rect inOutBounds) {
        int dockSide = getDockSide(inOutBounds);
        if (mDisplayContent.getDockedDividerController().canPrimaryStackDockTo(dockSide)) {
    void repositionSplitScreenStackAfterRotation(Configuration parentConfig, boolean primary,
            Rect inOutBounds) {
        final int dockSide = getDockSide(mDisplayContent, parentConfig, inOutBounds);
        final int otherDockSide = DockedDividerUtils.invertDockSide(dockSide);
        final int primaryDockSide = primary ? dockSide : otherDockSide;
        if (mDisplayContent.getDockedDividerController()
                .canPrimaryStackDockTo(primaryDockSide,
                        parentConfig.windowConfiguration.getBounds(),
                        mDisplayContent.getDisplayInfo().rotation)) {
            return;
        }
        mDisplayContent.getBounds(mTmpRect);
        dockSide = DockedDividerUtils.invertDockSide(dockSide);
        switch (dockSide) {
        final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
        switch (otherDockSide) {
            case DOCKED_LEFT:
                int movement = inOutBounds.left;
                inOutBounds.left -= movement;
                inOutBounds.right -= movement;
                break;
            case DOCKED_RIGHT:
                movement = mTmpRect.right - inOutBounds.right;
                movement = parentBounds.right - inOutBounds.right;
                inOutBounds.left += movement;
                inOutBounds.right += movement;
                break;
@@ -539,7 +549,7 @@ public class TaskStack extends WindowContainer<Task> implements
                inOutBounds.bottom -= movement;
                break;
            case DOCKED_BOTTOM:
                movement = mTmpRect.bottom - inOutBounds.bottom;
                movement = parentBounds.bottom - inOutBounds.bottom;
                inOutBounds.top += movement;
                inOutBounds.bottom += movement;
                break;
@@ -549,22 +559,22 @@ public class TaskStack extends WindowContainer<Task> implements
    /**
     * Snaps the bounds after rotation to the closest snap target for the docked stack.
     */
    private void snapDockedStackAfterRotation(Rect outBounds) {
    void snapDockedStackAfterRotation(Configuration parentConfig, DisplayCutout displayCutout,
            Rect outBounds) {

        // Calculate the current position.
        final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
        final int dividerSize = mDisplayContent.getDockedDividerController().getContentWidth();
        final int dockSide = getDockSide(outBounds);
        final int dockSide = getDockSide(parentConfig, outBounds);
        final int dividerPosition = DockedDividerUtils.calculatePositionForBounds(outBounds,
                dockSide, dividerSize);
        final int displayWidth = displayInfo.logicalWidth;
        final int displayHeight = displayInfo.logicalHeight;
        final int displayWidth = parentConfig.windowConfiguration.getBounds().width();
        final int displayHeight = parentConfig.windowConfiguration.getBounds().height();

        // Snap the position to a target.
        final int rotation = displayInfo.rotation;
        final int orientation = mDisplayContent.getConfiguration().orientation;
        final int rotation = mDisplayContent.getDisplayInfo().rotation;
        final int orientation = parentConfig.orientation;
        mService.mPolicy.getStableInsetsLw(rotation, displayWidth, displayHeight,
                displayInfo.displayCutout, outBounds);
                displayCutout, outBounds);
        final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
                mService.mContext.getResources(), displayWidth, displayHeight,
                dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds,
@@ -573,7 +583,7 @@ public class TaskStack extends WindowContainer<Task> implements

        // Recalculate the bounds based on the position of the target.
        DockedDividerUtils.calculateBoundsForPosition(target.position, dockSide,
                outBounds, displayInfo.logicalWidth, displayInfo.logicalHeight,
                outBounds, displayWidth, displayHeight,
                dividerSize);
    }

@@ -1473,27 +1483,27 @@ public class TaskStack extends WindowContainer<Task> implements
     * information which side of the screen was the dock anchored.
     */
    int getDockSide() {
        return getDockSide(getRawBounds());
        return getDockSide(mDisplayContent.getConfiguration(), getRawBounds());
    }

    int getDockSideForDisplay(DisplayContent dc) {
        return getDockSide(dc, getRawBounds());
        return getDockSide(dc, dc.getConfiguration(), getRawBounds());
    }

    private int getDockSide(Rect bounds) {
    int getDockSide(Configuration parentConfig, Rect bounds) {
        if (mDisplayContent == null) {
            return DOCKED_INVALID;
        }
        return getDockSide(mDisplayContent, bounds);
        return getDockSide(mDisplayContent, parentConfig, bounds);
    }

    private int getDockSide(DisplayContent dc, Rect bounds) {
    private int getDockSide(DisplayContent dc, Configuration parentConfig, Rect bounds) {
        if (!inSplitScreenWindowingMode()) {
            return DOCKED_INVALID;
        }
        dc.getBounds(mTmpRect);
        final int orientation = dc.getConfiguration().orientation;
        return dc.getDockedDividerController().getDockSide(bounds, mTmpRect, orientation);
        return dc.getDockedDividerController().getDockSide(bounds,
                parentConfig.windowConfiguration.getBounds(),
                parentConfig.orientation, dc.getDisplayInfo().rotation);
    }

    boolean hasTaskForUser(int userId) {