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

Commit 6565924b authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Undo parent's scale for child window with different override scale

An app of a different package can add a child window to another app's
window. If the app of parent window has override scale, it will draw
its content in a scaled environment. But if the child doesn't have
override scale, it still draw in with natural size of the device.
Then the child surface should still show without scale, so the scale
from parent surface should be reversed.

Bug: 182362657
Test: atest WindowStateTests#testCompatOverrideScale
Change-Id: I83b32090ceb2e92d644e83b9b14ea68ef2ca96f2
parent 188a4273
Loading
Loading
Loading
Loading
+8 −6
Original line number Original line Diff line number Diff line
@@ -5485,17 +5485,19 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    }
    }


    private void updateScaleIfNeeded() {
    private void updateScaleIfNeeded() {
        if (mIsChildWindow) {
            // Child window follows parent's scale.
            return;
        }
        if (!isVisibleRequested() && !(mIsWallpaper && mToken.isVisible())) {
        if (!isVisibleRequested() && !(mIsWallpaper && mToken.isVisible())) {
            // Skip if it is requested to be invisible, but if it is wallpaper, it may be in
            // Skip if it is requested to be invisible, but if it is wallpaper, it may be in
            // transition that still needs to update the scale for zoom effect.
            // transition that still needs to update the scale for zoom effect.
            return;
            return;
        }
        }
        float newHScale = mHScale * mGlobalScale * mWallpaperScale;
        float globalScale = mGlobalScale;
        float newVScale = mVScale * mGlobalScale * mWallpaperScale;
        final WindowState parent = getParentWindow();
        if (parent != null) {
            // Undo parent's scale because the child surface has inherited scale from parent.
            globalScale *= parent.mInvGlobalScale;
        }
        final float newHScale = mHScale * globalScale * mWallpaperScale;
        final float newVScale = mVScale * globalScale * mWallpaperScale;
        if (mLastHScale != newHScale || mLastVScale != newVScale) {
        if (mLastHScale != newHScale || mLastVScale != newVScale) {
            getSyncTransaction().setMatrix(mSurfaceControl, newHScale, 0, 0, newVScale);
            getSyncTransaction().setMatrix(mSurfaceControl, newHScale, 0, 0, newVScale);
            mLastHScale = newHScale;
            mLastHScale = newHScale;
+10 −4
Original line number Original line Diff line number Diff line
@@ -664,12 +664,11 @@ public class WindowStateTests extends WindowTestsBase {
        assertEquals(expectedChildPos, childPos);
        assertEquals(expectedChildPos, childPos);


        // Surface should apply the scale.
        // Surface should apply the scale.
        final SurfaceControl.Transaction t = w.getPendingTransaction();
        w.prepareSurfaces();
        w.prepareSurfaces();
        verify(w.getPendingTransaction()).setMatrix(w.getSurfaceControl(),
        verify(t).setMatrix(w.mSurfaceControl, overrideScale, 0, 0, overrideScale);
                overrideScale, 0, 0, overrideScale);
        // Child surface inherits parent's scale, so it doesn't need to scale.
        // Child surface inherits parent's scale, so it doesn't need to scale.
        verify(child.getPendingTransaction(), never()).setMatrix(any(), anyInt(), anyInt(),
        verify(t, never()).setMatrix(any(), anyInt(), anyInt(), anyInt(), anyInt());
                anyInt(), anyInt());


        // According to "dp * density / 160 = px", density is scaled and the size in dp is the same.
        // According to "dp * density / 160 = px", density is scaled and the size in dp is the same.
        final CompatibilityInfo compatInfo = cmp.compatibilityInfoForPackageLocked(
        final CompatibilityInfo compatInfo = cmp.compatibilityInfoForPackageLocked(
@@ -686,6 +685,13 @@ public class WindowStateTests extends WindowTestsBase {
        final Rect unscaledClientBounds = new Rect(clientConfig.windowConfiguration.getBounds());
        final Rect unscaledClientBounds = new Rect(clientConfig.windowConfiguration.getBounds());
        unscaledClientBounds.scale(overrideScale);
        unscaledClientBounds.scale(overrideScale);
        assertEquals(w.getWindowConfiguration().getBounds(), unscaledClientBounds);
        assertEquals(w.getWindowConfiguration().getBounds(), unscaledClientBounds);

        // Child window without scale (e.g. different app) should apply inverse scale of parent.
        doReturn(1f).when(cmp).getCompatScale(anyString(), anyInt());
        final WindowState child2 = createWindow(w, TYPE_APPLICATION_SUB_PANEL, "child2");
        clearInvocations(t);
        child2.prepareSurfaces();
        verify(t).setMatrix(child2.mSurfaceControl, w.mInvGlobalScale, 0, 0, w.mInvGlobalScale);
    }
    }


    @UseTestDisplay(addWindows = {W_ABOVE_ACTIVITY, W_NOTIFICATION_SHADE})
    @UseTestDisplay(addWindows = {W_ABOVE_ACTIVITY, W_NOTIFICATION_SHADE})