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 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotEquals;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.Mockito.eq;
25 import static org.mockito.Mockito.never;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 
29 import android.hardware.display.BrightnessInfo;
30 import android.os.Handler;
31 import android.os.IThermalEventListener;
32 import android.os.IThermalService;
33 import android.os.Message;
34 import android.os.PowerManager;
35 import android.os.Temperature;
36 import android.os.Temperature.ThrottlingStatus;
37 import android.os.test.TestLooper;
38 
39 import androidx.test.filters.SmallTest;
40 import androidx.test.runner.AndroidJUnit4;
41 
42 import com.android.internal.os.BackgroundThread;
43 import com.android.server.display.BrightnessThrottler.Injector;
44 import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData;
45 import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel;
46 import com.android.server.display.mode.DisplayModeDirectorTest;
47 
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.mockito.ArgumentCaptor;
52 import org.mockito.Captor;
53 import org.mockito.Mock;
54 import org.mockito.MockitoAnnotations;
55 
56 import java.util.ArrayList;
57 import java.util.HashMap;
58 import java.util.List;
59 
60 @SmallTest
61 @RunWith(AndroidJUnit4.class)
62 public class BrightnessThrottlerTest {
63     private static final float EPSILON = 0.000001f;
64 
65     private Handler mHandler;
66     private TestLooper mTestLooper;
67 
68     @Mock IThermalService mThermalServiceMock;
69     @Mock Injector mInjectorMock;
70 
71     DisplayModeDirectorTest.FakeDeviceConfig mDeviceConfigFake;
72 
73     @Captor ArgumentCaptor<IThermalEventListener> mThermalEventListenerCaptor;
74 
75     @Before
setUp()76     public void setUp() {
77         MockitoAnnotations.initMocks(this);
78         when(mInjectorMock.getThermalService()).thenReturn(mThermalServiceMock);
79         mTestLooper = new TestLooper();
80         mHandler = new Handler(mTestLooper.getLooper(), new Handler.Callback() {
81             @Override
82             public boolean handleMessage(Message msg) {
83                 return true;
84             }
85         });
86         mDeviceConfigFake = new DisplayModeDirectorTest.FakeDeviceConfig();
87         when(mInjectorMock.getDeviceConfig()).thenReturn(mDeviceConfigFake);
88 
89     }
90 
91     /////////////////
92     // Test Methods
93     /////////////////
94 
95     @Test
testThermalBrightnessThrottlingData()96     public void testThermalBrightnessThrottlingData() {
97         List<ThrottlingLevel> singleLevel = new ArrayList<>();
98         singleLevel.add(new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL, 0.25f));
99 
100         List<ThrottlingLevel> validLevels = new ArrayList<>();
101         validLevels.add(new ThrottlingLevel(PowerManager.THERMAL_STATUS_MODERATE, 0.62f));
102         validLevels.add(new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL, 0.25f));
103 
104         List<ThrottlingLevel> unsortedThermalLevels = new ArrayList<>();
105         unsortedThermalLevels.add(new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL, 0.62f));
106         unsortedThermalLevels.add(new ThrottlingLevel(PowerManager.THERMAL_STATUS_MODERATE, 0.25f));
107 
108         List<ThrottlingLevel> unsortedBrightnessLevels = new ArrayList<>();
109         unsortedBrightnessLevels.add(
110                 new ThrottlingLevel(PowerManager.THERMAL_STATUS_MODERATE, 0.25f));
111         unsortedBrightnessLevels.add(
112                 new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL, 0.62f));
113 
114         List<ThrottlingLevel> unsortedLevels = new ArrayList<>();
115         unsortedLevels.add(new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL, 0.25f));
116         unsortedLevels.add(new ThrottlingLevel(PowerManager.THERMAL_STATUS_MODERATE, 0.62f));
117 
118         List<ThrottlingLevel> invalidLevel = new ArrayList<>();
119         invalidLevel.add(new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
120                 PowerManager.BRIGHTNESS_MAX + EPSILON));
121 
122         // Test invalid data
123         ThermalBrightnessThrottlingData data;
124         data = ThermalBrightnessThrottlingData.create((List<ThrottlingLevel>) null);
125         assertEquals(data, null);
126         data = ThermalBrightnessThrottlingData.create(new ArrayList<ThrottlingLevel>());
127         assertEquals(data, null);
128         data = ThermalBrightnessThrottlingData.create(unsortedThermalLevels);
129         assertEquals(data, null);
130         data = ThermalBrightnessThrottlingData.create(unsortedBrightnessLevels);
131         assertEquals(data, null);
132         data = ThermalBrightnessThrottlingData.create(unsortedLevels);
133         assertEquals(data, null);
134         data = ThermalBrightnessThrottlingData.create(invalidLevel);
135         assertEquals(data, null);
136 
137         // Test valid data
138         data = ThermalBrightnessThrottlingData.create(singleLevel);
139         assertNotEquals(data, null);
140         assertThrottlingLevelsEquals(singleLevel, data.throttlingLevels);
141 
142         data = ThermalBrightnessThrottlingData.create(validLevels);
143         assertNotEquals(data, null);
144         assertThrottlingLevelsEquals(validLevels, data.throttlingLevels);
145     }
146 
147     @Test
testThermalThrottlingUnsupported()148     public void testThermalThrottlingUnsupported() {
149         final BrightnessThrottler throttler = createThrottlerUnsupported();
150         assertFalse(throttler.deviceSupportsThrottling());
151 
152         // Thermal listener shouldn't be registered if throttling is unsupported
153         verify(mInjectorMock, never()).getThermalService();
154 
155         // Ensure that brightness is uncapped when the device doesn't support throttling
156         assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f);
157     }
158 
159     @Test
testThermalThrottlingSingleLevel()160     public void testThermalThrottlingSingleLevel() throws Exception {
161         final ThrottlingLevel level = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
162                 0.25f);
163 
164         List<ThrottlingLevel> levels = new ArrayList<>();
165         levels.add(level);
166         final ThermalBrightnessThrottlingData data = ThermalBrightnessThrottlingData.create(levels);
167         final BrightnessThrottler throttler = createThrottlerSupported(data);
168         assertTrue(throttler.deviceSupportsThrottling());
169 
170         verify(mThermalServiceMock).registerThermalEventListenerWithType(
171                 mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
172         final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
173 
174         // Set status too low to trigger throttling
175         listener.notifyThrottling(getSkinTemp(level.thermalStatus - 1));
176         mTestLooper.dispatchAll();
177         assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f);
178         assertFalse(throttler.isThrottled());
179         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE, throttler.getBrightnessMaxReason());
180 
181         // Set status just high enough to trigger throttling
182         listener.notifyThrottling(getSkinTemp(level.thermalStatus));
183         mTestLooper.dispatchAll();
184         assertEquals(level.brightness, throttler.getBrightnessCap(), 0f);
185         assertTrue(throttler.isThrottled());
186         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL,
187                 throttler.getBrightnessMaxReason());
188 
189         // Set status more than high enough to trigger throttling
190         listener.notifyThrottling(getSkinTemp(level.thermalStatus + 1));
191         mTestLooper.dispatchAll();
192         assertEquals(level.brightness, throttler.getBrightnessCap(), 0f);
193         assertTrue(throttler.isThrottled());
194         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL,
195                 throttler.getBrightnessMaxReason());
196 
197         // Return to the lower throttling level
198         listener.notifyThrottling(getSkinTemp(level.thermalStatus));
199         mTestLooper.dispatchAll();
200         assertEquals(level.brightness, throttler.getBrightnessCap(), 0f);
201         assertTrue(throttler.isThrottled());
202         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL,
203                 throttler.getBrightnessMaxReason());
204 
205         // Cool down
206         listener.notifyThrottling(getSkinTemp(level.thermalStatus - 1));
207         mTestLooper.dispatchAll();
208         assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f);
209         assertFalse(throttler.isThrottled());
210         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE,
211                 throttler.getBrightnessMaxReason());
212     }
213 
214     @Test
testThermalThrottlingMultiLevel()215     public void testThermalThrottlingMultiLevel() throws Exception {
216         final ThrottlingLevel levelLo = new ThrottlingLevel(PowerManager.THERMAL_STATUS_MODERATE,
217                 0.62f);
218         final ThrottlingLevel levelHi = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
219                 0.25f);
220 
221         List<ThrottlingLevel> levels = new ArrayList<>();
222         levels.add(levelLo);
223         levels.add(levelHi);
224         final ThermalBrightnessThrottlingData data = ThermalBrightnessThrottlingData.create(levels);
225         final BrightnessThrottler throttler = createThrottlerSupported(data);
226         assertTrue(throttler.deviceSupportsThrottling());
227 
228         verify(mThermalServiceMock).registerThermalEventListenerWithType(
229                 mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
230         final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
231 
232         // Set status too low to trigger throttling
233         listener.notifyThrottling(getSkinTemp(levelLo.thermalStatus - 1));
234         mTestLooper.dispatchAll();
235         assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f);
236         assertFalse(throttler.isThrottled());
237         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE, throttler.getBrightnessMaxReason());
238 
239         // Set status just high enough to trigger throttling
240         listener.notifyThrottling(getSkinTemp(levelLo.thermalStatus));
241         mTestLooper.dispatchAll();
242         assertEquals(levelLo.brightness, throttler.getBrightnessCap(), 0f);
243         assertTrue(throttler.isThrottled());
244         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL,
245                 throttler.getBrightnessMaxReason());
246 
247         // Set status to an intermediate throttling level
248         listener.notifyThrottling(getSkinTemp(levelLo.thermalStatus + 1));
249         mTestLooper.dispatchAll();
250         assertEquals(levelLo.brightness, throttler.getBrightnessCap(), 0f);
251         assertTrue(throttler.isThrottled());
252         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL,
253                 throttler.getBrightnessMaxReason());
254 
255         // Set status to the highest configured throttling level
256         listener.notifyThrottling(getSkinTemp(levelHi.thermalStatus));
257         mTestLooper.dispatchAll();
258         assertEquals(levelHi.brightness, throttler.getBrightnessCap(), 0f);
259         assertTrue(throttler.isThrottled());
260         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL,
261                 throttler.getBrightnessMaxReason());
262 
263         // Set status to exceed the highest configured throttling level
264         listener.notifyThrottling(getSkinTemp(levelHi.thermalStatus + 1));
265         mTestLooper.dispatchAll();
266         assertEquals(levelHi.brightness, throttler.getBrightnessCap(), 0f);
267         assertTrue(throttler.isThrottled());
268         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL,
269                 throttler.getBrightnessMaxReason());
270 
271         // Return to an intermediate throttling level
272         listener.notifyThrottling(getSkinTemp(levelLo.thermalStatus + 1));
273         mTestLooper.dispatchAll();
274         assertEquals(levelLo.brightness, throttler.getBrightnessCap(), 0f);
275         assertTrue(throttler.isThrottled());
276         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL,
277                 throttler.getBrightnessMaxReason());
278 
279         // Return to the lowest configured throttling level
280         listener.notifyThrottling(getSkinTemp(levelLo.thermalStatus));
281         mTestLooper.dispatchAll();
282         assertEquals(levelLo.brightness, throttler.getBrightnessCap(), 0f);
283         assertTrue(throttler.isThrottled());
284         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL,
285                 throttler.getBrightnessMaxReason());
286 
287         // Cool down
288         listener.notifyThrottling(getSkinTemp(levelLo.thermalStatus - 1));
289         mTestLooper.dispatchAll();
290         assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f);
291         assertFalse(throttler.isThrottled());
292         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE, throttler.getBrightnessMaxReason());
293     }
294 
testUpdateThermalThrottlingData()295     @Test public void testUpdateThermalThrottlingData() throws Exception {
296         // Initialise brightness throttling levels
297         // Ensure that they are overridden by setting the data through device config.
298         final ThrottlingLevel level = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
299                 0.25f);
300         List<ThrottlingLevel> levels = new ArrayList<>();
301         levels.add(level);
302         final ThermalBrightnessThrottlingData data = ThermalBrightnessThrottlingData.create(levels);
303         mDeviceConfigFake.setThermalBrightnessThrottlingData("123,1,critical,0.4");
304         final BrightnessThrottler throttler = createThrottlerSupported(data);
305 
306         verify(mThermalServiceMock).registerThermalEventListenerWithType(
307                 mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
308         final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
309         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.4f);
310 
311         // Set new (valid) data from device config
312         mDeviceConfigFake.setThermalBrightnessThrottlingData("123,1,critical,0.8");
313         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.8f);
314 
315         mDeviceConfigFake.setThermalBrightnessThrottlingData(
316                 "123,1,critical,0.75;123,1,critical,0.99,id_2");
317         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.75f);
318         mDeviceConfigFake.setThermalBrightnessThrottlingData(
319                 "123,1,critical,0.8,default;123,1,critical,0.99,id_2");
320         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.8f);
321     }
322 
testInvalidThrottlingStrings()323     @Test public void testInvalidThrottlingStrings() throws Exception {
324         // Initialise brightness throttling levels
325         // Ensure that they are not overridden by invalid data through device config.
326         final ThrottlingLevel level = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
327                 0.25f);
328         List<ThrottlingLevel> levels = new ArrayList<>();
329         levels.add(level);
330         final ThermalBrightnessThrottlingData data = ThermalBrightnessThrottlingData.create(levels);
331         final BrightnessThrottler throttler = createThrottlerSupported(data);
332         verify(mThermalServiceMock).registerThermalEventListenerWithType(
333                 mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
334         final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
335 
336         // None of these are valid so shouldn't override the original data
337 
338         // Not the current id
339         mDeviceConfigFake.setThermalBrightnessThrottlingData("321,1,critical,0.4");
340         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
341         // Incorrect number
342         mDeviceConfigFake.setThermalBrightnessThrottlingData("123,0,critical,0.4");
343         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
344         // Incorrect number
345         mDeviceConfigFake.setThermalBrightnessThrottlingData("123,2,critical,0.4");
346         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
347         // Invalid level
348         mDeviceConfigFake.setThermalBrightnessThrottlingData("123,1,invalid,0.4");
349         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
350         // Invalid brightness
351         mDeviceConfigFake.setThermalBrightnessThrottlingData("123,1,critical,none");
352         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
353         // Invalid brightness
354         mDeviceConfigFake.setThermalBrightnessThrottlingData("123,1,critical,-3");
355         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
356         // Invalid format
357         mDeviceConfigFake.setThermalBrightnessThrottlingData("invalid string");
358         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
359         // Invalid format
360         mDeviceConfigFake.setThermalBrightnessThrottlingData("");
361         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
362         // Invalid string format
363         mDeviceConfigFake.setThermalBrightnessThrottlingData(
364                 "123,default,1,critical,0.75,1,critical,0.99");
365         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
366         // Invalid level string and number string
367         mDeviceConfigFake.setThermalBrightnessThrottlingData(
368                 "123,1,1,critical,0.75,id_2,1,critical,0.99");
369         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
370         // Invalid format - (two default ids for same display)
371         mDeviceConfigFake.setThermalBrightnessThrottlingData(
372                 "123,1,critical,0.75,default;123,1,critical,0.99");
373         testThermalThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
374     }
375 
testThermalThrottling(BrightnessThrottler throttler, IThermalEventListener listener, float tooLowCap, float tooHighCap)376     private void testThermalThrottling(BrightnessThrottler throttler,
377             IThermalEventListener listener, float tooLowCap, float tooHighCap) throws Exception {
378         final ThrottlingLevel level = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
379                 tooHighCap);
380 
381         // Set status too low to trigger throttling
382         listener.notifyThrottling(getSkinTemp(level.thermalStatus - 1));
383         mTestLooper.dispatchAll();
384         assertEquals(tooLowCap, throttler.getBrightnessCap(), 0f);
385         assertFalse(throttler.isThrottled());
386 
387         // Set status high enough to trigger throttling
388         listener.notifyThrottling(getSkinTemp(level.thermalStatus));
389         mTestLooper.dispatchAll();
390         assertEquals(tooHighCap, throttler.getBrightnessCap(), 0f);
391         assertTrue(throttler.isThrottled());
392     }
393 
testMultipleConfigPoints()394     @Test public void testMultipleConfigPoints() throws Exception {
395         // Initialise brightness throttling levels
396         final ThrottlingLevel level = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
397                 0.25f);
398         List<ThrottlingLevel> levels = new ArrayList<>();
399         levels.add(level);
400         final ThermalBrightnessThrottlingData data = ThermalBrightnessThrottlingData.create(levels);
401 
402         // These are identical to the string set below
403         final ThrottlingLevel levelSevere = new ThrottlingLevel(PowerManager.THERMAL_STATUS_SEVERE,
404                 0.9f);
405         final ThrottlingLevel levelCritical = new ThrottlingLevel(
406                 PowerManager.THERMAL_STATUS_CRITICAL, 0.5f);
407         final ThrottlingLevel levelEmergency = new ThrottlingLevel(
408                 PowerManager.THERMAL_STATUS_EMERGENCY, 0.1f);
409 
410         mDeviceConfigFake.setThermalBrightnessThrottlingData(
411                 "123,3,severe,0.9,critical,0.5,emergency,0.1");
412         final BrightnessThrottler throttler = createThrottlerSupported(data);
413 
414         verify(mThermalServiceMock).registerThermalEventListenerWithType(
415                 mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
416         final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
417 
418         // Ensure that the multiple levels set via the string through the device config correctly
419         // override the original display device config ones.
420 
421         // levelSevere
422         // Set status too low to trigger throttling
423         listener.notifyThrottling(getSkinTemp(levelSevere.thermalStatus - 1));
424         mTestLooper.dispatchAll();
425         assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f);
426         assertFalse(throttler.isThrottled());
427 
428         // Set status high enough to trigger throttling
429         listener.notifyThrottling(getSkinTemp(levelSevere.thermalStatus));
430         mTestLooper.dispatchAll();
431         assertEquals(0.9f, throttler.getBrightnessCap(), 0f);
432         assertTrue(throttler.isThrottled());
433 
434         // levelCritical
435         // Set status too low to trigger throttling
436         listener.notifyThrottling(getSkinTemp(levelCritical.thermalStatus - 1));
437         mTestLooper.dispatchAll();
438         assertEquals(0.9f, throttler.getBrightnessCap(), 0f);
439         assertTrue(throttler.isThrottled());
440 
441         // Set status high enough to trigger throttling
442         listener.notifyThrottling(getSkinTemp(levelCritical.thermalStatus));
443         mTestLooper.dispatchAll();
444         assertEquals(0.5f, throttler.getBrightnessCap(), 0f);
445         assertTrue(throttler.isThrottled());
446 
447         //levelEmergency
448         // Set status too low to trigger throttling
449         listener.notifyThrottling(getSkinTemp(levelEmergency.thermalStatus - 1));
450         mTestLooper.dispatchAll();
451         assertEquals(0.5f, throttler.getBrightnessCap(), 0f);
452         assertTrue(throttler.isThrottled());
453 
454         // Set status high enough to trigger throttling
455         listener.notifyThrottling(getSkinTemp(levelEmergency.thermalStatus));
456         mTestLooper.dispatchAll();
457         assertEquals(0.1f, throttler.getBrightnessCap(), 0f);
458         assertTrue(throttler.isThrottled());
459     }
460 
assertThrottlingLevelsEquals( List<ThrottlingLevel> expected, List<ThrottlingLevel> actual)461     private void assertThrottlingLevelsEquals(
462             List<ThrottlingLevel> expected,
463             List<ThrottlingLevel> actual) {
464         assertEquals(expected.size(), actual.size());
465 
466         for (int i = 0; i < expected.size(); i++) {
467             ThrottlingLevel expectedLevel = expected.get(i);
468             ThrottlingLevel actualLevel = actual.get(i);
469 
470             assertEquals(expectedLevel.thermalStatus, actualLevel.thermalStatus);
471             assertEquals(expectedLevel.brightness, actualLevel.brightness, 0.0f);
472         }
473     }
474 
createThrottlerUnsupported()475     private BrightnessThrottler createThrottlerUnsupported() {
476         return new BrightnessThrottler(mInjectorMock, mHandler, mHandler,
477                 /* throttlingChangeCallback= */ () -> {}, /* uniqueDisplayId= */ null,
478                 /* thermalThrottlingDataId= */ null,
479                 /* thermalThrottlingDataMap= */ new HashMap<>(1));
480     }
481 
createThrottlerSupported(ThermalBrightnessThrottlingData data)482     private BrightnessThrottler createThrottlerSupported(ThermalBrightnessThrottlingData data) {
483         assertNotNull(data);
484         HashMap<String, ThermalBrightnessThrottlingData> throttlingDataMap = new HashMap<>(1);
485         throttlingDataMap.put("default", data);
486         return new BrightnessThrottler(mInjectorMock, mHandler, BackgroundThread.getHandler(),
487                 () -> {}, "123", "default", throttlingDataMap);
488     }
489 
getSkinTemp(@hrottlingStatus int status)490     private Temperature getSkinTemp(@ThrottlingStatus int status) {
491         return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status);
492     }
493 }
494