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
17package com.android.systemui.doze;
18
19import static com.android.systemui.doze.DozeMachine.State.DOZE;
20import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
21import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
22import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
23import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
24
25import static org.mockito.ArgumentMatchers.any;
26import static org.mockito.ArgumentMatchers.anyInt;
27import static org.mockito.ArgumentMatchers.anyLong;
28import static org.mockito.ArgumentMatchers.eq;
29import static org.mockito.Mockito.clearInvocations;
30import static org.mockito.Mockito.mock;
31import static org.mockito.Mockito.never;
32import static org.mockito.Mockito.reset;
33import static org.mockito.Mockito.times;
34import static org.mockito.Mockito.verify;
35import static org.mockito.Mockito.when;
36
37import android.app.AlarmManager;
38import android.os.Handler;
39import android.os.HandlerThread;
40import android.os.PowerManager;
41import android.support.test.filters.SmallTest;
42import android.support.test.runner.AndroidJUnit4;
43
44import com.android.keyguard.KeyguardUpdateMonitor;
45import com.android.systemui.SysuiTestCase;
46import com.android.systemui.statusbar.phone.DozeParameters;
47import com.android.systemui.util.wakelock.WakeLockFake;
48
49import org.junit.After;
50import org.junit.Assert;
51import org.junit.Before;
52import org.junit.Test;
53import org.junit.runner.RunWith;
54import org.mockito.Mock;
55import org.mockito.MockitoAnnotations;
56
57@RunWith(AndroidJUnit4.class)
58@SmallTest
59public class DozeUiTest extends SysuiTestCase {
60
61    @Mock
62    private AlarmManager mAlarmManager;
63    @Mock
64    private DozeMachine mMachine;
65    @Mock
66    private DozeParameters mDozeParameters;
67    @Mock
68    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
69    @Mock
70    private DozeHost mHost;
71    private WakeLockFake mWakeLock;
72    private Handler mHandler;
73    private HandlerThread mHandlerThread;
74    private DozeUi mDozeUi;
75
76    @Before
77    public void setUp() throws Exception {
78        MockitoAnnotations.initMocks(this);
79
80        mHandlerThread = new HandlerThread("DozeUiTest");
81        mHandlerThread.start();
82        mWakeLock = new WakeLockFake();
83        mHandler = mHandlerThread.getThreadHandler();
84
85        mDozeUi = new DozeUi(mContext, mAlarmManager, mMachine, mWakeLock, mHost, mHandler,
86                mDozeParameters, mKeyguardUpdateMonitor);
87    }
88
89    @After
90    public void tearDown() throws Exception {
91        mHandlerThread.quit();
92        mHandler = null;
93        mHandlerThread = null;
94    }
95
96    @Test
97    public void pausingAndUnpausingAod_registersTimeTickAfterUnpausing() throws Exception {
98        mDozeUi.transitionTo(UNINITIALIZED, INITIALIZED);
99        mDozeUi.transitionTo(INITIALIZED, DOZE_AOD);
100        mDozeUi.transitionTo(DOZE_AOD, DOZE_AOD_PAUSED);
101
102        clearInvocations(mAlarmManager);
103
104        mDozeUi.transitionTo(DOZE_AOD_PAUSED, DOZE_AOD);
105
106        verify(mAlarmManager).setExact(anyInt(), anyLong(), eq("doze_time_tick"), any(), any());
107    }
108
109    @Test
110    public void propagatesAnimateScreenOff_noAlwaysOn() {
111        reset(mHost);
112        when(mDozeParameters.getAlwaysOn()).thenReturn(false);
113        when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(false);
114
115        mDozeUi.getKeyguardCallback().onKeyguardVisibilityChanged(false);
116        verify(mHost).setAnimateScreenOff(eq(false));
117    }
118
119    @Test
120    public void propagatesAnimateScreenOff_alwaysOn() {
121        reset(mHost);
122        when(mDozeParameters.getAlwaysOn()).thenReturn(true);
123        when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(false);
124
125        // Take over when the keyguard is visible.
126        mDozeUi.getKeyguardCallback().onKeyguardVisibilityChanged(true);
127        verify(mHost).setAnimateScreenOff(eq(true));
128
129        // Do not animate screen-off when keyguard isn't visible - PowerManager will do it.
130        mDozeUi.getKeyguardCallback().onKeyguardVisibilityChanged(false);
131        verify(mHost).setAnimateScreenOff(eq(false));
132    }
133
134    @Test
135    public void neverAnimateScreenOff_whenNotSupported() {
136        // Re-initialize DozeParameters saying that the display requires blanking.
137        reset(mDozeParameters);
138        reset(mHost);
139        when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true);
140        mDozeUi = new DozeUi(mContext, mAlarmManager, mMachine, mWakeLock, mHost, mHandler,
141                mDozeParameters, mKeyguardUpdateMonitor);
142
143        // Never animate if display doesn't support it.
144        mDozeUi.getKeyguardCallback().onKeyguardVisibilityChanged(true);
145        mDozeUi.getKeyguardCallback().onKeyguardVisibilityChanged(false);
146        verify(mHost, never()).setAnimateScreenOff(eq(false));
147    }
148
149    @Test
150    public void transitionSetsAnimateWakeup_alwaysOn() {
151        when(mDozeParameters.getAlwaysOn()).thenReturn(true);
152        when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(false);
153        mDozeUi.transitionTo(UNINITIALIZED, DOZE);
154        verify(mHost).setAnimateWakeup(eq(true));
155    }
156
157    @Test
158    public void keyguardVisibility_changesControlScreenOffAnimation() {
159        // Pre-condition
160        reset(mDozeParameters);
161        when(mDozeParameters.getAlwaysOn()).thenReturn(true);
162        when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(false);
163
164        mDozeUi.getKeyguardCallback().onKeyguardVisibilityChanged(false);
165        verify(mDozeParameters).setControlScreenOffAnimation(eq(false));
166        mDozeUi.getKeyguardCallback().onKeyguardVisibilityChanged(true);
167        verify(mDozeParameters).setControlScreenOffAnimation(eq(true));
168    }
169
170    @Test
171    public void transitionSetsAnimateWakeup_noAlwaysOn() {
172        mDozeUi.transitionTo(UNINITIALIZED, DOZE);
173        verify(mHost).setAnimateWakeup(eq(false));
174    }
175}