diff --git a/src/com/android/settings/connecteddevice/display/ExternalDisplaySettingsConfiguration.java b/src/com/android/settings/connecteddevice/display/ExternalDisplaySettingsConfiguration.java index 89d464c9a4e..c9ea8ae0a04 100644 --- a/src/com/android/settings/connecteddevice/display/ExternalDisplaySettingsConfiguration.java +++ b/src/com/android/settings/connecteddevice/display/ExternalDisplaySettingsConfiguration.java @@ -23,6 +23,8 @@ import static android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_CONNECT import static android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_REMOVED; import static android.view.Display.INVALID_DISPLAY; +import static com.android.server.display.feature.flags.Flags.enableModeLimitForExternalDisplay; + import android.content.Context; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; @@ -271,6 +273,13 @@ public class ExternalDisplaySettingsConfiguration { public void setUserPreferredDisplayMode(int displayId, @NonNull Mode mode) { DisplayManagerGlobal.getInstance().setUserPreferredDisplayMode(displayId, mode); } + + /** + * @return true if the display mode limit flag enabled. + */ + public boolean isModeLimitForExternalDisplayEnabled() { + return enableModeLimitForExternalDisplay(); + } } public abstract static class DisplayListener implements DisplayManager.DisplayListener { diff --git a/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragment.java b/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragment.java index 10314cb1e21..db81be89a42 100644 --- a/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragment.java +++ b/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragment.java @@ -52,7 +52,7 @@ import java.util.ArrayList; import java.util.HashSet; public class ResolutionPreferenceFragment extends SettingsPreferenceFragmentBase { - private static final String TAG = "ResolutionPreferenceFragment"; + private static final String TAG = "ResolutionPreference"; static final int DEFAULT_LOW_REFRESH_RATE = 60; static final String MORE_OPTIONS_KEY = "more_options"; static final String TOP_OPTIONS_KEY = "top_options"; @@ -60,6 +60,8 @@ public class ResolutionPreferenceFragment extends SettingsPreferenceFragmentBase R.string.external_display_more_options_title; static final int EXTERNAL_DISPLAY_RESOLUTION_SETTINGS_RESOURCE = R.xml.external_display_resolution_settings; + static final String DISPLAY_MODE_LIMIT_OVERRIDE_PROP = "persist.sys.com.android.server.display" + + ".feature.flags.enable_mode_limit_for_external_display-override"; @Nullable private Injector mInjector; @Nullable @@ -323,16 +325,29 @@ public class ResolutionPreferenceFragment extends SettingsPreferenceFragmentBase } } + private boolean isDisplayResolutionLimitEnabled() { + if (mInjector == null) { + return false; + } + var flagOverride = mInjector.getSystemProperty(DISPLAY_MODE_LIMIT_OVERRIDE_PROP); + var isOverrideEnabled = "true".equals(flagOverride); + var isOverrideEnabledOrNotSet = !"false".equals(flagOverride); + return (mInjector.isModeLimitForExternalDisplayEnabled() && isOverrideEnabledOrNotSet) + || isOverrideEnabled; + } + private void updateDisplayModeLimits(@Nullable Context context) { if (context == null) { return; } mExternalDisplayPeakRefreshRate = getResources(context).getInteger( com.android.internal.R.integer.config_externalDisplayPeakRefreshRate); - mExternalDisplayPeakWidth = getResources(context).getInteger( + if (isDisplayResolutionLimitEnabled()) { + mExternalDisplayPeakWidth = getResources(context).getInteger( com.android.internal.R.integer.config_externalDisplayPeakWidth); - mExternalDisplayPeakHeight = getResources(context).getInteger( + mExternalDisplayPeakHeight = getResources(context).getInteger( com.android.internal.R.integer.config_externalDisplayPeakHeight); + } mRefreshRateSynchronizationEnabled = getResources(context).getBoolean( com.android.internal.R.bool.config_refreshRateSynchronizationEnabled); Log.d(TAG, "mExternalDisplayPeakRefreshRate=" + mExternalDisplayPeakRefreshRate); diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java index 60b034288a0..4cba1ef4666 100644 --- a/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java +++ b/tests/unit/src/com/android/settings/connecteddevice/display/ExternalDisplayTestBase.java @@ -87,6 +87,7 @@ public class ExternalDisplayTestBase { doReturn(mHandler).when(mMockedInjector).getHandler(); doReturn("").when(mMockedInjector).getSystemProperty( VIRTUAL_DISPLAY_PACKAGE_NAME_SYSTEM_PROPERTY); + doReturn(true).when(mMockedInjector).isModeLimitForExternalDisplayEnabled(); doAnswer((arg) -> { mListener = arg.getArgument(0); return null; diff --git a/tests/unit/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragmentTest.java b/tests/unit/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragmentTest.java index ee38a1cbae2..c8663622e74 100644 --- a/tests/unit/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragmentTest.java +++ b/tests/unit/src/com/android/settings/connecteddevice/display/ResolutionPreferenceFragmentTest.java @@ -17,6 +17,7 @@ package com.android.settings.connecteddevice.display; import static android.view.Display.INVALID_DISPLAY; +import static com.android.settings.connecteddevice.display.ResolutionPreferenceFragment.DISPLAY_MODE_LIMIT_OVERRIDE_PROP; import static com.android.settings.connecteddevice.display.ResolutionPreferenceFragment.EXTERNAL_DISPLAY_RESOLUTION_SETTINGS_RESOURCE; import static com.android.settings.connecteddevice.display.ResolutionPreferenceFragment.MORE_OPTIONS_KEY; import static com.android.settings.connecteddevice.display.ResolutionPreferenceFragment.TOP_OPTIONS_KEY; @@ -29,6 +30,7 @@ import static org.mockito.Mockito.verify; import android.content.Context; import android.content.res.Resources; +import android.util.Pair; import android.view.View; import android.widget.TextView; @@ -83,18 +85,52 @@ public class ResolutionPreferenceFragmentTest extends ExternalDisplayTestBase { @Test @UiThreadTest - public void testModePreferences() { - mDisplayIdArg = 1; - initFragment(); - mHandler.flush(); - PreferenceCategory topPref = mPreferenceScreen.findPreference(TOP_OPTIONS_KEY); - assertThat(topPref).isNotNull(); - PreferenceCategory morePref = mPreferenceScreen.findPreference(MORE_OPTIONS_KEY); - assertThat(morePref).isNotNull(); + public void testModePreferences_modeLimitFlagIsOn_noOverride() { + doReturn(true).when(mMockedInjector).isModeLimitForExternalDisplayEnabled(); + doReturn(null).when(mMockedInjector).getSystemProperty( + DISPLAY_MODE_LIMIT_OVERRIDE_PROP); + var topAndMorePref = runTestModePreferences(); + PreferenceCategory topPref = topAndMorePref.first, morePref = topAndMorePref.second; assertThat(topPref.getPreferenceCount()).isEqualTo(3); assertThat(morePref.getPreferenceCount()).isEqualTo(1); } + @Test + @UiThreadTest + public void testModePreferences_noModeLimitFlag_overrideIsTrue() { + doReturn(false).when(mMockedInjector).isModeLimitForExternalDisplayEnabled(); + doReturn("true").when(mMockedInjector).getSystemProperty( + DISPLAY_MODE_LIMIT_OVERRIDE_PROP); + var topAndMorePref = runTestModePreferences(); + PreferenceCategory topPref = topAndMorePref.first, morePref = topAndMorePref.second; + assertThat(topPref.getPreferenceCount()).isEqualTo(3); + assertThat(morePref.getPreferenceCount()).isEqualTo(1); + } + + @Test + @UiThreadTest + public void testModePreferences_noModeLimitFlag_noOverride() { + doReturn(false).when(mMockedInjector).isModeLimitForExternalDisplayEnabled(); + doReturn(null).when(mMockedInjector).getSystemProperty( + DISPLAY_MODE_LIMIT_OVERRIDE_PROP); + var topAndMorePref = runTestModePreferences(); + PreferenceCategory topPref = topAndMorePref.first, morePref = topAndMorePref.second; + assertThat(topPref.getPreferenceCount()).isEqualTo(3); + assertThat(morePref.getPreferenceCount()).isEqualTo(2); + } + + @Test + @UiThreadTest + public void testModePreferences_modeLimitFlagIsOn_butOverrideIsFalse() { + doReturn(true).when(mMockedInjector).isModeLimitForExternalDisplayEnabled(); + doReturn("false").when(mMockedInjector).getSystemProperty( + DISPLAY_MODE_LIMIT_OVERRIDE_PROP); + var topAndMorePref = runTestModePreferences(); + PreferenceCategory topPref = topAndMorePref.first, morePref = topAndMorePref.second; + assertThat(topPref.getPreferenceCount()).isEqualTo(3); + assertThat(morePref.getPreferenceCount()).isEqualTo(2); + } + @Test @UiThreadTest public void testModeChange() { @@ -109,6 +145,17 @@ public class ResolutionPreferenceFragmentTest extends ExternalDisplayTestBase { verify(mMockedInjector).setUserPreferredDisplayMode(mDisplayIdArg, mode); } + private Pair runTestModePreferences() { + mDisplayIdArg = 1; + initFragment(); + mHandler.flush(); + PreferenceCategory topPref = mPreferenceScreen.findPreference(TOP_OPTIONS_KEY); + assertThat(topPref).isNotNull(); + PreferenceCategory morePref = mPreferenceScreen.findPreference(MORE_OPTIONS_KEY); + assertThat(morePref).isNotNull(); + return new Pair<>(topPref, morePref); + } + private void initFragment() { if (mFragment != null) { return;