OSDN Git Service

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