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

am: 1f4f57eab4

Change-Id: I7324013fadecc41a956a0b6f109b8aee9dd3a374
This commit is contained in:
Long Ling
2019-09-03 14:41:12 -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 { 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.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
* @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate * @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate
* @hide * @hide
*/ */
String KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS = String KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS =
"peak_refresh_rate_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.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER
* @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate * @see android.R.array#config_ambientThresholdsOfPeakRefreshRate
* @hide * @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 * Key for default peak refresh rate

View File

@@ -4196,6 +4196,10 @@
--> -->
</integer-array> </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 <!-- 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. --> auto-brightness. If unset, then it just gets the default sensor of type TYPE_LIGHT. -->
<string name="config_displayLightSensorType" translatable="false" /> <string name="config_displayLightSensorType" translatable="false" />

View File

@@ -3798,6 +3798,7 @@
<!-- For high refresh rate displays --> <!-- For high refresh rate displays -->
<java-symbol type="integer" name="config_defaultPeakRefreshRate" /> <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_brightnessThresholdsOfPeakRefreshRate" />
<java-symbol type="array" name="config_ambientThresholdsOfPeakRefreshRate" /> <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_ALLOWED_MODES_CHANGED = 1;
private static final int MSG_BRIGHTNESS_THRESHOLDS_CHANGED = 2; 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_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 // Special ID used to indicate that given vote is to be applied globally, rather than to a
// specific display. // specific display.
@@ -440,23 +441,48 @@ public class DisplayModeDirector {
mSettingsObserver.onDeviceConfigDefaultPeakRefreshRateChanged( mSettingsObserver.onDeviceConfigDefaultPeakRefreshRateChanged(
defaultPeakRefreshRate); defaultPeakRefreshRate);
break; break;
case MSG_REFRESH_RATE_IN_ZONE_CHANGED:
int refreshRateInZone = msg.arg1;
mBrightnessObserver.onDeviceConfigRefreshRateInZoneChanged(
refreshRateInZone);
break;
} }
} }
} }
private static final class Vote { private static final class Vote {
// We split the app request into two priorities in case we can satisfy one desire without // LOW_BRIGHTNESS votes for a single refresh rate like [60,60], [90,90] or null.
// the other. // If the higher voters result is a range, it will fix the rate to a single choice.
public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 0; // It's used to avoid rate switch in certain conditions.
public static final int PRIORITY_APP_REQUEST_SIZE = 1; public static final int PRIORITY_LOW_BRIGHTNESS = 0;
public static final int PRIORITY_USER_SETTING_REFRESH_RATE = 2;
public static final int PRIORITY_LOW_BRIGHTNESS = 3; // SETTING_MIN_REFRESH_RATE is used to propose a lower bound of display refresh rate.
public static final int PRIORITY_LOW_POWER_MODE = 4; // 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 // Whenever a new priority is added, remember to update MIN_PRIORITY and/or MAX_PRIORITY as
// appropriate, as well as priorityToString. // 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; public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
/** /**
@@ -500,12 +526,16 @@ public class DisplayModeDirector {
public static String priorityToString(int priority) { public static String priorityToString(int priority) {
switch (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: case PRIORITY_APP_REQUEST_REFRESH_RATE:
return "PRIORITY_APP_REQUEST_REFRESH_RATE"; return "PRIORITY_APP_REQUEST_REFRESH_RATE";
case PRIORITY_APP_REQUEST_SIZE: case PRIORITY_APP_REQUEST_SIZE:
return "PRIORITY_APP_REQUEST_SIZE"; return "PRIORITY_APP_REQUEST_SIZE";
case PRIORITY_USER_SETTING_REFRESH_RATE: case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE:
return "PRIORITY_USER_SETTING_REFRESH_RATE"; return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";
case PRIORITY_LOW_POWER_MODE: case PRIORITY_LOW_POWER_MODE:
return "PRIORITY_LOW_POWER_MODE"; return "PRIORITY_LOW_POWER_MODE";
default: default:
@@ -608,12 +638,11 @@ public class DisplayModeDirector {
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);
if (peakRefreshRate < minRefreshRate) { updateVoteLocked(Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE,
peakRefreshRate = minRefreshRate; 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); mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, peakRefreshRate);
} }
@@ -655,6 +684,7 @@ public class DisplayModeDirector {
refreshRateVote = null; refreshRateVote = null;
sizeVote = null; sizeVote = null;
} }
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, refreshRateVote); updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, refreshRateVote);
updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote); updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);
return; return;
@@ -799,6 +829,8 @@ public class DisplayModeDirector {
private boolean mRefreshRateChangeable = false; private boolean mRefreshRateChangeable = false;
private boolean mLowPowerModeEnabled = false; private boolean mLowPowerModeEnabled = false;
private int mRefreshRateInZone;
BrightnessObserver(Context context, Handler handler) { BrightnessObserver(Context context, Handler handler) {
super(handler); super(handler);
mContext = context; mContext = context;
@@ -815,6 +847,7 @@ public class DisplayModeDirector {
public void observe(SensorManager sensorManager) { public void observe(SensorManager sensorManager) {
mSensorManager = sensorManager; mSensorManager = sensorManager;
// DeviceConfig is accessible after system ready. // DeviceConfig is accessible after system ready.
int[] brightnessThresholds = mDeviceConfigDisplaySettings.getBrightnessThresholds(); int[] brightnessThresholds = mDeviceConfigDisplaySettings.getBrightnessThresholds();
int[] ambientThresholds = mDeviceConfigDisplaySettings.getAmbientThresholds(); int[] ambientThresholds = mDeviceConfigDisplaySettings.getAmbientThresholds();
@@ -824,6 +857,8 @@ public class DisplayModeDirector {
mDisplayBrightnessThresholds = brightnessThresholds; mDisplayBrightnessThresholds = brightnessThresholds;
mAmbientBrightnessThresholds = ambientThresholds; mAmbientBrightnessThresholds = ambientThresholds;
} }
mRefreshRateInZone = mDeviceConfigDisplaySettings.getRefreshRateInZone();
restartObserver(); restartObserver();
mDeviceConfigDisplaySettings.startListening(); mDeviceConfigDisplaySettings.startListening();
} }
@@ -863,8 +898,16 @@ public class DisplayModeDirector {
restartObserver(); restartObserver();
} }
public void onDeviceConfigRefreshRateInZoneChanged(int refreshRate) {
if (refreshRate != mRefreshRateInZone) {
mRefreshRateInZone = refreshRate;
restartObserver();
}
}
public void dumpLocked(PrintWriter pw) { public void dumpLocked(PrintWriter pw) {
pw.println(" BrightnessObserver"); pw.println(" BrightnessObserver");
pw.println(" mRefreshRateInZone: " + mRefreshRateInZone);
for (int d: mDisplayBrightnessThresholds) { for (int d: mDisplayBrightnessThresholds) {
pw.println(" mDisplayBrightnessThreshold: " + d); pw.println(" mDisplayBrightnessThreshold: " + d);
@@ -950,6 +993,10 @@ public class DisplayModeDirector {
* to value changes. * to value changes.
*/ */
private boolean checkShouldObserve(int[] a) { private boolean checkShouldObserve(int[] a) {
if (mRefreshRateInZone <= 0) {
return false;
}
for (int d: a) { for (int d: a) {
if (d >= 0) { if (d >= 0) {
return true; return true;
@@ -959,37 +1006,42 @@ public class DisplayModeDirector {
return false; 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() { private void onBrightnessChangedLocked() {
int brightness = Settings.System.getInt(mContext.getContentResolver(), int brightness = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, -1); Settings.System.SCREEN_BRIGHTNESS, -1);
Vote vote = null; Vote vote = null;
for (int i = 0; i < mDisplayBrightnessThresholds.length; i++) { boolean insideZone = isInsideZone(brightness, mAmbientLux);
int disp = mDisplayBrightnessThresholds[i]; if (insideZone) {
int ambi = mAmbientBrightnessThresholds[i]; vote = Vote.forRefreshRates(mRefreshRateInZone, mRefreshRateInZone);
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;
}
} }
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "Display brightness " + brightness + ", ambient lux " + mAmbientLux + 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); updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote);
} }
@@ -1104,7 +1156,6 @@ public class DisplayModeDirector {
} }
private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener { private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
public DeviceConfigDisplaySettings() { public DeviceConfigDisplaySettings() {
} }
@@ -1118,7 +1169,8 @@ public class DisplayModeDirector {
*/ */
public int[] getBrightnessThresholds() { public int[] getBrightnessThresholds() {
return getIntArrayProperty( return getIntArrayProperty(
DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS); DisplayManager.DeviceConfig.
KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS);
} }
/* /*
@@ -1126,7 +1178,8 @@ public class DisplayModeDirector {
*/ */
public int[] getAmbientThresholds() { public int[] getAmbientThresholds() {
return getIntArrayProperty( return getIntArrayProperty(
DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS); DisplayManager.DeviceConfig.
KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS);
} }
/* /*
@@ -1143,17 +1196,32 @@ public class DisplayModeDirector {
return defaultPeakRefreshRate; 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 @Override
public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
int[] brightnessThresholds = getBrightnessThresholds(); int[] brightnessThresholds = getBrightnessThresholds();
int[] ambientThresholds = getAmbientThresholds(); int[] ambientThresholds = getAmbientThresholds();
Float defaultPeakRefreshRate = getDefaultPeakRefreshRate(); Float defaultPeakRefreshRate = getDefaultPeakRefreshRate();
int refreshRateInZone = getRefreshRateInZone();
mHandler.obtainMessage(MSG_BRIGHTNESS_THRESHOLDS_CHANGED, mHandler.obtainMessage(MSG_BRIGHTNESS_THRESHOLDS_CHANGED,
new Pair<int[], int[]>(brightnessThresholds, ambientThresholds)) new Pair<int[], int[]>(brightnessThresholds, ambientThresholds))
.sendToTarget(); .sendToTarget();
mHandler.obtainMessage(MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED, mHandler.obtainMessage(MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED,
defaultPeakRefreshRate).sendToTarget(); defaultPeakRefreshRate).sendToTarget();
mHandler.obtainMessage(MSG_REFRESH_RATE_IN_ZONE_CHANGED, refreshRateInZone,
0).sendToTarget();
} }
private int[] getIntArrayProperty(String prop) { private int[] getIntArrayProperty(String prop) {