• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.color;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.common.truth.Truth.assertWithMessage;
21 
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.annotation.NonNull;
31 import android.app.ActivityManager;
32 import android.app.AlarmManager;
33 import android.content.Context;
34 import android.content.ContextWrapper;
35 import android.content.res.Resources;
36 import android.hardware.display.ColorDisplayManager;
37 import android.hardware.display.DisplayManagerInternal;
38 import android.hardware.display.Time;
39 import android.os.Handler;
40 import android.os.UserHandle;
41 import android.provider.Settings;
42 import android.provider.Settings.Secure;
43 import android.provider.Settings.System;
44 import android.test.mock.MockContentResolver;
45 import android.view.Display;
46 
47 import androidx.test.InstrumentationRegistry;
48 import androidx.test.runner.AndroidJUnit4;
49 
50 import com.android.internal.R;
51 import com.android.internal.util.test.FakeSettingsProvider;
52 import com.android.server.LocalServices;
53 import com.android.server.SystemService;
54 import com.android.server.twilight.TwilightListener;
55 import com.android.server.twilight.TwilightManager;
56 import com.android.server.twilight.TwilightState;
57 
58 import org.junit.After;
59 import org.junit.Before;
60 import org.junit.Test;
61 import org.junit.runner.RunWith;
62 import org.mockito.Mockito;
63 
64 import java.time.LocalDateTime;
65 import java.time.LocalTime;
66 import java.time.ZoneId;
67 import java.util.Calendar;
68 import java.util.HashMap;
69 import java.util.Map;
70 import java.util.concurrent.CountDownLatch;
71 import java.util.concurrent.TimeUnit;
72 
73 @RunWith(AndroidJUnit4.class)
74 public class ColorDisplayServiceTest {
75 
76     private Context mContext;
77     private int mUserId;
78 
79     private MockTwilightManager mTwilightManager;
80     private DisplayTransformManager mDisplayTransformManager;
81     private DisplayManagerInternal mDisplayManagerInternal;
82 
83     private ColorDisplayService mCds;
84     private ColorDisplayService.BinderService mBinderService;
85 
86     private Resources mResourcesSpy;
87 
88     private static final int[] MINIMAL_COLOR_MODES = new int[] {
89         ColorDisplayManager.COLOR_MODE_NATURAL,
90         ColorDisplayManager.COLOR_MODE_BOOSTED,
91     };
92 
93     @Before
setUp()94     public void setUp() {
95         mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
96         doReturn(mContext).when(mContext).getApplicationContext();
97 
98         final Resources res = Mockito.spy(mContext.getResources());
99         doReturn(MINIMAL_COLOR_MODES).when(res).getIntArray(R.array.config_availableColorModes);
100         doReturn(true).when(res).getBoolean(R.bool.config_nightDisplayAvailable);
101         doReturn(true).when(res).getBoolean(R.bool.config_displayWhiteBalanceAvailable);
102         when(mContext.getResources()).thenReturn(res);
103         mResourcesSpy = res;
104 
105         mUserId = ActivityManager.getCurrentUser();
106 
107         final MockContentResolver cr = new MockContentResolver(mContext);
108         cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
109         doReturn(cr).when(mContext).getContentResolver();
110 
111         final AlarmManager am = Mockito.mock(AlarmManager.class);
112         doReturn(am).when(mContext).getSystemService(Context.ALARM_SERVICE);
113 
114         mTwilightManager = new MockTwilightManager();
115         LocalServices.addService(TwilightManager.class, mTwilightManager);
116 
117         mDisplayTransformManager = Mockito.mock(DisplayTransformManager.class);
118         doReturn(true).when(mDisplayTransformManager).needsLinearColorMatrix();
119         LocalServices.addService(DisplayTransformManager.class, mDisplayTransformManager);
120 
121         mDisplayManagerInternal = Mockito.mock(DisplayManagerInternal.class);
122         LocalServices.removeServiceForTest(DisplayManagerInternal.class);
123         LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternal);
124 
125         mCds = new ColorDisplayService(mContext);
126         mBinderService = mCds.new BinderService();
127         LocalServices.addService(ColorDisplayService.ColorDisplayServiceInternal.class,
128                 mCds.new ColorDisplayServiceInternal());
129     }
130 
131     @After
tearDown()132     public void tearDown() {
133         /*
134          * Wait for internal {@link Handler} to finish processing pending messages, so that test
135          * code can safelyremove {@link DisplayTransformManager} mock from {@link LocalServices}.
136          */
137         mCds.mHandler.runWithScissors(() -> { /* nop */ }, /* timeout */ 1000);
138         mCds = null;
139 
140         LocalServices.removeServiceForTest(TwilightManager.class);
141         mTwilightManager = null;
142 
143         LocalServices.removeServiceForTest(DisplayTransformManager.class);
144 
145         mUserId = UserHandle.USER_NULL;
146         mContext = null;
147 
148         FakeSettingsProvider.clearSettingsProvider();
149 
150         LocalServices.removeServiceForTest(ColorDisplayService.ColorDisplayServiceInternal.class);
151         LocalServices.removeServiceForTest(DisplayManagerInternal.class);
152     }
153 
154     @Test
customSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff()155     public void customSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff() {
156         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
157         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
158 
159         startService();
160         assertActivated(false /* activated */);
161     }
162 
163     @Test
customSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff()164     public void customSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff() {
165         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
166         setNightDisplayActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
167 
168         startService();
169         assertActivated(false /* activated */);
170     }
171 
172     @Test
customSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff()173     public void customSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff() {
174         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
175         setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
176 
177         startService();
178         assertActivated(false /* activated */);
179     }
180 
181     @Test
customSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff()182     public void customSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff() {
183         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
184         setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
185 
186         startService();
187         assertActivated(false /* activated */);
188     }
189 
190     @Test
customSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn()191     public void customSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn() {
192         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
193         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
194 
195         startService();
196         assertActivated(true /* activated */);
197     }
198 
199     @Test
customSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff()200     public void customSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff() {
201         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
202         setNightDisplayActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
203 
204         startService();
205         assertActivated(false /* activated */);
206     }
207 
208     @Test
customSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff()209     public void customSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff() {
210         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
211         setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
212 
213         startService();
214         assertActivated(false /* activated */);
215     }
216 
217     @Test
customSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff()218     public void customSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff() {
219         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
220         setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
221 
222         startService();
223         assertActivated(false /* activated */);
224     }
225 
226     @Test
customSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff()227     public void customSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff() {
228         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
229         setNightDisplayActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
230 
231         startService();
232         assertActivated(false /* activated */);
233     }
234 
235     @Test
customSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff()236     public void customSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff() {
237         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
238         setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
239 
240         startService();
241         assertActivated(false /* activated */);
242     }
243 
244     @Test
customSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff()245     public void customSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff() {
246         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
247         setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
248 
249         startService();
250         assertActivated(false /* activated */);
251     }
252 
253     @Test
customSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff()254     public void customSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff() {
255         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
256         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
257 
258         startService();
259         assertActivated(false /* activated */);
260     }
261 
262     @Test
customSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff()263     public void customSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff() {
264         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
265         setNightDisplayActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
266 
267         startService();
268         assertActivated(false /* activated */);
269     }
270 
271     @Test
customSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff()272     public void customSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff() {
273         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
274         setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
275 
276         startService();
277         assertActivated(false /* activated */);
278     }
279 
280     @Test
customSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff()281     public void customSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff() {
282         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
283         setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
284 
285         startService();
286         assertActivated(false /* activated */);
287     }
288 
289     @Test
customSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn()290     public void customSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn() {
291         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
292         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
293 
294         startService();
295         assertActivated(true /* activated */);
296     }
297 
298     @Test
customSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn()299     public void customSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn() {
300         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
301         setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
302 
303         startService();
304         assertActivated(true /* activated */);
305     }
306 
307     @Test
customSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn()308     public void customSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn() {
309         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
310         setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
311 
312         startService();
313         assertActivated(true /* activated */);
314     }
315 
316     @Test
customSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn()317     public void customSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn() {
318         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
319         setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
320 
321         startService();
322         assertActivated(true /* activated */);
323     }
324 
325     @Test
customSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff()326     public void customSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff() {
327         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
328         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
329 
330         startService();
331         assertActivated(false /* activated */);
332     }
333 
334     @Test
customSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn()335     public void customSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn() {
336         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
337         setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
338 
339         startService();
340         assertActivated(true /* activated */);
341     }
342 
343     @Test
customSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn()344     public void customSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn() {
345         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
346         setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
347 
348         startService();
349         assertActivated(true /* activated */);
350     }
351 
352     @Test
customSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn()353     public void customSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn() {
354         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
355         setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
356 
357         startService();
358         assertActivated(true /* activated */);
359     }
360 
361     @Test
customSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn()362     public void customSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn() {
363         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
364         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
365 
366         startService();
367         assertActivated(true /* activated */);
368     }
369 
370     @Test
twilightSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff()371     public void twilightSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff() {
372         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
373         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
374 
375         startService();
376         assertActivated(false /* activated */);
377     }
378 
379     @Test
twilightSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff()380     public void twilightSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff() {
381         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
382         setNightDisplayActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
383 
384         startService();
385         assertActivated(false /* activated */);
386     }
387 
388     @Test
twilightSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff()389     public void twilightSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff() {
390         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
391         setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
392 
393         startService();
394         assertActivated(false /* activated */);
395     }
396 
397     @Test
twilightSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff()398     public void twilightSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff() {
399         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
400         setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
401 
402         startService();
403         assertActivated(false /* activated */);
404     }
405 
406     @Test
twilightSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn()407     public void twilightSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn() {
408         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
409         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
410 
411         startService();
412         assertActivated(true /* activated */);
413     }
414 
415     @Test
twilightSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff()416     public void twilightSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff() {
417         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
418         setNightDisplayActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
419 
420         startService();
421         assertActivated(false /* activated */);
422     }
423 
424     @Test
twilightSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff()425     public void twilightSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff() {
426         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
427         setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
428 
429         startService();
430         assertActivated(false /* activated */);
431     }
432 
433     @Test
twilightSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff()434     public void twilightSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff() {
435         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
436         setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
437 
438         startService();
439         assertActivated(false /* activated */);
440     }
441 
442     @Test
twilightSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff()443     public void twilightSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff() {
444         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
445         setNightDisplayActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
446 
447         startService();
448         assertActivated(false /* activated */);
449     }
450 
451     @Test
twilightSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff()452     public void twilightSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff() {
453         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
454         setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
455 
456         startService();
457         assertActivated(false /* activated */);
458     }
459 
460     @Test
twilightSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff()461     public void twilightSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff() {
462         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
463         setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
464 
465         startService();
466         assertActivated(false /* activated */);
467     }
468 
469     @Test
twilightSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff()470     public void twilightSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff() {
471         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
472         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
473 
474         startService();
475         assertActivated(false /* activated */);
476     }
477 
478     @Test
twilightSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff()479     public void twilightSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff() {
480         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
481         setNightDisplayActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
482 
483         startService();
484         assertActivated(false /* activated */);
485     }
486 
487     @Test
twilightSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff()488     public void twilightSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff() {
489         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
490         setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
491 
492         startService();
493         assertActivated(false /* activated */);
494     }
495 
496     @Test
twilightSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff()497     public void twilightSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff() {
498         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
499         setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
500 
501         startService();
502         assertActivated(false /* activated */);
503     }
504 
505     @Test
twilightSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn()506     public void twilightSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn() {
507         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
508         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
509 
510         startService();
511         assertActivated(true /* activated */);
512     }
513 
514     @Test
twilightSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn()515     public void twilightSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn() {
516         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
517         setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
518 
519         startService();
520         assertActivated(true /* activated */);
521     }
522 
523     @Test
twilightSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn()524     public void twilightSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn() {
525         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
526         setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
527 
528         startService();
529         assertActivated(true /* activated */);
530     }
531 
532     @Test
twilightSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn()533     public void twilightSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn() {
534         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
535         setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
536 
537         startService();
538         assertActivated(true /* activated */);
539     }
540 
541     @Test
twilightSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff()542     public void twilightSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff() {
543         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
544         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
545 
546         startService();
547         assertActivated(false /* activated */);
548     }
549 
550     @Test
twilightSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn()551     public void twilightSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn() {
552         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
553         setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
554 
555         startService();
556         assertActivated(true /* activated */);
557     }
558 
559     @Test
twilightSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn()560     public void twilightSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn() {
561         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
562         setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
563 
564         startService();
565         assertActivated(true /* activated */);
566     }
567 
568     @Test
twilightSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn()569     public void twilightSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn() {
570         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
571         setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
572 
573         startService();
574         assertActivated(true /* activated */);
575     }
576 
577     @Test
twilightSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn()578     public void twilightSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn() {
579         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
580         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
581 
582         startService();
583         assertActivated(true /* activated */);
584     }
585 
586     @Test
twilightSchedule_whenRebootedAfterNight_ifOffAfterNight_turnsOff()587     public void twilightSchedule_whenRebootedAfterNight_ifOffAfterNight_turnsOff() {
588         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
589         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
590 
591         final TwilightState state = mTwilightManager.getLastTwilightState();
592         mTwilightManager.setTwilightState(null);
593 
594         startService();
595         assertActivated(false /* activated */);
596 
597         mTwilightManager.setTwilightState(state);
598         assertActivated(false /* activated */);
599     }
600 
601     @Test
twilightSchedule_whenRebootedAfterNight_ifOffBeforeNight_turnsOff()602     public void twilightSchedule_whenRebootedAfterNight_ifOffBeforeNight_turnsOff() {
603         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
604         setNightDisplayActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
605 
606         final TwilightState state = mTwilightManager.getLastTwilightState();
607         mTwilightManager.setTwilightState(null);
608 
609         startService();
610         assertActivated(false /* activated */);
611 
612         mTwilightManager.setTwilightState(state);
613         assertActivated(false /* activated */);
614     }
615 
616     @Test
twilightSchedule_whenRebootedAfterNight_ifOffDuringNight_turnsOff()617     public void twilightSchedule_whenRebootedAfterNight_ifOffDuringNight_turnsOff() {
618         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
619         setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
620 
621         final TwilightState state = mTwilightManager.getLastTwilightState();
622         mTwilightManager.setTwilightState(null);
623 
624         startService();
625         assertActivated(false /* activated */);
626 
627         mTwilightManager.setTwilightState(state);
628         assertActivated(false /* activated */);
629     }
630 
631     @Test
twilightSchedule_whenRebootedAfterNight_ifOffInFuture_turnsOff()632     public void twilightSchedule_whenRebootedAfterNight_ifOffInFuture_turnsOff() {
633         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
634         setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
635 
636         final TwilightState state = mTwilightManager.getLastTwilightState();
637         mTwilightManager.setTwilightState(null);
638 
639         startService();
640         assertActivated(false /* activated */);
641 
642         mTwilightManager.setTwilightState(state);
643         assertActivated(false /* activated */);
644     }
645 
646     @Test
twilightSchedule_whenRebootedAfterNight_ifOnAfterNight_turnsOn()647     public void twilightSchedule_whenRebootedAfterNight_ifOnAfterNight_turnsOn() {
648         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
649         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
650 
651         final TwilightState state = mTwilightManager.getLastTwilightState();
652         mTwilightManager.setTwilightState(null);
653 
654         startService();
655         assertActivated(true /* activated */);
656 
657         mTwilightManager.setTwilightState(state);
658         assertActivated(true /* activated */);
659     }
660 
661     @Test
twilightSchedule_whenRebootedAfterNight_ifOnBeforeNight_turnsOff()662     public void twilightSchedule_whenRebootedAfterNight_ifOnBeforeNight_turnsOff() {
663         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
664         setNightDisplayActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
665 
666         final TwilightState state = mTwilightManager.getLastTwilightState();
667         mTwilightManager.setTwilightState(null);
668 
669         startService();
670         assertActivated(true /* activated */);
671 
672         mTwilightManager.setTwilightState(state);
673         assertActivated(false /* activated */);
674     }
675 
676     @Test
twilightSchedule_whenRebootedAfterNight_ifOnDuringNight_turnsOff()677     public void twilightSchedule_whenRebootedAfterNight_ifOnDuringNight_turnsOff() {
678         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
679         setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
680 
681         final TwilightState state = mTwilightManager.getLastTwilightState();
682         mTwilightManager.setTwilightState(null);
683 
684         startService();
685         assertActivated(true /* activated */);
686 
687         mTwilightManager.setTwilightState(state);
688         assertActivated(false /* activated */);
689     }
690 
691     @Test
twilightSchedule_whenRebootedAfterNight_ifOnInFuture_turnsOff()692     public void twilightSchedule_whenRebootedAfterNight_ifOnInFuture_turnsOff() {
693         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
694         setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
695 
696         final TwilightState state = mTwilightManager.getLastTwilightState();
697         mTwilightManager.setTwilightState(null);
698 
699         startService();
700         assertActivated(true /* activated */);
701 
702         mTwilightManager.setTwilightState(state);
703         assertActivated(false /* activated */);
704     }
705 
706     @Test
twilightSchedule_whenRebootedBeforeNight_ifOffAfterNight_turnsOff()707     public void twilightSchedule_whenRebootedBeforeNight_ifOffAfterNight_turnsOff() {
708         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
709         setNightDisplayActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
710 
711         final TwilightState state = mTwilightManager.getLastTwilightState();
712         mTwilightManager.setTwilightState(null);
713 
714         startService();
715         assertActivated(false /* activated */);
716 
717         mTwilightManager.setTwilightState(state);
718         assertActivated(false /* activated */);
719     }
720 
721     @Test
twilightSchedule_whenRebootedBeforeNight_ifOffBeforeNight_turnsOff()722     public void twilightSchedule_whenRebootedBeforeNight_ifOffBeforeNight_turnsOff() {
723         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
724         setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
725 
726         final TwilightState state = mTwilightManager.getLastTwilightState();
727         mTwilightManager.setTwilightState(null);
728 
729         startService();
730         assertActivated(false /* activated */);
731 
732         mTwilightManager.setTwilightState(state);
733         assertActivated(false /* activated */);
734     }
735 
736     @Test
twilightSchedule_whenRebootedBeforeNight_ifOffDuringNight_turnsOff()737     public void twilightSchedule_whenRebootedBeforeNight_ifOffDuringNight_turnsOff() {
738         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
739         setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
740 
741         final TwilightState state = mTwilightManager.getLastTwilightState();
742         mTwilightManager.setTwilightState(null);
743 
744         startService();
745         assertActivated(false /* activated */);
746 
747         mTwilightManager.setTwilightState(state);
748         assertActivated(false /* activated */);
749     }
750 
751     @Test
twilightSchedule_whenRebootedBeforeNight_ifOffInPast_turnsOff()752     public void twilightSchedule_whenRebootedBeforeNight_ifOffInPast_turnsOff() {
753         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
754         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
755 
756         final TwilightState state = mTwilightManager.getLastTwilightState();
757         mTwilightManager.setTwilightState(null);
758 
759         startService();
760         assertActivated(false /* activated */);
761 
762         mTwilightManager.setTwilightState(state);
763         assertActivated(false /* activated */);
764     }
765 
766     @Test
twilightSchedule_whenRebootedBeforeNight_ifOnAfterNight_turnsOff()767     public void twilightSchedule_whenRebootedBeforeNight_ifOnAfterNight_turnsOff() {
768         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
769         setNightDisplayActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
770 
771         final TwilightState state = mTwilightManager.getLastTwilightState();
772         mTwilightManager.setTwilightState(null);
773 
774         startService();
775         assertActivated(true /* activated */);
776 
777         mTwilightManager.setTwilightState(state);
778         assertActivated(false /* activated */);
779     }
780 
781     @Test
twilightSchedule_whenRebootedBeforeNight_ifOnBeforeNight_turnsOff()782     public void twilightSchedule_whenRebootedBeforeNight_ifOnBeforeNight_turnsOff() {
783         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
784         setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
785 
786         final TwilightState state = mTwilightManager.getLastTwilightState();
787         mTwilightManager.setTwilightState(null);
788 
789         startService();
790         assertActivated(true /* activated */);
791 
792         mTwilightManager.setTwilightState(state);
793         assertActivated(false /* activated */);
794     }
795 
796     @Test
twilightSchedule_whenRebootedBeforeNight_ifOnDuringNight_turnsOff()797     public void twilightSchedule_whenRebootedBeforeNight_ifOnDuringNight_turnsOff() {
798         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
799         setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
800 
801         final TwilightState state = mTwilightManager.getLastTwilightState();
802         mTwilightManager.setTwilightState(null);
803 
804         startService();
805         assertActivated(true /* activated */);
806 
807         mTwilightManager.setTwilightState(state);
808         assertActivated(false /* activated */);
809     }
810 
811     @Test
twilightSchedule_whenRebootedBeforeNight_ifOnInPast_turnsOn()812     public void twilightSchedule_whenRebootedBeforeNight_ifOnInPast_turnsOn() {
813         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
814         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
815 
816         final TwilightState state = mTwilightManager.getLastTwilightState();
817         mTwilightManager.setTwilightState(null);
818 
819         startService();
820         assertActivated(true /* activated */);
821 
822         mTwilightManager.setTwilightState(state);
823         assertActivated(true /* activated */);
824     }
825 
826     @Test
twilightSchedule_whenRebootedDuringNight_ifOffAfterNight_turnsOn()827     public void twilightSchedule_whenRebootedDuringNight_ifOffAfterNight_turnsOn() {
828         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
829         setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
830 
831         final TwilightState state = mTwilightManager.getLastTwilightState();
832         mTwilightManager.setTwilightState(null);
833 
834         startService();
835         assertActivated(false /* activated */);
836 
837         mTwilightManager.setTwilightState(state);
838         assertActivated(true /* activated */);
839     }
840 
841     @Test
twilightSchedule_whenRebootedDuringNight_ifOffBeforeNight_turnsOn()842     public void twilightSchedule_whenRebootedDuringNight_ifOffBeforeNight_turnsOn() {
843         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
844         setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
845 
846         final TwilightState state = mTwilightManager.getLastTwilightState();
847         mTwilightManager.setTwilightState(null);
848 
849         startService();
850         assertActivated(false /* activated */);
851 
852         mTwilightManager.setTwilightState(state);
853         assertActivated(true /* activated */);
854     }
855 
856     @Test
twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInFuture_turnsOn()857     public void twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInFuture_turnsOn() {
858         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
859         setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
860 
861         final TwilightState state = mTwilightManager.getLastTwilightState();
862         mTwilightManager.setTwilightState(null);
863 
864         startService();
865         assertActivated(false /* activated */);
866 
867         mTwilightManager.setTwilightState(state);
868         assertActivated(true /* activated */);
869     }
870 
871     @Test
twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInPast_turnsOff()872     public void twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInPast_turnsOff() {
873         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
874         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
875 
876         final TwilightState state = mTwilightManager.getLastTwilightState();
877         mTwilightManager.setTwilightState(null);
878 
879         startService();
880         assertActivated(false /* activated */);
881 
882         mTwilightManager.setTwilightState(state);
883         assertActivated(false /* activated */);
884     }
885 
886     @Test
twilightSchedule_whenRebootedDuringNight_ifOnAfterNight_turnsOn()887     public void twilightSchedule_whenRebootedDuringNight_ifOnAfterNight_turnsOn() {
888         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
889         setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
890 
891         final TwilightState state = mTwilightManager.getLastTwilightState();
892         mTwilightManager.setTwilightState(null);
893 
894         startService();
895         assertActivated(true /* activated */);
896 
897         mTwilightManager.setTwilightState(state);
898         assertActivated(true /* activated */);
899     }
900 
901     @Test
twilightSchedule_whenRebootedDuringNight_ifOnBeforeNight_turnsOn()902     public void twilightSchedule_whenRebootedDuringNight_ifOnBeforeNight_turnsOn() {
903         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
904         setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
905 
906         final TwilightState state = mTwilightManager.getLastTwilightState();
907         mTwilightManager.setTwilightState(null);
908 
909         startService();
910         assertActivated(true /* activated */);
911 
912         mTwilightManager.setTwilightState(state);
913         assertActivated(true /* activated */);
914     }
915 
916     @Test
twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInFuture_turnsOn()917     public void twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInFuture_turnsOn() {
918         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
919         setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
920 
921         final TwilightState state = mTwilightManager.getLastTwilightState();
922         mTwilightManager.setTwilightState(null);
923 
924         startService();
925         assertActivated(true /* activated */);
926 
927         mTwilightManager.setTwilightState(state);
928         assertActivated(true /* activated */);
929     }
930 
931     @Test
twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInPast_turnsOn()932     public void twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInPast_turnsOn() {
933         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
934         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
935 
936         final TwilightState state = mTwilightManager.getLastTwilightState();
937         mTwilightManager.setTwilightState(null);
938 
939         startService();
940         assertActivated(true /* activated */);
941 
942         mTwilightManager.setTwilightState(state);
943         assertActivated(true /* activated */);
944     }
945 
946     @Test
accessibility_colorInversion_transformActivated()947     public void accessibility_colorInversion_transformActivated() {
948         if (!mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
949             return;
950         }
951 
952         setAccessibilityColorInversion(true);
953         setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
954 
955         startService();
956         assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
957         assertActiveColorMode(mContext.getResources().getInteger(
958                 R.integer.config_accessibilityColorMode));
959     }
960 
961     @Test
accessibility_colorCorrection_transformActivated()962     public void accessibility_colorCorrection_transformActivated() {
963         if (!mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
964             return;
965         }
966 
967         setAccessibilityColorCorrection(true);
968         setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
969 
970         startService();
971         assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
972         assertActiveColorMode(mContext.getResources().getInteger(
973                 R.integer.config_accessibilityColorMode));
974     }
975 
976     @Test
accessibility_all_transformActivated()977     public void accessibility_all_transformActivated() {
978         if (!mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
979             return;
980         }
981 
982         setAccessibilityColorCorrection(true);
983         setAccessibilityColorInversion(true);
984         setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
985 
986         startService();
987         assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
988         assertActiveColorMode(mContext.getResources().getInteger(
989                 R.integer.config_accessibilityColorMode));
990     }
991 
992     @Test
accessibility_none_transformActivated()993     public void accessibility_none_transformActivated() {
994         if (!mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
995             return;
996         }
997 
998         setAccessibilityColorCorrection(false);
999         setAccessibilityColorInversion(false);
1000         setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
1001 
1002         startService();
1003         assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
1004         assertActiveColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
1005     }
1006 
1007     @Test
displayWhiteBalance_enabled()1008     public void displayWhiteBalance_enabled() {
1009         setDisplayWhiteBalanceEnabled(true);
1010         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
1011         mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
1012         startService();
1013         assertDwbActive(true);
1014     }
1015 
1016     @Test
displayWhiteBalance_disabledAfterNightDisplayEnabled()1017     public void displayWhiteBalance_disabledAfterNightDisplayEnabled() {
1018         setDisplayWhiteBalanceEnabled(true);
1019         startService();
1020         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
1021 
1022         /* Since we are using FakeSettingsProvider which could not trigger observer change,
1023          * force an update here.*/
1024         mCds.updateDisplayWhiteBalanceStatus();
1025         assertDwbActive(false);
1026     }
1027 
1028     @Test
displayWhiteBalance_enabledAfterNightDisplayDisabled()1029     public void displayWhiteBalance_enabledAfterNightDisplayDisabled() {
1030         setDisplayWhiteBalanceEnabled(true);
1031         startService();
1032         setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
1033 
1034         mCds.updateDisplayWhiteBalanceStatus();
1035         assertDwbActive(false);
1036 
1037         setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
1038         mCds.updateDisplayWhiteBalanceStatus();
1039         assertDwbActive(true);
1040     }
1041 
1042     @Test
displayWhiteBalance_enabledAfterLinearColorModeSelected()1043     public void displayWhiteBalance_enabledAfterLinearColorModeSelected() {
1044         if (!isColorModeValid(ColorDisplayManager.COLOR_MODE_SATURATED)) {
1045             return;
1046         }
1047         setDisplayWhiteBalanceEnabled(true);
1048         mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
1049         startService();
1050         assertDwbActive(false);
1051 
1052         mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
1053         mCds.updateDisplayWhiteBalanceStatus();
1054         assertDwbActive(true);
1055     }
1056 
1057     @Test
displayWhiteBalance_disabledWhileAccessibilityColorCorrectionEnabled()1058     public void displayWhiteBalance_disabledWhileAccessibilityColorCorrectionEnabled() {
1059         setDisplayWhiteBalanceEnabled(true);
1060         setAccessibilityColorCorrection(true);
1061         startService();
1062         assertDwbActive(false);
1063 
1064         setAccessibilityColorCorrection(false);
1065         mCds.updateDisplayWhiteBalanceStatus();
1066         assertDwbActive(true);
1067     }
1068 
1069     @Test
displayWhiteBalance_disabledWhileAccessibilityColorInversionEnabled()1070     public void displayWhiteBalance_disabledWhileAccessibilityColorInversionEnabled() {
1071         setDisplayWhiteBalanceEnabled(true);
1072         setAccessibilityColorInversion(true);
1073         startService();
1074         assertDwbActive(false);
1075 
1076         setAccessibilityColorInversion(false);
1077         mCds.updateDisplayWhiteBalanceStatus();
1078         assertDwbActive(true);
1079     }
1080 
1081     @Test
compositionColorSpaces_noResources()1082     public void compositionColorSpaces_noResources() {
1083         when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
1084             .thenReturn(new int[] {});
1085         when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
1086             .thenReturn(new int[] {});
1087         setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
1088         startService();
1089         verify(mDisplayTransformManager).setColorMode(
1090                 eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(), eq(Display.COLOR_MODE_INVALID));
1091     }
1092 
1093     @Test
compositionColorSpaces_invalidResources()1094     public void compositionColorSpaces_invalidResources() {
1095         when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
1096                 .thenReturn(new int[] {
1097                         ColorDisplayManager.COLOR_MODE_NATURAL,
1098                         // Missing second color mode
1099                 });
1100         when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
1101                 .thenReturn(new int[] {
1102                         Display.COLOR_MODE_SRGB,
1103                         Display.COLOR_MODE_DISPLAY_P3
1104                 });
1105         setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
1106         startService();
1107         verify(mDisplayTransformManager).setColorMode(
1108                 eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(), eq(Display.COLOR_MODE_INVALID));
1109     }
1110 
1111     @Test
compositionColorSpaces_validResources_validColorMode()1112     public void compositionColorSpaces_validResources_validColorMode() {
1113         when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
1114                 .thenReturn(new int[] {
1115                         ColorDisplayManager.COLOR_MODE_NATURAL
1116                 });
1117         when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
1118                 .thenReturn(new int[] {
1119                         Display.COLOR_MODE_SRGB,
1120                 });
1121         setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
1122         startService();
1123         verify(mDisplayTransformManager).setColorMode(
1124                 eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(), eq(Display.COLOR_MODE_SRGB));
1125     }
1126 
1127     @Test
compositionColorSpaces_validResources_invalidColorMode()1128     public void compositionColorSpaces_validResources_invalidColorMode() {
1129         when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
1130                 .thenReturn(new int[] {
1131                         ColorDisplayManager.COLOR_MODE_NATURAL
1132                 });
1133         when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
1134                 .thenReturn(new int[] {
1135                         Display.COLOR_MODE_SRGB,
1136                 });
1137         setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED);
1138         startService();
1139         verify(mDisplayTransformManager).setColorMode(
1140                 eq(ColorDisplayManager.COLOR_MODE_BOOSTED), any(), eq(Display.COLOR_MODE_INVALID));
1141     }
1142 
1143     @Test
getColorMode_noAvailableModes_returnsNotSet()1144     public void getColorMode_noAvailableModes_returnsNotSet() {
1145         when(mResourcesSpy.getIntArray(R.array.config_availableColorModes))
1146                     .thenReturn(new int[] {});
1147         startService();
1148         verify(mDisplayTransformManager, never()).setColorMode(anyInt(), any(), anyInt());
1149         assertThat(mBinderService.getColorMode()).isEqualTo(-1);
1150     }
1151 
1152     /**
1153      * Configures Night display to use a custom schedule.
1154      *
1155      * @param startTimeOffset the offset relative to now to activate Night display (in minutes)
1156      * @param endTimeOffset the offset relative to now to deactivate Night display (in minutes)
1157      */
setAutoModeCustom(int startTimeOffset, int endTimeOffset)1158     private void setAutoModeCustom(int startTimeOffset, int endTimeOffset) {
1159         mBinderService.setNightDisplayAutoMode(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
1160         mBinderService.setNightDisplayCustomStartTime(
1161                 new Time(getLocalTimeRelativeToNow(startTimeOffset)));
1162         mBinderService
1163                 .setNightDisplayCustomEndTime(new Time(getLocalTimeRelativeToNow(endTimeOffset)));
1164     }
1165 
1166     /**
1167      * Configures Night display to use the twilight schedule.
1168      *
1169      * @param sunsetOffset the offset relative to now for sunset (in minutes)
1170      * @param sunriseOffset the offset relative to now for sunrise (in minutes)
1171      */
setAutoModeTwilight(int sunsetOffset, int sunriseOffset)1172     private void setAutoModeTwilight(int sunsetOffset, int sunriseOffset) {
1173         mBinderService.setNightDisplayAutoMode(ColorDisplayManager.AUTO_MODE_TWILIGHT);
1174         mTwilightManager.setTwilightState(
1175                 getTwilightStateRelativeToNow(sunsetOffset, sunriseOffset));
1176     }
1177 
1178     /**
1179      * Configures the Night display activated state.
1180      *
1181      * @param activated {@code true} if Night display should be activated
1182      * @param lastActivatedTimeOffset the offset relative to now to record that Night display was
1183      * activated (in minutes)
1184      */
setNightDisplayActivated(boolean activated, int lastActivatedTimeOffset)1185     private void setNightDisplayActivated(boolean activated, int lastActivatedTimeOffset) {
1186         mBinderService.setNightDisplayActivated(activated);
1187         Secure.putStringForUser(mContext.getContentResolver(),
1188                 Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
1189                 LocalDateTime.now().plusMinutes(lastActivatedTimeOffset).toString(),
1190                 mUserId);
1191     }
1192 
1193     /**
1194      * Configures the Accessibility color correction setting state.
1195      *
1196      * @param state {@code true} if color inversion should be activated
1197      */
setAccessibilityColorCorrection(boolean state)1198     private void setAccessibilityColorCorrection(boolean state) {
1199         Secure.putIntForUser(mContext.getContentResolver(),
1200                 Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, state ? 1 : 0, mUserId);
1201     }
1202 
1203     /**
1204      * Configures the Accessibility color inversion setting state.
1205      *
1206      * @param state {@code true} if color inversion should be activated
1207      */
setAccessibilityColorInversion(boolean state)1208     private void setAccessibilityColorInversion(boolean state) {
1209         Secure.putIntForUser(mContext.getContentResolver(),
1210                 Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, state ? 1 : 0, mUserId);
1211     }
1212 
1213     /**
1214      * Configures the Display White Balance setting state.
1215      *
1216      * @param enabled {@code true} if display white balance should be enabled
1217      */
setDisplayWhiteBalanceEnabled(boolean enabled)1218     private void setDisplayWhiteBalanceEnabled(boolean enabled) {
1219         Secure.putIntForUser(mContext.getContentResolver(),
1220                 Secure.DISPLAY_WHITE_BALANCE_ENABLED, enabled ? 1 : 0, mUserId);
1221     }
1222 
1223     /**
1224      * Configures color mode.
1225      */
setColorMode(int colorMode)1226     private void setColorMode(int colorMode) {
1227         mBinderService.setColorMode(colorMode);
1228     }
1229 
1230     /**
1231      * Returns whether the color mode is valid on the device the tests are running on.
1232      */
isColorModeValid(int mode)1233     private boolean isColorModeValid(int mode) {
1234         final int[] availableColorModes = mContext.getResources().getIntArray(
1235                 R.array.config_availableColorModes);
1236         if (availableColorModes != null) {
1237             for (int availableMode : availableColorModes) {
1238                 if (mode == availableMode) {
1239                     return true;
1240                 }
1241             }
1242         }
1243         return false;
1244     }
1245 
1246     /**
1247      * Convenience method to start {@link #mCds}.
1248      */
startService()1249     private void startService() {
1250         Secure.putIntForUser(mContext.getContentResolver(), Secure.USER_SETUP_COMPLETE, 1, mUserId);
1251 
1252         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
1253             mCds.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
1254             mCds.onUserChanged(mUserId);
1255         });
1256     }
1257 
1258     /**
1259      * Convenience method for asserting whether Night display should be activated.
1260      *
1261      * @param activated the expected activated state of Night display
1262      */
assertActivated(boolean activated)1263     private void assertActivated(boolean activated) {
1264         assertWithMessage("Incorrect Night display activated state")
1265                 .that(mBinderService.isNightDisplayActivated())
1266                 .isEqualTo(activated);
1267     }
1268 
1269     /**
1270      * Convenience method for asserting that the active color mode matches expectation.
1271      *
1272      * @param mode the expected active color mode.
1273      */
assertActiveColorMode(int mode)1274     private void assertActiveColorMode(int mode) {
1275         assertWithMessage("Unexpected color mode setting")
1276                 .that(mBinderService.getColorMode())
1277                 .isEqualTo(mode);
1278     }
1279 
1280     /**
1281      * Convenience method for asserting that the user chosen color mode matches expectation.
1282      *
1283      * @param mode the expected color mode setting.
1284      */
assertUserColorMode(int mode)1285     private void assertUserColorMode(int mode) {
1286         final int actualMode = System.getIntForUser(mContext.getContentResolver(),
1287                 System.DISPLAY_COLOR_MODE, -1, mUserId);
1288         assertWithMessage("Unexpected color mode setting")
1289                 .that(actualMode)
1290                 .isEqualTo(mode);
1291     }
1292 
1293     /**
1294      * Convenience method for asserting that the DWB active status matches expectation.
1295      *
1296      * @param enabled the expected active status.
1297      */
assertDwbActive(boolean enabled)1298     private void assertDwbActive(boolean enabled) {
1299         assertWithMessage("Incorrect Display White Balance state")
1300                 .that(mCds.mDisplayWhiteBalanceTintController.isActivated())
1301                 .isEqualTo(enabled);
1302     }
1303 
1304     /**
1305      * Convenience for making a {@link LocalTime} instance with an offset relative to now.
1306      *
1307      * @param offsetMinutes the offset relative to now (in minutes)
1308      * @return the LocalTime instance
1309      */
getLocalTimeRelativeToNow(int offsetMinutes)1310     private static LocalTime getLocalTimeRelativeToNow(int offsetMinutes) {
1311         final Calendar c = Calendar.getInstance();
1312         c.add(Calendar.MINUTE, offsetMinutes);
1313         return LocalTime.of(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE));
1314     }
1315 
1316     /**
1317      * Convenience for making a {@link TwilightState} instance with sunrise/sunset relative to now.
1318      *
1319      * @param sunsetOffset the offset relative to now for sunset (in minutes)
1320      * @param sunriseOffset the offset relative to now for sunrise (in minutes)
1321      * @return the TwilightState instance
1322      */
getTwilightStateRelativeToNow(int sunsetOffset, int sunriseOffset)1323     private static TwilightState getTwilightStateRelativeToNow(int sunsetOffset,
1324             int sunriseOffset) {
1325         final LocalTime sunset = getLocalTimeRelativeToNow(sunsetOffset);
1326         final LocalTime sunrise = getLocalTimeRelativeToNow(sunriseOffset);
1327 
1328         final LocalDateTime now = LocalDateTime.now();
1329         final ZoneId zoneId = ZoneId.systemDefault();
1330 
1331         long sunsetMillis = ColorDisplayService.getDateTimeBefore(sunset, now)
1332                 .atZone(zoneId)
1333                 .toInstant()
1334                 .toEpochMilli();
1335         long sunriseMillis = ColorDisplayService.getDateTimeBefore(sunrise, now)
1336                 .atZone(zoneId)
1337                 .toInstant()
1338                 .toEpochMilli();
1339         if (sunsetMillis < sunriseMillis) {
1340             sunsetMillis = ColorDisplayService.getDateTimeAfter(sunset, now)
1341                     .atZone(zoneId)
1342                     .toInstant()
1343                     .toEpochMilli();
1344         } else {
1345             sunriseMillis = ColorDisplayService.getDateTimeAfter(sunrise, now)
1346                     .atZone(zoneId)
1347                     .toInstant()
1348                     .toEpochMilli();
1349         }
1350 
1351         return new TwilightState(sunriseMillis, sunsetMillis);
1352     }
1353 
1354     private static class MockTwilightManager implements TwilightManager {
1355 
1356         private final Map<TwilightListener, Handler> mListeners = new HashMap<>();
1357         private TwilightState mTwilightState;
1358 
1359         /**
1360          * Updates the TwilightState and notifies any registered listeners.
1361          *
1362          * @param state the new TwilightState to use
1363          */
setTwilightState(TwilightState state)1364         void setTwilightState(TwilightState state) {
1365             synchronized (mListeners) {
1366                 mTwilightState = state;
1367 
1368                 final CountDownLatch latch = new CountDownLatch(mListeners.size());
1369                 for (Map.Entry<TwilightListener, Handler> entry : mListeners.entrySet()) {
1370                     entry.getValue().post(new Runnable() {
1371                         @Override
1372                         public void run() {
1373                             entry.getKey().onTwilightStateChanged(state);
1374                             latch.countDown();
1375                         }
1376                     });
1377                 }
1378 
1379                 try {
1380                     latch.await(5, TimeUnit.SECONDS);
1381                 } catch (InterruptedException e) {
1382                     throw new RuntimeException(e);
1383                 }
1384             }
1385         }
1386 
1387         @Override
registerListener(@onNull TwilightListener listener, @NonNull Handler handler)1388         public void registerListener(@NonNull TwilightListener listener, @NonNull Handler handler) {
1389             synchronized (mListeners) {
1390                 mListeners.put(listener, handler);
1391             }
1392         }
1393 
1394         @Override
unregisterListener(@onNull TwilightListener listener)1395         public void unregisterListener(@NonNull TwilightListener listener) {
1396             synchronized (mListeners) {
1397                 mListeners.remove(listener);
1398             }
1399         }
1400 
1401         @Override
getLastTwilightState()1402         public TwilightState getLastTwilightState() {
1403             return mTwilightState;
1404         }
1405     }
1406 }
1407