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

Commit 2c484175 authored by Oleg Blinnikov's avatar Oleg Blinnikov
Browse files

Added vote to limit external display mode

Some devices prefer to limit external displays
modes up to a specific resolution and refresh rate

This CL allows OEMs to set max allowed mode for
external displays.

Change-Id: Iee8c15794d2120604cb5abbd27629bab2e7dc131
Test: atest DisplayObserverTest DisplayModeDirectorTest
Bug: 242093547
parent c5b123ad
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -5227,6 +5227,24 @@
         non-zero. -->
    <integer name="config_defaultPeakRefreshRate">0</integer>

    <!-- External display peak refresh rate for the given device. Change this value if you want to
         prevent the framework from using higher refresh rates, even if display modes with higher
         refresh rates are available from hardware composer. Only has an effect if this value and
         config_externalDisplayPeakWidth and config_externalDisplayPeakHeight are non-zero. -->
    <integer name="config_externalDisplayPeakRefreshRate">0</integer>

    <!-- External display peak width for the given device. Change this value if you want
         to prevent the framework from using higher resolution, even if display modes with higher
         resolutions are available from hardware composer. Only has an effect if this value and
         config_externalDisplayPeakRefreshRate and config_externalDisplayPeakHeight are non-zero.-->
    <integer name="config_externalDisplayPeakWidth">0</integer>

    <!-- External display peak height for the given device. Change this value if you want
         to prevent the framework from using higher resolution, even if display modes with higher
         resolutions are available from hardware composer. Only has an effect if this value and
         config_externalDisplayPeakRefreshRate and config_externalDisplayPeakWidth are non-zero. -->
    <integer name="config_externalDisplayPeakHeight">0</integer>

    <!-- The display uses different gamma curves for different refresh rates. It's hard for panel
         vendors to tune the curves to have exact same brightness for different refresh rate. So
         flicker could be observed at switch time. The issue is worse at the gamma lower end.
+3 −0
Original line number Diff line number Diff line
@@ -4231,6 +4231,9 @@
  <!-- For high refresh rate displays -->
  <java-symbol type="integer" name="config_defaultRefreshRate" />
  <java-symbol type="integer" name="config_defaultPeakRefreshRate" />
  <java-symbol type="integer" name="config_externalDisplayPeakRefreshRate" />
  <java-symbol type="integer" name="config_externalDisplayPeakWidth" />
  <java-symbol type="integer" name="config_externalDisplayPeakHeight" />
  <java-symbol type="integer" name="config_defaultRefreshRateInZone" />
  <java-symbol type="array" name="config_brightnessThresholdsOfPeakRefreshRate" />
  <java-symbol type="array" name="config_ambientThresholdsOfPeakRefreshRate" />
+11 −0
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@ public class DisplayManagerFlags {
            Flags.FLAG_ENABLE_USER_PREFERRED_MODE_VOTE,
            Flags::enableUserPreferredModeVote);

    private final FlagState mExternalDisplayLimitModeState = new FlagState(
            Flags.FLAG_ENABLE_MODE_LIMIT_FOR_EXTERNAL_DISPLAY,
            Flags::enableModeLimitForExternalDisplay);

    /** Returns whether connected display management is enabled or not. */
    public boolean isConnectedDisplayManagementEnabled() {
        return mConnectedDisplayManagementFlagState.isEnabled();
@@ -89,6 +93,13 @@ public class DisplayManagerFlags {
        return mUserPreferredModeVoteState.isEnabled();
    }

    /**
     * @return Whether external display mode limitation is enabled.
     */
    public boolean isExternalDisplayLimitModeEnabled() {
        return mExternalDisplayLimitModeState.isEnabled();
    }

    private static class FlagState {

        private final String mName;
+8 −0
Original line number Diff line number Diff line
@@ -49,3 +49,11 @@ flag {
    bug: "297018612"
    is_fixed_read_only: true
}

flag {
    name: "enable_mode_limit_for_external_display"
    namespace: "display_manager"
    description: "Feature limiting external display resolution and refresh rate"
    bug: "242093547"
    is_fixed_read_only: true
}
+54 −0
Original line number Diff line number Diff line
@@ -163,6 +163,11 @@ public class DisplayModeDirector {
     */
    private final boolean mIsUserPreferredModeVoteEnabled;

    /**
     * Whether limit display mode feature is enabled.
     */
    private final boolean mIsExternalDisplayLimitModeEnabled;

    public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler,
            @NonNull DisplayManagerFlags displayManagerFlags) {
        this(context, handler, new RealInjector(context), displayManagerFlags);
@@ -174,6 +179,8 @@ public class DisplayModeDirector {
        mIsDisplayResolutionRangeVotingEnabled = displayManagerFlags
                .isDisplayResolutionRangeVotingEnabled();
        mIsUserPreferredModeVoteEnabled = displayManagerFlags.isUserPreferredModeVoteEnabled();
        mIsExternalDisplayLimitModeEnabled =
            displayManagerFlags.isExternalDisplayLimitModeEnabled();
        mContext = context;
        mHandler = new DisplayModeDirectorHandler(handler.getLooper());
        mInjector = injector;
@@ -1457,11 +1464,29 @@ public class DisplayModeDirector {
        private final Context mContext;
        private final Handler mHandler;
        private final VotesStorage mVotesStorage;
        private int mExternalDisplayPeakWidth;
        private int mExternalDisplayPeakHeight;
        private int mExternalDisplayPeakRefreshRate;

        DisplayObserver(Context context, Handler handler, VotesStorage votesStorage) {
            mContext = context;
            mHandler = handler;
            mVotesStorage = votesStorage;
            mExternalDisplayPeakRefreshRate = mContext.getResources().getInteger(
                        R.integer.config_externalDisplayPeakRefreshRate);
            mExternalDisplayPeakWidth = mContext.getResources().getInteger(
                        R.integer.config_externalDisplayPeakWidth);
            mExternalDisplayPeakHeight = mContext.getResources().getInteger(
                        R.integer.config_externalDisplayPeakHeight);
        }

        private boolean isExternalDisplayLimitModeEnabled() {
            return mExternalDisplayPeakWidth > 0
                && mExternalDisplayPeakHeight > 0
                && mExternalDisplayPeakRefreshRate > 0
                && mIsExternalDisplayLimitModeEnabled
                && mIsDisplayResolutionRangeVotingEnabled
                && mIsUserPreferredModeVoteEnabled;
        }

        public void observe() {
@@ -1493,6 +1518,7 @@ public class DisplayModeDirector {
            updateDisplayModes(displayId, displayInfo);
            updateLayoutLimitedFrameRate(displayId, displayInfo);
            updateUserSettingDisplayPreferredSize(displayInfo);
            updateDisplaysPeakRefreshRateAndResolution(displayInfo);
        }

        @Override
@@ -1503,6 +1529,7 @@ public class DisplayModeDirector {
            }
            updateLayoutLimitedFrameRate(displayId, null);
            removeUserSettingDisplayPreferredSize(displayId);
            removeDisplaysPeakRefreshRateAndResolution(displayId);
        }

        @Override
@@ -1565,6 +1592,33 @@ public class DisplayModeDirector {
            return null;
        }

        private void removeDisplaysPeakRefreshRateAndResolution(int displayId) {
            if (!isExternalDisplayLimitModeEnabled()) {
                return;
            }

            mVotesStorage.updateVote(displayId,
                    Vote.PRIORITY_LIMIT_MODE, null);
        }

        private void updateDisplaysPeakRefreshRateAndResolution(@Nullable final DisplayInfo info) {
            // Only consider external display, only in case the refresh rate and resolution limits
            // are non-zero.
            if (info == null || info.type != Display.TYPE_EXTERNAL
                    || !isExternalDisplayLimitModeEnabled()) {
                return;
            }

            mVotesStorage.updateVote(info.displayId,
                    Vote.PRIORITY_LIMIT_MODE,
                    Vote.forSizeAndPhysicalRefreshRatesRange(
                            /* minWidth */ 0, /* minHeight */ 0,
                            mExternalDisplayPeakWidth,
                            mExternalDisplayPeakHeight,
                            /* minPhysicalRefreshRate */ 0,
                            mExternalDisplayPeakRefreshRate));
        }

        private void updateDisplayModes(int displayId, @Nullable DisplayInfo info) {
            if (info == null) {
                return;
Loading