Merge "DMD: Support 90hz only in the refresh rate zone" into qt-r1-dev

am: d44f2edc08

Change-Id: Iaa8a5aca0e16a97a1cd1de529f35a8eeb971cf8d
This commit is contained in:
Long Ling
2019-08-30 16:50:42 -07:00
committed by android-build-merger
4 changed files with 131 additions and 45 deletions

View File

@@ -829,23 +829,36 @@ public final class DisplayManager {
public interface DeviceConfig {
/**
* Key for accessing the 60 hz only regions.
* Key for refresh rate in the zone defined by thresholds.
*
* @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
* @see android.R.integer#config_defaultZoneBehavior
*/
String KEY_REFRESH_RATE_IN_ZONE = "refresh_rate_in_zone";
/**
* Key for accessing the display brightness thresholds for the configured refresh rate zone.
* The value will be a pair of comma separated integers representing the minimum and maximum
* thresholds of the zone, respectively, in display backlight units (i.e. [0, 255]).
*
* @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
* @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate
* @hide
*/
String KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS =
String KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS =
"peak_refresh_rate_brightness_thresholds";
/**
* Key for accessing the 60 hz only regions.
* Key for accessing the ambient brightness thresholds for the configured refresh rate zone.
* The value will be a pair of comma separated integers representing the minimum and maximum
* thresholds of the zone, respectively, in lux.
*
* @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
* @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate
* @see android.R.array#config_ambientThresholdsOfPeakRefreshRate
* @hide
*/
String KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS = "peak_refresh_rate_ambient_thresholds";
String KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS =
"peak_refresh_rate_ambient_thresholds";
/**
* Key for default peak refresh rate

View File

@@ -4196,6 +4196,10 @@
-->
</integer-array>
<!-- Default refresh rate in the zone defined by brightness and ambient thresholds.
If non-positive, then the refresh rate is unchanged even if thresholds are configured. -->
<integer name="config_defaultRefreshRateInZone">0</integer>
<!-- The type of the light sensor to be used by the display framework for things like
auto-brightness. If unset, then it just gets the default sensor of type TYPE_LIGHT. -->
<string name="config_displayLightSensorType" translatable="false" />

View File

@@ -3798,6 +3798,7 @@
<!-- For high refresh rate displays -->
<java-symbol type="integer" name="config_defaultPeakRefreshRate" />
<java-symbol type="integer" name="config_defaultRefreshRateInZone" />
<java-symbol type="array" name="config_brightnessThresholdsOfPeakRefreshRate" />
<java-symbol type="array" name="config_ambientThresholdsOfPeakRefreshRate" />

View File

@@ -69,6 +69,7 @@ public class DisplayModeDirector {
private static final int MSG_ALLOWED_MODES_CHANGED = 1;
private static final int MSG_BRIGHTNESS_THRESHOLDS_CHANGED = 2;
private static final int MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED = 3;
private static final int MSG_REFRESH_RATE_IN_ZONE_CHANGED = 4;
// Special ID used to indicate that given vote is to be applied globally, rather than to a
// specific display.
@@ -440,23 +441,48 @@ public class DisplayModeDirector {
mSettingsObserver.onDeviceConfigDefaultPeakRefreshRateChanged(
defaultPeakRefreshRate);
break;
case MSG_REFRESH_RATE_IN_ZONE_CHANGED:
int refreshRateInZone = msg.arg1;
mBrightnessObserver.onDeviceConfigRefreshRateInZoneChanged(
refreshRateInZone);
break;
}
}
}
private static final class Vote {
// We split the app request into two priorities in case we can satisfy one desire without
// the other.
public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 0;
public static final int PRIORITY_APP_REQUEST_SIZE = 1;
public static final int PRIORITY_USER_SETTING_REFRESH_RATE = 2;
public static final int PRIORITY_LOW_BRIGHTNESS = 3;
public static final int PRIORITY_LOW_POWER_MODE = 4;
// 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.
// It's used to avoid rate switch in certain conditions.
public static final int PRIORITY_LOW_BRIGHTNESS = 0;
// SETTING_MIN_REFRESH_RATE is used to propose a lower bound of display refresh rate.
// It votes [MIN_REFRESH_RATE, Float.POSITIVE_INFINITY]
public static final int PRIORITY_USER_SETTING_MIN_REFRESH_RATE = 1;
// We split the app request into different priorities in case we can satisfy one desire
// without the other.
// Application can specify preferred refresh rate with below attrs.
// @see android.view.WindowManager.LayoutParams#preferredRefreshRate
// @see android.view.WindowManager.LayoutParams#preferredDisplayModeId
// System also forces some apps like blacklisted app to run at a lower refresh rate.
// @see android.R.array#config_highRefreshRateBlacklist
public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 2;
public static final int PRIORITY_APP_REQUEST_SIZE = 3;
// 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)]
public static final int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 4;
// 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;
// Whenever a new priority is added, remember to update MIN_PRIORITY and/or MAX_PRIORITY as
// appropriate, as well as priorityToString.
public static final int MIN_PRIORITY = PRIORITY_APP_REQUEST_REFRESH_RATE;
public static final int MIN_PRIORITY = PRIORITY_LOW_BRIGHTNESS;
public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
/**
@@ -500,12 +526,16 @@ public class DisplayModeDirector {
public static String priorityToString(int priority) {
switch (priority) {
case PRIORITY_LOW_BRIGHTNESS:
return "PRIORITY_LOW_BRIGHTNESS";
case PRIORITY_USER_SETTING_MIN_REFRESH_RATE:
return "PRIORITY_USER_SETTING_MIN_REFRESH_RATE";
case PRIORITY_APP_REQUEST_REFRESH_RATE:
return "PRIORITY_APP_REQUEST_REFRESH_RATE";
case PRIORITY_APP_REQUEST_SIZE:
return "PRIORITY_APP_REQUEST_SIZE";
case PRIORITY_USER_SETTING_REFRESH_RATE:
return "PRIORITY_USER_SETTING_REFRESH_RATE";
case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE:
return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
case PRIORITY_LOW_POWER_MODE:
return "PRIORITY_LOW_POWER_MODE";
default:
@@ -608,12 +638,11 @@ public class DisplayModeDirector {
float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate);
if (peakRefreshRate < minRefreshRate) {
peakRefreshRate = minRefreshRate;
}
updateVoteLocked(Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE,
Vote.forRefreshRates(0f, Math.max(minRefreshRate, peakRefreshRate)));
updateVoteLocked(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE,
Vote.forRefreshRates(minRefreshRate, Float.POSITIVE_INFINITY));
Vote vote = Vote.forRefreshRates(minRefreshRate, peakRefreshRate);
updateVoteLocked(Vote.PRIORITY_USER_SETTING_REFRESH_RATE, vote);
mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, peakRefreshRate);
}
@@ -655,6 +684,7 @@ public class DisplayModeDirector {
refreshRateVote = null;
sizeVote = null;
}
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, refreshRateVote);
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);
return;
@@ -799,6 +829,8 @@ public class DisplayModeDirector {
private boolean mRefreshRateChangeable = false;
private boolean mLowPowerModeEnabled = false;
private int mRefreshRateInZone;
BrightnessObserver(Context context, Handler handler) {
super(handler);
mContext = context;
@@ -816,6 +848,7 @@ public class DisplayModeDirector {
public void observe(SensorManager sensorManager) {
mSensorManager = sensorManager;
// DeviceConfig is accessible after system ready.
int[] brightnessThresholds = mDeviceConfigDisplaySettings.getBrightnessThresholds();
int[] ambientThresholds = mDeviceConfigDisplaySettings.getAmbientThresholds();
@@ -825,6 +858,8 @@ public class DisplayModeDirector {
mDisplayBrightnessThresholds = brightnessThresholds;
mAmbientBrightnessThresholds = ambientThresholds;
}
mRefreshRateInZone = mDeviceConfigDisplaySettings.getRefreshRateInZone();
restartObserver();
mDeviceConfigDisplaySettings.startListening();
}
@@ -864,8 +899,16 @@ public class DisplayModeDirector {
restartObserver();
}
public void onDeviceConfigRefreshRateInZoneChanged(int refreshRate) {
if (refreshRate != mRefreshRateInZone) {
mRefreshRateInZone = refreshRate;
restartObserver();
}
}
public void dumpLocked(PrintWriter pw) {
pw.println(" BrightnessObserver");
pw.println(" mRefreshRateInZone: " + mRefreshRateInZone);
for (int d: mDisplayBrightnessThresholds) {
pw.println(" mDisplayBrightnessThreshold: " + d);
@@ -952,6 +995,10 @@ public class DisplayModeDirector {
* to value changes.
*/
private boolean checkShouldObserve(int[] a) {
if (mRefreshRateInZone <= 0) {
return false;
}
for (int d: a) {
if (d >= 0) {
return true;
@@ -961,37 +1008,42 @@ public class DisplayModeDirector {
return false;
}
private boolean isInsideZone(int brightness, float lux) {
for (int i = 0; i < mDisplayBrightnessThresholds.length; i++) {
int disp = mDisplayBrightnessThresholds[i];
int ambi = mAmbientBrightnessThresholds[i];
if (disp >= 0 && ambi >= 0) {
if (brightness <= disp && mAmbientLux <= ambi) {
return true;
}
} else if (disp >= 0) {
if (brightness <= disp) {
return true;
}
} else if (ambi >= 0) {
if (mAmbientLux <= ambi) {
return true;
}
}
}
return false;
}
private void onBrightnessChangedLocked() {
int brightness = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, -1);
Vote vote = null;
for (int i = 0; i < mDisplayBrightnessThresholds.length; i++) {
int disp = mDisplayBrightnessThresholds[i];
int ambi = mAmbientBrightnessThresholds[i];
if (disp >= 0 && ambi >= 0) {
if (brightness <= disp && mAmbientLux <= ambi) {
vote = Vote.forRefreshRates(0f, 60f);
}
} else if (disp >= 0) {
if (brightness <= disp) {
vote = Vote.forRefreshRates(0f, 60f);
}
} else if (ambi >= 0) {
if (mAmbientLux <= ambi) {
vote = Vote.forRefreshRates(0f, 60f);
}
}
if (vote != null) {
break;
}
boolean insideZone = isInsideZone(brightness, mAmbientLux);
if (insideZone) {
vote = Vote.forRefreshRates(mRefreshRateInZone, mRefreshRateInZone);
}
if (DEBUG) {
Slog.d(TAG, "Display brightness " + brightness + ", ambient lux " + mAmbientLux +
(vote != null ? " 60hz only" : " no refresh rate limit"));
", Vote " + vote);
}
updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote);
}
@@ -1133,7 +1185,6 @@ public class DisplayModeDirector {
}
private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
public DeviceConfigDisplaySettings() {
}
@@ -1147,7 +1198,8 @@ public class DisplayModeDirector {
*/
public int[] getBrightnessThresholds() {
return getIntArrayProperty(
DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS);
DisplayManager.DeviceConfig.
KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS);
}
/*
@@ -1155,7 +1207,8 @@ public class DisplayModeDirector {
*/
public int[] getAmbientThresholds() {
return getIntArrayProperty(
DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS);
DisplayManager.DeviceConfig.
KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS);
}
/*
@@ -1172,17 +1225,32 @@ public class DisplayModeDirector {
return defaultPeakRefreshRate;
}
public int getRefreshRateInZone() {
int defaultRefreshRateInZone = mContext.getResources().getInteger(
R.integer.config_defaultRefreshRateInZone);
int refreshRate = DeviceConfig.getInt(
DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_ZONE,
defaultRefreshRateInZone);
return refreshRate;
}
@Override
public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
int[] brightnessThresholds = getBrightnessThresholds();
int[] ambientThresholds = getAmbientThresholds();
Float defaultPeakRefreshRate = getDefaultPeakRefreshRate();
int refreshRateInZone = getRefreshRateInZone();
mHandler.obtainMessage(MSG_BRIGHTNESS_THRESHOLDS_CHANGED,
new Pair<int[], int[]>(brightnessThresholds, ambientThresholds))
.sendToTarget();
mHandler.obtainMessage(MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED,
defaultPeakRefreshRate).sendToTarget();
mHandler.obtainMessage(MSG_REFRESH_RATE_IN_ZONE_CHANGED, refreshRateInZone,
0).sendToTarget();
}
private int[] getIntArrayProperty(String prop) {