blob: 99d2b87c7c25af3dd4bc7202c7bda284917b0a63 [file] [log] [blame]
Chris Wren93bb8b82016-03-29 14:35:05 -04001/*
2 * Copyright (C) 2016 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 */
16package com.android.server.notification;
17
Julia Reynoldsa79c3712017-04-21 10:29:57 -040018import static android.app.Notification.GROUP_ALERT_ALL;
19import static android.app.Notification.GROUP_ALERT_CHILDREN;
20import static android.app.Notification.GROUP_ALERT_SUMMARY;
Julia Reynoldsca80d162017-04-23 12:39:32 -040021import static android.app.NotificationManager.IMPORTANCE_HIGH;
Julia Reynolds54369232018-07-03 10:43:35 -040022import static android.app.NotificationManager.IMPORTANCE_LOW;
Julia Reynolds94187562017-10-10 13:58:49 -040023import static android.app.NotificationManager.IMPORTANCE_MIN;
Julia Reynolds54369232018-07-03 10:43:35 -040024import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
Julia Reynoldsca80d162017-04-23 12:39:32 -040025
Julia Reynolds1fac86e2018-03-07 08:30:37 -050026import static junit.framework.Assert.assertFalse;
Julia Reynolds0c299d42016-11-15 14:37:04 -050027import static junit.framework.Assert.assertNull;
28import static junit.framework.Assert.assertTrue;
29
Julia Reynolds76c096d2017-06-19 08:16:04 -040030import static org.mockito.Matchers.any;
Chris Wren93bb8b82016-03-29 14:35:05 -040031import static org.mockito.Matchers.anyBoolean;
32import static org.mockito.Matchers.anyInt;
33import static org.mockito.Matchers.anyObject;
34import static org.mockito.Matchers.anyString;
Michael Wright71216972017-01-31 18:33:54 +000035import static org.mockito.Matchers.argThat;
Chris Wren93bb8b82016-03-29 14:35:05 -040036import static org.mockito.Matchers.eq;
37import static org.mockito.Mockito.never;
Tony Mantlerab55f0f2017-06-16 10:50:00 -070038import static org.mockito.Mockito.spy;
Jean-Michel Triviea0eb5f2017-05-25 18:32:40 -070039import static org.mockito.Mockito.timeout;
Chris Wren93bb8b82016-03-29 14:35:05 -040040import static org.mockito.Mockito.times;
41import static org.mockito.Mockito.verify;
42import static org.mockito.Mockito.when;
43
Tony Mantlerab55f0f2017-06-16 10:50:00 -070044import android.app.ActivityManager;
45import android.app.Notification;
46import android.app.Notification.Builder;
47import android.app.NotificationChannel;
48import android.app.NotificationManager;
49import android.content.Context;
50import android.content.pm.PackageManager;
51import android.graphics.Color;
52import android.media.AudioAttributes;
53import android.media.AudioManager;
54import android.net.Uri;
55import android.os.Handler;
56import android.os.RemoteException;
57import android.os.UserHandle;
58import android.os.VibrationEffect;
59import android.os.Vibrator;
60import android.provider.Settings;
61import android.service.notification.StatusBarNotification;
62import android.support.test.runner.AndroidJUnit4;
63import android.test.suitebuilder.annotation.SmallTest;
Julia Reynolds94187562017-10-10 13:58:49 -040064import android.view.accessibility.AccessibilityEvent;
65import android.view.accessibility.AccessibilityManager;
66import android.view.accessibility.IAccessibilityManager;
67import android.view.accessibility.IAccessibilityManagerClient;
Tony Mantlerab55f0f2017-06-16 10:50:00 -070068
Julia Reynolds94187562017-10-10 13:58:49 -040069import com.android.internal.util.IntPair;
Jason Monk74f5e362017-12-06 08:56:33 -050070import com.android.server.UiServiceTestCase;
Tony Mantlerab55f0f2017-06-16 10:50:00 -070071import com.android.server.lights.Light;
72
73import org.junit.Before;
74import org.junit.Test;
75import org.junit.runner.RunWith;
76import org.mockito.ArgumentMatcher;
77import org.mockito.Mock;
78import org.mockito.Mockito;
79import org.mockito.MockitoAnnotations;
80
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -040081@SmallTest
82@RunWith(AndroidJUnit4.class)
Jason Monk74f5e362017-12-06 08:56:33 -050083public class BuzzBeepBlinkTest extends UiServiceTestCase {
Chris Wren93bb8b82016-03-29 14:35:05 -040084
85 @Mock AudioManager mAudioManager;
86 @Mock Vibrator mVibrator;
87 @Mock android.media.IRingtonePlayer mRingtonePlayer;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -040088 @Mock Light mLight;
Julia Reynoldseb3dca72017-07-11 10:39:58 -040089 @Mock
90 NotificationManagerService.WorkerHandler mHandler;
Julia Reynolds76c096d2017-06-19 08:16:04 -040091 @Mock
92 NotificationUsageStats mUsageStats;
Julia Reynolds94187562017-10-10 13:58:49 -040093 @Mock
94 IAccessibilityManager mAccessibilityService;
Chris Wren93bb8b82016-03-29 14:35:05 -040095
96 private NotificationManagerService mService;
97 private String mPkg = "com.android.server.notification";
98 private int mId = 1001;
99 private int mOtherId = 1002;
100 private String mTag = null;
101 private int mUid = 1000;
102 private int mPid = 2000;
Chris Wren93bb8b82016-03-29 14:35:05 -0400103 private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
104
Michael Wright71216972017-01-31 18:33:54 +0000105 private VibrateRepeatMatcher mVibrateOnceMatcher = new VibrateRepeatMatcher(-1);
106 private VibrateRepeatMatcher mVibrateLoopMatcher = new VibrateRepeatMatcher(0);
107
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400108 private static final long[] CUSTOM_VIBRATION = new long[] {
109 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
110 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
111 300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 };
112 private static final Uri CUSTOM_SOUND = Settings.System.DEFAULT_ALARM_ALERT_URI;
Julia Reynolds619a69f2017-01-27 15:11:38 -0500113 private static final AudioAttributes CUSTOM_ATTRIBUTES = new AudioAttributes.Builder()
114 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
115 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
116 .build();
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400117 private static final int CUSTOM_LIGHT_COLOR = Color.BLACK;
118 private static final int CUSTOM_LIGHT_ON = 10000;
119 private static final int CUSTOM_LIGHT_OFF = 10000;
Michael Wright71216972017-01-31 18:33:54 +0000120 private static final long[] FALLBACK_VIBRATION_PATTERN = new long[] {100, 100, 100};
121 private static final VibrationEffect FALLBACK_VIBRATION =
122 VibrationEffect.createWaveform(FALLBACK_VIBRATION_PATTERN, -1);
Jean-Michel Triviea0eb5f2017-05-25 18:32:40 -0700123 private static final int MAX_VIBRATION_DELAY = 1000;
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400124
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400125 @Before
Julia Reynolds94187562017-10-10 13:58:49 -0400126 public void setUp() throws Exception {
Chris Wren93bb8b82016-03-29 14:35:05 -0400127 MockitoAnnotations.initMocks(this);
128
129 when(mAudioManager.isAudioFocusExclusive()).thenReturn(false);
130 when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer);
131 when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
132 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
Julia Reynolds76c096d2017-06-19 08:16:04 -0400133 when(mUsageStats.isAlertRateLimited(any())).thenReturn(false);
134
Julia Reynolds94187562017-10-10 13:58:49 -0400135 long serviceReturnValue = IntPair.of(
136 AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
137 AccessibilityEvent.TYPES_ALL_MASK);
138 when(mAccessibilityService.addClient(any(), anyInt())).thenReturn(serviceReturnValue);
139 AccessibilityManager accessibilityManager =
140 new AccessibilityManager(Handler.getMain(), mAccessibilityService, 0);
141 verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt());
142 assertTrue(accessibilityManager.isEnabled());
143
144 mService = spy(new NotificationManagerService(getContext()));
Chris Wren93bb8b82016-03-29 14:35:05 -0400145 mService.setAudioManager(mAudioManager);
146 mService.setVibrator(mVibrator);
147 mService.setSystemReady(true);
148 mService.setHandler(mHandler);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400149 mService.setLights(mLight);
150 mService.setScreenOn(false);
Michael Wright71216972017-01-31 18:33:54 +0000151 mService.setFallbackVibrationPattern(FALLBACK_VIBRATION_PATTERN);
Julia Reynolds76c096d2017-06-19 08:16:04 -0400152 mService.setUsageStats(mUsageStats);
Julia Reynolds94187562017-10-10 13:58:49 -0400153 mService.setAccessibilityManager(accessibilityManager);
Julia Reynolds54369232018-07-03 10:43:35 -0400154 mService.mScreenOn = false;
155 mService.mInCall = false;
156 mService.mNotificationPulseEnabled = true;
Chris Wren93bb8b82016-03-29 14:35:05 -0400157 }
158
159 //
160 // Convenience functions for creating notification records
161 //
162
163 private NotificationRecord getNoisyOtherNotification() {
164 return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400165 true /* noisy */, true /* buzzy*/, false /* lights */);
Chris Wren93bb8b82016-03-29 14:35:05 -0400166 }
167
168 private NotificationRecord getBeepyNotification() {
169 return getNotificationRecord(mId, false /* insistent */, false /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400170 true /* noisy */, false /* buzzy*/, false /* lights */);
Chris Wren93bb8b82016-03-29 14:35:05 -0400171 }
172
173 private NotificationRecord getBeepyOnceNotification() {
174 return getNotificationRecord(mId, false /* insistent */, true /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400175 true /* noisy */, false /* buzzy*/, false /* lights */);
Chris Wren93bb8b82016-03-29 14:35:05 -0400176 }
177
178 private NotificationRecord getQuietNotification() {
179 return getNotificationRecord(mId, false /* insistent */, false /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400180 false /* noisy */, false /* buzzy*/, false /* lights */);
Chris Wren93bb8b82016-03-29 14:35:05 -0400181 }
182
183 private NotificationRecord getQuietOtherNotification() {
184 return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400185 false /* noisy */, false /* buzzy*/, false /* lights */);
Chris Wren93bb8b82016-03-29 14:35:05 -0400186 }
187
188 private NotificationRecord getQuietOnceNotification() {
189 return getNotificationRecord(mId, false /* insistent */, true /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400190 false /* noisy */, false /* buzzy*/, false /* lights */);
Chris Wren93bb8b82016-03-29 14:35:05 -0400191 }
192
193 private NotificationRecord getInsistentBeepyNotification() {
194 return getNotificationRecord(mId, true /* insistent */, false /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400195 true /* noisy */, false /* buzzy*/, false /* lights */);
Chris Wren93bb8b82016-03-29 14:35:05 -0400196 }
197
Tony Mantlerab55f0f2017-06-16 10:50:00 -0700198 private NotificationRecord getInsistentBeepyLeanbackNotification() {
199 return getLeanbackNotificationRecord(mId, true /* insistent */, false /* once */,
200 true /* noisy */, false /* buzzy*/, false /* lights */);
201 }
202
Chris Wren93bb8b82016-03-29 14:35:05 -0400203 private NotificationRecord getBuzzyNotification() {
204 return getNotificationRecord(mId, false /* insistent */, false /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400205 false /* noisy */, true /* buzzy*/, false /* lights */);
Chris Wren93bb8b82016-03-29 14:35:05 -0400206 }
207
208 private NotificationRecord getBuzzyOnceNotification() {
209 return getNotificationRecord(mId, false /* insistent */, true /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400210 false /* noisy */, true /* buzzy*/, false /* lights */);
Chris Wren93bb8b82016-03-29 14:35:05 -0400211 }
212
213 private NotificationRecord getInsistentBuzzyNotification() {
214 return getNotificationRecord(mId, true /* insistent */, false /* once */,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400215 false /* noisy */, true /* buzzy*/, false /* lights */);
216 }
217
Julia Reynolds0c299d42016-11-15 14:37:04 -0500218 private NotificationRecord getBuzzyBeepyNotification() {
219 return getNotificationRecord(mId, false /* insistent */, false /* once */,
220 true /* noisy */, true /* buzzy*/, false /* lights */);
221 }
222
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400223 private NotificationRecord getLightsNotification() {
Julia Reynolds54369232018-07-03 10:43:35 -0400224 return getNotificationRecord(mId, false /* insistent */, false /* once */,
225 false /* noisy */, false /* buzzy*/, true /* lights */);
226 }
227
228 private NotificationRecord getLightsOnceNotification() {
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400229 return getNotificationRecord(mId, false /* insistent */, true /* once */,
Julia Reynolds54369232018-07-03 10:43:35 -0400230 false /* noisy */, false /* buzzy*/, true /* lights */);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400231 }
232
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400233 private NotificationRecord getCustomLightsNotification() {
234 return getNotificationRecord(mId, false /* insistent */, true /* once */,
235 false /* noisy */, true /* buzzy*/, true /* lights */,
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400236 true /* defaultVibration */, true /* defaultSound */, false /* defaultLights */,
Tony Mantlerab55f0f2017-06-16 10:50:00 -0700237 null, Notification.GROUP_ALERT_ALL, false);
Chris Wren93bb8b82016-03-29 14:35:05 -0400238 }
239
240 private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once,
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400241 boolean noisy, boolean buzzy, boolean lights) {
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400242 return getNotificationRecord(id, insistent, once, noisy, buzzy, lights, true, true, true,
Tony Mantlerab55f0f2017-06-16 10:50:00 -0700243 null, Notification.GROUP_ALERT_ALL, false);
244 }
245
246 private NotificationRecord getLeanbackNotificationRecord(int id, boolean insistent, boolean once,
247 boolean noisy, boolean buzzy, boolean lights) {
248 return getNotificationRecord(id, insistent, once, noisy, buzzy, lights, true, true, true,
249 null, Notification.GROUP_ALERT_ALL, true);
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400250 }
251
252 private NotificationRecord getBeepyNotificationRecord(String groupKey, int groupAlertBehavior) {
253 return getNotificationRecord(mId, false, false, true, false, false, true, true, true,
Tony Mantlerab55f0f2017-06-16 10:50:00 -0700254 groupKey, groupAlertBehavior, false);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400255 }
256
Julia Reynolds54369232018-07-03 10:43:35 -0400257 private NotificationRecord getLightsNotificationRecord(String groupKey,
258 int groupAlertBehavior) {
259 return getNotificationRecord(mId, false, false, false, false, true /*lights*/, true, true,
260 true, groupKey, groupAlertBehavior, false);
261 }
262
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400263 private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once,
264 boolean noisy, boolean buzzy, boolean lights, boolean defaultVibration,
Tony Mantlerab55f0f2017-06-16 10:50:00 -0700265 boolean defaultSound, boolean defaultLights, String groupKey, int groupAlertBehavior,
266 boolean isLeanback) {
Julia Reynolds0c299d42016-11-15 14:37:04 -0500267 NotificationChannel channel =
Julia Reynoldsca80d162017-04-23 12:39:32 -0400268 new NotificationChannel("test", "test", IMPORTANCE_HIGH);
Chris Wren93bb8b82016-03-29 14:35:05 -0400269 final Builder builder = new Builder(getContext())
270 .setContentTitle("foo")
271 .setSmallIcon(android.R.drawable.sym_def_app_icon)
272 .setPriority(Notification.PRIORITY_HIGH)
273 .setOnlyAlertOnce(once);
274
275 int defaults = 0;
276 if (noisy) {
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400277 if (defaultSound) {
278 defaults |= Notification.DEFAULT_SOUND;
Julia Reynolds619a69f2017-01-27 15:11:38 -0500279 channel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI,
280 Notification.AUDIO_ATTRIBUTES_DEFAULT);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400281 } else {
282 builder.setSound(CUSTOM_SOUND);
Julia Reynolds619a69f2017-01-27 15:11:38 -0500283 channel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400284 }
Julia Reynolds184b86d2017-04-12 13:27:58 -0400285 } else {
286 channel.setSound(null, null);
Chris Wren93bb8b82016-03-29 14:35:05 -0400287 }
288 if (buzzy) {
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400289 if (defaultVibration) {
290 defaults |= Notification.DEFAULT_VIBRATE;
291 } else {
292 builder.setVibrate(CUSTOM_VIBRATION);
Julia Reynoldsf57de462016-11-23 11:31:46 -0500293 channel.setVibrationPattern(CUSTOM_VIBRATION);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400294 }
Julia Reynoldsf57de462016-11-23 11:31:46 -0500295 channel.enableVibration(true);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400296 }
297 if (lights) {
298 if (defaultLights) {
299 defaults |= Notification.DEFAULT_LIGHTS;
300 } else {
301 builder.setLights(CUSTOM_LIGHT_COLOR, CUSTOM_LIGHT_ON, CUSTOM_LIGHT_OFF);
302 }
Julia Reynolds529e3322017-02-06 08:33:01 -0500303 channel.enableLights(true);
Chris Wren93bb8b82016-03-29 14:35:05 -0400304 }
305 builder.setDefaults(defaults);
306
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400307 builder.setGroup(groupKey);
308 builder.setGroupAlertBehavior(groupAlertBehavior);
309
Chris Wren93bb8b82016-03-29 14:35:05 -0400310 Notification n = builder.build();
311 if (insistent) {
312 n.flags |= Notification.FLAG_INSISTENT;
313 }
Julia Reynolds0c299d42016-11-15 14:37:04 -0500314
Tony Mantlerab55f0f2017-06-16 10:50:00 -0700315 Context context = spy(getContext());
316 PackageManager packageManager = spy(context.getPackageManager());
317 when(context.getPackageManager()).thenReturn(packageManager);
318 when(packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
319 .thenReturn(isLeanback);
320
Julia Reynolds924eed12017-01-19 09:52:07 -0500321 StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid,
Julia Reynolds423b9fc2016-11-09 09:51:08 -0500322 mPid, n, mUser, null, System.currentTimeMillis());
Tony Mantlerab55f0f2017-06-16 10:50:00 -0700323 NotificationRecord r = new NotificationRecord(context, sbn, channel);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400324 mService.addNotification(r);
325 return r;
Chris Wren93bb8b82016-03-29 14:35:05 -0400326 }
327
328 //
329 // Convenience functions for interacting with mocks
330 //
331
332 private void verifyNeverBeep() throws RemoteException {
333 verify(mRingtonePlayer, never()).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
334 anyBoolean(), (AudioAttributes) anyObject());
335 }
336
337 private void verifyBeep() throws RemoteException {
338 verify(mRingtonePlayer, times(1)).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
339 eq(true), (AudioAttributes) anyObject());
340 }
341
342 private void verifyBeepLooped() throws RemoteException {
343 verify(mRingtonePlayer, times(1)).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
344 eq(false), (AudioAttributes) anyObject());
345 }
346
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400347 private void verifyCustomBeep() throws RemoteException {
348 verify(mRingtonePlayer, times(1)).playAsync(eq(CUSTOM_SOUND), (UserHandle) anyObject(),
349 eq(false), (AudioAttributes) anyObject());
350 }
351
Chris Wren93bb8b82016-03-29 14:35:05 -0400352 private void verifyNeverStopAudio() throws RemoteException {
353 verify(mRingtonePlayer, never()).stopAsync();
354 }
355
356 private void verifyStopAudio() throws RemoteException {
357 verify(mRingtonePlayer, times(1)).stopAsync();
358 }
359
360 private void verifyNeverVibrate() {
Michael Wright71216972017-01-31 18:33:54 +0000361 verify(mVibrator, never()).vibrate(anyInt(), anyString(), (VibrationEffect) anyObject(),
362 (AudioAttributes) anyObject());
Chris Wren93bb8b82016-03-29 14:35:05 -0400363 }
364
365 private void verifyVibrate() {
Michael Wright71216972017-01-31 18:33:54 +0000366 verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), argThat(mVibrateOnceMatcher),
367 (AudioAttributes) anyObject());
Chris Wren93bb8b82016-03-29 14:35:05 -0400368 }
369
370 private void verifyVibrateLooped() {
Michael Wright71216972017-01-31 18:33:54 +0000371 verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), argThat(mVibrateLoopMatcher),
372 (AudioAttributes) anyObject());
Chris Wren93bb8b82016-03-29 14:35:05 -0400373 }
374
Jean-Michel Triviea0eb5f2017-05-25 18:32:40 -0700375 private void verifyDelayedVibrateLooped() {
376 verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(),
377 argThat(mVibrateLoopMatcher), (AudioAttributes) anyObject());
378 }
379
Chris Wren93bb8b82016-03-29 14:35:05 -0400380 private void verifyStopVibrate() {
381 verify(mVibrator, times(1)).cancel();
382 }
383
384 private void verifyNeverStopVibrate() throws RemoteException {
385 verify(mVibrator, never()).cancel();
386 }
387
Julia Reynolds54369232018-07-03 10:43:35 -0400388 private void verifyNeverLights() {
389 verify(mLight, never()).setFlashing(anyInt(), anyInt(), anyInt(), anyInt());
390 }
391
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400392 private void verifyLights() {
Julia Reynolds033a4122017-01-31 16:50:38 -0500393 verify(mLight, times(1)).setFlashing(anyInt(), anyInt(), anyInt(), anyInt());
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400394 }
395
396 private void verifyCustomLights() {
Julia Reynolds033a4122017-01-31 16:50:38 -0500397 verify(mLight, times(1)).setFlashing(
398 eq(CUSTOM_LIGHT_COLOR), anyInt(), eq(CUSTOM_LIGHT_ON), eq(CUSTOM_LIGHT_OFF));
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400399 }
400
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400401 //
402 // Tests
403 //
404
405 @Test
406 public void testLights() throws Exception {
407 NotificationRecord r = getLightsNotification();
408 r.setImportance(NotificationManager.IMPORTANCE_DEFAULT, "for testing");
409
410 mService.buzzBeepBlinkLocked(r);
411
412 verifyLights();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500413 assertTrue(r.isInterruptive());
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400414 }
415
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400416 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400417 public void testBeep() throws Exception {
418 NotificationRecord r = getBeepyNotification();
419
420 mService.buzzBeepBlinkLocked(r);
421
422 verifyBeepLooped();
423 verifyNeverVibrate();
Julia Reynolds94187562017-10-10 13:58:49 -0400424 verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500425 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400426 }
427
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400428 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400429 public void testBeepInsistently() throws Exception {
430 NotificationRecord r = getInsistentBeepyNotification();
431
432 mService.buzzBeepBlinkLocked(r);
433
434 verifyBeep();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500435 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400436 }
437
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400438 @Test
Tony Mantlerab55f0f2017-06-16 10:50:00 -0700439 public void testNoLeanbackBeep() throws Exception {
440 NotificationRecord r = getInsistentBeepyLeanbackNotification();
441
442 mService.buzzBeepBlinkLocked(r);
443
444 verifyNeverBeep();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500445 assertFalse(r.isInterruptive());
Tony Mantlerab55f0f2017-06-16 10:50:00 -0700446 }
447
448 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400449 public void testNoInterruptionForMin() throws Exception {
450 NotificationRecord r = getBeepyNotification();
Julia Reynolds85769912016-10-25 09:08:57 -0400451 r.setImportance(NotificationManager.IMPORTANCE_MIN, "foo");
Chris Wren93bb8b82016-03-29 14:35:05 -0400452
453 mService.buzzBeepBlinkLocked(r);
454
455 verifyNeverBeep();
456 verifyNeverVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500457 assertFalse(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400458 }
459
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400460 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400461 public void testNoInterruptionForIntercepted() throws Exception {
462 NotificationRecord r = getBeepyNotification();
463 r.setIntercepted(true);
464
465 mService.buzzBeepBlinkLocked(r);
466
467 verifyNeverBeep();
468 verifyNeverVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500469 assertFalse(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400470 }
471
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400472 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400473 public void testBeepTwice() throws Exception {
474 NotificationRecord r = getBeepyNotification();
475
476 // set up internal state
477 mService.buzzBeepBlinkLocked(r);
478 Mockito.reset(mRingtonePlayer);
479
480 // update should beep
481 r.isUpdate = true;
482 mService.buzzBeepBlinkLocked(r);
483 verifyBeepLooped();
Julia Reynolds94187562017-10-10 13:58:49 -0400484 verify(mAccessibilityService, times(2)).sendAccessibilityEvent(any(), anyInt());
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500485 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400486 }
487
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400488 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400489 public void testHonorAlertOnlyOnceForBeep() throws Exception {
490 NotificationRecord r = getBeepyNotification();
491 NotificationRecord s = getBeepyOnceNotification();
492 s.isUpdate = true;
493
494 // set up internal state
495 mService.buzzBeepBlinkLocked(r);
496 Mockito.reset(mRingtonePlayer);
497
498 // update should not beep
499 mService.buzzBeepBlinkLocked(s);
500 verifyNeverBeep();
Julia Reynolds94187562017-10-10 13:58:49 -0400501 verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
Chris Wren93bb8b82016-03-29 14:35:05 -0400502 }
503
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400504 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400505 public void testNoisyUpdateDoesNotCancelAudio() throws Exception {
506 NotificationRecord r = getBeepyNotification();
507
508 mService.buzzBeepBlinkLocked(r);
509 r.isUpdate = true;
510 mService.buzzBeepBlinkLocked(r);
511
512 verifyNeverStopAudio();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500513 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400514 }
515
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400516 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400517 public void testNoisyOnceUpdateDoesNotCancelAudio() throws Exception {
518 NotificationRecord r = getBeepyNotification();
519 NotificationRecord s = getBeepyOnceNotification();
520 s.isUpdate = true;
521
522 mService.buzzBeepBlinkLocked(r);
523 mService.buzzBeepBlinkLocked(s);
524
525 verifyNeverStopAudio();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500526 assertTrue(r.isInterruptive());
527 assertFalse(s.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400528 }
529
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400530 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400531 public void testQuietUpdateDoesNotCancelAudioFromOther() throws Exception {
532 NotificationRecord r = getBeepyNotification();
533 NotificationRecord s = getQuietNotification();
534 s.isUpdate = true;
535 NotificationRecord other = getNoisyOtherNotification();
536
537 // set up internal state
538 mService.buzzBeepBlinkLocked(r);
539 mService.buzzBeepBlinkLocked(other); // this takes the audio stream
540 Mockito.reset(mRingtonePlayer);
541
542 // should not stop noise, since we no longer own it
543 mService.buzzBeepBlinkLocked(s); // this no longer owns the stream
544 verifyNeverStopAudio();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500545 assertTrue(other.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400546 }
547
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400548 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400549 public void testQuietInterloperDoesNotCancelAudio() throws Exception {
550 NotificationRecord r = getBeepyNotification();
551 NotificationRecord other = getQuietOtherNotification();
552
553 // set up internal state
554 mService.buzzBeepBlinkLocked(r);
555 Mockito.reset(mRingtonePlayer);
556
557 // should not stop noise, since it does not own it
558 mService.buzzBeepBlinkLocked(other);
559 verifyNeverStopAudio();
560 }
561
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400562 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400563 public void testQuietUpdateCancelsAudio() throws Exception {
564 NotificationRecord r = getBeepyNotification();
565 NotificationRecord s = getQuietNotification();
566 s.isUpdate = true;
567
568 // set up internal state
569 mService.buzzBeepBlinkLocked(r);
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500570 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400571 Mockito.reset(mRingtonePlayer);
572
573 // quiet update should stop making noise
574 mService.buzzBeepBlinkLocked(s);
575 verifyStopAudio();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500576 assertFalse(s.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400577 }
578
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400579 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400580 public void testQuietOnceUpdateCancelsAudio() throws Exception {
581 NotificationRecord r = getBeepyNotification();
582 NotificationRecord s = getQuietOnceNotification();
583 s.isUpdate = true;
584
585 // set up internal state
586 mService.buzzBeepBlinkLocked(r);
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500587 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400588 Mockito.reset(mRingtonePlayer);
589
590 // stop making noise - this is a weird corner case, but quiet should override once
591 mService.buzzBeepBlinkLocked(s);
592 verifyStopAudio();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500593 assertFalse(s.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400594 }
595
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400596 @Test
Beverly5d463b62017-07-26 14:13:40 -0400597 public void testInCallNotification() throws Exception {
598 NotificationRecord r = getBeepyNotification();
599
600 // set up internal state
601 mService.buzzBeepBlinkLocked(r);
602 Mockito.reset(mRingtonePlayer);
603
604 mService.mInCall = true;
605 mService.buzzBeepBlinkLocked(r);
606
Julia Reynolds94187562017-10-10 13:58:49 -0400607 verify(mService, times(1)).playInCallNotification();
Beverly5d463b62017-07-26 14:13:40 -0400608 verifyNeverBeep(); // doesn't play normal beep
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500609 assertTrue(r.isInterruptive());
Beverly5d463b62017-07-26 14:13:40 -0400610 }
611
612 @Test
Julia Reynolds0c299d42016-11-15 14:37:04 -0500613 public void testNoDemoteSoundToVibrateIfVibrateGiven() throws Exception {
614 NotificationRecord r = getBuzzyBeepyNotification();
615 assertTrue(r.getSound() != null);
Chris Wren93bb8b82016-03-29 14:35:05 -0400616
617 // the phone is quiet
Chris Wren93bb8b82016-03-29 14:35:05 -0400618 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
Julia Reynolds85896572017-09-20 12:54:52 -0400619 when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
Chris Wren93bb8b82016-03-29 14:35:05 -0400620
621 mService.buzzBeepBlinkLocked(r);
622
Michael Wright71216972017-01-31 18:33:54 +0000623 VibrationEffect effect = VibrationEffect.createWaveform(r.getVibration(), -1);
624
Jean-Michel Triviea0eb5f2017-05-25 18:32:40 -0700625 verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(),
626 eq(effect), (AudioAttributes) anyObject());
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500627 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400628 }
629
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400630 @Test
Julia Reynolds85896572017-09-20 12:54:52 -0400631 public void testNoDemoteSoundToVibrateIfNonNotificationStream() throws Exception {
632 NotificationRecord r = getBeepyNotification();
633 assertTrue(r.getSound() != null);
634 assertNull(r.getVibration());
635
636 // the phone is quiet
637 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
638 when(mAudioManager.getStreamVolume(anyInt())).thenReturn(1);
639
640 mService.buzzBeepBlinkLocked(r);
641
642 verifyNeverVibrate();
643 verifyBeepLooped();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500644 assertTrue(r.isInterruptive());
Julia Reynolds85896572017-09-20 12:54:52 -0400645 }
646
647 @Test
Julia Reynolds0c299d42016-11-15 14:37:04 -0500648 public void testDemoteSoundToVibrate() throws Exception {
649 NotificationRecord r = getBeepyNotification();
650 assertTrue(r.getSound() != null);
651 assertNull(r.getVibration());
652
653 // the phone is quiet
654 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
Julia Reynolds85896572017-09-20 12:54:52 -0400655 when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
Julia Reynolds0c299d42016-11-15 14:37:04 -0500656
657 mService.buzzBeepBlinkLocked(r);
658
Jean-Michel Triviea0eb5f2017-05-25 18:32:40 -0700659 verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(),
660 eq(FALLBACK_VIBRATION), (AudioAttributes) anyObject());
Julia Reynolds619a69f2017-01-27 15:11:38 -0500661 verify(mRingtonePlayer, never()).playAsync
662 (anyObject(), anyObject(), anyBoolean(), anyObject());
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500663 assertTrue(r.isInterruptive());
Julia Reynolds0c299d42016-11-15 14:37:04 -0500664 }
665
666 @Test
667 public void testDemoteInsistentSoundToVibrate() throws Exception {
Chris Wren93bb8b82016-03-29 14:35:05 -0400668 NotificationRecord r = getInsistentBeepyNotification();
Julia Reynolds0c299d42016-11-15 14:37:04 -0500669 assertTrue(r.getSound() != null);
670 assertNull(r.getVibration());
Chris Wren93bb8b82016-03-29 14:35:05 -0400671
672 // the phone is quiet
673 when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
674 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
675
676 mService.buzzBeepBlinkLocked(r);
677
Jean-Michel Triviea0eb5f2017-05-25 18:32:40 -0700678 verifyDelayedVibrateLooped();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500679 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400680 }
681
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400682 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400683 public void testVibrate() throws Exception {
684 NotificationRecord r = getBuzzyNotification();
685
686 mService.buzzBeepBlinkLocked(r);
687
688 verifyNeverBeep();
689 verifyVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500690 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400691 }
692
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400693 @Test
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500694 public void testInsistentVibrate() {
Chris Wren93bb8b82016-03-29 14:35:05 -0400695 NotificationRecord r = getInsistentBuzzyNotification();
696
697 mService.buzzBeepBlinkLocked(r);
698 verifyVibrateLooped();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500699 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400700 }
701
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400702 @Test
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500703 public void testVibrateTwice() {
Chris Wren93bb8b82016-03-29 14:35:05 -0400704 NotificationRecord r = getBuzzyNotification();
705
706 // set up internal state
707 mService.buzzBeepBlinkLocked(r);
708 Mockito.reset(mVibrator);
709
710 // update should vibrate
711 r.isUpdate = true;
712 mService.buzzBeepBlinkLocked(r);
713 verifyVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500714 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400715 }
716
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400717 @Test
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400718 public void testGroupAlertSummarySilenceChild() throws Exception {
719 NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
720
721 mService.buzzBeepBlinkLocked(child);
722
723 verifyNeverBeep();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500724 assertFalse(child.isInterruptive());
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400725 }
726
727 @Test
728 public void testGroupAlertSummaryNoSilenceSummary() throws Exception {
729 NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
730 summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
731
732 mService.buzzBeepBlinkLocked(summary);
733
734 verifyBeepLooped();
Julia Reynolds54369232018-07-03 10:43:35 -0400735 // summaries are never interruptive for notification counts
736 assertFalse(summary.isInterruptive());
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400737 }
738
739 @Test
740 public void testGroupAlertSummaryNoSilenceNonGroupChild() throws Exception {
741 NotificationRecord nonGroup = getBeepyNotificationRecord(null, GROUP_ALERT_SUMMARY);
742
743 mService.buzzBeepBlinkLocked(nonGroup);
744
745 verifyBeepLooped();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500746 assertTrue(nonGroup.isInterruptive());
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400747 }
748
749 @Test
750 public void testGroupAlertChildSilenceSummary() throws Exception {
751 NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
752 summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
753
754 mService.buzzBeepBlinkLocked(summary);
755
756 verifyNeverBeep();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500757 assertFalse(summary.isInterruptive());
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400758 }
759
760 @Test
761 public void testGroupAlertChildNoSilenceChild() throws Exception {
762 NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
763
764 mService.buzzBeepBlinkLocked(child);
765
766 verifyBeepLooped();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500767 assertTrue(child.isInterruptive());
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400768 }
769
770 @Test
771 public void testGroupAlertChildNoSilenceNonGroupSummary() throws Exception {
772 NotificationRecord nonGroup = getBeepyNotificationRecord(null, GROUP_ALERT_CHILDREN);
773
774 mService.buzzBeepBlinkLocked(nonGroup);
775
776 verifyBeepLooped();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500777 assertTrue(nonGroup.isInterruptive());
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400778 }
779
780 @Test
781 public void testGroupAlertAllNoSilenceGroup() throws Exception {
782 NotificationRecord group = getBeepyNotificationRecord("a", GROUP_ALERT_ALL);
783
784 mService.buzzBeepBlinkLocked(group);
785
786 verifyBeepLooped();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500787 assertTrue(group.isInterruptive());
Julia Reynoldsa79c3712017-04-21 10:29:57 -0400788 }
789
790 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400791 public void testHonorAlertOnlyOnceForBuzz() throws Exception {
792 NotificationRecord r = getBuzzyNotification();
793 NotificationRecord s = getBuzzyOnceNotification();
794 s.isUpdate = true;
795
796 // set up internal state
797 mService.buzzBeepBlinkLocked(r);
798 Mockito.reset(mVibrator);
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500799 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400800
801 // update should not beep
802 mService.buzzBeepBlinkLocked(s);
803 verifyNeverVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500804 assertFalse(s.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400805 }
806
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400807 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400808 public void testNoisyUpdateDoesNotCancelVibrate() throws Exception {
809 NotificationRecord r = getBuzzyNotification();
810
811 mService.buzzBeepBlinkLocked(r);
812 r.isUpdate = true;
813 mService.buzzBeepBlinkLocked(r);
814
815 verifyNeverStopVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500816 assertTrue(r.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400817 }
818
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400819 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400820 public void testNoisyOnceUpdateDoesNotCancelVibrate() throws Exception {
821 NotificationRecord r = getBuzzyNotification();
822 NotificationRecord s = getBuzzyOnceNotification();
823 s.isUpdate = true;
824
825 mService.buzzBeepBlinkLocked(r);
826 mService.buzzBeepBlinkLocked(s);
827
828 verifyNeverStopVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500829 assertTrue(r.isInterruptive());
830 assertFalse(s.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400831 }
832
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400833 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400834 public void testQuietUpdateDoesNotCancelVibrateFromOther() throws Exception {
835 NotificationRecord r = getBuzzyNotification();
836 NotificationRecord s = getQuietNotification();
837 s.isUpdate = true;
838 NotificationRecord other = getNoisyOtherNotification();
839
840 // set up internal state
841 mService.buzzBeepBlinkLocked(r);
842 mService.buzzBeepBlinkLocked(other); // this takes the vibrate stream
843 Mockito.reset(mVibrator);
844
845 // should not stop vibrate, since we no longer own it
846 mService.buzzBeepBlinkLocked(s); // this no longer owns the stream
847 verifyNeverStopVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500848 assertTrue(r.isInterruptive());
849 assertTrue(other.isInterruptive());
850 assertFalse(s.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400851 }
852
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400853 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400854 public void testQuietInterloperDoesNotCancelVibrate() throws Exception {
855 NotificationRecord r = getBuzzyNotification();
856 NotificationRecord other = getQuietOtherNotification();
857
858 // set up internal state
859 mService.buzzBeepBlinkLocked(r);
860 Mockito.reset(mVibrator);
861
862 // should not stop noise, since it does not own it
863 mService.buzzBeepBlinkLocked(other);
864 verifyNeverStopVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500865 assertFalse(other.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400866 }
867
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400868 @Test
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500869 public void testQuietUpdateCancelsVibrate() {
Chris Wren93bb8b82016-03-29 14:35:05 -0400870 NotificationRecord r = getBuzzyNotification();
871 NotificationRecord s = getQuietNotification();
872 s.isUpdate = true;
873
874 // set up internal state
875 mService.buzzBeepBlinkLocked(r);
Julia Reynolds0c299d42016-11-15 14:37:04 -0500876 verifyVibrate();
Chris Wren93bb8b82016-03-29 14:35:05 -0400877
878 // quiet update should stop making noise
879 mService.buzzBeepBlinkLocked(s);
880 verifyStopVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500881 assertTrue(r.isInterruptive());
882 assertFalse(s.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400883 }
884
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400885 @Test
Julia Reynolds0c299d42016-11-15 14:37:04 -0500886 public void testQuietOnceUpdateCancelVibrate() throws Exception {
Chris Wren93bb8b82016-03-29 14:35:05 -0400887 NotificationRecord r = getBuzzyNotification();
888 NotificationRecord s = getQuietOnceNotification();
889 s.isUpdate = true;
890
891 // set up internal state
892 mService.buzzBeepBlinkLocked(r);
Julia Reynolds0c299d42016-11-15 14:37:04 -0500893 verifyVibrate();
Chris Wren93bb8b82016-03-29 14:35:05 -0400894
895 // stop making noise - this is a weird corner case, but quiet should override once
896 mService.buzzBeepBlinkLocked(s);
897 verifyStopVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500898 assertTrue(r.isInterruptive());
899 assertFalse(s.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400900 }
901
Geoffrey Pitsch0ffe7552016-08-29 10:07:40 -0400902 @Test
Chris Wren93bb8b82016-03-29 14:35:05 -0400903 public void testQuietUpdateCancelsDemotedVibrate() throws Exception {
904 NotificationRecord r = getBeepyNotification();
905 NotificationRecord s = getQuietNotification();
906
907 // the phone is quiet
908 when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
909 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
910
911 mService.buzzBeepBlinkLocked(r);
912
913 // quiet update should stop making noise
914 mService.buzzBeepBlinkLocked(s);
915 verifyStopVibrate();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500916 assertTrue(r.isInterruptive());
917 assertFalse(s.isInterruptive());
Chris Wren93bb8b82016-03-29 14:35:05 -0400918 }
Michael Wright71216972017-01-31 18:33:54 +0000919
Julia Reynoldsca80d162017-04-23 12:39:32 -0400920 @Test
Seungho Lee0e97ae62018-10-31 21:49:09 +0900921 public void testCanceledNoisyNeverVibrate() throws Exception {
922 NotificationRecord r = getBuzzyBeepyNotification();
923
924 final int waitMs = mAudioManager.getFocusRampTimeMs(
925 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
926 r.getAudioAttributes());
927
928 mService.buzzBeepBlinkLocked(r);
929 mService.clearNotifications();
930
931 verifyNeverVibrate();
932 Thread.sleep(waitMs);
933 verifyNeverVibrate();
934 }
935
936 @Test
Julia Reynoldsca80d162017-04-23 12:39:32 -0400937 public void testEmptyUriSoundTreatedAsNoSound() throws Exception {
938 NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH);
939 channel.setSound(Uri.EMPTY, null);
940 final Notification n = new Builder(getContext(), "test")
941 .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
942
943 StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
944 mPid, n, mUser, null, System.currentTimeMillis());
Geoffrey Pitscha22f6442017-05-05 16:47:38 +0000945 NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
Julia Reynoldsca80d162017-04-23 12:39:32 -0400946 mService.addNotification(r);
947
948 mService.buzzBeepBlinkLocked(r);
Julia Reynoldsca80d162017-04-23 12:39:32 -0400949 verifyNeverBeep();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500950 assertFalse(r.isInterruptive());
Julia Reynoldsca80d162017-04-23 12:39:32 -0400951 }
952
Julia Reynolds76c096d2017-06-19 08:16:04 -0400953 @Test
954 public void testRepeatedSoundOverLimitMuted() throws Exception {
955 when(mUsageStats.isAlertRateLimited(any())).thenReturn(true);
956
957 NotificationRecord r = getBeepyNotification();
958
959 mService.buzzBeepBlinkLocked(r);
960 verifyNeverBeep();
Julia Reynolds1fac86e2018-03-07 08:30:37 -0500961 assertFalse(r.isInterruptive());
Julia Reynolds76c096d2017-06-19 08:16:04 -0400962 }
963
964 @Test
965 public void testPostingSilentNotificationDoesNotAffectRateLimiting() throws Exception {
966 NotificationRecord r = getQuietNotification();
967 mService.buzzBeepBlinkLocked(r);
968
969 verify(mUsageStats, never()).isAlertRateLimited(any());
970 }
971
972 @Test
Julia Reynolds65b85cf2017-07-20 09:19:20 -0400973 public void testPostingGroupSuppressedDoesNotAffectRateLimiting() throws Exception {
974 NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
975 summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
976
977 mService.buzzBeepBlinkLocked(summary);
Julia Reynolds65b85cf2017-07-20 09:19:20 -0400978 verify(mUsageStats, never()).isAlertRateLimited(any());
979 }
980
981 @Test
Julia Reynolds79dfdd62018-04-17 15:36:33 -0400982 public void testGroupSuppressionFailureDoesNotAffectRateLimiting() {
983 NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
984 summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
985
986 mService.buzzBeepBlinkLocked(summary);
987 verify(mUsageStats, times(1)).isAlertRateLimited(any());
988 }
989
990 @Test
Julia Reynolds76c096d2017-06-19 08:16:04 -0400991 public void testCrossUserSoundMuted() throws Exception {
992 final Notification n = new Builder(getContext(), "test")
993 .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
994
995 int userId = mUser.getIdentifier() + 1;
996 StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
997 mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
998 NotificationRecord r = new NotificationRecord(getContext(), sbn,
999 new NotificationChannel("test", "test", IMPORTANCE_HIGH));
1000
1001 mService.buzzBeepBlinkLocked(r);
1002 verifyNeverBeep();
Julia Reynolds1fac86e2018-03-07 08:30:37 -05001003 assertFalse(r.isInterruptive());
Julia Reynolds76c096d2017-06-19 08:16:04 -04001004 }
1005
Julia Reynolds94187562017-10-10 13:58:49 -04001006 @Test
1007 public void testA11yMinInitialPost() throws Exception {
1008 NotificationRecord r = getQuietNotification();
1009 r.setImportance(IMPORTANCE_MIN, "");
1010 mService.buzzBeepBlinkLocked(r);
1011 verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt());
1012 }
1013
1014 @Test
1015 public void testA11yQuietInitialPost() throws Exception {
1016 NotificationRecord r = getQuietNotification();
1017 mService.buzzBeepBlinkLocked(r);
1018 verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
1019 }
1020
1021 @Test
1022 public void testA11yQuietUpdate() throws Exception {
1023 NotificationRecord r = getQuietNotification();
1024 mService.buzzBeepBlinkLocked(r);
1025 r.isUpdate = true;
1026 mService.buzzBeepBlinkLocked(r);
1027 verify(mAccessibilityService, times(1)).sendAccessibilityEvent(any(), anyInt());
1028 }
1029
Julia Reynolds54369232018-07-03 10:43:35 -04001030 @Test
1031 public void testLightsScreenOn() {
1032 mService.mScreenOn = true;
1033 NotificationRecord r = getLightsNotification();
1034 mService.buzzBeepBlinkLocked(r);
1035 verifyNeverLights();
1036 assertFalse(r.isInterruptive());
1037 }
1038
1039 @Test
1040 public void testLightsInCall() {
1041 mService.mInCall = true;
1042 NotificationRecord r = getLightsNotification();
1043 mService.buzzBeepBlinkLocked(r);
1044 verifyNeverLights();
1045 assertFalse(r.isInterruptive());
1046 }
1047
1048 @Test
1049 public void testLightsSilentUpdate() {
1050 NotificationRecord r = getLightsOnceNotification();
1051 mService.buzzBeepBlinkLocked(r);
1052 verifyLights();
1053 assertTrue(r.isInterruptive());
1054
1055 r = getLightsOnceNotification();
1056 r.isUpdate = true;
1057 mService.buzzBeepBlinkLocked(r);
1058 // checks that lights happened once, i.e. this new call didn't trigger them again
1059 verifyLights();
1060 assertFalse(r.isInterruptive());
1061 }
1062
1063 @Test
1064 public void testLightsUnimportant() {
1065 NotificationRecord r = getLightsNotification();
1066 r.setImportance(IMPORTANCE_LOW, "testing");
1067 mService.buzzBeepBlinkLocked(r);
1068 verifyNeverLights();
1069 assertFalse(r.isInterruptive());
1070 }
1071
1072 @Test
1073 public void testLightsNoLights() {
1074 NotificationRecord r = getQuietNotification();
1075 mService.buzzBeepBlinkLocked(r);
1076 verifyNeverLights();
1077 assertFalse(r.isInterruptive());
1078 }
1079
1080 @Test
1081 public void testLightsNoLightOnDevice() {
1082 mService.mHasLight = false;
1083 NotificationRecord r = getLightsNotification();
1084 mService.buzzBeepBlinkLocked(r);
1085 verifyNeverLights();
1086 assertFalse(r.isInterruptive());
1087 }
1088
1089 @Test
1090 public void testLightsLightsOffGlobally() {
1091 mService.mNotificationPulseEnabled = false;
1092 NotificationRecord r = getLightsNotification();
1093 mService.buzzBeepBlinkLocked(r);
1094 verifyNeverLights();
1095 assertFalse(r.isInterruptive());
1096 }
1097
1098 @Test
1099 public void testLightsDndIntercepted() {
1100 NotificationRecord r = getLightsNotification();
1101 r.setSuppressedVisualEffects(SUPPRESSED_EFFECT_LIGHTS);
1102 mService.buzzBeepBlinkLocked(r);
1103 verifyNeverLights();
1104 assertFalse(r.isInterruptive());
1105 }
1106
1107 @Test
1108 public void testGroupAlertSummaryNoLightsChild() {
1109 NotificationRecord child = getLightsNotificationRecord("a", GROUP_ALERT_SUMMARY);
1110
1111 mService.buzzBeepBlinkLocked(child);
1112
1113 verifyNeverLights();
1114 assertFalse(child.isInterruptive());
1115 }
1116
1117 @Test
1118 public void testGroupAlertSummaryLightsSummary() {
1119 NotificationRecord summary = getLightsNotificationRecord("a", GROUP_ALERT_SUMMARY);
1120 summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
1121
1122 mService.buzzBeepBlinkLocked(summary);
1123
1124 verifyLights();
1125 // summaries should never count for interruptiveness counts
1126 assertFalse(summary.isInterruptive());
1127 }
1128
1129 @Test
1130 public void testGroupAlertSummaryLightsNonGroupChild() {
1131 NotificationRecord nonGroup = getLightsNotificationRecord(null, GROUP_ALERT_SUMMARY);
1132
1133 mService.buzzBeepBlinkLocked(nonGroup);
1134
1135 verifyLights();
1136 assertTrue(nonGroup.isInterruptive());
1137 }
1138
1139 @Test
1140 public void testGroupAlertChildNoLightsSummary() {
1141 NotificationRecord summary = getLightsNotificationRecord("a", GROUP_ALERT_CHILDREN);
1142 summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
1143
1144 mService.buzzBeepBlinkLocked(summary);
1145
1146 verifyNeverLights();
1147 assertFalse(summary.isInterruptive());
1148 }
1149
1150 @Test
1151 public void testGroupAlertChildLightsChild() {
1152 NotificationRecord child = getLightsNotificationRecord("a", GROUP_ALERT_CHILDREN);
1153
1154 mService.buzzBeepBlinkLocked(child);
1155
1156 verifyLights();
1157 assertTrue(child.isInterruptive());
1158 }
1159
1160 @Test
1161 public void testGroupAlertChildLightsNonGroupSummary() {
1162 NotificationRecord nonGroup = getLightsNotificationRecord(null, GROUP_ALERT_CHILDREN);
1163
1164 mService.buzzBeepBlinkLocked(nonGroup);
1165
1166 verifyLights();
1167 assertTrue(nonGroup.isInterruptive());
1168 }
1169
1170 @Test
1171 public void testGroupAlertAllLightsGroup() {
1172 NotificationRecord group = getLightsNotificationRecord("a", GROUP_ALERT_ALL);
1173
1174 mService.buzzBeepBlinkLocked(group);
1175
1176 verifyLights();
1177 assertTrue(group.isInterruptive());
1178 }
1179
Michael Wright71216972017-01-31 18:33:54 +00001180 static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
1181 private final int mRepeatIndex;
1182
1183 VibrateRepeatMatcher(int repeatIndex) {
1184 mRepeatIndex = repeatIndex;
1185 }
1186
1187 @Override
1188 public boolean matches(VibrationEffect actual) {
1189 if (actual instanceof VibrationEffect.Waveform &&
1190 ((VibrationEffect.Waveform) actual).getRepeatIndex() == mRepeatIndex) {
1191 return true;
1192 }
1193 // All non-waveform effects are essentially one shots.
1194 return mRepeatIndex == -1;
1195 }
1196
1197 @Override
1198 public String toString() {
1199 return "repeatIndex=" + mRepeatIndex;
1200 }
1201 }
Chris Wren93bb8b82016-03-29 14:35:05 -04001202}