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

Commit 919de5f6 authored by Ebru Kurnaz's avatar Ebru Kurnaz
Browse files

Add a new field in DisplayContent for saving forced density ratio

This value is used to update forced density in external displays when a
resolution change happens. When the resolution change happens initial density
changes, but the ratio between initial and forced density should not change to preserve the size of the UI elements.

Flag: com.android.window.flags.enable_persisting_density_scale_for_connected_displays
Test: atest DisplayContentTests
Bug: 392855657
Change-Id: Id30f1c2fedd939d3191c28d25a2c465792ff799b
parent 5faf193a
Loading
Loading
Loading
Loading
+33 −10
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.STATE_UNKNOWN;
import static android.view.Display.TYPE_EXTERNAL;
import static android.view.Display.isSuspendedState;
import static android.view.InsetsSource.ID_IME;
import static android.view.Surface.ROTATION_0;
@@ -155,6 +156,7 @@ import static com.android.server.wm.utils.DisplayInfoOverrides.WM_OVERRIDE_FIELD
import static com.android.server.wm.utils.DisplayInfoOverrides.copyDisplayInfoFields;
import static com.android.server.wm.utils.RegionUtils.forEachRectReverse;
import static com.android.server.wm.utils.RegionUtils.rectListToRegion;
import static com.android.window.flags.Flags.enablePersistingDensityScaleForConnectedDisplays;

import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -426,6 +428,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     * @see WindowManagerService#setForcedDisplayDensityForUser(int, int, int)
     */
    int mBaseDisplayDensity = 0;

    /**
     * Ratio between overridden display density for current user and the initial display density,
     * used only for external displays.
     */
    float mExternalDisplayForcedDensityRatio = 0.0f;
    boolean mIsDensityForced = false;

    /**
@@ -3065,6 +3073,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                mDisplayPolicy.physicalDisplayChanged();
            }

            // Real display metrics changed, so we should also update initial values.
            mInitialDisplayWidth = newWidth;
            mInitialDisplayHeight = newHeight;
            mInitialDisplayDensity = newDensity;
            mInitialPhysicalXDpi = newXDpi;
            mInitialPhysicalYDpi = newYDpi;
            mInitialDisplayCutout = newCutout;
            mInitialRoundedCorners = newRoundedCorners;
            mInitialDisplayShape = newDisplayShape;
            mCurrentUniqueDisplayId = newUniqueId;

            // If there is an override set for base values - use it, otherwise use new values.
            updateBaseDisplayMetrics(mIsSizeForced ? mBaseDisplayWidth : newWidth,
                    mIsSizeForced ? mBaseDisplayHeight : newHeight,
@@ -3081,16 +3100,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                mWmService.mDisplayWindowSettings.applyRotationSettingsToDisplayLocked(this);
            }

            // Real display metrics changed, so we should also update initial values.
            mInitialDisplayWidth = newWidth;
            mInitialDisplayHeight = newHeight;
            mInitialDisplayDensity = newDensity;
            mInitialPhysicalXDpi = newXDpi;
            mInitialPhysicalYDpi = newYDpi;
            mInitialDisplayCutout = newCutout;
            mInitialRoundedCorners = newRoundedCorners;
            mInitialDisplayShape = newDisplayShape;
            mCurrentUniqueDisplayId = newUniqueId;
            reconfigureDisplayLocked();

            if (physicalDisplayChanged) {
@@ -3143,6 +3152,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                        + mBaseDisplayHeight + " on display:" + getDisplayId());
            }
        }
        // Update the base density if there is a forced density ratio.
        if (enablePersistingDensityScaleForConnectedDisplays()
                && mIsDensityForced && mExternalDisplayForcedDensityRatio != 0.0f) {
            mBaseDisplayDensity = (int)
                    (mInitialDisplayDensity * mExternalDisplayForcedDensityRatio + 0.5);
        }
        if (mDisplayReady && !mDisplayPolicy.shouldKeepCurrentDecorInsets()) {
            mDisplayPolicy.mDecorInsets.invalidate();
        }
@@ -3172,6 +3187,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        if (density == getInitialDisplayDensity()) {
            density = 0;
        }
        // Save the new density ratio to settings for external displays.
        if (enablePersistingDensityScaleForConnectedDisplays()
                && mDisplayInfo.type == TYPE_EXTERNAL) {
            mExternalDisplayForcedDensityRatio = (float)
                    mBaseDisplayDensity / getInitialDisplayDensity();
            mWmService.mDisplayWindowSettings.setForcedDensityRatio(getDisplayInfo(),
                    mExternalDisplayForcedDensityRatio);
        }
        mWmService.mDisplayWindowSettings.setForcedDensity(getDisplayInfo(), density, userId);
    }

+37 −6
Original line number Diff line number Diff line
@@ -23,11 +23,10 @@ import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;

import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_AUTO;
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_DISABLED;

import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
@@ -100,6 +99,13 @@ class DisplayWindowSettings {
        mSettingsProvider.updateOverrideSettings(info, overrideSettings);
    }

    void setForcedDensityRatio(@NonNull DisplayInfo info, float ratio) {
        final SettingsProvider.SettingsEntry overrideSettings =
                mSettingsProvider.getOverrideSettings(info);
        overrideSettings.mForcedDensityRatio = ratio;
        mSettingsProvider.updateOverrideSettings(info, overrideSettings);
    }

    void setForcedScalingMode(@NonNull DisplayContent displayContent, @ForceScalingMode int mode) {
        if (displayContent.isDefaultDisplay) {
            Settings.Global.putInt(mService.mContext.getContentResolver(),
@@ -367,6 +373,7 @@ class DisplayWindowSettings {
                mFixedToUserRotation);

        final boolean hasDensityOverride = settings.mForcedDensity != 0;
        final boolean hasDensityOverrideRatio = settings.mForcedDensityRatio != 0.0f;
        final boolean hasSizeOverride = settings.mForcedWidth != 0 && settings.mForcedHeight != 0;
        dc.mIsDensityForced = hasDensityOverride;
        dc.mIsSizeForced = hasSizeOverride;
@@ -378,6 +385,10 @@ class DisplayWindowSettings {
        final int height = hasSizeOverride ? settings.mForcedHeight : dc.mInitialDisplayHeight;
        final int density = hasDensityOverride ? settings.mForcedDensity
                : dc.getInitialDisplayDensity();
        if (hasDensityOverrideRatio) {
            dc.mExternalDisplayForcedDensityRatio = settings.mForcedDensityRatio;
        }

        dc.updateBaseDisplayMetrics(width, height, density, dc.mBaseDisplayPhysicalXDpi,
                dc.mBaseDisplayPhysicalYDpi);

@@ -496,6 +507,13 @@ class DisplayWindowSettings {
            int mForcedWidth;
            int mForcedHeight;
            int mForcedDensity;
            /**
             * The ratio of the forced density to the initial density of the display. This is only
             * saved for external displays, and used to make sure ratio between forced density and
             * initial density persist when a resolution change happens. Ratio is updated when
             * mForcedDensity is changed.
             */
            float mForcedDensityRatio;
            @Nullable
            @ForceScalingMode
            Integer mForcedScalingMode;
@@ -561,6 +579,10 @@ class DisplayWindowSettings {
                    mForcedDensity = other.mForcedDensity;
                    changed = true;
                }
                if (other.mForcedDensityRatio != mForcedDensityRatio) {
                    mForcedDensityRatio = other.mForcedDensityRatio;
                    changed = true;
                }
                if (!Objects.equals(other.mForcedScalingMode, mForcedScalingMode)) {
                    mForcedScalingMode = other.mForcedScalingMode;
                    changed = true;
@@ -649,6 +671,11 @@ class DisplayWindowSettings {
                    mForcedDensity = delta.mForcedDensity;
                    changed = true;
                }
                if (delta.mForcedDensityRatio != 0
                        && delta.mForcedDensityRatio != mForcedDensityRatio) {
                    mForcedDensityRatio = delta.mForcedDensityRatio;
                    changed = true;
                }
                if (delta.mForcedScalingMode != null
                        && !Objects.equals(delta.mForcedScalingMode, mForcedScalingMode)) {
                    mForcedScalingMode = delta.mForcedScalingMode;
@@ -713,6 +740,7 @@ class DisplayWindowSettings {
                        && mUserRotationMode == null
                        && mUserRotation == null
                        && mForcedWidth == 0 && mForcedHeight == 0 && mForcedDensity == 0
                        && mForcedDensityRatio == 0.0f
                        && mForcedScalingMode == null
                        && mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED
                        && mShouldShowWithInsecureKeyguard == null
@@ -736,6 +764,7 @@ class DisplayWindowSettings {
                        && mForcedHeight == that.mForcedHeight
                        && mForcedDensity == that.mForcedDensity
                        && mRemoveContentMode == that.mRemoveContentMode
                        && mForcedDensityRatio == that.mForcedDensityRatio
                        && Objects.equals(mUserRotationMode, that.mUserRotationMode)
                        && Objects.equals(mUserRotation, that.mUserRotation)
                        && Objects.equals(mForcedScalingMode, that.mForcedScalingMode)
@@ -755,10 +784,11 @@ class DisplayWindowSettings {
            @Override
            public int hashCode() {
                return Objects.hash(mWindowingMode, mUserRotationMode, mUserRotation, mForcedWidth,
                        mForcedHeight, mForcedDensity, mForcedScalingMode, mRemoveContentMode,
                        mShouldShowWithInsecureKeyguard, mShouldShowSystemDecors, mIsHomeSupported,
                        mImePolicy, mFixedToUserRotation, mIgnoreOrientationRequest,
                        mIgnoreDisplayCutout, mDontMoveToTop, mIgnoreActivitySizeRestrictions);
                        mForcedHeight, mForcedDensity, mForcedDensityRatio, mForcedScalingMode,
                        mRemoveContentMode, mShouldShowWithInsecureKeyguard,
                        mShouldShowSystemDecors, mIsHomeSupported, mImePolicy, mFixedToUserRotation,
                        mIgnoreOrientationRequest, mIgnoreDisplayCutout, mDontMoveToTop,
                        mIgnoreActivitySizeRestrictions);
            }

            @Override
@@ -770,6 +800,7 @@ class DisplayWindowSettings {
                        + ", mForcedWidth=" + mForcedWidth
                        + ", mForcedHeight=" + mForcedHeight
                        + ", mForcedDensity=" + mForcedDensity
                        + ", mForcedDensityRatio=" + mForcedDensityRatio
                        + ", mForcedScalingMode=" + mForcedScalingMode
                        + ", mRemoveContentMode=" + mRemoveContentMode
                        + ", mShouldShowWithInsecureKeyguard=" + mShouldShowWithInsecureKeyguard
+6 −0
Original line number Diff line number Diff line
@@ -511,6 +511,8 @@ class DisplayWindowSettingsProvider implements SettingsProvider {
                    0 /* defaultValue */);
            settingsEntry.mForcedDensity = getIntAttribute(parser, "forcedDensity",
                    0 /* defaultValue */);
            settingsEntry.mForcedDensityRatio = parser.getAttributeFloat(null, "forcedDensityRatio",
                    0.0f /* defaultValue */);
            settingsEntry.mForcedScalingMode = getIntegerAttribute(parser, "forcedScalingMode",
                    null /* defaultValue */);
            settingsEntry.mRemoveContentMode = getIntAttribute(parser, "removeContentMode",
@@ -599,6 +601,10 @@ class DisplayWindowSettingsProvider implements SettingsProvider {
                if (settingsEntry.mForcedDensity != 0) {
                    out.attributeInt(null, "forcedDensity", settingsEntry.mForcedDensity);
                }
                if (settingsEntry.mForcedDensityRatio != 0.0f) {
                    out.attributeFloat(null, "forcedDensityRatio",
                            settingsEntry.mForcedDensityRatio);
                }
                if (settingsEntry.mForcedScalingMode != null) {
                    out.attributeInt(null, "forcedScalingMode",
                            settingsEntry.mForcedScalingMode);
+69 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.window.flags.Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING;
import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE;
import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT;
import static com.android.window.flags.Flags.FLAG_ENABLE_PERSISTING_DENSITY_SCALE_FOR_CONNECTED_DISPLAYS;

import static com.google.common.truth.Truth.assertThat;

@@ -2872,6 +2873,74 @@ public class DisplayContentTests extends WindowTestsBase {
        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
    }

    @EnableFlags(FLAG_ENABLE_PERSISTING_DENSITY_SCALE_FOR_CONNECTED_DISPLAYS)
    @Test
    public void testForcedDensityRatioSetForExternalDisplays_persistDensityScaleFlagEnabled() {
        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
        displayInfo.displayId = DEFAULT_DISPLAY + 1;
        displayInfo.type = Display.TYPE_EXTERNAL;
        final DisplayContent displayContent = createNewDisplay(displayInfo);
        final int baseWidth = 1280;
        final int baseHeight = 720;
        final int baseDensity = 320;
        final float baseXDpi = 60;
        final float baseYDpi = 60;

        displayContent.mInitialDisplayWidth = baseWidth;
        displayContent.mInitialDisplayHeight = baseHeight;
        displayContent.mInitialDisplayDensity = baseDensity;
        displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity, baseXDpi,
                baseYDpi);

        final int forcedDensity = 640;

        // Verify that forcing the density is honored and the size doesn't change.
        displayContent.setForcedDensity(forcedDensity, 0 /* userId */);
        verifySizes(displayContent, baseWidth, baseHeight, forcedDensity);

        // Verify that density ratio is set correctly.
        assertEquals((float) forcedDensity / baseDensity,
                displayContent.mExternalDisplayForcedDensityRatio, 0.01);
    }

    @EnableFlags(FLAG_ENABLE_PERSISTING_DENSITY_SCALE_FOR_CONNECTED_DISPLAYS)
    @Test
    public void testForcedDensityUpdateForExternalDisplays_persistDensityScaleFlagEnabled() {
        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
        displayInfo.displayId = DEFAULT_DISPLAY + 1;
        displayInfo.type = Display.TYPE_EXTERNAL;
        final DisplayContent displayContent = createNewDisplay(displayInfo);
        final int baseWidth = 1280;
        final int baseHeight = 720;
        final int baseDensity = 320;
        final float baseXDpi = 60;
        final float baseYDpi = 60;

        displayContent.mInitialDisplayWidth = baseWidth;
        displayContent.mInitialDisplayHeight = baseHeight;
        displayContent.mInitialDisplayDensity = baseDensity;
        displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity, baseXDpi,
                baseYDpi);

        final int forcedDensity = 640;

        // Verify that forcing the density is honored and the size doesn't change.
        displayContent.setForcedDensity(forcedDensity, 0 /* userId */);
        verifySizes(displayContent, baseWidth, baseHeight, forcedDensity);

        // Verify that density ratio is set correctly.
        assertEquals((float) 2.0f,
                displayContent.mExternalDisplayForcedDensityRatio, 0.001);


        displayContent.mInitialDisplayDensity = 160;
        displayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity, baseXDpi,
                baseYDpi);

        // Verify that forced density is updated based on the ratio.
        assertEquals(320, displayContent.mBaseDisplayDensity);
    }

    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
    @Test
    public void testSetShouldShowSystemDecorations_nonDefaultNonPrivateDisplay() {
+19 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import static org.mockito.Matchers.eq;
import android.annotation.NonNull;
import android.app.WindowConfiguration;
import android.content.ContentResolver;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.view.Display;
@@ -53,6 +54,7 @@ import androidx.test.filters.SmallTest;
import com.android.server.LocalServices;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
import com.android.window.flags.Flags;

import org.junit.Before;
import org.junit.Test;
@@ -272,6 +274,23 @@ public class DisplayWindowSettingsTests extends WindowTestsBase {
                mSecondaryDisplay.mBaseDisplayDensity);
    }

    @EnableFlags(Flags.FLAG_ENABLE_PERSISTING_DENSITY_SCALE_FOR_CONNECTED_DISPLAYS)
    @Test
    public void testSetForcedDensityRatio() {
        mDisplayWindowSettings.setForcedDensity(mSecondaryDisplay.getDisplayInfo(),
                300 /* density */, 0 /* userId */);
        mDisplayWindowSettings.setForcedDensityRatio(mSecondaryDisplay.getDisplayInfo(),
                2.0f /* ratio */);
        mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);

        assertEquals(mSecondaryDisplay.mInitialDisplayDensity * 2.0f,
                mSecondaryDisplay.mBaseDisplayDensity, 0.01);

        mWm.clearForcedDisplayDensityForUser(mSecondaryDisplay.getDisplayId(), 0 /* userId */);
        assertEquals(mSecondaryDisplay.mInitialDisplayDensity,
                mSecondaryDisplay.mBaseDisplayDensity);
    }

    @Test
    public void testSetForcedScalingMode() {
        mDisplayWindowSettings.setForcedScalingMode(mSecondaryDisplay,