OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / services / tests / servicestests / src / com / android / server / notification / BuzzBeepBlinkTest.java
1 /*
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  */
16 package com.android.server.notification;
17
18
19 import android.app.ActivityManager;
20 import android.app.Notification;
21 import android.app.Notification.Builder;
22 import android.media.AudioAttributes;
23 import android.media.AudioManager;
24 import android.net.Uri;
25 import android.os.Handler;
26 import android.os.RemoteException;
27 import android.os.UserHandle;
28 import android.os.Vibrator;
29 import android.service.notification.NotificationListenerService.Ranking;
30 import android.service.notification.StatusBarNotification;
31 import android.test.AndroidTestCase;
32 import android.test.suitebuilder.annotation.SmallTest;
33
34 import org.mockito.Mock;
35 import org.mockito.Mockito;
36 import org.mockito.MockitoAnnotations;
37
38 import static org.mockito.Matchers.anyBoolean;
39 import static org.mockito.Matchers.anyInt;
40 import static org.mockito.Matchers.anyObject;
41 import static org.mockito.Matchers.anyString;
42 import static org.mockito.Matchers.eq;
43 import static org.mockito.Mockito.never;
44 import static org.mockito.Mockito.times;
45 import static org.mockito.Mockito.verify;
46 import static org.mockito.Mockito.when;
47
48 public class BuzzBeepBlinkTest extends AndroidTestCase {
49
50     @Mock AudioManager mAudioManager;
51     @Mock Vibrator mVibrator;
52     @Mock android.media.IRingtonePlayer mRingtonePlayer;
53     @Mock Handler mHandler;
54
55     private NotificationManagerService mService;
56     private String mPkg = "com.android.server.notification";
57     private int mId = 1001;
58     private int mOtherId = 1002;
59     private String mTag = null;
60     private int mUid = 1000;
61     private int mPid = 2000;
62     private int mScore = 10;
63     private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
64
65     @Override
66     public void setUp() {
67         MockitoAnnotations.initMocks(this);
68
69         when(mAudioManager.isAudioFocusExclusive()).thenReturn(false);
70         when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer);
71         when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
72         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
73
74         mService = new NotificationManagerService(getContext());
75         mService.setAudioManager(mAudioManager);
76         mService.setVibrator(mVibrator);
77         mService.setSystemReady(true);
78         mService.setHandler(mHandler);
79         mService.setSystemNotificationSound("beep!");
80     }
81
82     //
83     // Convenience functions for creating notification records
84     //
85
86     private NotificationRecord getNoisyOtherNotification() {
87         return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
88                 true /* noisy */, true /* buzzy*/);
89     }
90
91     private NotificationRecord getBeepyNotification() {
92         return getNotificationRecord(mId, false /* insistent */, false /* once */,
93                 true /* noisy */, false /* buzzy*/);
94     }
95
96     private NotificationRecord getBeepyOnceNotification() {
97         return getNotificationRecord(mId, false /* insistent */, true /* once */,
98                 true /* noisy */, false /* buzzy*/);
99     }
100
101     private NotificationRecord getQuietNotification() {
102         return getNotificationRecord(mId, false /* insistent */, false /* once */,
103                 false /* noisy */, false /* buzzy*/);
104     }
105
106     private NotificationRecord getQuietOtherNotification() {
107         return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
108                 false /* noisy */, false /* buzzy*/);
109     }
110
111     private NotificationRecord getQuietOnceNotification() {
112         return getNotificationRecord(mId, false /* insistent */, true /* once */,
113                 false /* noisy */, false /* buzzy*/);
114     }
115
116     private NotificationRecord getInsistentBeepyNotification() {
117         return getNotificationRecord(mId, true /* insistent */, false /* once */,
118                 true /* noisy */, false /* buzzy*/);
119     }
120
121     private NotificationRecord getBuzzyNotification() {
122         return getNotificationRecord(mId, false /* insistent */, false /* once */,
123                 false /* noisy */, true /* buzzy*/);
124     }
125
126     private NotificationRecord getBuzzyOnceNotification() {
127         return getNotificationRecord(mId, false /* insistent */, true /* once */,
128                 false /* noisy */, true /* buzzy*/);
129     }
130
131     private NotificationRecord getInsistentBuzzyNotification() {
132         return getNotificationRecord(mId, true /* insistent */, false /* once */,
133                 false /* noisy */, true /* buzzy*/);
134     }
135
136     private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once,
137             boolean noisy, boolean buzzy) {
138         final Builder builder = new Builder(getContext())
139                 .setContentTitle("foo")
140                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
141                 .setPriority(Notification.PRIORITY_HIGH)
142                 .setOnlyAlertOnce(once);
143
144         int defaults = 0;
145         if (noisy) {
146             defaults |= Notification.DEFAULT_SOUND;
147         }
148         if (buzzy) {
149             defaults |= Notification.DEFAULT_VIBRATE;
150         }
151         builder.setDefaults(defaults);
152
153         Notification n = builder.build();
154         if (insistent) {
155             n.flags |= Notification.FLAG_INSISTENT;
156         }
157         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, mPid,
158                 mScore, n, mUser, System.currentTimeMillis());
159         return new NotificationRecord(getContext(), sbn);
160     }
161
162     //
163     // Convenience functions for interacting with mocks
164     //
165
166     private void verifyNeverBeep() throws RemoteException {
167         verify(mRingtonePlayer, never()).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
168                 anyBoolean(), (AudioAttributes) anyObject());
169     }
170
171     private void verifyBeep() throws RemoteException {
172         verify(mRingtonePlayer, times(1)).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
173                 eq(true), (AudioAttributes) anyObject());
174     }
175
176     private void verifyBeepLooped() throws RemoteException {
177         verify(mRingtonePlayer, times(1)).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
178                 eq(false), (AudioAttributes) anyObject());
179     }
180
181     private void verifyNeverStopAudio() throws RemoteException {
182         verify(mRingtonePlayer, never()).stopAsync();
183     }
184
185     private void verifyStopAudio() throws RemoteException {
186         verify(mRingtonePlayer, times(1)).stopAsync();
187     }
188
189     private void verifyNeverVibrate() {
190         verify(mVibrator, never()).vibrate(anyInt(), anyString(), (long[]) anyObject(),
191                 anyInt(), (AudioAttributes) anyObject());
192     }
193
194     private void verifyVibrate() {
195         verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), (long[]) anyObject(),
196                 eq(-1), (AudioAttributes) anyObject());
197     }
198
199     private void verifyVibrateLooped() {
200         verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), (long[]) anyObject(),
201                 eq(0), (AudioAttributes) anyObject());
202     }
203
204     private void verifyStopVibrate() {
205         verify(mVibrator, times(1)).cancel();
206     }
207
208     private void verifyNeverStopVibrate() throws RemoteException {
209         verify(mVibrator, never()).cancel();
210     }
211
212     @SmallTest
213     public void testBeep() throws Exception {
214         NotificationRecord r = getBeepyNotification();
215
216         mService.buzzBeepBlinkLocked(r);
217
218         verifyBeepLooped();
219         verifyNeverVibrate();
220     }
221
222     //
223     // Tests
224     //
225
226     @SmallTest
227     public void testBeepInsistently() throws Exception {
228         NotificationRecord r = getInsistentBeepyNotification();
229
230         mService.buzzBeepBlinkLocked(r);
231
232         verifyBeep();
233     }
234
235     @SmallTest
236     public void testNoInterruptionForMin() throws Exception {
237         NotificationRecord r = getBeepyNotification();
238         r.setImportance(Ranking.IMPORTANCE_MIN, "foo");
239
240         mService.buzzBeepBlinkLocked(r);
241
242         verifyNeverBeep();
243         verifyNeverVibrate();
244     }
245
246     @SmallTest
247     public void testNoInterruptionForIntercepted() throws Exception {
248         NotificationRecord r = getBeepyNotification();
249         r.setIntercepted(true);
250
251         mService.buzzBeepBlinkLocked(r);
252
253         verifyNeverBeep();
254         verifyNeverVibrate();
255     }
256
257     @SmallTest
258     public void testBeepTwice() throws Exception {
259         NotificationRecord r = getBeepyNotification();
260
261         // set up internal state
262         mService.buzzBeepBlinkLocked(r);
263         Mockito.reset(mRingtonePlayer);
264
265         // update should beep
266         r.isUpdate = true;
267         mService.buzzBeepBlinkLocked(r);
268         verifyBeepLooped();
269     }
270
271     @SmallTest
272     public void testHonorAlertOnlyOnceForBeep() throws Exception {
273         NotificationRecord r = getBeepyNotification();
274         NotificationRecord s = getBeepyOnceNotification();
275         s.isUpdate = true;
276
277         // set up internal state
278         mService.buzzBeepBlinkLocked(r);
279         Mockito.reset(mRingtonePlayer);
280
281         // update should not beep
282         mService.buzzBeepBlinkLocked(s);
283         verifyNeverBeep();
284     }
285
286     @SmallTest
287     public void testNoisyUpdateDoesNotCancelAudio() throws Exception {
288         NotificationRecord r = getBeepyNotification();
289
290         mService.buzzBeepBlinkLocked(r);
291         r.isUpdate = true;
292         mService.buzzBeepBlinkLocked(r);
293
294         verifyNeverStopAudio();
295     }
296
297     @SmallTest
298     public void testNoisyOnceUpdateDoesNotCancelAudio() throws Exception {
299         NotificationRecord r = getBeepyNotification();
300         NotificationRecord s = getBeepyOnceNotification();
301         s.isUpdate = true;
302
303         mService.buzzBeepBlinkLocked(r);
304         mService.buzzBeepBlinkLocked(s);
305
306         verifyNeverStopAudio();
307     }
308
309     @SmallTest
310     public void testQuietUpdateDoesNotCancelAudioFromOther() throws Exception {
311         NotificationRecord r = getBeepyNotification();
312         NotificationRecord s = getQuietNotification();
313         s.isUpdate = true;
314         NotificationRecord other = getNoisyOtherNotification();
315
316         // set up internal state
317         mService.buzzBeepBlinkLocked(r);
318         mService.buzzBeepBlinkLocked(other); // this takes the audio stream
319         Mockito.reset(mRingtonePlayer);
320
321         // should not stop noise, since we no longer own it
322         mService.buzzBeepBlinkLocked(s); // this no longer owns the stream
323         verifyNeverStopAudio();
324     }
325
326     @SmallTest
327     public void testQuietInterloperDoesNotCancelAudio() throws Exception {
328         NotificationRecord r = getBeepyNotification();
329         NotificationRecord other = getQuietOtherNotification();
330
331         // set up internal state
332         mService.buzzBeepBlinkLocked(r);
333         Mockito.reset(mRingtonePlayer);
334
335         // should not stop noise, since it does not own it
336         mService.buzzBeepBlinkLocked(other);
337         verifyNeverStopAudio();
338     }
339
340     @SmallTest
341     public void testQuietUpdateCancelsAudio() throws Exception {
342         NotificationRecord r = getBeepyNotification();
343         NotificationRecord s = getQuietNotification();
344         s.isUpdate = true;
345
346         // set up internal state
347         mService.buzzBeepBlinkLocked(r);
348         Mockito.reset(mRingtonePlayer);
349
350         // quiet update should stop making noise
351         mService.buzzBeepBlinkLocked(s);
352         verifyStopAudio();
353     }
354
355     @SmallTest
356     public void testQuietOnceUpdateCancelsAudio() throws Exception {
357         NotificationRecord r = getBeepyNotification();
358         NotificationRecord s = getQuietOnceNotification();
359         s.isUpdate = true;
360
361         // set up internal state
362         mService.buzzBeepBlinkLocked(r);
363         Mockito.reset(mRingtonePlayer);
364
365         // stop making noise - this is a weird corner case, but quiet should override once
366         mService.buzzBeepBlinkLocked(s);
367         verifyStopAudio();
368     }
369
370     @SmallTest
371     public void testDemoteSoundToVibrate() throws Exception {
372         NotificationRecord r = getBeepyNotification();
373
374         // the phone is quiet
375         when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
376         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
377
378         mService.buzzBeepBlinkLocked(r);
379
380         verifyNeverBeep();
381         verifyVibrate();
382     }
383
384     @SmallTest
385     public void testDemotInsistenteSoundToVibrate() throws Exception {
386         NotificationRecord r = getInsistentBeepyNotification();
387
388         // the phone is quiet
389         when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
390         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
391
392         mService.buzzBeepBlinkLocked(r);
393
394         verifyVibrateLooped();
395     }
396
397     @SmallTest
398     public void testVibrate() throws Exception {
399         NotificationRecord r = getBuzzyNotification();
400
401         mService.buzzBeepBlinkLocked(r);
402
403         verifyNeverBeep();
404         verifyVibrate();
405     }
406
407     @SmallTest
408     public void testInsistenteVibrate() throws Exception {
409         NotificationRecord r = getInsistentBuzzyNotification();
410
411         mService.buzzBeepBlinkLocked(r);
412         verifyVibrateLooped();
413     }
414
415     @SmallTest
416     public void testVibratTwice() throws Exception {
417         NotificationRecord r = getBuzzyNotification();
418
419         // set up internal state
420         mService.buzzBeepBlinkLocked(r);
421         Mockito.reset(mVibrator);
422
423         // update should vibrate
424         r.isUpdate = true;
425         mService.buzzBeepBlinkLocked(r);
426         verifyVibrate();
427     }
428
429     @SmallTest
430     public void testHonorAlertOnlyOnceForBuzz() throws Exception {
431         NotificationRecord r = getBuzzyNotification();
432         NotificationRecord s = getBuzzyOnceNotification();
433         s.isUpdate = true;
434
435         // set up internal state
436         mService.buzzBeepBlinkLocked(r);
437         Mockito.reset(mVibrator);
438
439         // update should not beep
440         mService.buzzBeepBlinkLocked(s);
441         verifyNeverVibrate();
442     }
443
444     @SmallTest
445     public void testNoisyUpdateDoesNotCancelVibrate() throws Exception {
446         NotificationRecord r = getBuzzyNotification();
447
448         mService.buzzBeepBlinkLocked(r);
449         r.isUpdate = true;
450         mService.buzzBeepBlinkLocked(r);
451
452         verifyNeverStopVibrate();
453     }
454
455     @SmallTest
456     public void testNoisyOnceUpdateDoesNotCancelVibrate() throws Exception {
457         NotificationRecord r = getBuzzyNotification();
458         NotificationRecord s = getBuzzyOnceNotification();
459         s.isUpdate = true;
460
461         mService.buzzBeepBlinkLocked(r);
462         mService.buzzBeepBlinkLocked(s);
463
464         verifyNeverStopVibrate();
465     }
466
467     @SmallTest
468     public void testQuietUpdateDoesNotCancelVibrateFromOther() throws Exception {
469         NotificationRecord r = getBuzzyNotification();
470         NotificationRecord s = getQuietNotification();
471         s.isUpdate = true;
472         NotificationRecord other = getNoisyOtherNotification();
473
474         // set up internal state
475         mService.buzzBeepBlinkLocked(r);
476         mService.buzzBeepBlinkLocked(other); // this takes the vibrate stream
477         Mockito.reset(mVibrator);
478
479         // should not stop vibrate, since we no longer own it
480         mService.buzzBeepBlinkLocked(s); // this no longer owns the stream
481         verifyNeverStopVibrate();
482     }
483
484     @SmallTest
485     public void testQuietInterloperDoesNotCancelVibrate() throws Exception {
486         NotificationRecord r = getBuzzyNotification();
487         NotificationRecord other = getQuietOtherNotification();
488
489         // set up internal state
490         mService.buzzBeepBlinkLocked(r);
491         Mockito.reset(mVibrator);
492
493         // should not stop noise, since it does not own it
494         mService.buzzBeepBlinkLocked(other);
495         verifyNeverStopVibrate();
496     }
497
498     @SmallTest
499     public void testQuietUpdateCancelsVibrate() throws Exception {
500         NotificationRecord r = getBuzzyNotification();
501         NotificationRecord s = getQuietNotification();
502         s.isUpdate = true;
503
504         // set up internal state
505         mService.buzzBeepBlinkLocked(r);
506
507         // quiet update should stop making noise
508         mService.buzzBeepBlinkLocked(s);
509         verifyStopVibrate();
510     }
511
512     @SmallTest
513     public void testQuietOnceUpdateCancelsvibrate() throws Exception {
514         NotificationRecord r = getBuzzyNotification();
515         NotificationRecord s = getQuietOnceNotification();
516         s.isUpdate = true;
517
518         // set up internal state
519         mService.buzzBeepBlinkLocked(r);
520         Mockito.reset(mVibrator);
521
522         // stop making noise - this is a weird corner case, but quiet should override once
523         mService.buzzBeepBlinkLocked(s);
524         verifyStopVibrate();
525     }
526
527     @SmallTest
528     public void testQuietUpdateCancelsDemotedVibrate() throws Exception {
529         NotificationRecord r = getBeepyNotification();
530         NotificationRecord s = getQuietNotification();
531
532         // the phone is quiet
533         when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
534         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
535
536         mService.buzzBeepBlinkLocked(r);
537
538         // quiet update should stop making noise
539         mService.buzzBeepBlinkLocked(s);
540         verifyStopVibrate();
541     }
542 }