1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.display;
18 
19 
20 import static com.android.server.display.utils.DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat;
21 import static com.android.server.display.utils.DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat;
22 
23 import static org.junit.Assert.assertArrayEquals;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.mockito.ArgumentMatchers.anyFloat;
28 import static org.mockito.ArgumentMatchers.anyInt;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.when;
31 
32 import android.content.Context;
33 import android.content.res.Resources;
34 import android.content.res.TypedArray;
35 import android.os.Temperature;
36 import android.util.SparseArray;
37 import android.util.Spline;
38 import android.view.SurfaceControl;
39 
40 import androidx.test.ext.junit.runners.AndroidJUnit4;
41 import androidx.test.filters.SmallTest;
42 
43 import com.android.internal.R;
44 import com.android.server.display.config.ThermalStatus;
45 
46 import org.junit.Before;
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 import org.mockito.Mock;
50 import org.mockito.MockitoAnnotations;
51 
52 import java.io.IOException;
53 import java.nio.charset.StandardCharsets;
54 import java.nio.file.Files;
55 import java.nio.file.Path;
56 import java.util.ArrayList;
57 import java.util.HashMap;
58 import java.util.List;
59 import java.util.Map;
60 
61 @SmallTest
62 @RunWith(AndroidJUnit4.class)
63 public final class DisplayDeviceConfigTest {
64     private static final int DEFAULT_PEAK_REFRESH_RATE = 75;
65     private static final int DEFAULT_REFRESH_RATE = 120;
66     private static final int DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE = 55;
67     private static final int DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE = 95;
68     private static final int DEFAULT_REFRESH_RATE_IN_HBM_HDR = 90;
69     private static final int DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT = 100;
70     private static final int[] LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE =
71             new int[]{10, 30, -1};
72     private static final int[] LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{-1, 1, 21};
73     private static final int[] HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{160, -1};
74     private static final int[] HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{-1, 30000};
75     private static final float[] NITS = {2, 500, 800};
76     private static final float[] BRIGHTNESS = {0, 0.62f, 1};
77     private static final Spline NITS_TO_BRIGHTNESS_SPLINE =
78             Spline.createSpline(NITS, BRIGHTNESS);
79 
80     private DisplayDeviceConfig mDisplayDeviceConfig;
81     private static final float ZERO_DELTA = 0.0f;
82     private static final float SMALL_DELTA = 0.0001f;
83     @Mock
84     private Context mContext;
85 
86     @Mock
87     private Resources mResources;
88 
89     @Before
setUp()90     public void setUp() {
91         MockitoAnnotations.initMocks(this);
92         when(mContext.getResources()).thenReturn(mResources);
93         mockDeviceConfigs();
94     }
95 
96     @Test
testConfigValuesFromDisplayConfig()97     public void testConfigValuesFromDisplayConfig() throws IOException {
98         setupDisplayDeviceConfigFromDisplayConfigFile();
99 
100         assertEquals(mDisplayDeviceConfig.getName(), "Example Display");
101         assertEquals(mDisplayDeviceConfig.getAmbientHorizonLong(), 5000);
102         assertEquals(mDisplayDeviceConfig.getAmbientHorizonShort(), 50);
103         assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000);
104         assertEquals(mDisplayDeviceConfig.getBrightnessRampIncreaseMaxMillis(), 2000);
105         assertEquals(mDisplayDeviceConfig.getBrightnessRampFastDecrease(), 0.01f, ZERO_DELTA);
106         assertEquals(mDisplayDeviceConfig.getBrightnessRampFastIncrease(), 0.02f, ZERO_DELTA);
107         assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowIncrease(), 0.04f, ZERO_DELTA);
108         assertEquals(mDisplayDeviceConfig.getBrightnessRampSlowDecrease(), 0.03f, ZERO_DELTA);
109         assertEquals(mDisplayDeviceConfig.getBrightnessDefault(), 0.5f, ZERO_DELTA);
110         assertArrayEquals(mDisplayDeviceConfig.getBrightness(), BRIGHTNESS, ZERO_DELTA);
111         assertArrayEquals(mDisplayDeviceConfig.getNits(), NITS, ZERO_DELTA);
112         assertArrayEquals(mDisplayDeviceConfig.getBacklight(), BRIGHTNESS, ZERO_DELTA);
113         assertEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLightDebounce(), 2000);
114         assertEquals(mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounce(), 1000);
115         assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
116                 float[]{0.0f, 50.0f, 80.0f}, ZERO_DELTA);
117         assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
118                 float[]{45.32f, 75.43f}, ZERO_DELTA);
119 
120         // Test thresholds
121         assertEquals(10, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(),
122                 ZERO_DELTA);
123         assertEquals(20, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThresholdIdle(),
124                 ZERO_DELTA);
125         assertEquals(30, mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold(), ZERO_DELTA);
126         assertEquals(40, mDisplayDeviceConfig.getAmbientLuxDarkeningMinThresholdIdle(), ZERO_DELTA);
127 
128         assertEquals(0.1f, mDisplayDeviceConfig.getScreenBrighteningMinThreshold(), ZERO_DELTA);
129         assertEquals(0.2f, mDisplayDeviceConfig.getScreenBrighteningMinThresholdIdle(), ZERO_DELTA);
130         assertEquals(0.3f, mDisplayDeviceConfig.getScreenDarkeningMinThreshold(), ZERO_DELTA);
131         assertEquals(0.4f, mDisplayDeviceConfig.getScreenDarkeningMinThresholdIdle(), ZERO_DELTA);
132 
133         assertArrayEquals(new float[]{0, 0.10f, 0.20f},
134                 mDisplayDeviceConfig.getScreenBrighteningLevels(), ZERO_DELTA);
135         assertArrayEquals(new float[]{9, 10, 11},
136                 mDisplayDeviceConfig.getScreenBrighteningPercentages(), ZERO_DELTA);
137         assertArrayEquals(new float[]{0, 0.11f, 0.21f},
138                 mDisplayDeviceConfig.getScreenDarkeningLevels(), ZERO_DELTA);
139         assertArrayEquals(new float[]{11, 12, 13},
140                 mDisplayDeviceConfig.getScreenDarkeningPercentages(), ZERO_DELTA);
141 
142         assertArrayEquals(new float[]{0, 100, 200},
143                 mDisplayDeviceConfig.getAmbientBrighteningLevels(), ZERO_DELTA);
144         assertArrayEquals(new float[]{13, 14, 15},
145                 mDisplayDeviceConfig.getAmbientBrighteningPercentages(), ZERO_DELTA);
146         assertArrayEquals(new float[]{0, 300, 400},
147                 mDisplayDeviceConfig.getAmbientDarkeningLevels(), ZERO_DELTA);
148         assertArrayEquals(new float[]{15, 16, 17},
149                 mDisplayDeviceConfig.getAmbientDarkeningPercentages(), ZERO_DELTA);
150 
151         assertArrayEquals(new float[]{0, 0.12f, 0.22f},
152                 mDisplayDeviceConfig.getScreenBrighteningLevelsIdle(), ZERO_DELTA);
153         assertArrayEquals(new float[]{17, 18, 19},
154                 mDisplayDeviceConfig.getScreenBrighteningPercentagesIdle(), ZERO_DELTA);
155         assertArrayEquals(new float[]{0, 0.13f, 0.23f},
156                 mDisplayDeviceConfig.getScreenDarkeningLevelsIdle(), ZERO_DELTA);
157         assertArrayEquals(new float[]{19, 20, 21},
158                 mDisplayDeviceConfig.getScreenDarkeningPercentagesIdle(), ZERO_DELTA);
159 
160         assertArrayEquals(new float[]{0, 500, 600},
161                 mDisplayDeviceConfig.getAmbientBrighteningLevelsIdle(), ZERO_DELTA);
162         assertArrayEquals(new float[]{21, 22, 23},
163                 mDisplayDeviceConfig.getAmbientBrighteningPercentagesIdle(), ZERO_DELTA);
164         assertArrayEquals(new float[]{0, 700, 800},
165                 mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle(), ZERO_DELTA);
166         assertArrayEquals(new float[]{23, 24, 25},
167                 mDisplayDeviceConfig.getAmbientDarkeningPercentagesIdle(), ZERO_DELTA);
168 
169         assertEquals(75, mDisplayDeviceConfig.getDefaultLowBlockingZoneRefreshRate());
170         assertEquals(90, mDisplayDeviceConfig.getDefaultHighBlockingZoneRefreshRate());
171         assertEquals(85, mDisplayDeviceConfig.getDefaultPeakRefreshRate());
172         assertEquals(45, mDisplayDeviceConfig.getDefaultRefreshRate());
173         assertEquals(2, mDisplayDeviceConfig.getRefreshRangeProfiles().size());
174         assertEquals(60, mDisplayDeviceConfig.getRefreshRange("test1").min, SMALL_DELTA);
175         assertEquals(60, mDisplayDeviceConfig.getRefreshRange("test1").max, SMALL_DELTA);
176         assertEquals(80, mDisplayDeviceConfig.getRefreshRange("test2").min, SMALL_DELTA);
177         assertEquals(90, mDisplayDeviceConfig.getRefreshRange("test2").max, SMALL_DELTA);
178         assertEquals(82, mDisplayDeviceConfig.getDefaultRefreshRateInHbmHdr());
179         assertEquals(83, mDisplayDeviceConfig.getDefaultRefreshRateInHbmSunlight());
180 
181         assertEquals("sensor_12345",
182                 mDisplayDeviceConfig.getScreenOffBrightnessSensor().type);
183         assertEquals("Sensor 12345",
184                 mDisplayDeviceConfig.getScreenOffBrightnessSensor().name);
185 
186         assertArrayEquals(new int[]{-1, 10, 20, 30, 40},
187                 mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux());
188 
189         List<DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel>
190                 defaultThrottlingLevels = new ArrayList<>();
191         defaultThrottlingLevels.add(
192                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
193                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 0.4f
194         ));
195         defaultThrottlingLevels.add(
196                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
197                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 0.3f
198         ));
199         defaultThrottlingLevels.add(
200                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
201                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 0.2f
202         ));
203         defaultThrottlingLevels.add(
204                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
205                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 0.1f
206         ));
207         defaultThrottlingLevels.add(
208                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
209                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 0.05f
210         ));
211         defaultThrottlingLevels.add(
212                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
213                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 0.025f
214         ));
215 
216         DisplayDeviceConfig.ThermalBrightnessThrottlingData defaultThrottlingData =
217                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData(defaultThrottlingLevels);
218 
219         List<DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel>
220                 concurrentThrottlingLevels = new ArrayList<>();
221         concurrentThrottlingLevels.add(
222                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
223                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 0.2f
224         ));
225         concurrentThrottlingLevels.add(
226                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
227                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 0.15f
228         ));
229         concurrentThrottlingLevels.add(
230                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
231                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 0.1f
232         ));
233         concurrentThrottlingLevels.add(
234                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
235                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 0.05f
236         ));
237         concurrentThrottlingLevels.add(
238                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
239                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 0.025f
240         ));
241         concurrentThrottlingLevels.add(
242                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel(
243                 DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 0.0125f
244         ));
245         DisplayDeviceConfig.ThermalBrightnessThrottlingData concurrentThrottlingData =
246                 new DisplayDeviceConfig.ThermalBrightnessThrottlingData(concurrentThrottlingLevels);
247 
248         HashMap<String, DisplayDeviceConfig.ThermalBrightnessThrottlingData> throttlingDataMap =
249                 new HashMap<>(2);
250         throttlingDataMap.put("default", defaultThrottlingData);
251         throttlingDataMap.put("concurrent", concurrentThrottlingData);
252 
253         assertEquals(throttlingDataMap,
254                 mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId());
255 
256         assertNotNull(mDisplayDeviceConfig.getHostUsiVersion());
257         assertEquals(mDisplayDeviceConfig.getHostUsiVersion().getMajorVersion(), 2);
258         assertEquals(mDisplayDeviceConfig.getHostUsiVersion().getMinorVersion(), 0);
259 
260         // Max desired Hdr/SDR ratio upper-bounds the HDR brightness.
261         assertEquals(1.0f,
262                 mDisplayDeviceConfig.getHdrBrightnessFromSdr(0.62f, Float.POSITIVE_INFINITY),
263                 ZERO_DELTA);
264         assertEquals(0.62f,
265                 mDisplayDeviceConfig.getHdrBrightnessFromSdr(0.62f, 1.0f),
266                 ZERO_DELTA);
267         assertEquals(0.77787f,
268                 mDisplayDeviceConfig.getHdrBrightnessFromSdr(0.62f, 1.25f),
269                 SMALL_DELTA);
270 
271         // Low/High zone thermal maps
272         assertEquals(new SurfaceControl.RefreshRateRange(30, 40),
273                 mDisplayDeviceConfig.getLowBlockingZoneThermalMap()
274                 .get(Temperature.THROTTLING_CRITICAL));
275         assertEquals(new SurfaceControl.RefreshRateRange(40, 60),
276                 mDisplayDeviceConfig.getHighBlockingZoneThermalMap()
277                 .get(Temperature.THROTTLING_EMERGENCY));
278 
279         // Todo: Add asserts for DensityMapping,
280         // HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
281     }
282 
283     @Test
testConfigValuesFromConfigResource()284     public void testConfigValuesFromConfigResource() {
285         setupDisplayDeviceConfigFromConfigResourceFile();
286         assertNull(mDisplayDeviceConfig.getName());
287         assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
288                 float[]{2.0f, 200.0f, 600.0f}, ZERO_DELTA);
289         assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
290                 float[]{0.0f, 0.0f, 110.0f, 500.0f}, ZERO_DELTA);
291 
292         // Test thresholds
293         assertEquals(0, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(), ZERO_DELTA);
294         assertEquals(0, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThresholdIdle(),
295                 ZERO_DELTA);
296         assertEquals(0, mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold(), ZERO_DELTA);
297         assertEquals(0, mDisplayDeviceConfig.getAmbientLuxDarkeningMinThresholdIdle(), ZERO_DELTA);
298 
299         assertEquals(0, mDisplayDeviceConfig.getScreenBrighteningMinThreshold(), ZERO_DELTA);
300         assertEquals(0, mDisplayDeviceConfig.getScreenBrighteningMinThresholdIdle(), ZERO_DELTA);
301         assertEquals(0, mDisplayDeviceConfig.getScreenDarkeningMinThreshold(), ZERO_DELTA);
302         assertEquals(0, mDisplayDeviceConfig.getScreenDarkeningMinThresholdIdle(), ZERO_DELTA);
303 
304         // screen levels will be considered "old screen brightness scale"
305         // and therefore will divide by 255
306         assertArrayEquals(new float[]{0, 42 / 255f, 43 / 255f},
307                 mDisplayDeviceConfig.getScreenBrighteningLevels(), SMALL_DELTA);
308         assertArrayEquals(new float[]{35, 36, 37},
309                 mDisplayDeviceConfig.getScreenBrighteningPercentages(), ZERO_DELTA);
310         assertArrayEquals(new float[]{0, 42 / 255f, 43 / 255f},
311                 mDisplayDeviceConfig.getScreenDarkeningLevels(), SMALL_DELTA);
312         assertArrayEquals(new float[]{37, 38, 39},
313                 mDisplayDeviceConfig.getScreenDarkeningPercentages(), ZERO_DELTA);
314 
315         assertArrayEquals(new float[]{0, 30, 31},
316                 mDisplayDeviceConfig.getAmbientBrighteningLevels(), ZERO_DELTA);
317         assertArrayEquals(new float[]{27, 28, 29},
318                 mDisplayDeviceConfig.getAmbientBrighteningPercentages(), ZERO_DELTA);
319         assertArrayEquals(new float[]{0, 30, 31},
320                 mDisplayDeviceConfig.getAmbientDarkeningLevels(), ZERO_DELTA);
321         assertArrayEquals(new float[]{29, 30, 31},
322                 mDisplayDeviceConfig.getAmbientDarkeningPercentages(), ZERO_DELTA);
323 
324         assertArrayEquals(new float[]{0, 42 / 255f, 43 / 255f},
325                 mDisplayDeviceConfig.getScreenBrighteningLevelsIdle(), SMALL_DELTA);
326         assertArrayEquals(new float[]{35, 36, 37},
327                 mDisplayDeviceConfig.getScreenBrighteningPercentagesIdle(), ZERO_DELTA);
328         assertArrayEquals(new float[]{0, 42 / 255f, 43 / 255f},
329                 mDisplayDeviceConfig.getScreenDarkeningLevelsIdle(), SMALL_DELTA);
330         assertArrayEquals(new float[]{37, 38, 39},
331                 mDisplayDeviceConfig.getScreenDarkeningPercentagesIdle(), ZERO_DELTA);
332 
333         assertArrayEquals(new float[]{0, 30, 31},
334                 mDisplayDeviceConfig.getAmbientBrighteningLevelsIdle(), ZERO_DELTA);
335         assertArrayEquals(new float[]{27, 28, 29},
336                 mDisplayDeviceConfig.getAmbientBrighteningPercentagesIdle(), ZERO_DELTA);
337         assertArrayEquals(new float[]{0, 30, 31},
338                 mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle(), ZERO_DELTA);
339         assertArrayEquals(new float[]{29, 30, 31},
340                 mDisplayDeviceConfig.getAmbientDarkeningPercentagesIdle(), ZERO_DELTA);
341         assertEquals(mDisplayDeviceConfig.getDefaultLowBlockingZoneRefreshRate(),
342                 DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE);
343         assertEquals(mDisplayDeviceConfig.getDefaultHighBlockingZoneRefreshRate(),
344                 DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE);
345         assertEquals(mDisplayDeviceConfig.getDefaultPeakRefreshRate(), DEFAULT_PEAK_REFRESH_RATE);
346         assertEquals(mDisplayDeviceConfig.getDefaultRefreshRate(), DEFAULT_REFRESH_RATE);
347         assertEquals(0, mDisplayDeviceConfig.getRefreshRangeProfiles().size());
348         assertEquals(mDisplayDeviceConfig.getDefaultRefreshRateInHbmSunlight(),
349                 DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT);
350         assertEquals(mDisplayDeviceConfig.getDefaultRefreshRateInHbmHdr(),
351                 DEFAULT_REFRESH_RATE_IN_HBM_HDR);
352 
353         // Todo: Add asserts for ThermalBrightnessThrottlingData, DensityMapping,
354         // HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
355     }
356 
357     @Test
testThermalRefreshRateThrottlingFromDisplayConfig()358     public void testThermalRefreshRateThrottlingFromDisplayConfig() throws IOException {
359         setupDisplayDeviceConfigFromDisplayConfigFile();
360 
361         SparseArray<SurfaceControl.RefreshRateRange> defaultMap =
362                 mDisplayDeviceConfig.getThermalRefreshRateThrottlingData(null);
363         assertNotNull(defaultMap);
364         assertEquals(2, defaultMap.size());
365         assertEquals(30, defaultMap.get(Temperature.THROTTLING_CRITICAL).min, SMALL_DELTA);
366         assertEquals(60, defaultMap.get(Temperature.THROTTLING_CRITICAL).max, SMALL_DELTA);
367         assertEquals(0, defaultMap.get(Temperature.THROTTLING_SHUTDOWN).min, SMALL_DELTA);
368         assertEquals(30, defaultMap.get(Temperature.THROTTLING_SHUTDOWN).max, SMALL_DELTA);
369 
370         SparseArray<SurfaceControl.RefreshRateRange> testMap =
371                 mDisplayDeviceConfig.getThermalRefreshRateThrottlingData("test");
372         assertNotNull(testMap);
373         assertEquals(1, testMap.size());
374         assertEquals(60, testMap.get(Temperature.THROTTLING_EMERGENCY).min, SMALL_DELTA);
375         assertEquals(90, testMap.get(Temperature.THROTTLING_EMERGENCY).max, SMALL_DELTA);
376     }
377 
378     @Test
testValidLuxThrottling()379     public void testValidLuxThrottling() throws Exception {
380         setupDisplayDeviceConfigFromDisplayConfigFile();
381 
382         Map<DisplayDeviceConfig.BrightnessLimitMapType, Map<Float, Float>> luxThrottlingData =
383                 mDisplayDeviceConfig.getLuxThrottlingData();
384         assertEquals(2, luxThrottlingData.size());
385 
386         Map<Float, Float> adaptiveOnBrightnessPoints = luxThrottlingData.get(
387                 DisplayDeviceConfig.BrightnessLimitMapType.ADAPTIVE);
388         assertEquals(2, adaptiveOnBrightnessPoints.size());
389         assertEquals(0.3f, adaptiveOnBrightnessPoints.get(1000f), SMALL_DELTA);
390         assertEquals(0.5f, adaptiveOnBrightnessPoints.get(5000f), SMALL_DELTA);
391 
392         Map<Float, Float> adaptiveOffBrightnessPoints = luxThrottlingData.get(
393                 DisplayDeviceConfig.BrightnessLimitMapType.DEFAULT);
394         assertEquals(2, adaptiveOffBrightnessPoints.size());
395         assertEquals(0.35f, adaptiveOffBrightnessPoints.get(1500f), SMALL_DELTA);
396         assertEquals(0.55f, adaptiveOffBrightnessPoints.get(5500f), SMALL_DELTA);
397     }
398 
399     @Test
testInvalidLuxThrottling()400     public void testInvalidLuxThrottling() throws Exception {
401         setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getInvalidLuxThrottling()));
402 
403         Map<DisplayDeviceConfig.BrightnessLimitMapType, Map<Float, Float>> luxThrottlingData =
404                 mDisplayDeviceConfig.getLuxThrottlingData();
405         assertEquals(1, luxThrottlingData.size());
406 
407         Map<Float, Float> adaptiveOnBrightnessPoints = luxThrottlingData.get(
408                 DisplayDeviceConfig.BrightnessLimitMapType.ADAPTIVE);
409         assertEquals(1, adaptiveOnBrightnessPoints.size());
410         assertEquals(0.3f, adaptiveOnBrightnessPoints.get(1000f), SMALL_DELTA);
411     }
412 
413     @Test
testBlockingZoneThresholdsFromDisplayConfig()414     public void testBlockingZoneThresholdsFromDisplayConfig() throws IOException {
415         setupDisplayDeviceConfigFromDisplayConfigFile();
416 
417         assertArrayEquals(new float[]{ NITS_TO_BRIGHTNESS_SPLINE.interpolate(50),
418                         NITS_TO_BRIGHTNESS_SPLINE.interpolate(300),
419                         NITS_TO_BRIGHTNESS_SPLINE.interpolate(300), -1},
420                 mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(), SMALL_DELTA);
421         assertArrayEquals(new float[]{50, 60, -1, 60},
422                 mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(), ZERO_DELTA);
423         assertArrayEquals(new float[]{ NITS_TO_BRIGHTNESS_SPLINE.interpolate(80),
424                         NITS_TO_BRIGHTNESS_SPLINE.interpolate(100),
425                         NITS_TO_BRIGHTNESS_SPLINE.interpolate(100), -1},
426                 mDisplayDeviceConfig.getHighDisplayBrightnessThresholds(), SMALL_DELTA);
427         assertArrayEquals(new float[]{70, 80, -1, 80},
428                 mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(), ZERO_DELTA);
429     }
430 
431     @Test
testBlockingZoneThresholdsFromConfigResource()432     public void testBlockingZoneThresholdsFromConfigResource() {
433         setupDisplayDeviceConfigFromConfigResourceFile();
434 
435         assertArrayEquals(displayBrightnessThresholdsIntToFloat(
436                 LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE),
437                 mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(), SMALL_DELTA);
438         assertArrayEquals(ambientBrightnessThresholdsIntToFloat(
439                 LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE),
440                 mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(), ZERO_DELTA);
441         assertArrayEquals(displayBrightnessThresholdsIntToFloat(
442                 HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE),
443                 mDisplayDeviceConfig.getHighDisplayBrightnessThresholds(), SMALL_DELTA);
444         assertArrayEquals(ambientBrightnessThresholdsIntToFloat(
445                 HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE),
446                 mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(), ZERO_DELTA);
447     }
448 
getValidLuxThrottling()449     private String getValidLuxThrottling() {
450         return "<luxThrottling>\n"
451                 + "    <brightnessLimitMap>\n"
452                 + "        <type>adaptive</type>\n"
453                 + "        <map>\n"
454                 + "            <point>"
455                 + "                <first>1000</first>\n"
456                 + "                <second>0.3</second>\n"
457                 + "            </point>"
458                 + "            <point>"
459                 + "                <first>5000</first>\n"
460                 + "                <second>0.5</second>\n"
461                 + "            </point>"
462                 + "        </map>\n"
463                 + "    </brightnessLimitMap>\n"
464                 + "    <brightnessLimitMap>\n"
465                 + "        <type>default</type>\n"
466                 + "        <map>\n"
467                 + "            <point>"
468                 + "                <first>1500</first>\n"
469                 + "                <second>0.35</second>\n"
470                 + "            </point>"
471                 + "            <point>"
472                 + "                <first>5500</first>\n"
473                 + "                <second>0.55</second>\n"
474                 + "            </point>"
475                 + "        </map>\n"
476                 + "    </brightnessLimitMap>\n"
477                 + "</luxThrottling>";
478     }
479 
getInvalidLuxThrottling()480     private String getInvalidLuxThrottling() {
481         return "<luxThrottling>\n"
482                 + "    <brightnessLimitMap>\n"
483                 + "        <type>adaptive</type>\n"
484                 + "        <map>\n"
485                 + "            <point>"
486                 + "                <first>1000</first>\n"
487                 + "                <second>0.3</second>\n"
488                 + "            </point>"
489                 + "            <point>" // second > hbm.transitionPoint, skipped
490                 + "                <first>1500</first>\n"
491                 + "                <second>0.9</second>\n"
492                 + "            </point>"
493                 + "            <point>" // same lux value, skipped
494                 + "                <first>1000</first>\n"
495                 + "                <second>0.5</second>\n"
496                 + "            </point>"
497                 + "        </map>\n"
498                 + "    </brightnessLimitMap>\n"
499                 + "    <brightnessLimitMap>\n" // Same type, skipped
500                 + "        <type>adaptive</type>\n"
501                 + "        <map>\n"
502                 + "            <point>"
503                 + "                <first>2000</first>\n"
504                 + "                <second>0.35</second>\n"
505                 + "            </point>"
506                 + "            <point>"
507                 + "                <first>6000</first>\n"
508                 + "                <second>0.55</second>\n"
509                 + "            </point>"
510                 + "        </map>\n"
511                 + "    </brightnessLimitMap>\n"
512                 + "    <brightnessLimitMap>\n" // Invalid points only, skipped
513                 + "        <type>default</type>\n"
514                 + "        <map>\n"
515                 + "            <point>"
516                 + "                <first>2500</first>\n"
517                 + "                <second>0.99</second>\n"
518                 + "            </point>"
519                 + "        </map>\n"
520                 + "    </brightnessLimitMap>\n"
521                 + "</luxThrottling>";
522     }
523 
getRefreshThermalThrottlingMaps()524     private String getRefreshThermalThrottlingMaps() {
525         return "<refreshRateThrottlingMap>\n"
526                + "    <refreshRateThrottlingPoint>\n"
527                + "        <thermalStatus>critical</thermalStatus>\n"
528                + "        <refreshRateRange>\n"
529                + "            <minimum>30</minimum>\n"
530                + "            <maximum>60</maximum>\n"
531                + "        </refreshRateRange>\n"
532                + "    </refreshRateThrottlingPoint>\n"
533                + "    <refreshRateThrottlingPoint>\n"
534                + "        <thermalStatus>shutdown</thermalStatus>\n"
535                + "        <refreshRateRange>\n"
536                + "            <minimum>0</minimum>\n"
537                + "            <maximum>30</maximum>\n"
538                + "        </refreshRateRange>\n"
539                + "    </refreshRateThrottlingPoint>\n"
540                + "</refreshRateThrottlingMap>\n"
541                + "<refreshRateThrottlingMap id=\"thermalLow\">\n"
542                + "    <refreshRateThrottlingPoint>\n"
543                + "        <thermalStatus>critical</thermalStatus>\n"
544                + "        <refreshRateRange>\n"
545                + "            <minimum>30</minimum>\n"
546                + "            <maximum>40</maximum>\n"
547                + "        </refreshRateRange>\n"
548                + "    </refreshRateThrottlingPoint>\n"
549                + "</refreshRateThrottlingMap>\n"
550                + "<refreshRateThrottlingMap id=\"thermalHigh\">\n"
551                + "    <refreshRateThrottlingPoint>\n"
552                + "        <thermalStatus>emergency</thermalStatus>\n"
553                + "        <refreshRateRange>\n"
554                + "            <minimum>40</minimum>\n"
555                + "            <maximum>60</maximum>\n"
556                + "        </refreshRateRange>\n"
557                + "    </refreshRateThrottlingPoint>\n"
558                + "</refreshRateThrottlingMap>\n"
559                + "<refreshRateThrottlingMap id=\"test\">\n"
560                + "    <refreshRateThrottlingPoint>\n"
561                + "        <thermalStatus>emergency</thermalStatus>\n"
562                + "        <refreshRateRange>\n"
563                + "            <minimum>60</minimum>\n"
564                + "            <maximum>90</maximum>\n"
565                + "        </refreshRateRange>\n"
566                + "    </refreshRateThrottlingPoint>\n"
567                + "</refreshRateThrottlingMap>\n";
568     }
569 
getContent()570     private String getContent() {
571         return getContent(getValidLuxThrottling());
572     }
573 
getContent(String brightnessCapConfig)574     private String getContent(String brightnessCapConfig) {
575         return "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
576                 + "<displayConfiguration>\n"
577                 +   "<name>Example Display</name>"
578                 +   "<screenBrightnessMap>\n"
579                 +       "<point>\n"
580                 +           "<value>" + BRIGHTNESS[0] + "</value>\n"
581                 +           "<nits>" + NITS[0] + "</nits>\n"
582                 +       "</point>\n"
583                 +       "<point>\n"
584                 +           "<value>" + BRIGHTNESS[1] + "</value>\n"
585                 +           "<nits>" + NITS[1] + "</nits>\n"
586                 +       "</point>\n"
587                 +       "<point>\n"
588                 +           "<value>" + BRIGHTNESS[2] + "</value>\n"
589                 +           "<nits>" + NITS[2] + "</nits>\n"
590                 +       "</point>\n"
591                 +   "</screenBrightnessMap>\n"
592                 +   "<autoBrightness>\n"
593                 +       "<brighteningLightDebounceMillis>2000</brighteningLightDebounceMillis>\n"
594                 +       "<darkeningLightDebounceMillis>1000</darkeningLightDebounceMillis>\n"
595                 +       "<displayBrightnessMapping>\n"
596                 +            "<displayBrightnessPoint>\n"
597                 +                "<lux>50</lux>\n"
598                 +                "<nits>45.32</nits>\n"
599                 +            "</displayBrightnessPoint>\n"
600                 +            "<displayBrightnessPoint>\n"
601                 +                "<lux>80</lux>\n"
602                 +                "<nits>75.43</nits>\n"
603                 +            "</displayBrightnessPoint>\n"
604                 +       "</displayBrightnessMapping>\n"
605                 +   "</autoBrightness>\n"
606                 +   "<highBrightnessMode enabled=\"true\">\n"
607                 +       "<transitionPoint>0.62</transitionPoint>\n"
608                 +       "<minimumLux>10000</minimumLux>\n"
609                 +       "<timing>\n"
610                 +           "<!-- allow for 5 minutes out of every 30 minutes -->\n"
611                 +           "<timeWindowSecs>1800</timeWindowSecs>\n"
612                 +           "<timeMaxSecs>300</timeMaxSecs>\n"
613                 +           "<timeMinSecs>60</timeMinSecs>\n"
614                 +       "</timing>\n"
615                 +       "<refreshRate>\n"
616                 +           "<minimum>120</minimum>\n"
617                 +           "<maximum>120</maximum>\n"
618                 +       "</refreshRate>\n"
619                 +       "<thermalStatusLimit>light</thermalStatusLimit>\n"
620                 +       "<allowInLowPowerMode>false</allowInLowPowerMode>\n"
621                 +       "<sdrHdrRatioMap>\n"
622                 +            "<point>\n"
623                 +                "<sdrNits>2.000</sdrNits>\n"
624                 +                "<hdrRatio>4.000</hdrRatio>\n"
625                 +            "</point>\n"
626                 +            "<point>\n"
627                 +                "<sdrNits>500.0</sdrNits>\n"
628                 +                "<hdrRatio>1.6</hdrRatio>\n"
629                 +            "</point>\n"
630                 +       "</sdrHdrRatioMap>\n"
631                 +   "</highBrightnessMode>\n"
632                 + brightnessCapConfig
633                 +   "<screenOffBrightnessSensor>\n"
634                 +       "<type>sensor_12345</type>\n"
635                 +       "<name>Sensor 12345</name>\n"
636                 +   "</screenOffBrightnessSensor>\n"
637                 +   "<ambientBrightnessChangeThresholds>\n"
638                 +       "<brighteningThresholds>\n"
639                 +           "<minimum>10</minimum>\n"
640                 +           "<brightnessThresholdPoints>\n"
641                 +               "<brightnessThresholdPoint>\n"
642                 +                   "<threshold>0</threshold><percentage>13</percentage>\n"
643                 +               "</brightnessThresholdPoint>\n"
644                 +               "<brightnessThresholdPoint>\n"
645                 +                   "<threshold>100</threshold><percentage>14</percentage>\n"
646                 +               "</brightnessThresholdPoint>\n"
647                 +               "<brightnessThresholdPoint>\n"
648                 +                   "<threshold>200</threshold><percentage>15</percentage>\n"
649                 +               "</brightnessThresholdPoint>\n"
650                 +           "</brightnessThresholdPoints>\n"
651                 +       "</brighteningThresholds>\n"
652                 +       "<darkeningThresholds>\n"
653                 +           "<minimum>30</minimum>\n"
654                 +           "<brightnessThresholdPoints>\n"
655                 +               "<brightnessThresholdPoint>\n"
656                 +                   "<threshold>0</threshold><percentage>15</percentage>\n"
657                 +               "</brightnessThresholdPoint>\n"
658                 +               "<brightnessThresholdPoint>\n"
659                 +                   "<threshold>300</threshold><percentage>16</percentage>\n"
660                 +               "</brightnessThresholdPoint>\n"
661                 +               "<brightnessThresholdPoint>\n"
662                 +                   "<threshold>400</threshold><percentage>17</percentage>\n"
663                 +               "</brightnessThresholdPoint>\n"
664                 +           "</brightnessThresholdPoints>\n"
665                 +       "</darkeningThresholds>\n"
666                 +   "</ambientBrightnessChangeThresholds>\n"
667                 +   "<displayBrightnessChangeThresholds>\n"
668                 +       "<brighteningThresholds>\n"
669                 +           "<minimum>0.1</minimum>\n"
670                 +           "<brightnessThresholdPoints>\n"
671                 +               "<brightnessThresholdPoint>\n"
672                 +                   "<threshold>0</threshold>\n"
673                 +                   "<percentage>9</percentage>\n"
674                 +               "</brightnessThresholdPoint>\n"
675                 +               "<brightnessThresholdPoint>\n"
676                 +                   "<threshold>0.10</threshold>\n"
677                 +                   "<percentage>10</percentage>\n"
678                 +               "</brightnessThresholdPoint>\n"
679                 +               "<brightnessThresholdPoint>\n"
680                 +                   "<threshold>0.20</threshold>\n"
681                 +                   "<percentage>11</percentage>\n"
682                 +               "</brightnessThresholdPoint>\n"
683                 +           "</brightnessThresholdPoints>\n"
684                 +       "</brighteningThresholds>\n"
685                 +       "<darkeningThresholds>\n"
686                 +           "<minimum>0.3</minimum>\n"
687                 +           "<brightnessThresholdPoints>\n"
688                 +               "<brightnessThresholdPoint>\n"
689                 +                   "<threshold>0</threshold><percentage>11</percentage>\n"
690                 +               "</brightnessThresholdPoint>\n"
691                 +               "<brightnessThresholdPoint>\n"
692                 +                   "<threshold>0.11</threshold><percentage>12</percentage>\n"
693                 +               "</brightnessThresholdPoint>\n"
694                 +               "<brightnessThresholdPoint>\n"
695                 +                   "<threshold>0.21</threshold><percentage>13</percentage>\n"
696                 +               "</brightnessThresholdPoint>\n"
697                 +           "</brightnessThresholdPoints>\n"
698                 +       "</darkeningThresholds>\n"
699                 +   "</displayBrightnessChangeThresholds>\n"
700                 +   "<ambientBrightnessChangeThresholdsIdle>\n"
701                 +       "<brighteningThresholds>\n"
702                 +           "<minimum>20</minimum>\n"
703                 +           "<brightnessThresholdPoints>\n"
704                 +               "<brightnessThresholdPoint>\n"
705                 +                   "<threshold>0</threshold><percentage>21</percentage>\n"
706                 +               "</brightnessThresholdPoint>\n"
707                 +               "<brightnessThresholdPoint>\n"
708                 +                   "<threshold>500</threshold><percentage>22</percentage>\n"
709                 +               "</brightnessThresholdPoint>\n"
710                 +               "<brightnessThresholdPoint>\n"
711                 +                   "<threshold>600</threshold><percentage>23</percentage>\n"
712                 +               "</brightnessThresholdPoint>\n"
713                 +           "</brightnessThresholdPoints>\n"
714                 +       "</brighteningThresholds>\n"
715                 +       "<darkeningThresholds>\n"
716                 +           "<minimum>40</minimum>\n"
717                 +           "<brightnessThresholdPoints>\n"
718                 +               "<brightnessThresholdPoint>\n"
719                 +                   "<threshold>0</threshold><percentage>23</percentage>\n"
720                 +               "</brightnessThresholdPoint>\n"
721                 +               "<brightnessThresholdPoint>\n"
722                 +                   "<threshold>700</threshold><percentage>24</percentage>\n"
723                 +               "</brightnessThresholdPoint>\n"
724                 +               "<brightnessThresholdPoint>\n"
725                 +                   "<threshold>800</threshold><percentage>25</percentage>\n"
726                 +               "</brightnessThresholdPoint>\n"
727                 +           "</brightnessThresholdPoints>\n"
728                 +       "</darkeningThresholds>\n"
729                 +   "</ambientBrightnessChangeThresholdsIdle>\n"
730                 +   "<displayBrightnessChangeThresholdsIdle>\n"
731                 +       "<brighteningThresholds>\n"
732                 +           "<minimum>0.2</minimum>\n"
733                 +           "<brightnessThresholdPoints>\n"
734                 +               "<brightnessThresholdPoint>\n"
735                 +                   "<threshold>0</threshold><percentage>17</percentage>\n"
736                 +               "</brightnessThresholdPoint>\n"
737                 +               "<brightnessThresholdPoint>\n"
738                 +                   "<threshold>0.12</threshold><percentage>18</percentage>\n"
739                 +               "</brightnessThresholdPoint>\n"
740                 +               "<brightnessThresholdPoint>\n"
741                 +                   "<threshold>0.22</threshold><percentage>19</percentage>\n"
742                 +               "</brightnessThresholdPoint>\n"
743                 +           "</brightnessThresholdPoints>\n"
744                 +       "</brighteningThresholds>\n"
745                 +       "<darkeningThresholds>\n"
746                 +           "<minimum>0.4</minimum>\n"
747                 +           "<brightnessThresholdPoints>\n"
748                 +               "<brightnessThresholdPoint>\n"
749                 +                   "<threshold>0</threshold><percentage>19</percentage>\n"
750                 +               "</brightnessThresholdPoint>\n"
751                 +               "<brightnessThresholdPoint>\n"
752                 +                   "<threshold>0.13</threshold><percentage>20</percentage>\n"
753                 +               "</brightnessThresholdPoint>\n"
754                 +               "<brightnessThresholdPoint>\n"
755                 +                   "<threshold>0.23</threshold><percentage>21</percentage>\n"
756                 +               "</brightnessThresholdPoint>\n"
757                 +           "</brightnessThresholdPoints>\n"
758                 +       "</darkeningThresholds>\n"
759                 +   "</displayBrightnessChangeThresholdsIdle>\n"
760                 +   "<screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease> "
761                 +   "<screenBrightnessRampFastIncrease>0.02</screenBrightnessRampFastIncrease>  "
762                 +   "<screenBrightnessRampSlowDecrease>0.03</screenBrightnessRampSlowDecrease>"
763                 +   "<screenBrightnessRampSlowIncrease>0.04</screenBrightnessRampSlowIncrease>"
764                 +   "<screenBrightnessRampIncreaseMaxMillis>"
765                 +       "2000"
766                 +   "</screenBrightnessRampIncreaseMaxMillis>"
767                 +   "<screenBrightnessRampDecreaseMaxMillis>"
768                 +       "3000"
769                 +   "</screenBrightnessRampDecreaseMaxMillis>"
770                 +   "<ambientLightHorizonLong>5000</ambientLightHorizonLong>\n"
771                 +   "<ambientLightHorizonShort>50</ambientLightHorizonShort>\n"
772                 +   "<screenBrightnessRampIncreaseMaxMillis>"
773                 +       "2000"
774                 +   "</screenBrightnessRampIncreaseMaxMillis>\n"
775                 +   "<thermalThrottling>\n"
776                 +       "<brightnessThrottlingMap>\n"
777                 +           "<brightnessThrottlingPoint>\n"
778                 +               "<thermalStatus>light</thermalStatus>\n"
779                 +               "<brightness>0.4</brightness>\n"
780                 +           "</brightnessThrottlingPoint>\n"
781                 +           "<brightnessThrottlingPoint>\n"
782                 +               "<thermalStatus>moderate</thermalStatus>\n"
783                 +               "<brightness>0.3</brightness>\n"
784                 +           "</brightnessThrottlingPoint>\n"
785                 +           "<brightnessThrottlingPoint>\n"
786                 +               "<thermalStatus>severe</thermalStatus>\n"
787                 +               "<brightness>0.2</brightness>\n"
788                 +           "</brightnessThrottlingPoint>\n"
789                 +           "<brightnessThrottlingPoint>\n"
790                 +               "<thermalStatus>critical</thermalStatus>\n"
791                 +               "<brightness>0.1</brightness>\n"
792                 +           "</brightnessThrottlingPoint>\n"
793                 +           "<brightnessThrottlingPoint>\n"
794                 +               "<thermalStatus>emergency</thermalStatus>\n"
795                 +               "<brightness>0.05</brightness>\n"
796                 +           "</brightnessThrottlingPoint>\n"
797                 +           "<brightnessThrottlingPoint>\n"
798                 +               "<thermalStatus>shutdown</thermalStatus>\n"
799                 +               "<brightness>0.025</brightness>\n"
800                 +           "</brightnessThrottlingPoint>\n"
801                 +       "</brightnessThrottlingMap>\n"
802                 +       "<brightnessThrottlingMap id=\"concurrent\">\n"
803                 +           "<brightnessThrottlingPoint>\n"
804                 +               "<thermalStatus>light</thermalStatus>\n"
805                 +               "<brightness>0.2</brightness>\n"
806                 +           "</brightnessThrottlingPoint>\n"
807                 +           "<brightnessThrottlingPoint>\n"
808                 +               "<thermalStatus>moderate</thermalStatus>\n"
809                 +               "<brightness>0.15</brightness>\n"
810                 +           "</brightnessThrottlingPoint>\n"
811                 +           "<brightnessThrottlingPoint>\n"
812                 +               "<thermalStatus>severe</thermalStatus>\n"
813                 +               "<brightness>0.1</brightness>\n"
814                 +           "</brightnessThrottlingPoint>\n"
815                 +           "<brightnessThrottlingPoint>\n"
816                 +               "<thermalStatus>critical</thermalStatus>\n"
817                 +               "<brightness>0.05</brightness>\n"
818                 +           "</brightnessThrottlingPoint>\n"
819                 +           "<brightnessThrottlingPoint>\n"
820                 +               "<thermalStatus>emergency</thermalStatus>\n"
821                 +               "<brightness>0.025</brightness>\n"
822                 +           "</brightnessThrottlingPoint>\n"
823                 +           "<brightnessThrottlingPoint>\n"
824                 +               "<thermalStatus>shutdown</thermalStatus>\n"
825                 +               "<brightness>0.0125</brightness>\n"
826                 +           "</brightnessThrottlingPoint>\n"
827                 +       "</brightnessThrottlingMap>\n"
828                 +  getRefreshThermalThrottlingMaps()
829                 +   "</thermalThrottling>\n"
830                 +   "<refreshRate>\n"
831                 +       "<defaultRefreshRate>45</defaultRefreshRate>\n"
832                 +       "<defaultPeakRefreshRate>85</defaultPeakRefreshRate>\n"
833                 +       "<refreshRateZoneProfiles>"
834                 +           "<refreshRateZoneProfile id=\"test1\">"
835                 +               "<refreshRateRange>\n"
836                 +                   "<minimum>60</minimum>\n"
837                 +                   "<maximum>60</maximum>\n"
838                 +               "</refreshRateRange>\n"
839                 +           "</refreshRateZoneProfile>\n"
840                 +           "<refreshRateZoneProfile id=\"test2\">"
841                 +               "<refreshRateRange>\n"
842                 +                   "<minimum>80</minimum>\n"
843                 +                   "<maximum>90</maximum>\n"
844                 +               "</refreshRateRange>\n"
845                 +           "</refreshRateZoneProfile>\n"
846                 +       "</refreshRateZoneProfiles>"
847                 +       "<defaultRefreshRateInHbmHdr>82</defaultRefreshRateInHbmHdr>\n"
848                 +       "<defaultRefreshRateInHbmSunlight>83</defaultRefreshRateInHbmSunlight>\n"
849                 +       "<lowerBlockingZoneConfigs>\n"
850                 +           "<defaultRefreshRate>75</defaultRefreshRate>\n"
851                 +           "<refreshRateThermalThrottlingId>thermalLow"
852                 +           "</refreshRateThermalThrottlingId>\n"
853                 +           "<blockingZoneThreshold>\n"
854                 +               "<displayBrightnessPoint>\n"
855                 +                   "<lux>50</lux>\n"
856                 +                   "<nits>50</nits>\n"
857                 +               "</displayBrightnessPoint>\n"
858                 +               "<displayBrightnessPoint>\n"
859                 +                   "<lux>60</lux>\n"
860                 +                   "<nits>300</nits>\n"
861                 +               "</displayBrightnessPoint>\n"
862                 +               "<displayBrightnessPoint>\n"
863                 +                   "<lux>-1</lux>\n"
864                 +                   "<nits>300</nits>\n"
865                 +               "</displayBrightnessPoint>\n"
866                 +               "<displayBrightnessPoint>\n"
867                 +                   "<lux>60</lux>\n"
868                 +                   "<nits>-1</nits>\n"
869                 +               "</displayBrightnessPoint>\n"
870                 +           "</blockingZoneThreshold>\n"
871                 +       "</lowerBlockingZoneConfigs>\n"
872                 +       "<higherBlockingZoneConfigs>\n"
873                 +           "<defaultRefreshRate>90</defaultRefreshRate>\n"
874                 +           "<refreshRateThermalThrottlingId>thermalHigh"
875                 +           "</refreshRateThermalThrottlingId>\n"
876                 +           "<blockingZoneThreshold>\n"
877                 +               "<displayBrightnessPoint>\n"
878                 +                   "<lux>70</lux>\n"
879                 +                   "<nits>80</nits>\n"
880                 +               "</displayBrightnessPoint>\n"
881                 +               "<displayBrightnessPoint>\n"
882                 +                   "<lux>80</lux>\n"
883                 +                   "<nits>100</nits>\n"
884                 +               "</displayBrightnessPoint>\n"
885                 +               "<displayBrightnessPoint>\n"
886                 +                   "<lux>-1</lux>\n"
887                 +                   "<nits>100</nits>\n"
888                 +               "</displayBrightnessPoint>\n"
889                 +               "<displayBrightnessPoint>\n"
890                 +                   "<lux>80</lux>\n"
891                 +                   "<nits>-1</nits>\n"
892                 +               "</displayBrightnessPoint>\n"
893                 +           "</blockingZoneThreshold>\n"
894                 +       "</higherBlockingZoneConfigs>\n"
895                 +   "</refreshRate>\n"
896                 +   "<screenOffBrightnessSensorValueToLux>\n"
897                 +       "<item>-1</item>\n"
898                 +       "<item>10</item>\n"
899                 +       "<item>20</item>\n"
900                 +       "<item>30</item>\n"
901                 +       "<item>40</item>\n"
902                 +   "</screenOffBrightnessSensorValueToLux>\n"
903                 +   "<usiVersion>\n"
904                 +       "<majorVersion>2</majorVersion>\n"
905                 +       "<minorVersion>0</minorVersion>\n"
906                 +   "</usiVersion>\n"
907                 + "</displayConfiguration>\n";
908     }
909 
mockDeviceConfigs()910     private void mockDeviceConfigs() {
911         when(mResources.getFloat(com.android.internal.R.dimen
912                 .config_screenBrightnessSettingDefaultFloat)).thenReturn(0.5f);
913         when(mResources.getFloat(com.android.internal.R.dimen
914                 .config_screenBrightnessSettingMaximumFloat)).thenReturn(1.0f);
915     }
916 
setupDisplayDeviceConfigFromDisplayConfigFile()917     private void setupDisplayDeviceConfigFromDisplayConfigFile() throws IOException {
918         setupDisplayDeviceConfigFromDisplayConfigFile(getContent());
919     }
920 
setupDisplayDeviceConfigFromDisplayConfigFile(String content)921     private void setupDisplayDeviceConfigFromDisplayConfigFile(String content) throws IOException {
922         Path tempFile = Files.createTempFile("display_config", ".tmp");
923         Files.write(tempFile, content.getBytes(StandardCharsets.UTF_8));
924         mDisplayDeviceConfig = new DisplayDeviceConfig(mContext);
925         mDisplayDeviceConfig.initFromFile(tempFile.toFile());
926     }
927 
setupDisplayDeviceConfigFromConfigResourceFile()928     private void setupDisplayDeviceConfigFromConfigResourceFile() {
929         TypedArray screenBrightnessNits = createFloatTypedArray(new float[]{2.0f, 250.0f, 650.0f});
930         when(mResources.obtainTypedArray(
931                 com.android.internal.R.array.config_screenBrightnessNits))
932                 .thenReturn(screenBrightnessNits);
933         TypedArray screenBrightnessBacklight = createFloatTypedArray(new
934                 float[]{0.0f, 120.0f, 255.0f});
935         when(mResources.obtainTypedArray(
936                 com.android.internal.R.array.config_screenBrightnessBacklight))
937                 .thenReturn(screenBrightnessBacklight);
938         when(mResources.getIntArray(com.android.internal.R.array
939                 .config_screenBrightnessBacklight)).thenReturn(new int[]{0, 120, 255});
940 
941         when(mResources.getIntArray(com.android.internal.R.array
942                 .config_autoBrightnessLevels)).thenReturn(new int[]{30, 80});
943         when(mResources.getIntArray(com.android.internal.R.array
944                 .config_autoBrightnessDisplayValuesNits)).thenReturn(new int[]{25, 55});
945 
946         TypedArray screenBrightnessLevelNits = createFloatTypedArray(new
947                 float[]{2.0f, 200.0f, 600.0f});
948         when(mResources.obtainTypedArray(
949                 com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
950                 .thenReturn(screenBrightnessLevelNits);
951         int[] screenBrightnessLevelLux = new int[]{0, 110, 500};
952         when(mResources.getIntArray(
953                 com.android.internal.R.array.config_autoBrightnessLevels))
954                 .thenReturn(screenBrightnessLevelLux);
955 
956         // Thresholds
957         // Config.xml requires the levels arrays to be of length N and the thresholds arrays to be
958         // of length N+1
959         when(mResources.getIntArray(com.android.internal.R.array.config_ambientThresholdLevels))
960                 .thenReturn(new int[]{30, 31});
961         when(mResources.getIntArray(com.android.internal.R.array.config_screenThresholdLevels))
962                 .thenReturn(new int[]{42, 43});
963         when(mResources.getIntArray(
964                 com.android.internal.R.array.config_ambientBrighteningThresholds))
965                 .thenReturn(new int[]{270, 280, 290});
966         when(mResources.getIntArray(com.android.internal.R.array.config_ambientDarkeningThresholds))
967                 .thenReturn(new int[]{290, 300, 310});
968         when(mResources.getIntArray(R.array.config_screenBrighteningThresholds))
969                 .thenReturn(new int[]{350, 360, 370});
970         when(mResources.getIntArray(R.array.config_screenDarkeningThresholds))
971                 .thenReturn(new int[]{370, 380, 390});
972 
973         // Configs related to refresh rates and blocking zones
974         when(mResources.getInteger(R.integer.config_defaultPeakRefreshRate))
975                 .thenReturn(DEFAULT_PEAK_REFRESH_RATE);
976         when(mResources.getInteger(R.integer.config_defaultRefreshRate))
977                 .thenReturn(DEFAULT_REFRESH_RATE);
978         when(mResources.getInteger(R.integer.config_fixedRefreshRateInHighZone))
979             .thenReturn(DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE);
980         when(mResources.getInteger(R.integer.config_defaultRefreshRateInZone))
981             .thenReturn(DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE);
982         when(mResources.getIntArray(R.array.config_brightnessThresholdsOfPeakRefreshRate))
983                 .thenReturn(LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
984         when(mResources.getIntArray(R.array.config_ambientThresholdsOfPeakRefreshRate))
985                 .thenReturn(LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
986         when(mResources.getIntArray(
987                 R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate))
988                 .thenReturn(HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
989         when(mResources.getIntArray(
990                 R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
991                 .thenReturn(HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
992         when(mResources.getInteger(
993             R.integer.config_defaultRefreshRateInHbmHdr))
994             .thenReturn(DEFAULT_REFRESH_RATE_IN_HBM_HDR);
995         when(mResources.getInteger(
996             R.integer.config_defaultRefreshRateInHbmSunlight))
997             .thenReturn(DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT);
998 
999         mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
1000     }
1001 
createFloatTypedArray(float[] vals)1002     private TypedArray createFloatTypedArray(float[] vals) {
1003         TypedArray mockArray = mock(TypedArray.class);
1004         when(mockArray.length()).thenAnswer(invocation -> {
1005             return vals.length;
1006         });
1007         when(mockArray.getFloat(anyInt(), anyFloat())).thenAnswer(invocation -> {
1008             final float def = (float) invocation.getArguments()[1];
1009             if (vals == null) {
1010                 return def;
1011             }
1012             int idx = (int) invocation.getArguments()[0];
1013             if (idx >= 0 && idx < vals.length) {
1014                 return vals[idx];
1015             } else {
1016                 return def;
1017             }
1018         });
1019         return mockArray;
1020     }
1021 }
1022