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