Back up the smooth display setting

- Convert "Smooth display" and "Force peak refresh rate" to a boolean. If they are a boolean, they can be backed up without being device-specific.
- Back up "Smooth display" and add a validator
- Upgrade the settings in SettingsProvider
- Create a utils class - RefreshRateSettingsUtils

Bug: 211737588
Test: atest DisplayModeDirectorTest
Test: atest ForcePeakRefreshRatePreferenceControllerTest
Test: atest PeakRefreshRatePreferenceControllerTest
Test: atest SettingsBackupTest
Test: atest SettingsProviderTest
Test: atest RefreshRateSettingsUtilsTest
Change-Id: Ib2cb2dd100f06f5452083b7606109a486e795a0e
Merged-In: Ib2cb2dd100f06f5452083b7606109a486e795a0e
This commit is contained in:
Piotr Wilczyński
2023-03-10 16:35:19 +00:00
parent 766ec400f2
commit 492e36aa05
9 changed files with 457 additions and 53 deletions

View File

@@ -4668,22 +4668,16 @@ public final class Settings {
"display_color_mode_vendor_hint";
/**
* The user selected min refresh rate in frames per second.
*
* If this isn't set, 0 will be used.
* Whether or not the peak refresh rate should be forced. 0=no, 1=yes
* @hide
*/
@Readable
public static final String MIN_REFRESH_RATE = "min_refresh_rate";
public static final String FORCE_PEAK_REFRESH_RATE = "force_peak_refresh_rate";
/**
* The user selected peak refresh rate in frames per second.
*
* If this isn't set, the system falls back to a device specific default.
* Whether or not the peak refresh rate should be used for some content. 0=no, 1=yes
* @hide
*/
@Readable
public static final String PEAK_REFRESH_RATE = "peak_refresh_rate";
public static final String SMOOTH_DISPLAY = "smooth_display";
/**
* The amount of time in milliseconds before the device goes to sleep or begins

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.display;
import android.content.ContentResolver;
import android.content.Context;
import android.hardware.display.DisplayManager;
import android.provider.Settings;
import android.util.Log;
import android.view.Display;
/**
* Constants and utility methods for refresh rate settings.
*/
public class RefreshRateSettingsUtils {
private static final String TAG = "RefreshRateSettingsUtils";
public static final float DEFAULT_REFRESH_RATE = 60f;
/**
* Find the highest refresh rate among all the modes of the default display.
* @param context The context
* @return The highest refresh rate
*/
public static float findHighestRefreshRateForDefaultDisplay(Context context) {
final DisplayManager dm = context.getSystemService(DisplayManager.class);
final Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
if (display == null) {
Log.w(TAG, "No valid default display device");
return DEFAULT_REFRESH_RATE;
}
float maxRefreshRate = DEFAULT_REFRESH_RATE;
for (Display.Mode mode : display.getSupportedModes()) {
if (Math.round(mode.getRefreshRate()) > maxRefreshRate) {
maxRefreshRate = mode.getRefreshRate();
}
}
return maxRefreshRate;
}
/**
* Get the min refresh rate which is determined by
* {@link Settings.System.FORCE_PEAK_REFRESH_RATE}.
* @param context The context
* @return The min refresh rate
*/
public static float getMinRefreshRate(Context context) {
final ContentResolver cr = context.getContentResolver();
int forcePeakRefreshRateSetting = Settings.System.getIntForUser(cr,
Settings.System.FORCE_PEAK_REFRESH_RATE, -1, cr.getUserId());
return forcePeakRefreshRateSetting == 1
? findHighestRefreshRateForDefaultDisplay(context)
: 0;
}
/**
* Get the peak refresh rate which is determined by {@link Settings.System.SMOOTH_DISPLAY}.
* @param context The context
* @param defaultPeakRefreshRate The refresh rate to return if the setting doesn't have a value
* @return The peak refresh rate
*/
public static float getPeakRefreshRate(Context context, float defaultPeakRefreshRate) {
final ContentResolver cr = context.getContentResolver();
int smoothDisplaySetting = Settings.System.getIntForUser(cr,
Settings.System.SMOOTH_DISPLAY, -1, cr.getUserId());
switch (smoothDisplaySetting) {
case 0:
return DEFAULT_REFRESH_RATE;
case 1:
return findHighestRefreshRateForDefaultDisplay(context);
default:
return defaultPeakRefreshRate;
}
}
}

View File

@@ -100,5 +100,6 @@ public class SystemSettings {
Settings.System.CAMERA_FLASH_NOTIFICATION,
Settings.System.SCREEN_FLASH_NOTIFICATION,
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR,
Settings.System.SMOOTH_DISPLAY
};
}

View File

@@ -226,5 +226,6 @@ public class SystemSettingsValidators {
VALIDATORS.put(System.CAMERA_FLASH_NOTIFICATION, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.SCREEN_FLASH_NOTIFICATION, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.SCREEN_FLASH_NOTIFICATION_COLOR, ANY_INTEGER_VALIDATOR);
VALIDATORS.put(System.SMOOTH_DISPLAY, BOOLEAN_VALIDATOR);
}
}

View File

@@ -34,6 +34,7 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OV
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.util.AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM;
import static com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
import static com.android.providers.settings.SettingsState.FALLBACK_FILE_SUFFIX;
import static com.android.providers.settings.SettingsState.getTypeFromKey;
import static com.android.providers.settings.SettingsState.getUserIdFromKey;
@@ -3748,7 +3749,7 @@ public class SettingsProvider extends ContentProvider {
}
private final class UpgradeController {
private static final int SETTINGS_VERSION = 218;
private static final int SETTINGS_VERSION = 219;
private final int mUserId;
@@ -5673,7 +5674,7 @@ public class SettingsProvider extends ContentProvider {
providers.addAll(Arrays.asList(resources.getStringArray(resourceId)));
} catch (Resources.NotFoundException e) {
Slog.w(LOG_TAG,
"Get default array Cred Provider not found: " + e.toString());
"Get default array Cred Provider not found: " + e.toString());
}
try {
final String storedValue = resources.getString(resourceId);
@@ -5682,7 +5683,7 @@ public class SettingsProvider extends ContentProvider {
}
} catch (Resources.NotFoundException e) {
Slog.w(LOG_TAG,
"Get default Cred Provider not found: " + e.toString());
"Get default Cred Provider not found: " + e.toString());
}
if (!providers.isEmpty()) {
@@ -5731,8 +5732,8 @@ public class SettingsProvider extends ContentProvider {
final Setting currentSetting = secureSettings
.getSettingLocked(Settings.Secure.CREDENTIAL_SERVICE);
if (currentSetting.isNull()) {
final int resourceId =
com.android.internal.R.array.config_defaultCredentialProviderService;
final int resourceId = com.android.internal.R.array
.config_defaultCredentialProviderService;
final Resources resources = getContext().getResources();
// If the config has not be defined we might get an exception.
final List<String> providers = new ArrayList<>();
@@ -5740,7 +5741,7 @@ public class SettingsProvider extends ContentProvider {
providers.addAll(Arrays.asList(resources.getStringArray(resourceId)));
} catch (Resources.NotFoundException e) {
Slog.w(LOG_TAG,
"Get default array Cred Provider not found: " + e.toString());
"Get default array Cred Provider not found: " + e.toString());
}
if (!providers.isEmpty()) {
@@ -5839,6 +5840,47 @@ public class SettingsProvider extends ContentProvider {
currentVersion = 218;
}
// v218: Convert Smooth Display and Force Peak Refresh Rate to a boolean
if (currentVersion == 218) {
final String peakRefreshRateSettingName = "peak_refresh_rate";
final String minRefreshRateSettingName = "min_refresh_rate";
final SettingsState systemSettings = getSystemSettingsLocked(userId);
final Setting peakRefreshRateSetting =
systemSettings.getSettingLocked(peakRefreshRateSettingName);
final Setting minRefreshRateSetting =
systemSettings.getSettingLocked(minRefreshRateSettingName);
float peakRefreshRate = DEFAULT_REFRESH_RATE;
float minRefreshRate = 0;
try {
if (!peakRefreshRateSetting.isNull()) {
peakRefreshRate = Float.parseFloat(peakRefreshRateSetting.getValue());
}
} catch (NumberFormatException e) {
// Do nothing. Overwrite with default value.
}
try {
if (!minRefreshRateSetting.isNull()) {
minRefreshRate = Float.parseFloat(minRefreshRateSetting.getValue());
}
} catch (NumberFormatException e) {
// Do nothing. Overwrite with default value.
}
systemSettings.deleteSettingLocked(peakRefreshRateSettingName);
systemSettings.deleteSettingLocked(minRefreshRateSettingName);
systemSettings.insertSettingLocked(Settings.System.SMOOTH_DISPLAY,
peakRefreshRate > DEFAULT_REFRESH_RATE ? "1" : "0", /* tag= */ null,
/* makeDefault= */ false, SettingsState.SYSTEM_PACKAGE_NAME);
systemSettings.insertSettingLocked(Settings.System.FORCE_PEAK_REFRESH_RATE,
minRefreshRate > 0 ? "1" : "0", /* tag= */ null,
/* makeDefault= */ false, SettingsState.SYSTEM_PACKAGE_NAME);
currentVersion = 219;
}
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {

View File

@@ -97,8 +97,7 @@ public class SettingsBackupTest {
Settings.System.WHEN_TO_MAKE_WIFI_CALLS, // bug?
Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, // used for debugging only
Settings.System.DESKTOP_MODE, // developer setting for internal prototyping
Settings.System.MIN_REFRESH_RATE, // depends on hardware capabilities
Settings.System.PEAK_REFRESH_RATE, // depends on hardware capabilities
Settings.System.FORCE_PEAK_REFRESH_RATE, // depends on hardware capabilities
Settings.System.SCREEN_BRIGHTNESS_FLOAT,
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
Settings.System.MULTI_AUDIO_FOCUS_ENABLED // form-factor/OEM specific

View File

@@ -65,6 +65,7 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.display.RefreshRateSettingsUtils;
import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
import com.android.server.display.DisplayDeviceConfig;
@@ -1171,7 +1172,7 @@ public class DisplayModeDirector {
public static final int PRIORITY_HIGH_BRIGHTNESS_MODE = 2;
// SETTING_MIN_RENDER_FRAME_RATE is used to propose a lower bound of the render frame rate.
// It votes [MIN_REFRESH_RATE, Float.POSITIVE_INFINITY]
// It votes [minRefreshRate, Float.POSITIVE_INFINITY]
public static final int PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE = 3;
// APP_REQUEST_RENDER_FRAME_RATE_RANGE is used to for internal apps to limit the render
@@ -1376,10 +1377,10 @@ public class DisplayModeDirector {
@VisibleForTesting
final class SettingsObserver extends ContentObserver {
private final Uri mPeakRefreshRateSetting =
Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
private final Uri mMinRefreshRateSetting =
Settings.System.getUriFor(Settings.System.MIN_REFRESH_RATE);
private final Uri mSmoothDisplaySetting =
Settings.System.getUriFor(Settings.System.SMOOTH_DISPLAY);
private final Uri mForcePeakRefreshRateSetting =
Settings.System.getUriFor(Settings.System.FORCE_PEAK_REFRESH_RATE);
private final Uri mLowPowerModeSetting =
Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE);
private final Uri mMatchContentFrameRateSetting =
@@ -1415,9 +1416,8 @@ public class DisplayModeDirector {
public void observe() {
final ContentResolver cr = mContext.getContentResolver();
mInjector.registerPeakRefreshRateObserver(cr, this);
cr.registerContentObserver(mMinRefreshRateSetting, false /*notifyDescendants*/, this,
UserHandle.USER_SYSTEM);
mInjector.registerSmoothDisplayObserver(cr, this);
mInjector.registerForcePeakRefreshRateObserver(cr, this);
cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this,
UserHandle.USER_SYSTEM);
cr.registerContentObserver(mMatchContentFrameRateSetting, false /*notifyDescendants*/,
@@ -1459,8 +1459,8 @@ public class DisplayModeDirector {
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
synchronized (mLock) {
if (mPeakRefreshRateSetting.equals(uri)
|| mMinRefreshRateSetting.equals(uri)) {
if (mSmoothDisplaySetting.equals(uri)
|| mForcePeakRefreshRateSetting.equals(uri)) {
updateRefreshRateSettingLocked();
} else if (mLowPowerModeSetting.equals(uri)) {
updateLowPowerModeSettingLocked();
@@ -1515,12 +1515,9 @@ public class DisplayModeDirector {
}
private void updateRefreshRateSettingLocked() {
final ContentResolver cr = mContext.getContentResolver();
float minRefreshRate = Settings.System.getFloatForUser(cr,
Settings.System.MIN_REFRESH_RATE, 0f, cr.getUserId());
float peakRefreshRate = Settings.System.getFloatForUser(cr,
Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate, cr.getUserId());
updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate);
updateRefreshRateSettingLocked(RefreshRateSettingsUtils.getMinRefreshRate(mContext),
RefreshRateSettingsUtils.getPeakRefreshRate(mContext, mDefaultPeakRefreshRate),
mDefaultRefreshRate);
}
private void updateRefreshRateSettingLocked(
@@ -3165,12 +3162,17 @@ public class DisplayModeDirector {
}
interface Injector {
Uri PEAK_REFRESH_RATE_URI = Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
Uri SMOOTH_DISPLAY_URI = Settings.System.getUriFor(Settings.System.SMOOTH_DISPLAY);
Uri FORCE_PEAK_REFRESH_RATE_URI =
Settings.System.getUriFor(Settings.System.FORCE_PEAK_REFRESH_RATE);
@NonNull
DeviceConfigInterface getDeviceConfig();
void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
void registerSmoothDisplayObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer);
void registerForcePeakRefreshRateObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer);
void registerDisplayListener(@NonNull DisplayManager.DisplayListener listener,
@@ -3205,9 +3207,16 @@ public class DisplayModeDirector {
}
@Override
public void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
public void registerSmoothDisplayObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer) {
cr.registerContentObserver(PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/,
cr.registerContentObserver(SMOOTH_DISPLAY_URI, false /*notifyDescendants*/,
observer, UserHandle.USER_SYSTEM);
}
@Override
public void registerForcePeakRefreshRateObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer) {
cr.registerContentObserver(FORCE_PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/,
observer, UserHandle.USER_SYSTEM);
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.display;
import static com.android.internal.display.RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import android.hardware.display.DisplayManager;
import android.provider.Settings;
import android.testing.TestableContext;
import android.view.Display;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.display.RefreshRateSettingsUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class RefreshRateSettingsUtilsTest {
@Rule
public final TestableContext mContext = new TestableContext(
InstrumentationRegistry.getInstrumentation().getContext());
@Mock
private DisplayManager mDisplayManagerMock;
@Mock
private Display mDisplayMock;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext.addMockSystemService(DisplayManager.class, mDisplayManagerMock);
Display.Mode[] modes = new Display.Mode[] {
new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
/* refreshRate= */ 60),
new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
/* refreshRate= */ 120),
new Display.Mode(/* modeId= */ 0, /* width= */ 800, /* height= */ 600,
/* refreshRate= */ 90)
};
when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
when(mDisplayMock.getSupportedModes()).thenReturn(modes);
}
@Test
public void testFindHighestRefreshRateForDefaultDisplay() {
when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(null);
assertEquals(DEFAULT_REFRESH_RATE,
RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
/* delta= */ 0);
when(mDisplayManagerMock.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mDisplayMock);
assertEquals(120,
RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
/* delta= */ 0);
}
@Test
public void testGetMinRefreshRate() {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.FORCE_PEAK_REFRESH_RATE, -1);
assertEquals(0, RefreshRateSettingsUtils.getMinRefreshRate(mContext), /* delta= */ 0);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.FORCE_PEAK_REFRESH_RATE, 0);
assertEquals(0, RefreshRateSettingsUtils.getMinRefreshRate(mContext), /* delta= */ 0);
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.FORCE_PEAK_REFRESH_RATE, 1);
assertEquals(120, RefreshRateSettingsUtils.getMinRefreshRate(mContext), /* delta= */ 0);
}
@Test
public void testGetPeakRefreshRate() {
float defaultPeakRefreshRate = 100;
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY, -1);
assertEquals(defaultPeakRefreshRate,
RefreshRateSettingsUtils.getPeakRefreshRate(mContext, defaultPeakRefreshRate),
/* delta= */ 0);
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY, 0);
assertEquals(DEFAULT_REFRESH_RATE,
RefreshRateSettingsUtils.getPeakRefreshRate(mContext, defaultPeakRefreshRate),
/* delta= */ 0);
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY, 1);
assertEquals(120,
RefreshRateSettingsUtils.getPeakRefreshRate(mContext, defaultPeakRefreshRate),
/* delta= */ 0);
}
}

View File

@@ -84,6 +84,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.display.RefreshRateSettingsUtils;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.Preconditions;
import com.android.internal.util.test.FakeSettingsProvider;
@@ -158,6 +159,9 @@ public class DisplayModeDirectorTest {
LocalServices.addService(SensorManagerInternal.class, mSensorManagerInternalMock);
LocalServices.removeServiceForTest(DisplayManagerInternal.class);
LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock);
clearSmoothDisplaySetting();
clearForcePeakRefreshRateSetting();
}
private DisplayModeDirector createDirectorFromRefreshRateArray(
@@ -919,7 +923,6 @@ public class DisplayModeDirectorTest {
public void testLockFpsForLowZone() throws Exception {
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
setPeakRefreshRate(90);
director.getSettingsObserver().setDefaultRefreshRate(90);
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
@@ -927,6 +930,7 @@ public class DisplayModeDirectorTest {
config.setRefreshRateInLowZone(90);
config.setLowDisplayBrightnessThresholds(new int[] { 10 });
config.setLowAmbientBrightnessThresholds(new int[] { 20 });
config.setDefaultPeakRefreshRate(90);
Sensor lightSensor = createLightSensor();
SensorManager sensorManager = createMockSensorManager(lightSensor);
@@ -977,7 +981,6 @@ public class DisplayModeDirectorTest {
public void testLockFpsForHighZone() throws Exception {
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
setPeakRefreshRate(90 /*fps*/);
director.getSettingsObserver().setDefaultRefreshRate(90);
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
@@ -985,6 +988,7 @@ public class DisplayModeDirectorTest {
config.setRefreshRateInHighZone(60);
config.setHighDisplayBrightnessThresholds(new int[] { 255 });
config.setHighAmbientBrightnessThresholds(new int[] { 8000 });
config.setDefaultPeakRefreshRate(90);
Sensor lightSensor = createLightSensor();
SensorManager sensorManager = createMockSensorManager(lightSensor);
@@ -1031,6 +1035,113 @@ public class DisplayModeDirectorTest {
assertThat(vote.disableRefreshRateSwitching).isTrue();
}
@Test
public void testSmoothDisplay() {
float defaultRefreshRate = 60;
int defaultPeakRefreshRate = 100;
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
director.getSettingsObserver().setDefaultRefreshRate(defaultRefreshRate);
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
final FakeDeviceConfig config = mInjector.getDeviceConfig();
config.setDefaultPeakRefreshRate(defaultPeakRefreshRate);
Sensor lightSensor = createLightSensor();
SensorManager sensorManager = createMockSensorManager(lightSensor);
director.start(sensorManager);
// Default value of the setting
Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
defaultPeakRefreshRate);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
Float.POSITIVE_INFINITY);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
defaultRefreshRate);
setSmoothDisplayEnabled(false);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
Float.POSITIVE_INFINITY);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
defaultRefreshRate);
setSmoothDisplayEnabled(true);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
Float.POSITIVE_INFINITY);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
defaultRefreshRate);
}
@Test
public void testForcePeakRefreshRate() {
float defaultRefreshRate = 60;
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
director.getSettingsObserver().setDefaultRefreshRate(defaultRefreshRate);
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
Sensor lightSensor = createLightSensor();
SensorManager sensorManager = createMockSensorManager(lightSensor);
director.start(sensorManager);
setForcePeakRefreshRateEnabled(false);
setSmoothDisplayEnabled(false);
Vote vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0,
/* frameRateHigh= */ Float.POSITIVE_INFINITY);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
defaultRefreshRate);
setForcePeakRefreshRateEnabled(true);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext));
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */
RefreshRateSettingsUtils.findHighestRefreshRateForDefaultDisplay(mContext),
/* frameRateHigh= */ Float.POSITIVE_INFINITY);
vote = director.getVote(Display.DEFAULT_DISPLAY,
Vote.PRIORITY_DEFAULT_RENDER_FRAME_RATE);
assertVoteForRenderFrameRateRange(vote, /* frameRateLow= */ 0, /* frameRateHigh= */
defaultRefreshRate);
}
@Test
public void testSensorRegistration() {
// First, configure brightness zones or DMD won't register for sensor data.
@@ -1038,10 +1149,10 @@ public class DisplayModeDirectorTest {
config.setRefreshRateInHighZone(60);
config.setHighDisplayBrightnessThresholds(new int[] { 255 });
config.setHighAmbientBrightnessThresholds(new int[] { 8000 });
config.setDefaultPeakRefreshRate(90);
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
setPeakRefreshRate(90 /*fps*/);
director.getSettingsObserver().setDefaultRefreshRate(90);
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
@@ -2417,10 +2528,10 @@ public class DisplayModeDirectorTest {
config.setRefreshRateInHighZone(60);
config.setHighDisplayBrightnessThresholds(new int[] { 255 });
config.setHighAmbientBrightnessThresholds(new int[] { 8000 });
config.setDefaultPeakRefreshRate(90);
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, 0);
setPeakRefreshRate(90 /*fps*/);
director.getSettingsObserver().setDefaultRefreshRate(90);
director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);
@@ -2671,10 +2782,30 @@ public class DisplayModeDirectorTest {
listener.onDisplayChanged(DISPLAY_ID);
}
private void setPeakRefreshRate(float fps) {
Settings.System.putFloat(mContext.getContentResolver(), Settings.System.PEAK_REFRESH_RATE,
fps);
mInjector.notifyPeakRefreshRateChanged();
private void setSmoothDisplayEnabled(boolean enabled) {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY,
enabled ? 1 : 0);
mInjector.notifySmoothDisplaySettingChanged();
waitForIdleSync();
}
private void clearSmoothDisplaySetting() {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SMOOTH_DISPLAY, -1);
mInjector.notifySmoothDisplaySettingChanged();
waitForIdleSync();
}
private void setForcePeakRefreshRateEnabled(boolean enabled) {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.FORCE_PEAK_REFRESH_RATE, enabled ? 1 : 0);
mInjector.notifyForcePeakRefreshRateSettingChanged();
waitForIdleSync();
}
private void clearForcePeakRefreshRateSetting() {
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.FORCE_PEAK_REFRESH_RATE, -1);
mInjector.notifySmoothDisplaySettingChanged();
waitForIdleSync();
}
@@ -2720,7 +2851,8 @@ public class DisplayModeDirectorTest {
public static class FakesInjector implements DisplayModeDirector.Injector {
private final FakeDeviceConfig mDeviceConfig;
private ContentObserver mBrightnessObserver;
private ContentObserver mPeakRefreshRateObserver;
private ContentObserver mSmoothDisplaySettingObserver;
private ContentObserver mForcePeakRefreshRateSettingObserver;
FakesInjector() {
mDeviceConfig = new FakeDeviceConfig();
@@ -2732,9 +2864,15 @@ public class DisplayModeDirectorTest {
}
@Override
public void registerPeakRefreshRateObserver(@NonNull ContentResolver cr,
public void registerSmoothDisplayObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer) {
mPeakRefreshRateObserver = observer;
mSmoothDisplaySettingObserver = observer;
}
@Override
public void registerForcePeakRefreshRateObserver(@NonNull ContentResolver cr,
@NonNull ContentObserver observer) {
mForcePeakRefreshRateSettingObserver = observer;
}
@Override
@@ -2775,10 +2913,17 @@ public class DisplayModeDirectorTest {
ApplicationProvider.getApplicationContext().getResources());
}
void notifyPeakRefreshRateChanged() {
if (mPeakRefreshRateObserver != null) {
mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/,
PEAK_REFRESH_RATE_URI);
void notifySmoothDisplaySettingChanged() {
if (mSmoothDisplaySettingObserver != null) {
mSmoothDisplaySettingObserver.dispatchChange(false /*selfChange*/,
SMOOTH_DISPLAY_URI);
}
}
void notifyForcePeakRefreshRateSettingChanged() {
if (mForcePeakRefreshRateSettingObserver != null) {
mForcePeakRefreshRateSettingObserver.dispatchChange(false /*selfChange*/,
FORCE_PEAK_REFRESH_RATE_URI);
}
}
}