Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f775f2a authored by Rupesh Bansal's avatar Rupesh Bansal Committed by Android (Google) Code Review
Browse files

Merge "Fixed latency spike" into tm-qpr-dev

parents 280d2b87 de3be891
Loading
Loading
Loading
Loading
+76 −27
Original line number Diff line number Diff line
@@ -523,8 +523,10 @@ public class DisplayModeDirector {
     * changed
     */
    public void defaultDisplayDeviceUpdated(DisplayDeviceConfig displayDeviceConfig) {
        mSettingsObserver.setRefreshRates(displayDeviceConfig);
        mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig);
        mSettingsObserver.setRefreshRates(displayDeviceConfig,
            /* attemptLoadingFromDeviceConfig= */ true);
        mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig,
            /* attemptLoadingFromDeviceConfig= */ true);
    }

    /**
@@ -1142,15 +1144,21 @@ public class DisplayModeDirector {
        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)
@@ -1215,14 +1223,28 @@ public class DisplayModeDirector {
            }
        }

        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;

            if (attemptLoadingFromDeviceConfig) {
                try {
                    defaultPeakRefreshRate =
                        mDeviceConfigDisplaySettings.getDefaultPeakRefreshRate();
                } catch (Exception exception) {
                    // Do nothing
                }
            }
            if (defaultPeakRefreshRate == null) {
                defaultPeakRefreshRate =
                        (displayDeviceConfig == null) ? (float) mContext.getResources().getInteger(
@@ -1544,7 +1566,8 @@ public class DisplayModeDirector {
            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 @@ public class DisplayModeDirector {
         * 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);
        }

        @VisibleForTesting
        int[] getLowDisplayBrightnessThreshold() {
            return mLowDisplayBrightnessThresholds;
        }

        private void loadLowBrightnessThresholds(DisplayDeviceConfig displayDeviceConfig) {
        @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 @@ public class DisplayModeDirector {
            }
        }

        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,14 +1651,17 @@ public class DisplayModeDirector {
                Callable<int[]> loadFromDeviceConfigDisplaySettingsCallable,
                Callable<int[]> loadFromDisplayDeviceConfigCallable,
                int brightnessThresholdOfFixedRefreshRateKey,
                DisplayDeviceConfig displayDeviceConfig) {
                DisplayDeviceConfig displayDeviceConfig, boolean attemptLoadingFromDeviceConfig) {
            int[] brightnessThresholds = null;

            if (attemptLoadingFromDeviceConfig) {
                try {
                    brightnessThresholds =
                        loadFromDeviceConfigDisplaySettingsCallable.call();
                } catch (Exception exception) {
                    // Do nothing
                }
            }
            if (brightnessThresholds == null) {
                try {
                    brightnessThresholds =
+85 −7
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REF
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.android.server.display.HighBrightnessModeController.HBM_TRANSI

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.annotation.NonNull;
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.core.app.ApplicationProvider;
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 @@ public class DisplayModeDirectorTest {

    @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);

        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);
        verify(displayDeviceConfig).getDefaultRefreshRate();
        verify(displayDeviceConfig).getDefaultPeakRefreshRate();

        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 @@ public class DisplayModeDirectorTest {
                    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);