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

Commit 8818f3b3 authored by Ebru Kurnaz's avatar Ebru Kurnaz Committed by Android (Google) Code Review
Browse files

Merge "Add hidden WM API to set external display density ratio." into main

parents 3539a606 fc1a2e08
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -135,8 +135,29 @@ interface IWindowManager
    int getDisplayIdByUniqueId(String uniqueId);
    @EnforcePermission("WRITE_SECURE_SETTINGS")
    void setForcedDisplayDensityForUser(int displayId, int density, int userId);
    /**
    * Clears forced density and forced density ratio in DisplayWindowSettings for the given
    * displayId.
    *
    * @param displayId Id of the display.
    * @param userId Id of the user.
    */
    @EnforcePermission("WRITE_SECURE_SETTINGS")
    void clearForcedDisplayDensityForUser(int displayId, int userId);
    /**
    * Sets display forced density ratio and forced density in DisplayWindowSettings for
    * the given displayId. Ratio is used to update forced density to persist display size when
    * resolution change happens. Use {@link #setForcedDisplayDensityForUser} when there is no need
    * to handle resolution changes for the display. If setForcedDisplayDensityForUser is used after,
    * this the ratio will be updated to use the last set forced density. Use
    * {@link #clearForcedDisplayDensityForUser} to reset.
    *
    * @param displayId Id of the display.
    * @param ratio The ratio of forced density to the default density.
    * @param userId Id of the user.
    */
    @EnforcePermission("WRITE_SECURE_SETTINGS")
    void setForcedDisplayDensityRatio(int displayId, float ratio, int userId);

    /**
     * Sets settings for a specific user in a batch to minimize configuration updates.
+38 −4
Original line number Diff line number Diff line
@@ -97,6 +97,12 @@ public class DisplayDensityUtils {
    @Nullable
    private final int[] mValues;

    /**
     * The density values before rounding to an integer.
     */
    @Nullable
    private final float[] mFloatValues;

    private final int mDefaultDensity;
    private final int mCurrentIndex;

@@ -124,6 +130,7 @@ public class DisplayDensityUtils {
            Log.w(LOG_TAG, "Cannot fetch display info for the default display");
            mEntries = null;
            mValues = null;
            mFloatValues = null;
            mDefaultDensity = 0;
            mCurrentIndex = -1;
            return;
@@ -154,6 +161,7 @@ public class DisplayDensityUtils {
            Log.w(LOG_TAG, "No display satisfies the predicate");
            mEntries = null;
            mValues = null;
            mFloatValues = null;
            mDefaultDensity = 0;
            mCurrentIndex = -1;
            return;
@@ -165,6 +173,7 @@ public class DisplayDensityUtils {
            Log.w(LOG_TAG, "Cannot fetch default density for display " + idOfSmallestDisplay);
            mEntries = null;
            mValues = null;
            mFloatValues = null;
            mDefaultDensity = 0;
            mCurrentIndex = -1;
            return;
@@ -197,18 +206,25 @@ public class DisplayDensityUtils {

        String[] entries = new String[1 + numSmaller + numLarger];
        int[] values = new int[entries.length];
        float[] valuesFloat = new float[entries.length];
        int curIndex = 0;

        if (numSmaller > 0) {
            final float interval = (1 - minScale) / numSmaller;
            for (int i = numSmaller - 1; i >= 0; i--) {
                // Save the float density value before rounding to be used to set the density ratio
                // of overridden density to default density in WM.
                final float densityFloat = defaultDensity * (1 - (i + 1) * interval);
                // Round down to a multiple of 2 by truncating the low bit.
                final int density = ((int) (defaultDensity * (1 - (i + 1) * interval))) & ~1;
                // LINT.IfChange
                final int density = ((int) densityFloat) & ~1;
                // LINT.ThenChange(/services/core/java/com/android/server/wm/DisplayContent.java:getBaseDensityFromRatio)
                if (currentDensity == density) {
                    currentDensityIndex = curIndex;
                }
                entries[curIndex] = res.getString(SUMMARIES_SMALLER[i]);
                values[curIndex] = density;
                valuesFloat[curIndex] = densityFloat;
                entries[curIndex] = res.getString(SUMMARIES_SMALLER[i]);
                curIndex++;
            }
        }
@@ -217,18 +233,25 @@ public class DisplayDensityUtils {
            currentDensityIndex = curIndex;
        }
        values[curIndex] = defaultDensity;
        valuesFloat[curIndex] = (float) defaultDensity;
        entries[curIndex] = res.getString(SUMMARY_DEFAULT);
        curIndex++;

        if (numLarger > 0) {
            final float interval = (maxScale - 1) / numLarger;
            for (int i = 0; i < numLarger; i++) {
                // Save the float density value before rounding to be used to set the density ratio
                // of overridden density to default density in WM.
                final float densityFloat = defaultDensity * (1 + (i + 1) * interval);
                // Round down to a multiple of 2 by truncating the low bit.
                final int density = ((int) (defaultDensity * (1 + (i + 1) * interval))) & ~1;
                // LINT.IfChange
                final int density = ((int) densityFloat) & ~1;
                // LINT.ThenChange(/services/core/java/com/android/server/wm/DisplayContent.java:getBaseDensityFromRatio)
                if (currentDensity == density) {
                    currentDensityIndex = curIndex;
                }
                values[curIndex] = density;
                valuesFloat[curIndex] = densityFloat;
                entries[curIndex] = res.getString(SUMMARIES_LARGER[i]);
                curIndex++;
            }
@@ -244,6 +267,9 @@ public class DisplayDensityUtils {
            values = Arrays.copyOf(values, newLength);
            values[curIndex] = currentDensity;

            valuesFloat = Arrays.copyOf(valuesFloat, newLength);
            valuesFloat[curIndex] = (float) currentDensity;

            entries = Arrays.copyOf(entries, newLength);
            entries[curIndex] = res.getString(SUMMARY_CUSTOM, currentDensity);

@@ -254,6 +280,7 @@ public class DisplayDensityUtils {
        mCurrentIndex = displayIndex;
        mEntries = entries;
        mValues = values;
        mFloatValues = valuesFloat;
    }

    @Nullable
@@ -348,8 +375,15 @@ public class DisplayDensityUtils {
                    }

                    final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
                    // Only set the ratio for external displays as Settings uses
                    // ScreenResolutionFragment to handle density update for internal display.
                    if (info.type == Display.TYPE_EXTERNAL) {
                        wm.setForcedDisplayDensityRatio(displayId,
                                mFloatValues[index] / mDefaultDensity, userId);
                    } else {
                        wm.setForcedDisplayDensityForUser(displayId, mValues[index], userId);
                    }
                }
            } catch (RemoteException exc) {
                Log.w(LOG_TAG, "Unable to save forced display density setting");
            }
+29 −16
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@ 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;
@@ -433,9 +432,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    /**
     * Ratio between overridden display density for current user and the initial display density,
     * used only for external displays.
     * used for updating the base density when resolution change happens to preserve display size.
     */
    float mExternalDisplayForcedDensityRatio = 0.0f;
    float mForcedDisplayDensityRatio = 0.0f;
    boolean mIsDensityForced = false;

    /**
@@ -3120,6 +3119,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            mBaseRoundedCorners = loadRoundedCorners(baseWidth, baseHeight);
        }

        // Update the base density if there is a forced density ratio.
        if (DesktopExperienceFlags.ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS.isTrue()
                && mForcedDisplayDensityRatio != 0.0f) {
            mBaseDisplayDensity = getBaseDensityFromRatio();
        }

        if (mMaxUiWidth > 0 && mBaseDisplayWidth > mMaxUiWidth) {
            final float ratio = mMaxUiWidth / (float) mBaseDisplayWidth;
            mBaseDisplayHeight = (int) (mBaseDisplayHeight * ratio);
@@ -3137,17 +3142,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                        + mBaseDisplayHeight + " on display:" + getDisplayId());
            }
        }
        // Update the base density if there is a forced density ratio.
        if (DesktopExperienceFlags.ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS.isTrue()
                && mIsDensityForced && mExternalDisplayForcedDensityRatio != 0.0f) {
            mBaseDisplayDensity = (int)
                    (mInitialDisplayDensity * mExternalDisplayForcedDensityRatio + 0.5);
        }
        if (mDisplayReady && !mDisplayPolicy.shouldKeepCurrentDecorInsets()) {
            mDisplayPolicy.mDecorInsets.invalidate();
        }
    }

    /**
     * Returns the forced density from forcedDensityRatio if the ratio is valid by rounding the
     * density down to an even number. Returns the initial density if the ratio is 0.
     */
    private int getBaseDensityFromRatio() {
        return (mForcedDisplayDensityRatio != 0.0f)
                ? ((int) (mInitialDisplayDensity * mForcedDisplayDensityRatio)) & ~1
                : mInitialDisplayDensity;
    }

    /**
     * Forces this display to use the specified density.
     *
@@ -3172,15 +3181,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        if (density == getInitialDisplayDensity()) {
            density = 0;
        }
        // Save the new density ratio to settings for external displays.
        if (DesktopExperienceFlags.ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS.isTrue()
                && mDisplayInfo.type == TYPE_EXTERNAL) {
            mExternalDisplayForcedDensityRatio = (float)
                    mBaseDisplayDensity / getInitialDisplayDensity();
        mWmService.mDisplayWindowSettings.setForcedDensity(getDisplayInfo(), density, userId);
    }

    void setForcedDensityRatio(float ratio, int userId) {
        // Save the new density ratio to settings and update forced density with the ratio.
        if (DesktopExperienceFlags.ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS.isTrue()) {
            mForcedDisplayDensityRatio = ratio;
            mWmService.mDisplayWindowSettings.setForcedDensityRatio(getDisplayInfo(),
                    mExternalDisplayForcedDensityRatio);
                    mForcedDisplayDensityRatio);

            // Set forced density from ratio.
            setForcedDensity(getBaseDensityFromRatio(), userId);
        }
        mWmService.mDisplayWindowSettings.setForcedDensity(getDisplayInfo(), density, userId);
    }

    /** @param mode {@link #FORCE_SCALING_MODE_AUTO} or {@link #FORCE_SCALING_MODE_DISABLED}. */
+1 −1
Original line number Diff line number Diff line
@@ -391,7 +391,7 @@ class DisplayWindowSettings {
        final int density = hasDensityOverride ? settings.mForcedDensity
                : dc.getInitialDisplayDensity();
        if (hasDensityOverrideRatio) {
            dc.mExternalDisplayForcedDensityRatio = settings.mForcedDensityRatio;
            dc.mForcedDisplayDensityRatio = settings.mForcedDensityRatio;
        }

        dc.updateBaseDisplayMetrics(width, height, density, dc.mBaseDisplayPhysicalXDpi,
+35 −0
Original line number Diff line number Diff line
@@ -6231,6 +6231,10 @@ public class WindowManagerService extends IWindowManager.Stub
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                // Clear forced display density ratio
                setForcedDisplayDensityRatioInternal(displayId, 0.0f, userId);

                // Clear forced display density
                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                if (displayContent != null) {
                    displayContent.setForcedDensity(displayContent.getInitialDisplayDensity(),
@@ -6253,6 +6257,37 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    @EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
    @Override
    public void setForcedDisplayDensityRatio(int displayId, float ratio, int userId) {
        setForcedDisplayDensityRatio_enforcePermission();
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                setForcedDisplayDensityRatioInternal(displayId, ratio, userId);
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    private void setForcedDisplayDensityRatioInternal(
            int displayId, float ratio, int userId) {
        final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
        if (displayContent != null) {
            displayContent.setForcedDensityRatio(ratio, userId);
            return;
        }

        final DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId);
        if (info == null) {
            ProtoLog.e(WM_ERROR, "Failed to get information about logical display %d. "
                    + "Skip setting forced display density.", displayId);
            return;
        }
        mDisplayWindowSettings.setForcedDensityRatio(info, ratio);
    }

    @EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
    @Override
    public void setConfigurationChangeSettingsForUser(
Loading