blob: 4a66bb7deca062cff5d065563a445562f8ed4da3 [file] [log] [blame]
Adrian Roosef7a4022017-01-19 14:48:35 -08001/*
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.statusbar.phone;
18
Julia Reynolds30203152017-05-26 13:36:31 -040019import static android.app.NotificationManager.IMPORTANCE_HIGH;
20
Julia Reynoldsed1c9af2018-03-21 15:21:09 -040021import static junit.framework.Assert.assertEquals;
Julia Reynolds30203152017-05-26 13:36:31 -040022import static junit.framework.Assert.assertFalse;
Julia Reynoldsed1c9af2018-03-21 15:21:09 -040023import static junit.framework.Assert.assertNotNull;
Julia Reynolds30203152017-05-26 13:36:31 -040024import static junit.framework.Assert.assertTrue;
Chris Wren621933f2017-06-14 15:59:03 -040025import static junit.framework.TestCase.fail;
Julia Reynolds30203152017-05-26 13:36:31 -040026
Chris Wren621933f2017-06-14 15:59:03 -040027import static org.mockito.ArgumentMatchers.any;
28import static org.mockito.ArgumentMatchers.anyBoolean;
29import static org.mockito.ArgumentMatchers.anyInt;
30import static org.mockito.ArgumentMatchers.anyString;
Lucas Dupin311eac82017-12-11 14:40:07 -080031import static org.mockito.ArgumentMatchers.eq;
Adrian Roosef7a4022017-01-19 14:48:35 -080032import static org.mockito.Mockito.doAnswer;
33import static org.mockito.Mockito.mock;
Chris Wren621933f2017-06-14 15:59:03 -040034import static org.mockito.Mockito.never;
Lucas Dupind5107302018-03-19 15:30:29 -070035import static org.mockito.Mockito.reset;
Chris Wren621933f2017-06-14 15:59:03 -040036import static org.mockito.Mockito.times;
Chris Wren621933f2017-06-14 15:59:03 -040037import static org.mockito.Mockito.verify;
Jason Monk9c4faa82017-08-15 09:32:27 -040038import static org.mockito.Mockito.when;
Adrian Roosef7a4022017-01-19 14:48:35 -080039
Julia Reynolds30203152017-05-26 13:36:31 -040040import android.app.Notification;
Charles He2eda2422017-09-24 17:55:21 +010041import android.app.StatusBarManager;
Jason Monk51305372017-06-22 11:41:08 -040042import android.app.trust.TrustManager;
Eliot Courtneya6d8cf22017-10-20 13:26:58 +090043import android.content.Context;
Jason Monk51305372017-06-22 11:41:08 -040044import android.hardware.fingerprint.FingerprintManager;
Chris Wren27a52fa2017-02-01 14:21:43 -050045import android.metrics.LogMaker;
Jason Monk9c4faa82017-08-15 09:32:27 -040046import android.os.Binder;
Julia Reynolds30203152017-05-26 13:36:31 -040047import android.os.Handler;
48import android.os.HandlerThread;
49import android.os.IPowerManager;
Julia Reynolds30203152017-05-26 13:36:31 -040050import android.os.PowerManager;
Chris Wren621933f2017-06-14 15:59:03 -040051import android.os.RemoteException;
Julia Reynolds30203152017-05-26 13:36:31 -040052import android.os.UserHandle;
53import android.service.notification.StatusBarNotification;
Adrian Roosef7a4022017-01-19 14:48:35 -080054import android.support.test.filters.SmallTest;
Chris Wren27a52fa2017-02-01 14:21:43 -050055import android.support.test.metricshelper.MetricsAsserts;
Chris Wren621933f2017-06-14 15:59:03 -040056import android.testing.AndroidTestingRunner;
57import android.testing.TestableLooper;
Chris Wren621933f2017-06-14 15:59:03 -040058import android.testing.TestableLooper.RunWithLooper;
Eliot Courtney09322282017-11-09 15:31:19 +090059import android.util.SparseArray;
Julia Reynoldsed1c9af2018-03-21 15:21:09 -040060import android.view.Gravity;
61import android.view.View;
Jason Monk51305372017-06-22 11:41:08 -040062import android.view.ViewGroup.LayoutParams;
Adrian Roosef7a4022017-01-19 14:48:35 -080063
Chris Wrenef319902017-03-07 17:58:31 -050064import com.android.internal.logging.MetricsLogger;
Chris Wren27a52fa2017-02-01 14:21:43 -050065import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Chris Wrenef319902017-03-07 17:58:31 -050066import com.android.internal.logging.testing.FakeMetricsLogger;
Chris Wren621933f2017-06-14 15:59:03 -040067import com.android.internal.statusbar.IStatusBarService;
Adrian Roosef7a4022017-01-19 14:48:35 -080068import com.android.keyguard.KeyguardHostView.OnDismissAction;
Eliot Courtneya6d8cf22017-10-20 13:26:58 +090069import com.android.systemui.ForegroundServiceController;
Jason Monk9c4faa82017-08-15 09:32:27 -040070import com.android.systemui.R;
Adrian Roosef7a4022017-01-19 14:48:35 -080071import com.android.systemui.SysuiTestCase;
Jason Monk9c4faa82017-08-15 09:32:27 -040072import com.android.systemui.assist.AssistManager;
Lucas Dupin47a65c72018-02-15 14:16:18 -080073import com.android.systemui.keyguard.KeyguardViewMediator;
Adrian Roos6d5ebb72017-08-03 15:10:22 +020074import com.android.systemui.keyguard.WakefulnessLifecycle;
Julia Reynolds30203152017-05-26 13:36:31 -040075import com.android.systemui.recents.misc.SystemServicesProxy;
Chris Wren27a52fa2017-02-01 14:21:43 -050076import com.android.systemui.statusbar.ActivatableNotificationView;
Julia Reynoldsfc640012018-02-21 12:25:27 -050077import com.android.systemui.statusbar.AppOpsListener;
Jason Monk5ecf80c2017-07-06 15:28:17 -040078import com.android.systemui.statusbar.CommandQueue;
Julia Reynoldsed1c9af2018-03-21 15:21:09 -040079import com.android.systemui.statusbar.ExpandableNotificationRow;
80import com.android.systemui.statusbar.FooterView;
81import com.android.systemui.statusbar.FooterViewButton;
Chris Wren27a52fa2017-02-01 14:21:43 -050082import com.android.systemui.statusbar.KeyguardIndicationController;
83import com.android.systemui.statusbar.NotificationData;
Chris Wren621933f2017-06-14 15:59:03 -040084import com.android.systemui.statusbar.NotificationData.Entry;
Eliot Courtneya6d8cf22017-10-20 13:26:58 +090085import com.android.systemui.statusbar.NotificationEntryManager;
86import com.android.systemui.statusbar.NotificationGutsManager;
Eliot Courtney2b4c3a02017-11-27 13:27:46 +090087import com.android.systemui.statusbar.NotificationListContainer;
Eliot Courtney3985ad52017-11-17 16:51:52 +090088import com.android.systemui.statusbar.NotificationListener;
Eliot Courtney09322282017-11-09 15:31:19 +090089import com.android.systemui.statusbar.NotificationLockscreenUserManager;
Eliot Courtney3985ad52017-11-17 16:51:52 +090090import com.android.systemui.statusbar.NotificationLogger;
Eliot Courtneya6d8cf22017-10-20 13:26:58 +090091import com.android.systemui.statusbar.NotificationMediaManager;
92import com.android.systemui.statusbar.NotificationPresenter;
93import com.android.systemui.statusbar.NotificationRemoteInputManager;
Eliot Courtney2b4c3a02017-11-27 13:27:46 +090094import com.android.systemui.statusbar.NotificationViewHierarchyManager;
Chris Wren621933f2017-06-14 15:59:03 -040095import com.android.systemui.statusbar.StatusBarState;
Selim Cinek7e222c3c2018-01-25 12:22:41 -080096import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
Eliot Courtneya6d8cf22017-10-20 13:26:58 +090097import com.android.systemui.statusbar.notification.VisualStabilityManager;
Jason Monk9c4faa82017-08-15 09:32:27 -040098import com.android.systemui.statusbar.policy.DeviceProvisionedController;
Jason Monk9c4faa82017-08-15 09:32:27 -040099import com.android.systemui.statusbar.policy.KeyguardMonitor;
100import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
Chris Wren27a52fa2017-02-01 14:21:43 -0500101import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
Adrian Roosef7a4022017-01-19 14:48:35 -0800102
103import org.junit.Before;
104import org.junit.Test;
105import org.junit.runner.RunWith;
Julia Reynoldsed1c9af2018-03-21 15:21:09 -0400106import org.mockito.ArgumentCaptor;
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900107import org.mockito.Mock;
108import org.mockito.MockitoAnnotations;
Adrian Roosef7a4022017-01-19 14:48:35 -0800109
Jason Monk51305372017-06-22 11:41:08 -0400110import java.io.ByteArrayOutputStream;
111import java.io.PrintWriter;
Chris Wren621933f2017-06-14 15:59:03 -0400112import java.util.ArrayList;
Julia Reynoldsed1c9af2018-03-21 15:21:09 -0400113import java.util.function.Predicate;
Chris Wren621933f2017-06-14 15:59:03 -0400114
Adrian Roos02de4982017-02-11 09:35:54 +0100115@SmallTest
Chris Wren621933f2017-06-14 15:59:03 -0400116@RunWith(AndroidTestingRunner.class)
117@RunWithLooper
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500118public class StatusBarTest extends SysuiTestCase {
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900119 @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
120 @Mock private UnlockMethodCache mUnlockMethodCache;
121 @Mock private KeyguardIndicationController mKeyguardIndicationController;
122 @Mock private NotificationStackScrollLayout mStackScroller;
yoshiki iguchi4e30e762018-02-06 12:09:23 +0900123 @Mock private HeadsUpManagerPhone mHeadsUpManager;
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900124 @Mock private SystemServicesProxy mSystemServicesProxy;
125 @Mock private NotificationPanelView mNotificationPanelView;
126 @Mock private IStatusBarService mBarService;
127 @Mock private ScrimController mScrimController;
128 @Mock private ArrayList<Entry> mNotificationList;
129 @Mock private FingerprintUnlockController mFingerprintUnlockController;
130 @Mock private NotificationData mNotificationData;
Adrian Roosef7a4022017-01-19 14:48:35 -0800131
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900132 // Mock dependencies:
133 @Mock private NotificationViewHierarchyManager mViewHierarchyManager;
134 @Mock private VisualStabilityManager mVisualStabilityManager;
135 @Mock private NotificationListener mNotificationListener;
Lucas Dupin47a65c72018-02-15 14:16:18 -0800136 @Mock private KeyguardViewMediator mKeyguardViewMediator;
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900137
Eliot Courtney2b4c3a02017-11-27 13:27:46 +0900138 private TestableStatusBar mStatusBar;
139 private FakeMetricsLogger mMetricsLogger;
Eliot Courtney2b4c3a02017-11-27 13:27:46 +0900140 private PowerManager mPowerManager;
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900141 private TestableNotificationEntryManager mEntryManager;
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900142 private NotificationLogger mNotificationLogger;
Chris Wren27a52fa2017-02-01 14:21:43 -0500143
Adrian Roos02de4982017-02-11 09:35:54 +0100144 @Before
Julia Reynolds30203152017-05-26 13:36:31 -0400145 public void setup() throws Exception {
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900146 MockitoAnnotations.initMocks(this);
Jason Monk9c4faa82017-08-15 09:32:27 -0400147 mDependency.injectMockDependency(AssistManager.class);
148 mDependency.injectMockDependency(DeviceProvisionedController.class);
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900149 mDependency.injectMockDependency(NotificationGroupManager.class);
150 mDependency.injectMockDependency(NotificationGutsManager.class);
151 mDependency.injectMockDependency(NotificationRemoteInputManager.class);
152 mDependency.injectMockDependency(NotificationMediaManager.class);
153 mDependency.injectMockDependency(ForegroundServiceController.class);
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900154 mDependency.injectTestDependency(NotificationViewHierarchyManager.class,
155 mViewHierarchyManager);
156 mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
157 mDependency.injectTestDependency(NotificationListener.class, mNotificationListener);
Jason Monk9c4faa82017-08-15 09:32:27 -0400158 mDependency.injectTestDependency(KeyguardMonitor.class, mock(KeyguardMonitorImpl.class));
Julia Reynoldsfc640012018-02-21 12:25:27 -0500159 mDependency.injectTestDependency(AppOpsListener.class, mock(AppOpsListener.class));
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900160
Jason Monk51305372017-06-22 11:41:08 -0400161 mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
162 mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900163
Chris Wrenef319902017-03-07 17:58:31 -0500164 mMetricsLogger = new FakeMetricsLogger();
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900165 mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
Eliot Courtney6c313d32017-12-14 19:57:51 +0900166 mNotificationLogger = new NotificationLogger();
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900167 mDependency.injectTestDependency(NotificationLogger.class, mNotificationLogger);
168
Julia Reynolds30203152017-05-26 13:36:31 -0400169 IPowerManager powerManagerService = mock(IPowerManager.class);
170 HandlerThread handlerThread = new HandlerThread("TestThread");
171 handlerThread.start();
172 mPowerManager = new PowerManager(mContext, powerManagerService,
173 new Handler(handlerThread.getLooper()));
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900174
175 CommandQueue commandQueue = mock(CommandQueue.class);
176 when(commandQueue.asBinder()).thenReturn(new Binder());
177 mContext.putComponent(CommandQueue.class, commandQueue);
178
179 mContext.setTheme(R.style.Theme_SystemUI_Light);
180
181 when(mStackScroller.generateLayoutParams(any())).thenReturn(new LayoutParams(0, 0));
182 when(mNotificationPanelView.getLayoutParams()).thenReturn(new LayoutParams(0, 0));
Julia Reynolds30203152017-05-26 13:36:31 -0400183 when(powerManagerService.isInteractive()).thenReturn(true);
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900184 when(mStackScroller.getActivatedChild()).thenReturn(null);
Julia Reynolds30203152017-05-26 13:36:31 -0400185
Adrian Roosef7a4022017-01-19 14:48:35 -0800186 doAnswer(invocation -> {
187 OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
188 onDismissAction.onDismiss();
189 return null;
190 }).when(mStatusBarKeyguardViewManager).dismissWithAction(any(), any(), anyBoolean());
191
192 doAnswer(invocation -> {
193 Runnable runnable = (Runnable) invocation.getArguments()[0];
194 runnable.run();
195 return null;
196 }).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
Chris Wren27a52fa2017-02-01 14:21:43 -0500197
Eliot Courtney6c313d32017-12-14 19:57:51 +0900198 mEntryManager = new TestableNotificationEntryManager(mSystemServicesProxy, mPowerManager,
199 mContext);
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900200 mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
201 mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
202 mPowerManager, mNotificationPanelView, mBarService, mNotificationListener,
203 mNotificationLogger, mVisualStabilityManager, mViewHierarchyManager,
Selim Cinek7e222c3c2018-01-25 12:22:41 -0800204 mEntryManager, mScrimController, mFingerprintUnlockController,
Lucas Dupin47a65c72018-02-15 14:16:18 -0800205 mock(ActivityLaunchAnimator.class), mKeyguardViewMediator);
Eliot Courtney8f56b0e2017-12-14 18:54:28 +0900206 mStatusBar.mContext = mContext;
207 mStatusBar.mComponents = mContext.getComponents();
Eliot Courtney2b4c3a02017-11-27 13:27:46 +0900208 mEntryManager.setUpForTest(mStatusBar, mStackScroller, mStatusBar, mHeadsUpManager,
209 mNotificationData);
Eliot Courtney4a96b362017-12-14 19:38:52 +0900210 mNotificationLogger.setUpWithEntryManager(mEntryManager, mStackScroller);
Eliot Courtney3985ad52017-11-17 16:51:52 +0900211
Eliot Courtney3985ad52017-11-17 16:51:52 +0900212 TestableLooper.get(this).setMessageHandler(m -> {
213 if (m.getCallback() == mStatusBar.mNotificationLogger.getVisibilityReporter()) {
214 return false;
Chris Wren621933f2017-06-14 15:59:03 -0400215 }
Eliot Courtney3985ad52017-11-17 16:51:52 +0900216 return true;
Chris Wren621933f2017-06-14 15:59:03 -0400217 });
Adrian Roosef7a4022017-01-19 14:48:35 -0800218 }
219
Adrian Roos02de4982017-02-11 09:35:54 +0100220 @Test
Jason Monk5ecf80c2017-07-06 15:28:17 -0400221 public void testSetBouncerShowing_noCrash() {
222 mStatusBar.mCommandQueue = mock(CommandQueue.class);
223 mStatusBar.setBouncerShowing(true);
224 }
225
226 @Test
Adrian Roosef7a4022017-01-19 14:48:35 -0800227 public void executeRunnableDismissingKeyguard_nullRunnable_showingAndOccluded() {
228 when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
229 when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(true);
230
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500231 mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
Adrian Roosef7a4022017-01-19 14:48:35 -0800232 }
233
Adrian Roos02de4982017-02-11 09:35:54 +0100234 @Test
Adrian Roosef7a4022017-01-19 14:48:35 -0800235 public void executeRunnableDismissingKeyguard_nullRunnable_showing() {
236 when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
237 when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
238
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500239 mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
Adrian Roosef7a4022017-01-19 14:48:35 -0800240 }
241
Adrian Roos02de4982017-02-11 09:35:54 +0100242 @Test
Adrian Roosef7a4022017-01-19 14:48:35 -0800243 public void executeRunnableDismissingKeyguard_nullRunnable_notShowing() {
244 when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
245 when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
246
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500247 mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
Adrian Roosef7a4022017-01-19 14:48:35 -0800248 }
249
Adrian Roos02de4982017-02-11 09:35:54 +0100250 @Test
Chris Wren27a52fa2017-02-01 14:21:43 -0500251 public void lockscreenStateMetrics_notShowing() {
252 // uninteresting state, except that fingerprint must be non-zero
253 when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
254 when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
255 // interesting state
256 when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
257 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
258 when(mUnlockMethodCache.isMethodSecure()).thenReturn(false);
Chris Wren27a52fa2017-02-01 14:21:43 -0500259 mStatusBar.onKeyguardViewManagerStatesUpdated();
260
Chris Wrenef319902017-03-07 17:58:31 -0500261 MetricsAsserts.assertHasLog("missing hidden insecure lockscreen log",
262 mMetricsLogger.getLogs(),
Chris Wren27a52fa2017-02-01 14:21:43 -0500263 new LogMaker(MetricsEvent.LOCKSCREEN)
264 .setType(MetricsEvent.TYPE_CLOSE)
265 .setSubtype(0));
266 }
267
Adrian Roos02de4982017-02-11 09:35:54 +0100268 @Test
Chris Wren27a52fa2017-02-01 14:21:43 -0500269 public void lockscreenStateMetrics_notShowing_secure() {
270 // uninteresting state, except that fingerprint must be non-zero
271 when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
272 when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
273 // interesting state
274 when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
275 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
276 when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
277
278 mStatusBar.onKeyguardViewManagerStatesUpdated();
279
Chris Wrenef319902017-03-07 17:58:31 -0500280 MetricsAsserts.assertHasLog("missing hidden secure lockscreen log",
281 mMetricsLogger.getLogs(),
Chris Wren27a52fa2017-02-01 14:21:43 -0500282 new LogMaker(MetricsEvent.LOCKSCREEN)
283 .setType(MetricsEvent.TYPE_CLOSE)
284 .setSubtype(1));
285 }
286
Adrian Roos02de4982017-02-11 09:35:54 +0100287 @Test
Chris Wren27a52fa2017-02-01 14:21:43 -0500288 public void lockscreenStateMetrics_isShowing() {
289 // uninteresting state, except that fingerprint must be non-zero
290 when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
291 when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
292 // interesting state
293 when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
294 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
295 when(mUnlockMethodCache.isMethodSecure()).thenReturn(false);
296
297 mStatusBar.onKeyguardViewManagerStatesUpdated();
298
Chris Wrenef319902017-03-07 17:58:31 -0500299 MetricsAsserts.assertHasLog("missing insecure lockscreen showing",
300 mMetricsLogger.getLogs(),
Chris Wren27a52fa2017-02-01 14:21:43 -0500301 new LogMaker(MetricsEvent.LOCKSCREEN)
302 .setType(MetricsEvent.TYPE_OPEN)
303 .setSubtype(0));
304 }
305
Adrian Roos02de4982017-02-11 09:35:54 +0100306 @Test
Chris Wren27a52fa2017-02-01 14:21:43 -0500307 public void lockscreenStateMetrics_isShowing_secure() {
308 // uninteresting state, except that fingerprint must be non-zero
309 when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
310 when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
311 // interesting state
312 when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
313 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
314 when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
315
316 mStatusBar.onKeyguardViewManagerStatesUpdated();
317
Chris Wrenef319902017-03-07 17:58:31 -0500318 MetricsAsserts.assertHasLog("missing secure lockscreen showing log",
319 mMetricsLogger.getLogs(),
Chris Wren27a52fa2017-02-01 14:21:43 -0500320 new LogMaker(MetricsEvent.LOCKSCREEN)
321 .setType(MetricsEvent.TYPE_OPEN)
322 .setSubtype(1));
323 }
324
Adrian Roos02de4982017-02-11 09:35:54 +0100325 @Test
Chris Wren27a52fa2017-02-01 14:21:43 -0500326 public void lockscreenStateMetrics_isShowingBouncer() {
327 // uninteresting state, except that fingerprint must be non-zero
328 when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
329 when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
330 // interesting state
331 when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
332 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
333 when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
334
335 mStatusBar.onKeyguardViewManagerStatesUpdated();
336
Chris Wrenef319902017-03-07 17:58:31 -0500337 MetricsAsserts.assertHasLog("missing bouncer log",
338 mMetricsLogger.getLogs(),
Chris Wren27a52fa2017-02-01 14:21:43 -0500339 new LogMaker(MetricsEvent.BOUNCER)
340 .setType(MetricsEvent.TYPE_OPEN)
341 .setSubtype(1));
342 }
343
Adrian Roos02de4982017-02-11 09:35:54 +0100344 @Test
Chris Wren27a52fa2017-02-01 14:21:43 -0500345 public void onActivatedMetrics() {
346 ActivatableNotificationView view = mock(ActivatableNotificationView.class);
347 mStatusBar.onActivated(view);
348
Chris Wrenef319902017-03-07 17:58:31 -0500349 MetricsAsserts.assertHasLog("missing lockscreen note tap log",
350 mMetricsLogger.getLogs(),
Chris Wren27a52fa2017-02-01 14:21:43 -0500351 new LogMaker(MetricsEvent.ACTION_LS_NOTE)
352 .setType(MetricsEvent.TYPE_ACTION));
353 }
354
Julia Reynolds30203152017-05-26 13:36:31 -0400355 @Test
356 public void testShouldPeek_nonSuppressedGroupSummary() {
357 when(mPowerManager.isScreenOn()).thenReturn(true);
358 when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
Julia Reynolds24653c32018-03-02 13:16:37 -0500359 when(mNotificationData.shouldSuppressStatusBar(any())).thenReturn(false);
Julia Reynolds30203152017-05-26 13:36:31 -0400360 when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
361 when(mSystemServicesProxy.isDreaming()).thenReturn(false);
362 when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
363
364 Notification n = new Notification.Builder(getContext(), "a")
365 .setGroup("a")
366 .setGroupSummary(true)
367 .setGroupAlertBehavior(Notification.GROUP_ALERT_SUMMARY)
368 .build();
369 StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
370 UserHandle.of(0), null, 0);
371 NotificationData.Entry entry = new NotificationData.Entry(sbn);
372
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900373 assertTrue(mEntryManager.shouldPeek(entry, sbn));
Julia Reynolds30203152017-05-26 13:36:31 -0400374 }
375
376 @Test
377 public void testShouldPeek_suppressedGroupSummary() {
378 when(mPowerManager.isScreenOn()).thenReturn(true);
379 when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
Julia Reynolds24653c32018-03-02 13:16:37 -0500380 when(mNotificationData.shouldSuppressStatusBar(any())).thenReturn(false);
Julia Reynolds30203152017-05-26 13:36:31 -0400381 when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
382 when(mSystemServicesProxy.isDreaming()).thenReturn(false);
383 when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
384
385 Notification n = new Notification.Builder(getContext(), "a")
386 .setGroup("a")
387 .setGroupSummary(true)
388 .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
389 .build();
390 StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
391 UserHandle.of(0), null, 0);
392 NotificationData.Entry entry = new NotificationData.Entry(sbn);
393
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900394 assertFalse(mEntryManager.shouldPeek(entry, sbn));
Julia Reynolds30203152017-05-26 13:36:31 -0400395 }
396
Chris Wren621933f2017-06-14 15:59:03 -0400397 @Test
Julia Reynolds24653c32018-03-02 13:16:37 -0500398 public void testShouldPeek_suppressedPeek() {
Beverly38159ce2017-07-13 16:39:24 -0400399 when(mPowerManager.isScreenOn()).thenReturn(true);
400 when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
401 when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
402 when(mSystemServicesProxy.isDreaming()).thenReturn(false);
403 when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
404
Julia Reynolds24653c32018-03-02 13:16:37 -0500405 when(mNotificationData.shouldSuppressPeek(any())).thenReturn(true);
406
407 Notification n = new Notification.Builder(getContext(), "a").build();
408 StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
409 UserHandle.of(0), null, 0);
410 NotificationData.Entry entry = new NotificationData.Entry(sbn);
411
412 assertFalse(mEntryManager.shouldPeek(entry, sbn));
413 }
414
415 @Test
416 public void testShouldPeek_noSuppressedPeek() {
417 when(mPowerManager.isScreenOn()).thenReturn(true);
418 when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
419 when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
420 when(mSystemServicesProxy.isDreaming()).thenReturn(false);
421 when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
422
423 when(mNotificationData.shouldSuppressPeek(any())).thenReturn(false);
Beverly38159ce2017-07-13 16:39:24 -0400424
425 Notification n = new Notification.Builder(getContext(), "a").build();
426 StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
427 UserHandle.of(0), null, 0);
428 NotificationData.Entry entry = new NotificationData.Entry(sbn);
429
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900430 assertTrue(mEntryManager.shouldPeek(entry, sbn));
Beverly38159ce2017-07-13 16:39:24 -0400431 }
432
433 @Test
Chris Wren621933f2017-06-14 15:59:03 -0400434 public void testLogHidden() {
435 try {
436 mStatusBar.handleVisibleToUserChanged(false);
Selim Cinek1a891a92017-12-04 17:41:27 +0100437 waitForUiOffloadThread();
Chris Wren621933f2017-06-14 15:59:03 -0400438 verify(mBarService, times(1)).onPanelHidden();
439 verify(mBarService, never()).onPanelRevealed(anyBoolean(), anyInt());
440 } catch (RemoteException e) {
441 fail();
442 }
443 }
444
445 @Test
446 public void testPanelOpenForPeek() {
447 when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
448 when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList);
449 when(mNotificationList.size()).thenReturn(5);
450 when(mNotificationPanelView.isFullyCollapsed()).thenReturn(true);
451 mStatusBar.setBarStateForTest(StatusBarState.SHADE);
452
453 try {
454 mStatusBar.handleVisibleToUserChanged(true);
Selim Cinek1a891a92017-12-04 17:41:27 +0100455 waitForUiOffloadThread();
Chris Wren621933f2017-06-14 15:59:03 -0400456 verify(mBarService, never()).onPanelHidden();
457 verify(mBarService, times(1)).onPanelRevealed(false, 1);
458 } catch (RemoteException e) {
459 fail();
460 }
461 TestableLooper.get(this).processAllMessages();
462 }
463
464 @Test
465 public void testPanelOpenAndClear() {
466 when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
467 when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList);
468 when(mNotificationList.size()).thenReturn(5);
469 when(mNotificationPanelView.isFullyCollapsed()).thenReturn(false);
470 mStatusBar.setBarStateForTest(StatusBarState.SHADE);
471
472 try {
473 mStatusBar.handleVisibleToUserChanged(true);
Selim Cinek1a891a92017-12-04 17:41:27 +0100474 waitForUiOffloadThread();
Chris Wren621933f2017-06-14 15:59:03 -0400475 verify(mBarService, never()).onPanelHidden();
476 verify(mBarService, times(1)).onPanelRevealed(true, 5);
477 } catch (RemoteException e) {
478 fail();
479 }
480 TestableLooper.get(this).processAllMessages();
481 }
482
483 @Test
484 public void testPanelOpenAndNoClear() {
485 when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
486 when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList);
487 when(mNotificationList.size()).thenReturn(5);
488 when(mNotificationPanelView.isFullyCollapsed()).thenReturn(false);
489 mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
490
491 try {
492 mStatusBar.handleVisibleToUserChanged(true);
Selim Cinek1a891a92017-12-04 17:41:27 +0100493 waitForUiOffloadThread();
Chris Wren621933f2017-06-14 15:59:03 -0400494 verify(mBarService, never()).onPanelHidden();
495 verify(mBarService, times(1)).onPanelRevealed(false, 5);
496 } catch (RemoteException e) {
497 fail();
498 }
499 TestableLooper.get(this).processAllMessages();
500 }
501
Jason Monk51305372017-06-22 11:41:08 -0400502 @Test
Charles He2eda2422017-09-24 17:55:21 +0100503 public void testDisableExpandStatusBar() {
504 mStatusBar.setBarStateForTest(StatusBarState.SHADE);
505 mStatusBar.setUserSetupForTest(true);
506 when(mStatusBar.isDeviceProvisioned()).thenReturn(true);
507
508 mStatusBar.disable(StatusBarManager.DISABLE_NONE,
509 StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false);
510 verify(mNotificationPanelView).setQsExpansionEnabled(false);
511 mStatusBar.animateExpandNotificationsPanel();
512 verify(mNotificationPanelView, never()).expand(anyBoolean());
513 mStatusBar.animateExpandSettingsPanel(null);
514 verify(mNotificationPanelView, never()).expand(anyBoolean());
515
516 mStatusBar.disable(StatusBarManager.DISABLE_NONE, StatusBarManager.DISABLE2_NONE, false);
517 verify(mNotificationPanelView).setQsExpansionEnabled(true);
518 mStatusBar.animateExpandNotificationsPanel();
519 verify(mNotificationPanelView).expand(anyBoolean());
520 mStatusBar.animateExpandSettingsPanel(null);
521 verify(mNotificationPanelView).expand(anyBoolean());
522 }
523
524 @Test
Jason Monk51305372017-06-22 11:41:08 -0400525 public void testDump_DoesNotCrash() {
526 mStatusBar.dump(null, new PrintWriter(new ByteArrayOutputStream()), null);
527 }
528
Jason Monk9c4faa82017-08-15 09:32:27 -0400529 @Test
530 @RunWithLooper(setAsMainLooper = true)
531 public void testUpdateKeyguardState_DoesNotCrash() {
532 mStatusBar.mStatusBarWindow = mock(StatusBarWindowView.class);
533 mStatusBar.mState = StatusBarState.KEYGUARD;
534 mStatusBar.mDozeScrimController = mock(DozeScrimController.class);
535 mStatusBar.mNotificationIconAreaController = mock(NotificationIconAreaController.class);
Eliot Courtney09322282017-11-09 15:31:19 +0900536 mStatusBar.mLockscreenUserManager = mock(NotificationLockscreenUserManager.class);
537 when(mStatusBar.mLockscreenUserManager.getCurrentProfiles()).thenReturn(
538 new SparseArray<>());
Jason Monk9c4faa82017-08-15 09:32:27 -0400539 mStatusBar.updateKeyguardState(false, false);
540 }
541
Lucas Dupinc2e75462017-12-06 13:59:25 -0800542 @Test
543 public void testFingerprintNotification_UpdatesScrims() {
544 mStatusBar.mStatusBarWindowManager = mock(StatusBarWindowManager.class);
Lucas Dupinc2e75462017-12-06 13:59:25 -0800545 mStatusBar.mDozeScrimController = mock(DozeScrimController.class);
Julia Reynolds24653c32018-03-02 13:16:37 -0500546 mStatusBar.mNotificationIconAreaController = mock(NotificationIconAreaController.class);
Lucas Dupinc2e75462017-12-06 13:59:25 -0800547 mStatusBar.notifyFpAuthModeChanged();
548 verify(mScrimController).transitionTo(any(), any());
549 }
550
Lucas Dupin311eac82017-12-11 14:40:07 -0800551 @Test
552 public void testFingerprintUnlock_UpdatesScrims() {
553 // Simulate unlocking from AoD with fingerprint.
554 when(mFingerprintUnlockController.getMode())
555 .thenReturn(FingerprintUnlockController.MODE_WAKE_AND_UNLOCK);
556 mStatusBar.updateScrimController();
557 verify(mScrimController).transitionTo(eq(ScrimState.UNLOCKED), any());
558 }
559
Lucas Dupind5107302018-03-19 15:30:29 -0700560 @Test
561 public void testSetOccluded_propagatesToScrimController() {
562 mStatusBar.setOccluded(true);
563 verify(mScrimController).setKeyguardOccluded(eq(true));
564
565 reset(mScrimController);
566 mStatusBar.setOccluded(false);
567 verify(mScrimController).setKeyguardOccluded(eq(false));
568 }
569
Julia Reynoldsed1c9af2018-03-21 15:21:09 -0400570 @Test
571 public void testInflateFooterView() {
572 mStatusBar.reevaluateStyles();
573 ArgumentCaptor<FooterView> captor = ArgumentCaptor.forClass(FooterView.class);
574 verify(mStackScroller).setFooterView(captor.capture());
575
576 assertNotNull(captor.getValue().findViewById(R.id.manage_text).hasOnClickListeners());
577 assertNotNull(captor.getValue().findViewById(R.id.dismiss_text).hasOnClickListeners());
578 }
579
580 @Test
581 public void testUpdateFooter_noNotifications() {
582 mStatusBar.setBarStateForTest(StatusBarState.SHADE);
583 assertEquals(0, mEntryManager.getNotificationData().getActiveNotifications().size());
584
585 mStatusBar.updateFooter();
586 verify(mStackScroller).updateFooterView(false, false);
587 }
588
589 @Test
590 public void testUpdateFooter_oneClearableNotification() {
591 mStatusBar.setBarStateForTest(StatusBarState.SHADE);
592 ArrayList<Entry> entries = new ArrayList<>();
593 entries.add(mock(Entry.class));
594 when(mNotificationData.getActiveNotifications()).thenReturn(entries);
595
596 ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
597 when(row.canViewBeDismissed()).thenReturn(true);
598 when(mStackScroller.getChildCount()).thenReturn(1);
599 when(mStackScroller.getChildAt(anyInt())).thenReturn(row);
600
601 mStatusBar.updateFooter();
602 verify(mStackScroller).updateFooterView(true, true);
603 }
604
605 @Test
606 public void testUpdateFooter_oneNonClearableNotification() {
607 mStatusBar.setBarStateForTest(StatusBarState.SHADE);
608 ArrayList<Entry> entries = new ArrayList<>();
609 entries.add(mock(Entry.class));
610 when(mNotificationData.getActiveNotifications()).thenReturn(entries);
611
612 mStatusBar.updateFooter();
613 verify(mStackScroller).updateFooterView(true, false);
614 }
615
616 @Test
617 public void testUpdateFooter_atEnd() {
618 // add footer
619 mStatusBar.reevaluateStyles();
620
621 // add notification
622 ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
623 when(row.isClearable()).thenReturn(true);
624 mStackScroller.addContainerView(row);
625
626 mStatusBar.onUpdateRowStates();
627
628 // move footer to end
629 verify(mStackScroller).changeViewPosition(any(FooterView.class), eq(-1 /* end */));
630 }
631
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500632 static class TestableStatusBar extends StatusBar {
Chris Wren27a52fa2017-02-01 14:21:43 -0500633 public TestableStatusBar(StatusBarKeyguardViewManager man,
634 UnlockMethodCache unlock, KeyguardIndicationController key,
yoshiki iguchi4e30e762018-02-06 12:09:23 +0900635 NotificationStackScrollLayout stack, HeadsUpManagerPhone hum,
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900636 PowerManager pm, NotificationPanelView panelView,
Eliot Courtney3985ad52017-11-17 16:51:52 +0900637 IStatusBarService barService, NotificationListener notificationListener,
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900638 NotificationLogger notificationLogger,
Eliot Courtney2b4c3a02017-11-27 13:27:46 +0900639 VisualStabilityManager visualStabilityManager,
640 NotificationViewHierarchyManager viewHierarchyManager,
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900641 TestableNotificationEntryManager entryManager, ScrimController scrimController,
Selim Cinek7e222c3c2018-01-25 12:22:41 -0800642 FingerprintUnlockController fingerprintUnlockController,
Lucas Dupin47a65c72018-02-15 14:16:18 -0800643 ActivityLaunchAnimator launchAnimator, KeyguardViewMediator keyguardViewMediator) {
Adrian Roosef7a4022017-01-19 14:48:35 -0800644 mStatusBarKeyguardViewManager = man;
Chris Wren27a52fa2017-02-01 14:21:43 -0500645 mUnlockMethodCache = unlock;
646 mKeyguardIndicationController = key;
647 mStackScroller = stack;
Julia Reynolds30203152017-05-26 13:36:31 -0400648 mHeadsUpManager = hum;
Julia Reynolds30203152017-05-26 13:36:31 -0400649 mPowerManager = pm;
Jorim Jaggifd3b1a12017-06-06 17:04:19 -0700650 mNotificationPanel = panelView;
Chris Wren621933f2017-06-14 15:59:03 -0400651 mBarService = barService;
Eliot Courtney3985ad52017-11-17 16:51:52 +0900652 mNotificationListener = notificationListener;
653 mNotificationLogger = notificationLogger;
Adrian Roos6d5ebb72017-08-03 15:10:22 +0200654 mWakefulnessLifecycle = createAwakeWakefulnessLifecycle();
Eliot Courtney2b4c3a02017-11-27 13:27:46 +0900655 mVisualStabilityManager = visualStabilityManager;
656 mViewHierarchyManager = viewHierarchyManager;
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900657 mEntryManager = entryManager;
Lucas Dupinc2e75462017-12-06 13:59:25 -0800658 mScrimController = scrimController;
Lucas Dupin311eac82017-12-11 14:40:07 -0800659 mFingerprintUnlockController = fingerprintUnlockController;
Selim Cinek7e222c3c2018-01-25 12:22:41 -0800660 mActivityLaunchAnimator = launchAnimator;
Lucas Dupin47a65c72018-02-15 14:16:18 -0800661 mKeyguardViewMediator = keyguardViewMediator;
Julia Reynoldsed1c9af2018-03-21 15:21:09 -0400662 mClearAllEnabled = true;
Adrian Roos6d5ebb72017-08-03 15:10:22 +0200663 }
664
665 private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
666 WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
667 wakefulnessLifecycle.dispatchStartedWakingUp();
668 wakefulnessLifecycle.dispatchFinishedWakingUp();
669 return wakefulnessLifecycle;
Adrian Roosef7a4022017-01-19 14:48:35 -0800670 }
671
Jason Monk9c4faa82017-08-15 09:32:27 -0400672 @Override
673 protected void updateTheme() {
674 // Do nothing for now, until we have more mocking and StatusBar is smaller.
675 }
676
Chris Wren621933f2017-06-14 15:59:03 -0400677 public void setBarStateForTest(int state) {
678 mState = state;
Adrian Roosef7a4022017-01-19 14:48:35 -0800679 }
Charles He2eda2422017-09-24 17:55:21 +0100680
681 public void setUserSetupForTest(boolean userSetup) {
682 mUserSetup = userSetup;
683 }
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900684
685 }
686
687 private class TestableNotificationEntryManager extends NotificationEntryManager {
688
Eliot Courtney6c313d32017-12-14 19:57:51 +0900689 public TestableNotificationEntryManager(SystemServicesProxy systemServicesProxy,
690 PowerManager powerManager, Context context) {
691 super(context);
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900692 mSystemServicesProxy = systemServicesProxy;
693 mPowerManager = powerManager;
694 }
695
696 public void setUpForTest(NotificationPresenter presenter,
Eliot Courtney2b4c3a02017-11-27 13:27:46 +0900697 NotificationListContainer listContainer,
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900698 Callback callback,
yoshiki iguchi4e30e762018-02-06 12:09:23 +0900699 HeadsUpManagerPhone headsUpManager,
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900700 NotificationData notificationData) {
Eliot Courtney2b4c3a02017-11-27 13:27:46 +0900701 super.setUpWithPresenter(presenter, listContainer, callback, headsUpManager);
Eliot Courtneya6d8cf22017-10-20 13:26:58 +0900702 mNotificationData = notificationData;
703 mUseHeadsUp = true;
704 }
Adrian Roosef7a4022017-01-19 14:48:35 -0800705 }
Eliot Courtney09322282017-11-09 15:31:19 +0900706}