blob: b05172c6d7c2e41b4455b41455305dde2608eef1 [file] [log] [blame]
Dave Mankoff1193aa42019-10-28 17:51:26 -04001/*
2 * Copyright (C) 2019 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.statusbar.phone;
18
19import static org.junit.Assert.assertFalse;
20import static org.mockito.ArgumentMatchers.any;
21import static org.mockito.ArgumentMatchers.anyInt;
22import static org.mockito.ArgumentMatchers.eq;
23import static org.mockito.Mockito.doAnswer;
24import static org.mockito.Mockito.mock;
25import static org.mockito.Mockito.never;
26import static org.mockito.Mockito.reset;
27import static org.mockito.Mockito.verify;
28import static org.mockito.Mockito.when;
29
30import android.os.PowerManager;
31import android.testing.AndroidTestingRunner;
32import android.view.View;
33
34import androidx.test.filters.SmallTest;
35
36import com.android.keyguard.KeyguardUpdateMonitor;
37import com.android.systemui.SysuiTestCase;
38import com.android.systemui.assist.AssistManager;
39import com.android.systemui.doze.DozeEvent;
40import com.android.systemui.doze.DozeHost;
41import com.android.systemui.doze.DozeLog;
42import com.android.systemui.keyguard.KeyguardViewMediator;
43import com.android.systemui.keyguard.WakefulnessLifecycle;
44import com.android.systemui.statusbar.PulseExpansionHandler;
45import com.android.systemui.statusbar.StatusBarState;
46import com.android.systemui.statusbar.StatusBarStateControllerImpl;
47import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
48import com.android.systemui.statusbar.notification.VisualStabilityManager;
49import com.android.systemui.statusbar.policy.BatteryController;
50import com.android.systemui.statusbar.policy.DeviceProvisionedController;
51
52import org.junit.Before;
53import org.junit.Test;
54import org.junit.runner.RunWith;
55import org.mockito.ArgumentCaptor;
56import org.mockito.Mock;
57import org.mockito.MockitoAnnotations;
58
59import java.util.Arrays;
60import java.util.Collections;
61import java.util.HashSet;
62
63import dagger.Lazy;
64
65@SmallTest
66@RunWith(AndroidTestingRunner.class)
67public class DozeServiceHostTest extends SysuiTestCase {
68
69 private DozeServiceHost mDozeServiceHost;
70
71 @Mock private HeadsUpManagerPhone mHeadsUpManager;
72 @Mock private ScrimController mScrimController;
73 @Mock private DozeScrimController mDozeScrimController;
74 @Mock private Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
75 @Mock private VisualStabilityManager mVisualStabilityManager;
76 @Mock private KeyguardViewMediator mKeyguardViewMediator;
77 @Mock private StatusBarStateControllerImpl mStatusBarStateController;
78 @Mock private BatteryController mBatteryController;
79 @Mock private DeviceProvisionedController mDeviceProvisionedController;
80 @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
81 @Mock private AssistManager mAssistManager;
82 @Mock private DozeLog mDozeLog;
83 @Mock private PulseExpansionHandler mPulseExpansionHandler;
84 @Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
85 @Mock private StatusBarWindowController mStatusBarWindowController;
86 @Mock private PowerManager mPowerManager;
87 @Mock private WakefulnessLifecycle mWakefullnessLifecycle;
88 @Mock private StatusBar mStatusBar;
89 @Mock private NotificationIconAreaController mNotificationIconAreaController;
90 @Mock private StatusBarWindowViewController mStatusBarWindowViewController;
91 @Mock private StatusBarWindowView mStatusBarWindow;
92 @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
93 @Mock private NotificationPanelView mNotificationPanel;
94 @Mock private View mAmbientIndicationContainer;
95 @Mock private BiometricUnlockController mBiometricUnlockController;
96
97 @Before
98 public void setup() {
99 MockitoAnnotations.initMocks(this);
100 when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController);
101 mDozeServiceHost = new DozeServiceHost(mDozeLog, mPowerManager, mWakefullnessLifecycle,
102 mStatusBarStateController, mDeviceProvisionedController, mHeadsUpManager,
103 mBatteryController, mScrimController, mBiometricUnlockControllerLazy,
104 mKeyguardViewMediator, mAssistManager, mDozeScrimController, mKeyguardUpdateMonitor,
105 mVisualStabilityManager, mPulseExpansionHandler, mStatusBarWindowController,
106 mNotificationWakeUpCoordinator);
107
108 mDozeServiceHost.initialize(mStatusBar, mNotificationIconAreaController,
109 mStatusBarWindowViewController, mStatusBarWindow, mStatusBarKeyguardViewManager,
110 mNotificationPanel, mAmbientIndicationContainer);
111 }
112
113 @Test
114 public void testStartStopDozing() {
115 when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
116 when(mStatusBarStateController.isKeyguardRequested()).thenReturn(true);
117
118 assertFalse(mDozeServiceHost.getDozingRequested());
119
120 mDozeServiceHost.startDozing();
121 verify(mStatusBarStateController).setIsDozing(eq(true));
122 verify(mStatusBar).updateIsKeyguard();
123
124 mDozeServiceHost.stopDozing();
125 verify(mStatusBarStateController).setIsDozing(eq(false));
126 }
127
128
129 @Test
130 public void testPulseWhileDozing_updatesScrimController() {
131 mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
132 mStatusBar.showKeyguardImpl();
133
134 // Keep track of callback to be able to stop the pulse
135// DozeHost.PulseCallback[] pulseCallback = new DozeHost.PulseCallback[1];
136// doAnswer(invocation -> {
137// pulseCallback[0] = invocation.getArgument(0);
138// return null;
139// }).when(mDozeScrimController).pulse(any(), anyInt());
140
141 // Starting a pulse should change the scrim controller to the pulsing state
142 mDozeServiceHost.pulseWhileDozing(new DozeHost.PulseCallback() {
143 @Override
144 public void onPulseStarted() {
145 }
146
147 @Override
148 public void onPulseFinished() {
149 }
150 }, DozeEvent.PULSE_REASON_NOTIFICATION);
151
152 ArgumentCaptor<DozeHost.PulseCallback> pulseCallbackArgumentCaptor =
153 ArgumentCaptor.forClass(DozeHost.PulseCallback.class);
154
155 verify(mDozeScrimController).pulse(
156 pulseCallbackArgumentCaptor.capture(), eq(DozeEvent.PULSE_REASON_NOTIFICATION));
157 verify(mStatusBar).updateScrimController();
158 reset(mStatusBar);
159
160 pulseCallbackArgumentCaptor.getValue().onPulseFinished();
161 assertFalse(mDozeScrimController.isPulsing());
162 verify(mStatusBar).updateScrimController();
163 }
164
165
166 @Test
167 public void testPulseWhileDozingWithDockingReason_suppressWakeUpGesture() {
168 // Keep track of callback to be able to stop the pulse
169 final DozeHost.PulseCallback[] pulseCallback = new DozeHost.PulseCallback[1];
170 doAnswer(invocation -> {
171 pulseCallback[0] = invocation.getArgument(0);
172 return null;
173 }).when(mDozeScrimController).pulse(any(), anyInt());
174
175 // Starting a pulse while docking should suppress wakeup gesture
176 mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class),
177 DozeEvent.PULSE_REASON_DOCKING);
178 verify(mStatusBarWindowViewController).suppressWakeUpGesture(eq(true));
179
180 // Ending a pulse should restore wakeup gesture
181 pulseCallback[0].onPulseFinished();
182 verify(mStatusBarWindowViewController).suppressWakeUpGesture(eq(false));
183 }
184
185 @Test
186 public void testPulseWhileDozing_notifyAuthInterrupt() {
187 HashSet<Integer> reasonsWantingAuth = new HashSet<>(
188 Collections.singletonList(DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN));
189 HashSet<Integer> reasonsSkippingAuth = new HashSet<>(
190 Arrays.asList(DozeEvent.PULSE_REASON_INTENT,
191 DozeEvent.PULSE_REASON_NOTIFICATION,
192 DozeEvent.PULSE_REASON_SENSOR_SIGMOTION,
193 DozeEvent.REASON_SENSOR_PICKUP,
194 DozeEvent.REASON_SENSOR_DOUBLE_TAP,
195 DozeEvent.PULSE_REASON_SENSOR_LONG_PRESS,
196 DozeEvent.PULSE_REASON_DOCKING,
197 DozeEvent.REASON_SENSOR_WAKE_UP,
198 DozeEvent.REASON_SENSOR_TAP));
199 HashSet<Integer> reasonsThatDontPulse = new HashSet<>(
200 Arrays.asList(DozeEvent.REASON_SENSOR_PICKUP,
201 DozeEvent.REASON_SENSOR_DOUBLE_TAP,
202 DozeEvent.REASON_SENSOR_TAP));
203
204 doAnswer(invocation -> {
205 DozeHost.PulseCallback callback = invocation.getArgument(0);
206 callback.onPulseStarted();
207 return null;
208 }).when(mDozeScrimController).pulse(any(), anyInt());
209
210 mDozeServiceHost.mWakeLockScreenPerformsAuth = true;
211 for (int i = 0; i < DozeEvent.TOTAL_REASONS; i++) {
212 reset(mKeyguardUpdateMonitor);
213 mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class), i);
214 if (reasonsWantingAuth.contains(i)) {
215 verify(mKeyguardUpdateMonitor).onAuthInterruptDetected(eq(true));
216 } else if (reasonsSkippingAuth.contains(i) || reasonsThatDontPulse.contains(i)) {
217 verify(mKeyguardUpdateMonitor, never()).onAuthInterruptDetected(eq(true));
218 } else {
219 throw new AssertionError("Reason " + i + " isn't specified as wanting or skipping"
220 + " passive auth. Please consider how this pulse reason should behave.");
221 }
222 }
223 }
224}