Merge "External display mode limit flag in settings" into main

This commit is contained in:
Oleg Blinnikov
2024-07-24 20:50:46 +00:00
committed by Android (Google) Code Review
4 changed files with 83 additions and 11 deletions

View File

@@ -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.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_REMOVED;
import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.display.feature.flags.Flags.enableModeLimitForExternalDisplay;
import android.content.Context; import android.content.Context;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.DisplayManagerGlobal;
@@ -271,6 +273,13 @@ public class ExternalDisplaySettingsConfiguration {
public void setUserPreferredDisplayMode(int displayId, @NonNull Mode mode) { public void setUserPreferredDisplayMode(int displayId, @NonNull Mode mode) {
DisplayManagerGlobal.getInstance().setUserPreferredDisplayMode(displayId, 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 { public abstract static class DisplayListener implements DisplayManager.DisplayListener {

View File

@@ -52,7 +52,7 @@ import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
public class ResolutionPreferenceFragment extends SettingsPreferenceFragmentBase { 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 int DEFAULT_LOW_REFRESH_RATE = 60;
static final String MORE_OPTIONS_KEY = "more_options"; static final String MORE_OPTIONS_KEY = "more_options";
static final String TOP_OPTIONS_KEY = "top_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; R.string.external_display_more_options_title;
static final int EXTERNAL_DISPLAY_RESOLUTION_SETTINGS_RESOURCE = static final int EXTERNAL_DISPLAY_RESOLUTION_SETTINGS_RESOURCE =
R.xml.external_display_resolution_settings; 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 @Nullable
private Injector mInjector; private Injector mInjector;
@Nullable @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) { private void updateDisplayModeLimits(@Nullable Context context) {
if (context == null) { if (context == null) {
return; return;
} }
mExternalDisplayPeakRefreshRate = getResources(context).getInteger( mExternalDisplayPeakRefreshRate = getResources(context).getInteger(
com.android.internal.R.integer.config_externalDisplayPeakRefreshRate); com.android.internal.R.integer.config_externalDisplayPeakRefreshRate);
mExternalDisplayPeakWidth = getResources(context).getInteger( if (isDisplayResolutionLimitEnabled()) {
mExternalDisplayPeakWidth = getResources(context).getInteger(
com.android.internal.R.integer.config_externalDisplayPeakWidth); com.android.internal.R.integer.config_externalDisplayPeakWidth);
mExternalDisplayPeakHeight = getResources(context).getInteger( mExternalDisplayPeakHeight = getResources(context).getInteger(
com.android.internal.R.integer.config_externalDisplayPeakHeight); com.android.internal.R.integer.config_externalDisplayPeakHeight);
}
mRefreshRateSynchronizationEnabled = getResources(context).getBoolean( mRefreshRateSynchronizationEnabled = getResources(context).getBoolean(
com.android.internal.R.bool.config_refreshRateSynchronizationEnabled); com.android.internal.R.bool.config_refreshRateSynchronizationEnabled);
Log.d(TAG, "mExternalDisplayPeakRefreshRate=" + mExternalDisplayPeakRefreshRate); Log.d(TAG, "mExternalDisplayPeakRefreshRate=" + mExternalDisplayPeakRefreshRate);

View File

@@ -87,6 +87,7 @@ public class ExternalDisplayTestBase {
doReturn(mHandler).when(mMockedInjector).getHandler(); doReturn(mHandler).when(mMockedInjector).getHandler();
doReturn("").when(mMockedInjector).getSystemProperty( doReturn("").when(mMockedInjector).getSystemProperty(
VIRTUAL_DISPLAY_PACKAGE_NAME_SYSTEM_PROPERTY); VIRTUAL_DISPLAY_PACKAGE_NAME_SYSTEM_PROPERTY);
doReturn(true).when(mMockedInjector).isModeLimitForExternalDisplayEnabled();
doAnswer((arg) -> { doAnswer((arg) -> {
mListener = arg.getArgument(0); mListener = arg.getArgument(0);
return null; return null;

View File

@@ -17,6 +17,7 @@ package com.android.settings.connecteddevice.display;
import static android.view.Display.INVALID_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.EXTERNAL_DISPLAY_RESOLUTION_SETTINGS_RESOURCE;
import static com.android.settings.connecteddevice.display.ResolutionPreferenceFragment.MORE_OPTIONS_KEY; import static com.android.settings.connecteddevice.display.ResolutionPreferenceFragment.MORE_OPTIONS_KEY;
import static com.android.settings.connecteddevice.display.ResolutionPreferenceFragment.TOP_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.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.util.Pair;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
@@ -83,18 +85,52 @@ public class ResolutionPreferenceFragmentTest extends ExternalDisplayTestBase {
@Test @Test
@UiThreadTest @UiThreadTest
public void testModePreferences() { public void testModePreferences_modeLimitFlagIsOn_noOverride() {
mDisplayIdArg = 1; doReturn(true).when(mMockedInjector).isModeLimitForExternalDisplayEnabled();
initFragment(); doReturn(null).when(mMockedInjector).getSystemProperty(
mHandler.flush(); DISPLAY_MODE_LIMIT_OVERRIDE_PROP);
PreferenceCategory topPref = mPreferenceScreen.findPreference(TOP_OPTIONS_KEY); var topAndMorePref = runTestModePreferences();
assertThat(topPref).isNotNull(); PreferenceCategory topPref = topAndMorePref.first, morePref = topAndMorePref.second;
PreferenceCategory morePref = mPreferenceScreen.findPreference(MORE_OPTIONS_KEY);
assertThat(morePref).isNotNull();
assertThat(topPref.getPreferenceCount()).isEqualTo(3); assertThat(topPref.getPreferenceCount()).isEqualTo(3);
assertThat(morePref.getPreferenceCount()).isEqualTo(1); 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 @Test
@UiThreadTest @UiThreadTest
public void testModeChange() { public void testModeChange() {
@@ -109,6 +145,17 @@ public class ResolutionPreferenceFragmentTest extends ExternalDisplayTestBase {
verify(mMockedInjector).setUserPreferredDisplayMode(mDisplayIdArg, mode); verify(mMockedInjector).setUserPreferredDisplayMode(mDisplayIdArg, mode);
} }
private Pair<PreferenceCategory, PreferenceCategory> 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() { private void initFragment() {
if (mFragment != null) { if (mFragment != null) {
return; return;