Merge "Add default frame rate setting" into rvc-dev am: 3d6a1cfb1b am: c09a66b3e5
Change-Id: Iead9424643cb8c87ff0385223719166d3c7595c8
This commit is contained in:
@@ -4165,9 +4165,21 @@
|
|||||||
and a second time clipped to the fill level to indicate charge -->
|
and a second time clipped to the fill level to indicate charge -->
|
||||||
<bool name="config_batterymeterDualTone">false</bool>
|
<bool name="config_batterymeterDualTone">false</bool>
|
||||||
|
|
||||||
<!-- The default peak refresh rate for a given device. Change this value if you want to allow
|
<!-- The default refresh rate for a given device. Change this value to set a higher default
|
||||||
for higher refresh rates to be automatically used out of the box -->
|
refresh rate. If the hardware composer on the device supports display modes with a higher
|
||||||
<integer name="config_defaultPeakRefreshRate">60</integer>
|
refresh rate than the default value specified here, the framework may use those higher
|
||||||
|
refresh rate modes if an app chooses one by setting preferredDisplayModeId or calling
|
||||||
|
setFrameRate().
|
||||||
|
If a non-zero value is set for config_defaultPeakRefreshRate, then
|
||||||
|
config_defaultRefreshRate may be set to 0, in which case the value set for
|
||||||
|
config_defaultPeakRefreshRate will act as the default frame rate. -->
|
||||||
|
<integer name="config_defaultRefreshRate">60</integer>
|
||||||
|
|
||||||
|
<!-- The default peak refresh rate for a 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 the value is
|
||||||
|
non-zero. -->
|
||||||
|
<integer name="config_defaultPeakRefreshRate">0</integer>
|
||||||
|
|
||||||
<!-- The display uses different gamma curves for different refresh rates. It's hard for panel
|
<!-- The display uses different gamma curves for different refresh rates. It's hard for panel
|
||||||
vendor to tune the curves to have exact same brightness for different refresh rate. So
|
vendor to tune the curves to have exact same brightness for different refresh rate. So
|
||||||
|
|||||||
@@ -3772,6 +3772,7 @@
|
|||||||
<java-symbol type="string" name="bluetooth_airplane_mode_toast" />
|
<java-symbol type="string" name="bluetooth_airplane_mode_toast" />
|
||||||
|
|
||||||
<!-- For high refresh rate displays -->
|
<!-- 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_defaultPeakRefreshRate" />
|
||||||
<java-symbol type="integer" name="config_defaultRefreshRateInZone" />
|
<java-symbol type="integer" name="config_defaultRefreshRateInZone" />
|
||||||
<java-symbol type="array" name="config_brightnessThresholdsOfPeakRefreshRate" />
|
<java-symbol type="array" name="config_brightnessThresholdsOfPeakRefreshRate" />
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class DisplayModeDirector {
|
|||||||
private final AppRequestObserver mAppRequestObserver;
|
private final AppRequestObserver mAppRequestObserver;
|
||||||
private final SettingsObserver mSettingsObserver;
|
private final SettingsObserver mSettingsObserver;
|
||||||
private final DisplayObserver mDisplayObserver;
|
private final DisplayObserver mDisplayObserver;
|
||||||
private final BrightnessObserver mBrightnessObserver;
|
private BrightnessObserver mBrightnessObserver;
|
||||||
|
|
||||||
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
|
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
|
||||||
private DesiredDisplayModeSpecsListener mDesiredDisplayModeSpecsListener;
|
private DesiredDisplayModeSpecsListener mDesiredDisplayModeSpecsListener;
|
||||||
@@ -460,6 +460,21 @@ public class DisplayModeDirector {
|
|||||||
mVotesByDisplay = votesByDisplay;
|
mVotesByDisplay = votesByDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void injectBrightnessObserver(BrightnessObserver brightnessObserver) {
|
||||||
|
mBrightnessObserver = brightnessObserver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings(
|
||||||
|
float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mSettingsObserver.updateRefreshRateSettingLocked(
|
||||||
|
minRefreshRate, peakRefreshRate, defaultRefreshRate);
|
||||||
|
return getDesiredDisplayModeSpecs(Display.DEFAULT_DISPLAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listens for changes refresh rate coordination.
|
* Listens for changes refresh rate coordination.
|
||||||
*/
|
*/
|
||||||
@@ -666,14 +681,18 @@ public class DisplayModeDirector {
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final class Vote {
|
static final class Vote {
|
||||||
|
// DEFAULT_FRAME_RATE votes for [0, DEFAULT]. As the lowest priority vote, it's overridden
|
||||||
|
// by all other considerations. It acts to set a default frame rate for a device.
|
||||||
|
public static final int PRIORITY_DEFAULT_REFRESH_RATE = 0;
|
||||||
|
|
||||||
// LOW_BRIGHTNESS votes for a single refresh rate like [60,60], [90,90] or null.
|
// LOW_BRIGHTNESS votes for a single refresh rate like [60,60], [90,90] or null.
|
||||||
// If the higher voters result is a range, it will fix the rate to a single choice.
|
// If the higher voters result is a range, it will fix the rate to a single choice.
|
||||||
// It's used to avoid rate switch in certain conditions.
|
// It's used to avoid rate switch in certain conditions.
|
||||||
public static final int PRIORITY_LOW_BRIGHTNESS = 0;
|
public static final int PRIORITY_LOW_BRIGHTNESS = 1;
|
||||||
|
|
||||||
// SETTING_MIN_REFRESH_RATE is used to propose a lower bound of display refresh rate.
|
// SETTING_MIN_REFRESH_RATE is used to propose a lower bound of display refresh rate.
|
||||||
// It votes [MIN_REFRESH_RATE, Float.POSITIVE_INFINITY]
|
// It votes [MIN_REFRESH_RATE, Float.POSITIVE_INFINITY]
|
||||||
public static final int PRIORITY_USER_SETTING_MIN_REFRESH_RATE = 1;
|
public static final int PRIORITY_USER_SETTING_MIN_REFRESH_RATE = 2;
|
||||||
|
|
||||||
// We split the app request into different priorities in case we can satisfy one desire
|
// We split the app request into different priorities in case we can satisfy one desire
|
||||||
// without the other.
|
// without the other.
|
||||||
@@ -683,20 +702,20 @@ public class DisplayModeDirector {
|
|||||||
// @see android.view.WindowManager.LayoutParams#preferredDisplayModeId
|
// @see android.view.WindowManager.LayoutParams#preferredDisplayModeId
|
||||||
// System also forces some apps like blacklisted app to run at a lower refresh rate.
|
// System also forces some apps like blacklisted app to run at a lower refresh rate.
|
||||||
// @see android.R.array#config_highRefreshRateBlacklist
|
// @see android.R.array#config_highRefreshRateBlacklist
|
||||||
public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 2;
|
public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 3;
|
||||||
public static final int PRIORITY_APP_REQUEST_SIZE = 3;
|
public static final int PRIORITY_APP_REQUEST_SIZE = 4;
|
||||||
|
|
||||||
// SETTING_PEAK_REFRESH_RATE has a high priority and will restrict the bounds of the rest
|
// SETTING_PEAK_REFRESH_RATE has a high priority and will restrict the bounds of the rest
|
||||||
// of low priority voters. It votes [0, max(PEAK, MIN)]
|
// of low priority voters. It votes [0, max(PEAK, MIN)]
|
||||||
public static final int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 4;
|
public static final int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 5;
|
||||||
|
|
||||||
// LOW_POWER_MODE force display to [0, 60HZ] if Settings.Global.LOW_POWER_MODE is on.
|
// LOW_POWER_MODE force display to [0, 60HZ] if Settings.Global.LOW_POWER_MODE is on.
|
||||||
public static final int PRIORITY_LOW_POWER_MODE = 5;
|
public static final int PRIORITY_LOW_POWER_MODE = 6;
|
||||||
|
|
||||||
// Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
|
// Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
|
||||||
// APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
|
// APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
|
||||||
|
|
||||||
public static final int MIN_PRIORITY = PRIORITY_LOW_BRIGHTNESS;
|
public static final int MIN_PRIORITY = PRIORITY_DEFAULT_REFRESH_RATE;
|
||||||
public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
|
public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
|
||||||
|
|
||||||
// The cutoff for the app request refresh rate range. Votes with priorities lower than this
|
// The cutoff for the app request refresh rate range. Votes with priorities lower than this
|
||||||
@@ -740,6 +759,8 @@ public class DisplayModeDirector {
|
|||||||
|
|
||||||
public static String priorityToString(int priority) {
|
public static String priorityToString(int priority) {
|
||||||
switch (priority) {
|
switch (priority) {
|
||||||
|
case PRIORITY_DEFAULT_REFRESH_RATE:
|
||||||
|
return "PRIORITY_DEFAULT_REFRESH_RATE";
|
||||||
case PRIORITY_LOW_BRIGHTNESS:
|
case PRIORITY_LOW_BRIGHTNESS:
|
||||||
return "PRIORITY_LOW_BRIGHTNESS";
|
return "PRIORITY_LOW_BRIGHTNESS";
|
||||||
case PRIORITY_USER_SETTING_MIN_REFRESH_RATE:
|
case PRIORITY_USER_SETTING_MIN_REFRESH_RATE:
|
||||||
@@ -776,12 +797,15 @@ public class DisplayModeDirector {
|
|||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private float mDefaultPeakRefreshRate;
|
private float mDefaultPeakRefreshRate;
|
||||||
|
private float mDefaultRefreshRate;
|
||||||
|
|
||||||
SettingsObserver(@NonNull Context context, @NonNull Handler handler) {
|
SettingsObserver(@NonNull Context context, @NonNull Handler handler) {
|
||||||
super(handler);
|
super(handler);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDefaultPeakRefreshRate = (float) context.getResources().getInteger(
|
mDefaultPeakRefreshRate = (float) context.getResources().getInteger(
|
||||||
R.integer.config_defaultPeakRefreshRate);
|
R.integer.config_defaultPeakRefreshRate);
|
||||||
|
mDefaultRefreshRate =
|
||||||
|
(float) context.getResources().getInteger(R.integer.config_defaultRefreshRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void observe() {
|
public void observe() {
|
||||||
@@ -849,17 +873,48 @@ public class DisplayModeDirector {
|
|||||||
Settings.System.MIN_REFRESH_RATE, 0f);
|
Settings.System.MIN_REFRESH_RATE, 0f);
|
||||||
float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
|
float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
|
||||||
Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate);
|
Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate);
|
||||||
|
updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate);
|
||||||
|
}
|
||||||
|
|
||||||
updateVoteLocked(Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE,
|
private void updateRefreshRateSettingLocked(
|
||||||
Vote.forRefreshRates(0f, Math.max(minRefreshRate, peakRefreshRate)));
|
float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) {
|
||||||
|
// TODO(b/156304339): The logic in here, aside from updating the refresh rate votes, is
|
||||||
|
// used to predict if we're going to be doing frequent refresh rate switching, and if
|
||||||
|
// so, enable the brightness observer. The logic here is more complicated and fragile
|
||||||
|
// than necessary, and we should improve it. See b/156304339 for more info.
|
||||||
|
Vote peakVote = peakRefreshRate == 0f
|
||||||
|
? null
|
||||||
|
: Vote.forRefreshRates(0f, Math.max(minRefreshRate, peakRefreshRate));
|
||||||
|
updateVoteLocked(Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, peakVote);
|
||||||
updateVoteLocked(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE,
|
updateVoteLocked(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE,
|
||||||
Vote.forRefreshRates(minRefreshRate, Float.POSITIVE_INFINITY));
|
Vote.forRefreshRates(minRefreshRate, Float.POSITIVE_INFINITY));
|
||||||
|
Vote defaultVote =
|
||||||
|
defaultRefreshRate == 0f ? null : Vote.forRefreshRates(0f, defaultRefreshRate);
|
||||||
|
updateVoteLocked(Vote.PRIORITY_DEFAULT_REFRESH_RATE, defaultVote);
|
||||||
|
|
||||||
mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, peakRefreshRate);
|
float maxRefreshRate;
|
||||||
|
if (peakRefreshRate == 0f && defaultRefreshRate == 0f) {
|
||||||
|
// We require that at least one of the peak or default refresh rate values are
|
||||||
|
// set. The brightness observer requires that we're able to predict whether or not
|
||||||
|
// we're going to do frequent refresh rate switching, and with the way the code is
|
||||||
|
// currently written, we need either a default or peak refresh rate value for that.
|
||||||
|
Slog.e(TAG, "Default and peak refresh rates are both 0. One of them should be set"
|
||||||
|
+ " to a valid value.");
|
||||||
|
maxRefreshRate = minRefreshRate;
|
||||||
|
} else if (peakRefreshRate == 0f) {
|
||||||
|
maxRefreshRate = defaultRefreshRate;
|
||||||
|
} else if (defaultRefreshRate == 0f) {
|
||||||
|
maxRefreshRate = peakRefreshRate;
|
||||||
|
} else {
|
||||||
|
maxRefreshRate = Math.min(defaultRefreshRate, peakRefreshRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, maxRefreshRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dumpLocked(PrintWriter pw) {
|
public void dumpLocked(PrintWriter pw) {
|
||||||
pw.println(" SettingsObserver");
|
pw.println(" SettingsObserver");
|
||||||
|
pw.println(" mDefaultRefreshRate: " + mDefaultRefreshRate);
|
||||||
pw.println(" mDefaultPeakRefreshRate: " + mDefaultPeakRefreshRate);
|
pw.println(" mDefaultPeakRefreshRate: " + mDefaultPeakRefreshRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1014,7 +1069,8 @@ public class DisplayModeDirector {
|
|||||||
* {@link R.array#config_brightnessThresholdsOfPeakRefreshRate} and
|
* {@link R.array#config_brightnessThresholdsOfPeakRefreshRate} and
|
||||||
* {@link R.array#config_ambientThresholdsOfPeakRefreshRate}.
|
* {@link R.array#config_ambientThresholdsOfPeakRefreshRate}.
|
||||||
*/
|
*/
|
||||||
private class BrightnessObserver extends ContentObserver {
|
@VisibleForTesting
|
||||||
|
public class BrightnessObserver extends ContentObserver {
|
||||||
// TODO: brightnessfloat: change this to the float setting
|
// TODO: brightnessfloat: change this to the float setting
|
||||||
private final Uri mDisplayBrightnessSetting =
|
private final Uri mDisplayBrightnessSetting =
|
||||||
Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
|
Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.display;
|
package com.android.server.display;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -28,6 +29,7 @@ import androidx.test.InstrumentationRegistry;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.android.server.display.DisplayModeDirector.BrightnessObserver;
|
||||||
import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs;
|
import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs;
|
||||||
import com.android.server.display.DisplayModeDirector.Vote;
|
import com.android.server.display.DisplayModeDirector.Vote;
|
||||||
|
|
||||||
@@ -36,6 +38,7 @@ import com.google.common.truth.Truth;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@@ -52,16 +55,15 @@ public class DisplayModeDirectorTest {
|
|||||||
mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DisplayModeDirector createDisplayModeDirectorWithDisplayFpsRange(
|
private DisplayModeDirector createDirectorFromRefreshRateArray(
|
||||||
int minFps, int maxFps) {
|
float[] refreshRates, int baseModeId) {
|
||||||
DisplayModeDirector director =
|
DisplayModeDirector director =
|
||||||
new DisplayModeDirector(mContext, new Handler(Looper.getMainLooper()));
|
new DisplayModeDirector(mContext, new Handler(Looper.getMainLooper()));
|
||||||
int displayId = 0;
|
int displayId = 0;
|
||||||
int numModes = maxFps - minFps + 1;
|
Display.Mode[] modes = new Display.Mode[refreshRates.length];
|
||||||
Display.Mode[] modes = new Display.Mode[numModes];
|
for (int i = 0; i < refreshRates.length; i++) {
|
||||||
for (int i = minFps; i <= maxFps; i++) {
|
modes[i] = new Display.Mode(
|
||||||
modes[i - minFps] = new Display.Mode(
|
/*modeId=*/baseModeId + i, /*width=*/1000, /*height=*/1000, refreshRates[i]);
|
||||||
/*modeId=*/i, /*width=*/1000, /*height=*/1000, /*refreshRate=*/i);
|
|
||||||
}
|
}
|
||||||
SparseArray<Display.Mode[]> supportedModesByDisplay = new SparseArray<>();
|
SparseArray<Display.Mode[]> supportedModesByDisplay = new SparseArray<>();
|
||||||
supportedModesByDisplay.put(displayId, modes);
|
supportedModesByDisplay.put(displayId, modes);
|
||||||
@@ -72,14 +74,22 @@ public class DisplayModeDirectorTest {
|
|||||||
return director;
|
return director;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DisplayModeDirector createDirectorFromFpsRange(int minFps, int maxFps) {
|
||||||
|
int numRefreshRates = maxFps - minFps + 1;
|
||||||
|
float[] refreshRates = new float[numRefreshRates];
|
||||||
|
for (int i = 0; i < numRefreshRates; i++) {
|
||||||
|
refreshRates[i] = minFps + i;
|
||||||
|
}
|
||||||
|
return createDirectorFromRefreshRateArray(refreshRates, /*baseModeId=*/minFps);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisplayModeVoting() {
|
public void testDisplayModeVoting() {
|
||||||
int displayId = 0;
|
int displayId = 0;
|
||||||
|
|
||||||
// With no votes present, DisplayModeDirector should allow any refresh rate.
|
// With no votes present, DisplayModeDirector should allow any refresh rate.
|
||||||
DesiredDisplayModeSpecs modeSpecs =
|
DesiredDisplayModeSpecs modeSpecs =
|
||||||
createDisplayModeDirectorWithDisplayFpsRange(60, 90).getDesiredDisplayModeSpecs(
|
createDirectorFromFpsRange(60, 90).getDesiredDisplayModeSpecs(displayId);
|
||||||
displayId);
|
|
||||||
Truth.assertThat(modeSpecs.baseModeId).isEqualTo(60);
|
Truth.assertThat(modeSpecs.baseModeId).isEqualTo(60);
|
||||||
Truth.assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(0f);
|
Truth.assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(0f);
|
||||||
Truth.assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(Float.POSITIVE_INFINITY);
|
Truth.assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(Float.POSITIVE_INFINITY);
|
||||||
@@ -92,7 +102,7 @@ public class DisplayModeDirectorTest {
|
|||||||
{
|
{
|
||||||
int minFps = 60;
|
int minFps = 60;
|
||||||
int maxFps = 90;
|
int maxFps = 90;
|
||||||
DisplayModeDirector director = createDisplayModeDirectorWithDisplayFpsRange(60, 90);
|
DisplayModeDirector director = createDirectorFromFpsRange(60, 90);
|
||||||
assertTrue(2 * numPriorities < maxFps - minFps + 1);
|
assertTrue(2 * numPriorities < maxFps - minFps + 1);
|
||||||
SparseArray<Vote> votes = new SparseArray<>();
|
SparseArray<Vote> votes = new SparseArray<>();
|
||||||
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
||||||
@@ -114,7 +124,7 @@ public class DisplayModeDirectorTest {
|
|||||||
// presence of higher priority votes.
|
// presence of higher priority votes.
|
||||||
{
|
{
|
||||||
assertTrue(numPriorities >= 2);
|
assertTrue(numPriorities >= 2);
|
||||||
DisplayModeDirector director = createDisplayModeDirectorWithDisplayFpsRange(60, 90);
|
DisplayModeDirector director = createDirectorFromFpsRange(60, 90);
|
||||||
SparseArray<Vote> votes = new SparseArray<>();
|
SparseArray<Vote> votes = new SparseArray<>();
|
||||||
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
||||||
votesByDisplay.put(displayId, votes);
|
votesByDisplay.put(displayId, votes);
|
||||||
@@ -131,7 +141,7 @@ public class DisplayModeDirectorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testVotingWithFloatingPointErrors() {
|
public void testVotingWithFloatingPointErrors() {
|
||||||
int displayId = 0;
|
int displayId = 0;
|
||||||
DisplayModeDirector director = createDisplayModeDirectorWithDisplayFpsRange(50, 90);
|
DisplayModeDirector director = createDirectorFromFpsRange(50, 90);
|
||||||
SparseArray<Vote> votes = new SparseArray<>();
|
SparseArray<Vote> votes = new SparseArray<>();
|
||||||
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
||||||
votesByDisplay.put(displayId, votes);
|
votesByDisplay.put(displayId, votes);
|
||||||
@@ -154,7 +164,7 @@ public class DisplayModeDirectorTest {
|
|||||||
assertTrue(Vote.PRIORITY_LOW_BRIGHTNESS < Vote.PRIORITY_APP_REQUEST_SIZE);
|
assertTrue(Vote.PRIORITY_LOW_BRIGHTNESS < Vote.PRIORITY_APP_REQUEST_SIZE);
|
||||||
|
|
||||||
int displayId = 0;
|
int displayId = 0;
|
||||||
DisplayModeDirector director = createDisplayModeDirectorWithDisplayFpsRange(60, 90);
|
DisplayModeDirector director = createDirectorFromFpsRange(60, 90);
|
||||||
SparseArray<Vote> votes = new SparseArray<>();
|
SparseArray<Vote> votes = new SparseArray<>();
|
||||||
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
||||||
votesByDisplay.put(displayId, votes);
|
votesByDisplay.put(displayId, votes);
|
||||||
@@ -202,7 +212,7 @@ public class DisplayModeDirectorTest {
|
|||||||
>= Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF);
|
>= Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF);
|
||||||
|
|
||||||
int displayId = 0;
|
int displayId = 0;
|
||||||
DisplayModeDirector director = createDisplayModeDirectorWithDisplayFpsRange(60, 90);
|
DisplayModeDirector director = createDirectorFromFpsRange(60, 90);
|
||||||
SparseArray<Vote> votes = new SparseArray<>();
|
SparseArray<Vote> votes = new SparseArray<>();
|
||||||
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
||||||
votesByDisplay.put(displayId, votes);
|
votesByDisplay.put(displayId, votes);
|
||||||
@@ -235,4 +245,61 @@ public class DisplayModeDirectorTest {
|
|||||||
.isWithin(FLOAT_TOLERANCE)
|
.isWithin(FLOAT_TOLERANCE)
|
||||||
.of(75);
|
.of(75);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void verifySpecsWithRefreshRateSettings(DisplayModeDirector director, float minFps,
|
||||||
|
float peakFps, float defaultFps, float primaryMin, float primaryMax,
|
||||||
|
float appRequestMin, float appRequestMax) {
|
||||||
|
DesiredDisplayModeSpecs specs = director.getDesiredDisplayModeSpecsWithInjectedFpsSettings(
|
||||||
|
minFps, peakFps, defaultFps);
|
||||||
|
Truth.assertThat(specs.primaryRefreshRateRange.min).isEqualTo(primaryMin);
|
||||||
|
Truth.assertThat(specs.primaryRefreshRateRange.max).isEqualTo(primaryMax);
|
||||||
|
Truth.assertThat(specs.appRequestRefreshRateRange.min).isEqualTo(appRequestMin);
|
||||||
|
Truth.assertThat(specs.appRequestRefreshRateRange.max).isEqualTo(appRequestMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSpecsFromRefreshRateSettings() {
|
||||||
|
// Confirm that, with varying settings for min, peak, and default refresh rate,
|
||||||
|
// DesiredDisplayModeSpecs is calculated correctly.
|
||||||
|
float[] refreshRates = {30.f, 60.f, 90.f, 120.f, 150.f};
|
||||||
|
DisplayModeDirector director =
|
||||||
|
createDirectorFromRefreshRateArray(refreshRates, /*baseModeId=*/0);
|
||||||
|
|
||||||
|
float inf = Float.POSITIVE_INFINITY;
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 0, 0, 0, 0, inf, 0, inf);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 0, 0, 90, 0, 90, 0, inf);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 0, 90, 0, 0, 90, 0, 90);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 0, 90, 60, 0, 60, 0, 90);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 0, 90, 120, 0, 90, 0, 90);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 90, 0, 0, 90, inf, 0, inf);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 90, 0, 120, 90, 120, 0, inf);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 90, 0, 60, 90, inf, 0, inf);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 90, 120, 0, 90, 120, 0, 120);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 90, 60, 0, 90, 90, 0, 90);
|
||||||
|
verifySpecsWithRefreshRateSettings(director, 60, 120, 90, 60, 90, 0, 120);
|
||||||
|
}
|
||||||
|
|
||||||
|
void verifyBrightnessObserverCall(DisplayModeDirector director, float minFps, float peakFps,
|
||||||
|
float defaultFps, float brightnessObserverMin, float brightnessObserverMax) {
|
||||||
|
BrightnessObserver brightnessObserver = Mockito.mock(BrightnessObserver.class);
|
||||||
|
director.injectBrightnessObserver(brightnessObserver);
|
||||||
|
director.getDesiredDisplayModeSpecsWithInjectedFpsSettings(minFps, peakFps, defaultFps);
|
||||||
|
verify(brightnessObserver)
|
||||||
|
.onRefreshRateSettingChangedLocked(brightnessObserverMin, brightnessObserverMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBrightnessObserverCallWithRefreshRateSettings() {
|
||||||
|
// Confirm that, with varying settings for min, peak, and default refresh rate, we make the
|
||||||
|
// correct call to the brightness observer.
|
||||||
|
float[] refreshRates = {60.f, 90.f, 120.f};
|
||||||
|
DisplayModeDirector director =
|
||||||
|
createDirectorFromRefreshRateArray(refreshRates, /*baseModeId=*/0);
|
||||||
|
verifyBrightnessObserverCall(director, 0, 0, 0, 0, 0);
|
||||||
|
verifyBrightnessObserverCall(director, 0, 0, 90, 0, 90);
|
||||||
|
verifyBrightnessObserverCall(director, 0, 90, 0, 0, 90);
|
||||||
|
verifyBrightnessObserverCall(director, 0, 90, 60, 0, 60);
|
||||||
|
verifyBrightnessObserverCall(director, 90, 90, 0, 90, 90);
|
||||||
|
verifyBrightnessObserverCall(director, 120, 90, 0, 120, 90);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user