Merge "Fixed latency spike" into tm-qpr-dev
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 912b1b2..c131ed6 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -523,8 +523,10 @@
* changed
*/
public void defaultDisplayDeviceUpdated(DisplayDeviceConfig displayDeviceConfig) {
- mSettingsObserver.setRefreshRates(displayDeviceConfig);
- mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig);
+ mSettingsObserver.setRefreshRates(displayDeviceConfig,
+ /* attemptLoadingFromDeviceConfig= */ true);
+ mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig,
+ /* attemptLoadingFromDeviceConfig= */ true);
}
/**
@@ -1142,19 +1144,25 @@
SettingsObserver(@NonNull Context context, @NonNull Handler handler) {
super(handler);
mContext = context;
- setRefreshRates(/* displayDeviceConfig= */ null);
+ // We don't want to load from the DeviceConfig while constructing since this leads to
+ // a spike in the latency of DisplayManagerService startup. This happens because
+ // reading from the DeviceConfig is an intensive IO operation and having it in the
+ // startup phase where we thrive to keep the latency very low has significant impact.
+ setRefreshRates(/* displayDeviceConfig= */ null,
+ /* attemptLoadingFromDeviceConfig= */ false);
}
/**
* This is used to update the refresh rate configs from the DeviceConfig, which
* if missing from DisplayDeviceConfig, and finally fallback to config.xml.
*/
- public void setRefreshRates(DisplayDeviceConfig displayDeviceConfig) {
- setDefaultPeakRefreshRate(displayDeviceConfig);
+ public void setRefreshRates(DisplayDeviceConfig displayDeviceConfig,
+ boolean attemptLoadingFromDeviceConfig) {
+ setDefaultPeakRefreshRate(displayDeviceConfig, attemptLoadingFromDeviceConfig);
mDefaultRefreshRate =
(displayDeviceConfig == null) ? (float) mContext.getResources().getInteger(
- R.integer.config_defaultRefreshRate)
- : (float) displayDeviceConfig.getDefaultRefreshRate();
+ R.integer.config_defaultRefreshRate)
+ : (float) displayDeviceConfig.getDefaultRefreshRate();
}
public void observe() {
@@ -1215,13 +1223,27 @@
}
}
- private void setDefaultPeakRefreshRate(DisplayDeviceConfig displayDeviceConfig) {
+ @VisibleForTesting
+ float getDefaultRefreshRate() {
+ return mDefaultRefreshRate;
+ }
+
+ @VisibleForTesting
+ float getDefaultPeakRefreshRate() {
+ return mDefaultPeakRefreshRate;
+ }
+
+ private void setDefaultPeakRefreshRate(DisplayDeviceConfig displayDeviceConfig,
+ boolean attemptLoadingFromDeviceConfig) {
Float defaultPeakRefreshRate = null;
- try {
- defaultPeakRefreshRate =
+
+ if (attemptLoadingFromDeviceConfig) {
+ try {
+ defaultPeakRefreshRate =
mDeviceConfigDisplaySettings.getDefaultPeakRefreshRate();
- } catch (Exception exception) {
- // Do nothing
+ } catch (Exception exception) {
+ // Do nothing
+ }
}
if (defaultPeakRefreshRate == null) {
defaultPeakRefreshRate =
@@ -1544,7 +1566,8 @@
mContext = context;
mHandler = handler;
mInjector = injector;
- updateBlockingZoneThresholds(/* displayDeviceConfig= */ null);
+ updateBlockingZoneThresholds(/* displayDeviceConfig= */ null,
+ /* attemptLoadingFromDeviceConfig= */ false);
mRefreshRateInHighZone = context.getResources().getInteger(
R.integer.config_fixedRefreshRateInHighZone);
}
@@ -1553,22 +1576,44 @@
* This is used to update the blocking zone thresholds from the DeviceConfig, which
* if missing from DisplayDeviceConfig, and finally fallback to config.xml.
*/
- public void updateBlockingZoneThresholds(DisplayDeviceConfig displayDeviceConfig) {
- loadLowBrightnessThresholds(displayDeviceConfig);
- loadHighBrightnessThresholds(displayDeviceConfig);
+ public void updateBlockingZoneThresholds(DisplayDeviceConfig displayDeviceConfig,
+ boolean attemptLoadingFromDeviceConfig) {
+ loadLowBrightnessThresholds(displayDeviceConfig, attemptLoadingFromDeviceConfig);
+ loadHighBrightnessThresholds(displayDeviceConfig, attemptLoadingFromDeviceConfig);
}
- private void loadLowBrightnessThresholds(DisplayDeviceConfig displayDeviceConfig) {
+ @VisibleForTesting
+ int[] getLowDisplayBrightnessThreshold() {
+ return mLowDisplayBrightnessThresholds;
+ }
+
+ @VisibleForTesting
+ int[] getLowAmbientBrightnessThreshold() {
+ return mLowAmbientBrightnessThresholds;
+ }
+
+ @VisibleForTesting
+ int[] getHighDisplayBrightnessThreshold() {
+ return mHighDisplayBrightnessThresholds;
+ }
+
+ @VisibleForTesting
+ int[] getHighAmbientBrightnessThreshold() {
+ return mHighAmbientBrightnessThresholds;
+ }
+
+ private void loadLowBrightnessThresholds(DisplayDeviceConfig displayDeviceConfig,
+ boolean attemptLoadingFromDeviceConfig) {
mLowDisplayBrightnessThresholds = loadBrightnessThresholds(
() -> mDeviceConfigDisplaySettings.getLowDisplayBrightnessThresholds(),
() -> displayDeviceConfig.getLowDisplayBrightnessThresholds(),
R.array.config_brightnessThresholdsOfPeakRefreshRate,
- displayDeviceConfig);
+ displayDeviceConfig, attemptLoadingFromDeviceConfig);
mLowAmbientBrightnessThresholds = loadBrightnessThresholds(
() -> mDeviceConfigDisplaySettings.getLowAmbientBrightnessThresholds(),
() -> displayDeviceConfig.getLowAmbientBrightnessThresholds(),
R.array.config_ambientThresholdsOfPeakRefreshRate,
- displayDeviceConfig);
+ displayDeviceConfig, attemptLoadingFromDeviceConfig);
if (mLowDisplayBrightnessThresholds.length != mLowAmbientBrightnessThresholds.length) {
throw new RuntimeException("display low brightness threshold array and ambient "
+ "brightness threshold array have different length: "
@@ -1579,17 +1624,18 @@
}
}
- private void loadHighBrightnessThresholds(DisplayDeviceConfig displayDeviceConfig) {
+ private void loadHighBrightnessThresholds(DisplayDeviceConfig displayDeviceConfig,
+ boolean attemptLoadingFromDeviceConfig) {
mHighDisplayBrightnessThresholds = loadBrightnessThresholds(
() -> mDeviceConfigDisplaySettings.getHighDisplayBrightnessThresholds(),
() -> displayDeviceConfig.getHighDisplayBrightnessThresholds(),
R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate,
- displayDeviceConfig);
+ displayDeviceConfig, attemptLoadingFromDeviceConfig);
mHighAmbientBrightnessThresholds = loadBrightnessThresholds(
() -> mDeviceConfigDisplaySettings.getHighAmbientBrightnessThresholds(),
() -> displayDeviceConfig.getHighAmbientBrightnessThresholds(),
R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate,
- displayDeviceConfig);
+ displayDeviceConfig, attemptLoadingFromDeviceConfig);
if (mHighDisplayBrightnessThresholds.length
!= mHighAmbientBrightnessThresholds.length) {
throw new RuntimeException("display high brightness threshold array and ambient "
@@ -1605,13 +1651,16 @@
Callable<int[]> loadFromDeviceConfigDisplaySettingsCallable,
Callable<int[]> loadFromDisplayDeviceConfigCallable,
int brightnessThresholdOfFixedRefreshRateKey,
- DisplayDeviceConfig displayDeviceConfig) {
+ DisplayDeviceConfig displayDeviceConfig, boolean attemptLoadingFromDeviceConfig) {
int[] brightnessThresholds = null;
- try {
- brightnessThresholds =
+
+ if (attemptLoadingFromDeviceConfig) {
+ try {
+ brightnessThresholds =
loadFromDeviceConfigDisplaySettingsCallable.call();
- } catch (Exception exception) {
- // Do nothing
+ } catch (Exception exception) {
+ // Do nothing
+ }
}
if (brightnessThresholds == null) {
try {
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index 18dd264..fb0cdfa 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -21,6 +21,7 @@
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_DISPLAY_BRIGHTNESS_THRESHOLDS;
+import static android.hardware.display.DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_DEFAULT;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT;
import static android.hardware.display.DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HIGH_ZONE;
@@ -31,6 +32,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -48,6 +51,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEventListener;
@@ -76,6 +80,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.R;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.test.FakeSettingsProvider;
@@ -1855,16 +1860,83 @@
@Test
public void testNotifyDefaultDisplayDeviceUpdated() {
- DisplayDeviceConfig displayDeviceConfig = mock(DisplayDeviceConfig.class);
- when(displayDeviceConfig.getLowDisplayBrightnessThresholds()).thenReturn(new int[]{});
- when(displayDeviceConfig.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{});
- when(displayDeviceConfig.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{});
- when(displayDeviceConfig.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{});
+ Resources resources = mock(Resources.class);
+ when(mContext.getResources()).thenReturn(resources);
+ when(resources.getInteger(com.android.internal.R.integer.config_defaultPeakRefreshRate))
+ .thenReturn(75);
+ when(resources.getInteger(R.integer.config_defaultRefreshRate))
+ .thenReturn(45);
+ when(resources.getIntArray(R.array.config_brightnessThresholdsOfPeakRefreshRate))
+ .thenReturn(new int[]{5});
+ when(resources.getIntArray(R.array.config_ambientThresholdsOfPeakRefreshRate))
+ .thenReturn(new int[]{10});
+ when(
+ resources.getIntArray(R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate))
+ .thenReturn(new int[]{250});
+ when(
+ resources.getIntArray(R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
+ .thenReturn(new int[]{7000});
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0);
+ // We don't expect any interaction with DeviceConfig when the director is initialized
+ // because we explicitly avoid doing this as this can lead to a latency spike in the
+ // startup of DisplayManagerService
+ // Verify all the loaded values are from DisplayDeviceConfig
+ assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 45, 0.0);
+ assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 75,
+ 0.0);
+ assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
+ new int[]{250});
+ assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
+ new int[]{7000});
+ assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThreshold(),
+ new int[]{5});
+ assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
+ new int[]{10});
+
+ // Notify that the default display is updated, such that DisplayDeviceConfig has new values
+ DisplayDeviceConfig displayDeviceConfig = mock(DisplayDeviceConfig.class);
+ when(displayDeviceConfig.getDefaultRefreshRate()).thenReturn(50);
+ when(displayDeviceConfig.getDefaultPeakRefreshRate()).thenReturn(55);
+ when(displayDeviceConfig.getLowDisplayBrightnessThresholds()).thenReturn(new int[]{25});
+ when(displayDeviceConfig.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30});
+ when(displayDeviceConfig.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210});
+ when(displayDeviceConfig.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{2100});
director.defaultDisplayDeviceUpdated(displayDeviceConfig);
- verify(displayDeviceConfig).getDefaultRefreshRate();
- verify(displayDeviceConfig).getDefaultPeakRefreshRate();
+
+ assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 50, 0.0);
+ assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 55,
+ 0.0);
+ assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
+ new int[]{210});
+ assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
+ new int[]{2100});
+ assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThreshold(),
+ new int[]{25});
+ assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
+ new int[]{30});
+
+ // Notify that the default display is updated, such that DeviceConfig has new values
+ FakeDeviceConfig config = mInjector.getDeviceConfig();
+ config.setDefaultPeakRefreshRate(60);
+ config.setLowAmbientBrightnessThresholds(new int[]{20});
+ config.setLowDisplayBrightnessThresholds(new int[]{10});
+ config.setHighDisplayBrightnessThresholds(new int[]{255});
+ config.setHighAmbientBrightnessThresholds(new int[]{8000});
+
+ director.defaultDisplayDeviceUpdated(displayDeviceConfig);
+
+ assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 50, 0.0);
+ assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 60,
+ 0.0);
+ assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
+ new int[]{255});
+ assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
+ new int[]{8000});
+ assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThreshold(),
+ new int[]{10});
+ assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
+ new int[]{20});
}
private Temperature getSkinTemp(@Temperature.ThrottlingStatus int status) {
@@ -1954,6 +2026,12 @@
String.valueOf(fps));
}
+ void setDefaultPeakRefreshRate(int fps) {
+ putPropertyAndNotify(
+ DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_PEAK_REFRESH_RATE_DEFAULT,
+ String.valueOf(fps));
+ }
+
void setHighDisplayBrightnessThresholds(int[] brightnessThresholds) {
String thresholds = toPropertyValue(brightnessThresholds);