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

Commit 329e7358 authored by Oleg Petšjonkin's avatar Oleg Petšjonkin Committed by Android (Google) Code Review
Browse files

Merge "Allow setting display mode without persisting it" into main

parents 0325d0f3 95bb63c8
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -1219,11 +1219,36 @@ public final class DisplayManagerGlobal {

    /**
     * Sets the default display mode, according to the refresh rate and the resolution chosen by the
     * user.
     * user. Persists selected mode.
     * @hide
     */
    @RequiresPermission("android.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE")
    public void setUserPreferredDisplayMode(int displayId, Display.Mode mode) {
        setUserPreferredDisplayMode(displayId, mode, true);
    }

    /**
     * Sets the default display mode, according to the refresh rate and the resolution chosen by the
     * user. Allows to set display mode without persisting.
     * @hide
     */
    @RequiresPermission("android.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE")
    public void setUserPreferredDisplayMode(int displayId, Display.Mode mode, boolean storeMode) {
        try {
            mDm.setUserPreferredDisplayMode(displayId, mode, storeMode);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    /**
     * Resets the default display mode from persistence
     * @hide
     */
    @RequiresPermission("android.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE")
    public void resetUserPreferredDisplayMode(int displayId) {
        try {
            mDm.setUserPreferredDisplayMode(displayId, mode);
            mDm.resetUserPreferredDisplayMode(displayId);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
+3 −1
Original line number Diff line number Diff line
@@ -194,7 +194,9 @@ interface IDisplayManager {
    // Sets the user preferred display mode.
    // Requires MODIFY_USER_PREFERRED_DISPLAY_MODE permission.
    @EnforcePermission("MODIFY_USER_PREFERRED_DISPLAY_MODE")
    void setUserPreferredDisplayMode(int displayId, in Mode mode);
    void setUserPreferredDisplayMode(int displayId, in Mode mode, boolean storeMode);
    @EnforcePermission("MODIFY_USER_PREFERRED_DISPLAY_MODE")
    void resetUserPreferredDisplayMode(int displayId);
    Mode getUserPreferredDisplayMode(int displayId);
    Mode getSystemPreferredDisplayMode(int displayId);

+27 −1
Original line number Diff line number Diff line
@@ -1675,11 +1675,37 @@ public final class Display {
    @TestApi
    @RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
    public void setUserPreferredDisplayMode(@NonNull Display.Mode mode) {
        setUserPreferredDisplayMode(mode, true);
    }

    /**
     * Sets the default {@link Display.Mode} to use for the display.  The display mode includes
     * preference for resolution and refresh rate.
     * If the mode specified is not supported by the display, then no mode change occurs.
     *
     * @param mode The {@link Display.Mode} to set, which can include resolution and/or
     * refresh-rate. It is created using {@link Display.Mode.Builder}.
     * @param storeMode controls if the mode should be persisted or not.
     *`
     * @hide
     */
    @RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
    public void setUserPreferredDisplayMode(@NonNull Display.Mode mode, boolean storeMode) {
        // Create a new object containing default values for the unused fields like mode ID and
        // alternative refresh rates.
        Display.Mode preferredMode = new Display.Mode(mode.getPhysicalWidth(),
                mode.getPhysicalHeight(), mode.getRefreshRate());
        mGlobal.setUserPreferredDisplayMode(mDisplayId, preferredMode);
        mGlobal.setUserPreferredDisplayMode(mDisplayId, preferredMode, storeMode);
    }

    /**
     * Resets the default {@link Display.Mode} to use for the display from persistence.
     *`
     * @hide
     */
    @RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
    public void resetUserPreferredDisplayMode() {
        mGlobal.resetUserPreferredDisplayMode(mDisplayId);
    }

    /**
+103 −35
Original line number Diff line number Diff line
@@ -493,7 +493,7 @@ public final class DisplayManagerService extends SystemService {
    private final ArrayList<DisplayViewport> mViewports = new ArrayList<>();

    // Persistent data store for all internal settings maintained by the display manager service.
    private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
    private final PersistentDataStore mPersistentDataStore;

    // Temporary callback list, used when sending display events to applications.
    // May be used outside of the lock but only on the handler thread.
@@ -649,6 +649,7 @@ public final class DisplayManagerService extends SystemService {
        mHandler = new DisplayManagerHandler(displayThreadLooper);
        mHandlerExecutor = new HandlerExecutor(mHandler);
        mUiHandler = UiThread.getHandler();
        mPersistentDataStore = mInjector.getPersistentDataStore();
        mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
        mLogicalDisplayMapper = new LogicalDisplayMapper(mContext,
                foldSettingProvider,
@@ -2740,12 +2741,20 @@ public final class DisplayManagerService extends SystemService {
    }

    private void configurePreferredDisplayModeLocked(LogicalDisplay display) {
        final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
        final Point userPreferredResolution =
        DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
        Display.Mode mode = getStoredUserPreferredModeLocked(device);
        if (mode != null) {
            device.setUserPreferredDisplayModeLocked(mode);
        }
    }

    @Nullable
    private Display.Mode getStoredUserPreferredModeLocked(@Nullable DisplayDevice device) {
        Point userPreferredResolution =
                mPersistentDataStore.getUserPreferredResolution(device);
        final float refreshRate = mPersistentDataStore.getUserPreferredRefreshRate(device);
        float refreshRate = mPersistentDataStore.getUserPreferredRefreshRate(device);
        if (userPreferredResolution == null && Float.isNaN(refreshRate)) {
            return;
            return null;
        }
        Display.Mode.Builder modeBuilder = new Display.Mode.Builder();
        if (userPreferredResolution != null) {
@@ -2754,7 +2763,7 @@ public final class DisplayManagerService extends SystemService {
        if (!Float.isNaN(refreshRate)) {
            modeBuilder.setRefreshRate(refreshRate);
        }
        device.setUserPreferredDisplayModeLocked(modeBuilder.build());
        return modeBuilder.build();
    }

    @GuardedBy("mSyncRoot")
@@ -2837,33 +2846,80 @@ public final class DisplayManagerService extends SystemService {
        return mOverlayProperties;
    }

    void setUserPreferredDisplayModeInternal(int displayId, Display.Mode mode) {
    void resetUserPreferredDisplayModeInternal(int displayId) {
        if (!mFlags.isModeSwitchWithoutSavingEnabled()) {
            return;
        }
        synchronized (mSyncRoot) {
            Display.Mode mode;
            if (displayId == Display.INVALID_DISPLAY) {
                float refreshRate = Settings.Global.getFloat(mContext.getContentResolver(),
                        Settings.Global.USER_PREFERRED_REFRESH_RATE,
                        Display.INVALID_DISPLAY_REFRESH_RATE);
                int height = Settings.Global.getInt(mContext.getContentResolver(),
                        Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT,
                        Display.INVALID_DISPLAY_HEIGHT);
                int width = Settings.Global.getInt(mContext.getContentResolver(),
                        Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH,
                        Display.INVALID_DISPLAY_WIDTH);
                mode = new Display.Mode(width, height, refreshRate);
            } else {
                DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId);
                mode = getStoredUserPreferredModeLocked(displayDevice);
            }
            setUserPreferredDisplayModeInternal(displayId, mode, false);
        }
    }

    void setUserPreferredDisplayModeInternal(int displayId, @Nullable Display.Mode mode) {
        setUserPreferredDisplayModeInternal(displayId, mode, true);
    }

    void setUserPreferredDisplayModeInternal(
            int displayId, @Nullable Display.Mode mode, boolean storeMode) {
        synchronized (mSyncRoot) {
            if (mode != null && !isResolutionAndRefreshRateValid(mode)
                    && displayId == Display.INVALID_DISPLAY) {
                throw new IllegalArgumentException("width, height and refresh rate of mode should "
                        + "be greater than 0 when setting the global user preferred display mode.");
            }

            final int resolutionHeight = mode == null ? Display.INVALID_DISPLAY_HEIGHT
                    : mode.getPhysicalHeight();
            final int resolutionWidth = mode == null ? Display.INVALID_DISPLAY_WIDTH
                    : mode.getPhysicalWidth();
            final float refreshRate = mode == null ? Display.INVALID_DISPLAY_REFRESH_RATE
                    : mode.getRefreshRate();

            storeModeInPersistentDataStoreLocked(
                    displayId, resolutionWidth, resolutionHeight, refreshRate);
            DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId);
            if (displayDevice == null) {
                return;
            }
            if (!mFlags.isModeSwitchWithoutSavingEnabled()) {
                storeMode = true;
            }
            if (storeMode) {
                storeModeLocked(displayId, mode);
            }
            if (displayId != Display.INVALID_DISPLAY) {
                setUserPreferredModeForDisplayLocked(displayId, mode);
            } else {
                mUserPreferredMode = mode;
                storeModeInGlobalSettingsLocked(
                        resolutionWidth, resolutionHeight, refreshRate, mode);
                mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> {
                    device.setUserPreferredDisplayModeLocked(mode);
                });
            }
        }
    }

    void  storeModeLocked(int displayId, @Nullable Display.Mode mode) {
        int resolutionHeight = mode == null ? Display.INVALID_DISPLAY_HEIGHT
                : mode.getPhysicalHeight();
        int resolutionWidth = mode == null ? Display.INVALID_DISPLAY_WIDTH
                : mode.getPhysicalWidth();
        float refreshRate = mode == null ? Display.INVALID_DISPLAY_REFRESH_RATE
                : mode.getRefreshRate();
        if (displayId == Display.INVALID_DISPLAY) {
            storeModeInGlobalSettingsLocked(
                    resolutionWidth, resolutionHeight, refreshRate);
        } else {
            storeModeInPersistentDataStoreLocked(displayId,
                    resolutionWidth, resolutionHeight, refreshRate);
        }
    }

    private void storeModeInPersistentDataStoreLocked(int displayId, int resolutionWidth,
            int resolutionHeight, float refreshRate) {
        DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId);
@@ -2877,13 +2933,6 @@ public final class DisplayManagerService extends SystemService {
        } finally {
            mPersistentDataStore.saveIfNeeded();
        }
    }

    private void setUserPreferredModeForDisplayLocked(int displayId, Display.Mode mode) {
        DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId);
        if (displayDevice == null) {
            return;
        }

        // We do not yet support backup and restore for our PersistentDataStore, however, we want to
        // preserve the user's choice for HIGH/FULL resolution setting, so we when we are given a
@@ -2896,7 +2945,7 @@ public final class DisplayManagerService extends SystemService {
            //     more than two resolutions using explicit mode enums long-term.
            Point[] resolutions = displayDevice.getSupportedResolutionsLocked();
            if (resolutions.length == 2) {
                Point newMode = new Point(mode.getPhysicalWidth(), mode.getPhysicalHeight());
                Point newMode = new Point(resolutionWidth, resolutionHeight);
                int resolutionMode = newMode.equals(resolutions[0]) ? RESOLUTION_MODE_HIGH
                        : newMode.equals(resolutions[1]) ? RESOLUTION_MODE_FULL
                                : RESOLUTION_MODE_UNKNOWN;
@@ -2905,21 +2954,23 @@ public final class DisplayManagerService extends SystemService {
                        UserHandle.USER_CURRENT);
            }
        }
    }

    private void setUserPreferredModeForDisplayLocked(int displayId, Display.Mode mode) {
        DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId);
        if (displayDevice != null) {
            displayDevice.setUserPreferredDisplayModeLocked(mode);
        }
    }

    private void storeModeInGlobalSettingsLocked(
            int resolutionWidth, int resolutionHeight, float refreshRate, Display.Mode mode) {
            int resolutionWidth, int resolutionHeight, float refreshRate) {
        Settings.Global.putFloat(mContext.getContentResolver(),
                Settings.Global.USER_PREFERRED_REFRESH_RATE, refreshRate);
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT, resolutionHeight);
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH, resolutionWidth);
        mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> {
            device.setUserPreferredDisplayModeLocked(mode);
        });
    }

    /**
@@ -4060,6 +4111,10 @@ public final class DisplayManagerService extends SystemService {
        boolean canInternalDisplayHostDesktops(Context context) {
            return DesktopModeHelper.canInternalDisplayHostDesktops(context);
        }

        PersistentDataStore getPersistentDataStore() {
            return new PersistentDataStore();
        }
    }

    @VisibleForTesting
@@ -5400,11 +5455,24 @@ public final class DisplayManagerService extends SystemService {

        @EnforcePermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
        @Override // Binder call
        public void setUserPreferredDisplayMode(int displayId, Display.Mode mode) {
        public void setUserPreferredDisplayMode(int displayId, Display.Mode mode,
                boolean storeMode) {
            setUserPreferredDisplayMode_enforcePermission();
            final long token = Binder.clearCallingIdentity();
            try {
                setUserPreferredDisplayModeInternal(displayId, mode);
                setUserPreferredDisplayModeInternal(displayId, mode, storeMode);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        @EnforcePermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
        @Override // Binder call
        public void resetUserPreferredDisplayMode(int displayId) {
            resetUserPreferredDisplayMode_enforcePermission();
            final long token = Binder.clearCallingIdentity();
            try {
                resetUserPreferredDisplayModeInternal(displayId);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
+35 −2
Original line number Diff line number Diff line
@@ -86,6 +86,8 @@ class DisplayManagerShellCommand extends ShellCommand {
                return setAmbientColorTemperatureOverride();
            case "set-user-preferred-display-mode":
                return setUserPreferredDisplayMode();
            case "reset-user-preferred-display-mode":
                return resetUserPreferredDisplayMode();
            case "clear-user-preferred-display-mode":
                return clearUserPreferredDisplayMode();
            case "get-user-preferred-display-mode":
@@ -163,7 +165,17 @@ class DisplayManagerShellCommand extends ShellCommand {
        pw.println("  dwb-set-cct CCT");
        pw.println("    Sets the ambient color temperature override to CCT (use -1 to disable).");
        pw.println("  set-user-preferred-display-mode WIDTH HEIGHT REFRESH-RATE "
                + "DISPLAY_ID (optional)");
                + "DISPLAY_ID (optional) STORE_MODE (optional)");
        pw.println("    Sets the user preferred display mode which has fields WIDTH, HEIGHT and "
                + "REFRESH-RATE. If DISPLAY_ID is passed, the mode change is applied to display"
                + "with id = DISPLAY_ID, if DISPLAY_ID == -1 or missing change is applied globally."
                + " If STORE_MODE is true or missing, mode will be persisted, otherwise it will be"
                + "applied without persisting. Should be used only together with DISPLAY_ID.");
        pw.println("  reset-user-preferred-display-mode DISPLAY_ID (optional)");
        pw.println("    Resets the user preferred display mode with stored mode. "
                + "If DISPLAY_ID is passed, the persisted mode is applied to display with "
                + "id = DISPLAY_ID, if DISPLAY_ID == -1 or missing persisted mode "
                + "is applied globally.");
        pw.println("    Sets the user preferred display mode which has fields WIDTH, HEIGHT and "
                + "REFRESH-RATE. If DISPLAY_ID is passed, the mode change is applied to display"
                + "with id = DISPLAY_ID, else mode change is applied globally.");
@@ -492,8 +504,29 @@ class DisplayManagerShellCommand extends ShellCommand {
                return 1;
            }
        }
        final String storeModeText = getNextArg();
        boolean storeMode = true;
        if (storeModeText != null) {
            storeMode = Boolean.parseBoolean(storeModeText);
        }

        mService.setUserPreferredDisplayModeInternal(
                displayId, new Display.Mode(width, height, refreshRate));
                displayId, new Display.Mode(width, height, refreshRate), storeMode);
        return 0;
    }

    private int resetUserPreferredDisplayMode() {
        final String displayIdText = getNextArg();
        int displayId = Display.INVALID_DISPLAY;
        if (displayIdText != null) {
            try {
                displayId = Integer.parseInt(displayIdText);
            } catch (NumberFormatException e) {
                getErrPrintWriter().println("Error: invalid format of display ID");
                return 1;
            }
        }
        mService.resetUserPreferredDisplayModeInternal(displayId);
        return 0;
    }

Loading