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

Commit 9dcb0345 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Compute surface position of scaled child window"

parents 169716d3 443f9acd
Loading
Loading
Loading
Loading
+19 −41
Original line number Diff line number Diff line
@@ -259,7 +259,6 @@ import com.android.internal.util.ToBooleanFunction;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.utils.CoordinateTransforms;

import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -1177,14 +1176,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

    /**
     * @return {@code true} if the application runs in size compatibility mode or has an app level
     * scaling override set. This method always returns {@code false} on child window because it
     * should follow parent's scale.
     * scaling override set.
     * @see CompatModePackages#getCompatScale
     * @see android.content.res.CompatibilityInfo#supportsScreen
     * @see ActivityRecord#hasSizeCompatBounds()
     */
    boolean hasCompatScale() {
        return (mOverrideScale != 1f || hasCompatScale(mAttrs, mActivityRecord)) && !mIsChildWindow;
        return mOverrideScale != 1f || hasCompatScale(mAttrs, mActivityRecord);
    }

    /**
@@ -4478,22 +4476,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            h = Math.min(h, ph);
        }

        if (mIsChildWindow) {
            final WindowState parent = getTopParentWindow();
            if (parent.hasCompatScale()) {
                // Scale the containing and display frames because they are in screen coordinates.
                // The position of frames are already relative to parent so only size is scaled.
                mTmpRect.set(containingFrame);
                containingFrame = mTmpRect;
                CoordinateTransforms.scaleRectSize(containingFrame, parent.mInvGlobalScale);
                if (fitToDisplay) {
                    mTmpRect2.set(displayFrame);
                    displayFrame = mTmpRect2;
                    CoordinateTransforms.scaleRectSize(displayFrame, parent.mInvGlobalScale);
                }
            }
        }

        // Set mFrame
        Gravity.apply(attrs.gravity, w, h, containingFrame,
                (int) (x + attrs.horizontalMargin * pw),
@@ -5124,19 +5106,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        }
    }

    /**
     * Expand the given rectangle by this windows surface insets. This
     * takes you from the 'window size' to the 'surface size'.
     * The surface insets are positive in each direction, so we inset by
     * the inverse.
     */
    void expandForSurfaceInsets(Rect r) {
        r.inset(-mAttrs.surfaceInsets.left,
                -mAttrs.surfaceInsets.top,
                -mAttrs.surfaceInsets.right,
                -mAttrs.surfaceInsets.bottom);
    }

    boolean surfaceInsetsChanging() {
        return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets);
    }
@@ -5454,6 +5423,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    }

    private void updateScaleIfNeeded() {
        if (mIsChildWindow) {
            // Child window follows parent's scale.
            return;
        }
        float newHScale = mHScale * mGlobalScale * mWallpaperScale;
        float newVScale = mVScale * mGlobalScale * mWallpaperScale;
        if (mLastHScale != newHScale ||
@@ -5537,15 +5510,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        // If changed, also adjust getTransformationMatrix
        final WindowContainer parentWindowContainer = getParent();
        if (isChildWindow()) {
            // TODO: This probably falls apart at some point and we should
            // actually compute relative coordinates.

            final WindowState parent = getParentWindow();
            outPoint.offset(-parent.mWindowFrames.mFrame.left, -parent.mWindowFrames.mFrame.top);
            // Undo the scale of window position because the relative coordinates for child are
            // based on the scaled parent.
            if (mInvGlobalScale != 1f) {
                outPoint.x = (int) (outPoint.x * mInvGlobalScale + 0.5f);
                outPoint.y = (int) (outPoint.y * mInvGlobalScale + 0.5f);
            }
            // Since the parent was outset by its surface insets, we need to undo the outsetting
            // with insetting by the same amount.
            final WindowState parent = getParentWindow();
            transformSurfaceInsetsPosition(mTmpPoint, parent.mAttrs.surfaceInsets);
            outPoint.offset(-parent.mWindowFrames.mFrame.left + mTmpPoint.x,
                    -parent.mWindowFrames.mFrame.top + mTmpPoint.y);
            outPoint.offset(mTmpPoint.x, mTmpPoint.y);
        } else if (parentWindowContainer != null) {
            final Rect parentBounds = isStartingWindowAssociatedToTask()
                    ? mStartingData.mAssociatedTask.getBounds()
@@ -5564,7 +5540,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            outPoint.offset(outset, outset);
        }

        // Expand for surface insets. See WindowState.expandForSurfaceInsets.
        // The surface size is larger than the window if the window has positive surface insets.
        transformSurfaceInsetsPosition(mTmpPoint, mAttrs.surfaceInsets);
        outPoint.offset(-mTmpPoint.x, -mTmpPoint.y);

@@ -5576,7 +5552,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
     * scaled, the insets also need to be scaled for surface position in global coordinate.
     */
    private void transformSurfaceInsetsPosition(Point outPos, Rect surfaceInsets) {
        if (!hasCompatScale()) {
        // Ignore the scale for child window because its insets have been scaled with the
        // parent surface.
        if (mGlobalScale == 1f || mIsChildWindow) {
            outPos.x = surfaceInsets.left;
            outPos.y = surfaceInsets.top;
            return;
+0 −6
Original line number Diff line number Diff line
@@ -152,10 +152,4 @@ public class CoordinateTransforms {
        transform.mapRect(tmp);
        inOutRect.set((int) tmp.left, (int) tmp.top, (int) tmp.right, (int) tmp.bottom);
    }

    /** Scales the rect without changing its position. */
    public static void scaleRectSize(Rect inOutRect, float scale) {
        inOutRect.right = inOutRect.left + (int) (inOutRect.width() * scale + .5f);
        inOutRect.bottom = inOutRect.top + (int) (inOutRect.height() * scale + .5f);
    }
}
+17 −11
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ import static org.mockito.Mockito.when;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.RemoteException;
@@ -563,7 +564,7 @@ public class WindowStateTests extends WindowTestsBase {
        final WindowState child = createWindow(w, TYPE_APPLICATION_PANEL, "child");

        assertTrue(w.hasCompatScale());
        assertFalse(child.hasCompatScale());
        assertTrue(child.hasCompatScale());

        makeWindowVisible(w, child);
        w.setRequestedSize(100, 200);
@@ -574,21 +575,26 @@ public class WindowStateTests extends WindowTestsBase {
        w.mAttrs.gravity = Gravity.TOP | Gravity.LEFT;
        child.mAttrs.gravity = Gravity.CENTER;
        DisplayContentTests.performLayout(mDisplayContent);
        final Rect parentFrame = w.getFrame();
        final Rect childFrame = child.getFrame();

        // Frame on screen = 200x400 (200, 200 - 400, 600). Compat frame on client = 100x200.
        final Rect unscaledCompatFrame = new Rect(w.getWindowFrames().mCompatFrame);
        unscaledCompatFrame.scale(overrideScale);
        final Rect parentFrame = w.getFrame();
        assertEquals(w.getWindowFrames().mFrame, unscaledCompatFrame);
        assertEquals(parentFrame, unscaledCompatFrame);

        final Rect childFrame = child.getFrame();
        assertEquals(childFrame, child.getWindowFrames().mCompatFrame);
        // Child frame = 50x100 (225, 250 - 275, 350) according to Gravity.CENTER.
        final int childX = parentFrame.left + child.mRequestedWidth / 2;
        final int childY = parentFrame.top + child.mRequestedHeight / 2;
        final Rect expectedChildFrame = new Rect(childX, childY, childX + child.mRequestedWidth,
                childY + child.mRequestedHeight);
        assertEquals(expectedChildFrame, childFrame);
        // Frame on screen = 100x200 (250, 300 - 350, 500). Compat frame on client = 50x100.
        unscaledCompatFrame.set(child.getWindowFrames().mCompatFrame);
        unscaledCompatFrame.scale(overrideScale);
        assertEquals(childFrame, unscaledCompatFrame);

        // The position of child is relative to parent. So the local coordinates should be scaled.
        final Point expectedChildPos = new Point(
                (int) ((childFrame.left - parentFrame.left) / overrideScale),
                (int) ((childFrame.top - parentFrame.top) / overrideScale));
        final Point childPos = new Point();
        child.transformFrameToSurfacePosition(childFrame.left, childFrame.top, childPos);
        assertEquals(expectedChildPos, childPos);

        // Surface should apply the scale.
        w.prepareSurfaces();