2 * Copyright (C) 2017 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distriZenbuted 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.
17 package com.android.server.notification;
19 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
20 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
21 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
22 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
24 import static junit.framework.Assert.assertFalse;
25 import static junit.framework.Assert.assertEquals;
26 import static junit.framework.TestCase.assertTrue;
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.ArgumentMatchers.anyBoolean;
30 import static org.mockito.ArgumentMatchers.anyInt;
31 import static org.mockito.ArgumentMatchers.eq;
32 import static org.mockito.Mockito.atLeastOnce;
33 import static org.mockito.Mockito.doNothing;
34 import static org.mockito.Mockito.mock;
35 import static org.mockito.Mockito.never;
36 import static org.mockito.Mockito.spy;
37 import static org.mockito.Mockito.times;
38 import static org.mockito.Mockito.verify;
39 import static org.mockito.Mockito.when;
41 import android.app.AppOpsManager;
42 import android.app.NotificationManager;
43 import android.content.ComponentName;
44 import android.content.ContentResolver;
45 import android.content.Context;
46 import android.content.res.Resources;
47 import android.media.AudioAttributes;
48 import android.media.AudioManager;
49 import android.media.AudioManagerInternal;
50 import android.media.VolumePolicy;
51 import android.media.AudioSystem;
52 import android.provider.Settings;
53 import android.provider.Settings.Global;
54 import android.service.notification.ZenModeConfig;
55 import android.service.notification.ZenModeConfig.ScheduleInfo;
56 import android.test.suitebuilder.annotation.SmallTest;
57 import android.testing.AndroidTestingRunner;
58 import android.testing.TestableLooper;
59 import android.util.ArrayMap;
60 import android.util.Xml;
62 import com.android.internal.R;
63 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
64 import com.android.internal.util.FastXmlSerializer;
65 import com.android.server.UiServiceTestCase;
66 import android.util.Slog;
68 import org.junit.Before;
69 import org.junit.Test;
70 import org.junit.runner.RunWith;
71 import org.mockito.Mock;
72 import org.mockito.MockitoAnnotations;
73 import org.xmlpull.v1.XmlPullParser;
74 import org.xmlpull.v1.XmlSerializer;
76 import java.io.BufferedInputStream;
77 import java.io.BufferedOutputStream;
78 import java.io.ByteArrayInputStream;
79 import java.io.ByteArrayOutputStream;
82 @RunWith(AndroidTestingRunner.class)
83 @TestableLooper.RunWithLooper
84 public class ZenModeHelperTest extends UiServiceTestCase {
86 @Mock ConditionProviders mConditionProviders;
87 @Mock NotificationManager mNotificationManager;
88 @Mock private Resources mResources;
89 private TestableLooper mTestableLooper;
90 private ZenModeHelper mZenModeHelperSpy;
91 private Context mContext;
92 private ContentResolver mContentResolver;
96 MockitoAnnotations.initMocks(this);
98 mTestableLooper = TestableLooper.get(this);
99 mContext = spy(getContext());
100 mContentResolver = mContext.getContentResolver();
101 when(mContext.getResources()).thenReturn(mResources);
102 when(mResources.getString(R.string.zen_mode_default_every_night_name)).thenReturn("night");
103 when(mResources.getString(R.string.zen_mode_default_events_name)).thenReturn("events");
104 when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager);
106 mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(),
107 mConditionProviders));
110 private ByteArrayOutputStream writeXmlAndPurge(boolean forBackup, Integer version)
112 XmlSerializer serializer = new FastXmlSerializer();
113 ByteArrayOutputStream baos = new ByteArrayOutputStream();
114 serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
115 serializer.startDocument(null, true);
116 mZenModeHelperSpy.writeXml(serializer, forBackup, version);
117 serializer.endDocument();
119 mZenModeHelperSpy.setConfig(new ZenModeConfig(), "writing xml");
124 public void testZenOff_NoMuteApplied() {
125 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_OFF;
126 assertTrue(mZenModeHelperSpy.mConfig.allowAlarms);
127 mZenModeHelperSpy.applyRestrictions();
129 doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyInt());
130 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
131 AudioAttributes.USAGE_ALARM);
132 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
133 AudioAttributes.USAGE_MEDIA);
137 public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() {
138 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
139 assertTrue(mZenModeHelperSpy.mConfig.allowAlarms);
140 assertTrue(mZenModeHelperSpy.mConfig.allowMedia);
141 mZenModeHelperSpy.applyRestrictions();
142 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
143 AudioAttributes.USAGE_ALARM);
144 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
145 AudioAttributes.USAGE_MEDIA);
149 public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() {
150 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
151 mZenModeHelperSpy.mConfig.allowAlarms = false;
152 mZenModeHelperSpy.mConfig.allowMedia = false;
153 mZenModeHelperSpy.mConfig.allowSystem = false;
154 assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
155 assertFalse(mZenModeHelperSpy.mConfig.allowMedia);
156 assertFalse(mZenModeHelperSpy.mConfig.allowSystem);
157 mZenModeHelperSpy.applyRestrictions();
158 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
159 AudioAttributes.USAGE_ALARM);
161 // Media is a catch-all that includes games
162 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
163 AudioAttributes.USAGE_MEDIA);
164 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
165 AudioAttributes.USAGE_GAME);
169 public void testTotalSilence() {
170 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
171 mZenModeHelperSpy.applyRestrictions();
173 // Total silence will silence alarms, media and system noises (but not vibrations)
174 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
175 AudioAttributes.USAGE_ALARM);
176 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
177 AudioAttributes.USAGE_MEDIA);
178 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
179 AudioAttributes.USAGE_GAME);
180 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
181 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO);
182 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
183 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_VIBRATE);
184 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
185 AudioAttributes.USAGE_UNKNOWN);
189 public void testAlarmsOnly_alarmMediaMuteNotApplied() {
190 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
191 mZenModeHelperSpy.mConfig.allowAlarms = false;
192 mZenModeHelperSpy.mConfig.allowSystem = false;
193 mZenModeHelperSpy.mConfig.allowMedia = false;
194 assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
195 assertFalse(mZenModeHelperSpy.mConfig.allowMedia);
196 mZenModeHelperSpy.applyRestrictions();
198 // Alarms only mode will not silence alarms
199 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
200 AudioAttributes.USAGE_ALARM);
202 // Alarms only mode will not silence media
203 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
204 AudioAttributes.USAGE_MEDIA);
205 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
206 AudioAttributes.USAGE_GAME);
207 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
208 AudioAttributes.USAGE_UNKNOWN);
210 // Alarms only will silence system noises (but not vibrations)
211 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
212 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO);
216 public void testAlarmsOnly_callsMuteApplied() {
217 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
218 mZenModeHelperSpy.mConfig.allowCalls = true;
219 assertTrue(mZenModeHelperSpy.mConfig.allowCalls);
220 mZenModeHelperSpy.applyRestrictions();
222 // Alarms only mode will silence calls despite priority-mode config
223 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
224 AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
225 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
226 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
230 public void testAlarmsOnly_allZenConfigToggledCannotBypass_alarmMuteNotApplied() {
231 // Only audio attributes with SUPPRESIBLE_NEVER can bypass
232 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
233 mZenModeHelperSpy.mConfig.allowAlarms = false;
234 mZenModeHelperSpy.mConfig.allowMedia = false;
235 mZenModeHelperSpy.mConfig.allowSystem = false;
236 mZenModeHelperSpy.mConfig.allowReminders = false;
237 mZenModeHelperSpy.mConfig.allowCalls = false;
238 mZenModeHelperSpy.mConfig.allowMessages = false;
239 mZenModeHelperSpy.mConfig.allowEvents = false;
240 mZenModeHelperSpy.mConfig.allowRepeatCallers= false;
241 assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
242 assertFalse(mZenModeHelperSpy.mConfig.allowMedia);
243 assertFalse(mZenModeHelperSpy.mConfig.allowReminders);
244 assertFalse(mZenModeHelperSpy.mConfig.allowCalls);
245 assertFalse(mZenModeHelperSpy.mConfig.allowMessages);
246 assertFalse(mZenModeHelperSpy.mConfig.allowEvents);
247 assertFalse(mZenModeHelperSpy.mConfig.allowRepeatCallers);
248 mZenModeHelperSpy.applyRestrictions();
250 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
251 AudioAttributes.USAGE_ALARM);
255 public void testZenAllCannotBypass() {
256 // Only audio attributes with SUPPRESIBLE_NEVER can bypass
257 // with special case USAGE_ASSISTANCE_SONIFICATION
258 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
259 mZenModeHelperSpy.mConfig.allowAlarms = false;
260 mZenModeHelperSpy.mConfig.allowMedia = false;
261 mZenModeHelperSpy.mConfig.allowSystem = false;
262 mZenModeHelperSpy.mConfig.allowReminders = false;
263 mZenModeHelperSpy.mConfig.allowCalls = false;
264 mZenModeHelperSpy.mConfig.allowMessages = false;
265 mZenModeHelperSpy.mConfig.allowEvents = false;
266 mZenModeHelperSpy.mConfig.allowRepeatCallers= false;
267 assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
268 assertFalse(mZenModeHelperSpy.mConfig.allowMedia);
269 assertFalse(mZenModeHelperSpy.mConfig.allowReminders);
270 assertFalse(mZenModeHelperSpy.mConfig.allowCalls);
271 assertFalse(mZenModeHelperSpy.mConfig.allowMessages);
272 assertFalse(mZenModeHelperSpy.mConfig.allowEvents);
273 assertFalse(mZenModeHelperSpy.mConfig.allowRepeatCallers);
274 mZenModeHelperSpy.applyRestrictions();
276 for (int usage : AudioAttributes.SDK_USAGES) {
277 if (usage == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) {
278 // only mute audio, not vibrations
279 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, usage,
280 AppOpsManager.OP_PLAY_AUDIO);
281 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, usage,
282 AppOpsManager.OP_VIBRATE);
284 boolean shouldMute = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage)
285 != AudioAttributes.SUPPRESSIBLE_NEVER;
286 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(shouldMute, usage);
292 public void testZenUpgradeNotification() {
293 // shows zen upgrade notification if stored settings says to shows, boot is completed
294 // and we're setting zen mode on
295 Settings.Global.putInt(mContentResolver, Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);
296 mZenModeHelperSpy.mIsBootComplete = true;
297 mZenModeHelperSpy.setZenModeSetting(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
299 verify(mZenModeHelperSpy, times(1)).createZenUpgradeNotification();
300 verify(mNotificationManager, times(1)).notify(eq(ZenModeHelper.TAG),
301 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
302 assertEquals(0, Settings.Global.getInt(mContentResolver,
303 Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION, -1));
307 public void testNoZenUpgradeNotification() {
308 // doesn't show upgrade notification if stored settings says don't show
309 Settings.Global.putInt(mContentResolver, Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
310 mZenModeHelperSpy.mIsBootComplete = true;
311 mZenModeHelperSpy.setZenModeSetting(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
313 verify(mZenModeHelperSpy, never()).createZenUpgradeNotification();
314 verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG),
315 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
319 public void testZenSetInternalRinger_AllPriorityNotificationSoundsMuted() {
320 AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
321 mZenModeHelperSpy.mAudioManager = mAudioManager;
322 Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
323 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
325 // 1. Current ringer is normal
326 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
327 // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
328 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
329 mZenModeHelperSpy.mConfig.allowReminders = false;
330 mZenModeHelperSpy.mConfig.allowCalls = false;
331 mZenModeHelperSpy.mConfig.allowMessages = false;
332 mZenModeHelperSpy.mConfig.allowEvents = false;
333 mZenModeHelperSpy.mConfig.allowRepeatCallers= false;
335 // 2. apply priority only zen - verify ringer is unchanged
336 mZenModeHelperSpy.applyZenToRingerMode();
337 verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
338 mZenModeHelperSpy.TAG);
340 // 3. apply zen off - verify zen is set to previous ringer (normal)
341 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
342 mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
343 mZenModeHelperSpy.applyZenToRingerMode();
344 verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
345 mZenModeHelperSpy.TAG);
349 public void testRingerAffectedStreamsTotalSilence() {
351 // ringtone, notification, system, alarm, streams, music are affected by ringer mode
352 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
353 ZenModeHelper.RingerModeDelegate ringerModeDelegate =
354 mZenModeHelperSpy.new RingerModeDelegate();
355 int ringerModeAffectedStreams = ringerModeDelegate.getRingerModeAffectedStreams(0);
356 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
357 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
359 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0);
360 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) != 0);
361 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) != 0);
365 public void testRingerAffectedStreamsPriorityOnly() {
366 // in priority only mode:
367 // ringtone, notification and system streams are affected by ringer mode
368 // UNLESS ringer is muted due to all the other priority only dnd sounds being muted
369 mZenModeHelperSpy.mConfig.allowAlarms = true;
370 mZenModeHelperSpy.mConfig.allowReminders = true;
371 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
372 ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerMuted =
373 mZenModeHelperSpy.new RingerModeDelegate();
375 int ringerModeAffectedStreams =
376 ringerModeDelegateRingerMuted.getRingerModeAffectedStreams(0);
377 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
378 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
380 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0);
381 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0);
382 assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0);
384 // special case: if ringer is muted (since all notification sounds cannot bypass)
385 // then system stream is not affected by ringer mode
386 mZenModeHelperSpy.mConfig.allowReminders = false;
387 mZenModeHelperSpy.mConfig.allowCalls = false;
388 mZenModeHelperSpy.mConfig.allowMessages = false;
389 mZenModeHelperSpy.mConfig.allowEvents = false;
390 mZenModeHelperSpy.mConfig.allowRepeatCallers= false;
391 ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerNotMuted =
392 mZenModeHelperSpy.new RingerModeDelegate();
394 int ringerMutedRingerModeAffectedStreams =
395 ringerModeDelegateRingerNotMuted.getRingerModeAffectedStreams(0);
396 assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
397 assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
399 assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM))
401 assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0);
402 assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0);
406 public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartNormal() {
407 AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
408 mZenModeHelperSpy.mAudioManager = mAudioManager;
409 Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
410 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
412 // 1. Current ringer is normal
413 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
414 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
415 mZenModeHelperSpy.mConfig.allowReminders = true;
417 // 2. apply priority only zen - verify ringer is normal
418 mZenModeHelperSpy.applyZenToRingerMode();
419 verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
420 mZenModeHelperSpy.TAG);
422 // 3. apply zen off - verify ringer remains normal
423 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
424 mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
425 mZenModeHelperSpy.applyZenToRingerMode();
426 verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
427 mZenModeHelperSpy.TAG);
431 public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartSilent() {
432 AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
433 mZenModeHelperSpy.mAudioManager = mAudioManager;
434 Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
435 Integer.toString(AudioManager.RINGER_MODE_SILENT));
437 // 1. Current ringer is silent
438 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
439 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
440 mZenModeHelperSpy.mConfig.allowReminders = true;
442 // 2. apply priority only zen - verify ringer is silent
443 mZenModeHelperSpy.applyZenToRingerMode();
444 verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
445 mZenModeHelperSpy.TAG);
447 // 3. apply zen-off - verify ringer is still silent
448 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
449 mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
450 mZenModeHelperSpy.applyZenToRingerMode();
451 verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
452 mZenModeHelperSpy.TAG);
456 public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_RingerChanges() {
457 AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
458 mZenModeHelperSpy.mAudioManager = mAudioManager;
459 Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
460 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
462 // 1. Current ringer is normal
463 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
464 // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
465 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
466 mZenModeHelperSpy.mConfig.allowReminders = true;
468 // 2. apply priority only zen - verify zen will still be normal
469 mZenModeHelperSpy.applyZenToRingerMode();
470 verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
471 mZenModeHelperSpy.TAG);
473 // 3. change ringer from normal to silent, verify previous ringer set to new ringer (silent)
474 ZenModeHelper.RingerModeDelegate ringerModeDelegate =
475 mZenModeHelperSpy.new RingerModeDelegate();
476 ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
477 AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
478 VolumePolicy.DEFAULT);
479 assertEquals(AudioManager.RINGER_MODE_SILENT, Global.getInt(mContext.getContentResolver(),
480 Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
482 // 4. apply zen off - verify ringer still silenced
483 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
484 mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
485 mZenModeHelperSpy.applyZenToRingerMode();
486 verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
487 mZenModeHelperSpy.TAG);
491 public void testSilentRingerSavedInZenOff_startsZenOff() {
492 AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
493 mZenModeHelperSpy.mAudioManager = mAudioManager;
495 // apply zen off multiple times - verify ringer is not set to normal
496 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
497 mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
498 mZenModeHelperSpy.mConfig = null; // will evaluate config to zen mode off
499 for (int i = 0; i < 3; i++) {
500 // if zen doesn't change, zen should not reapply itself to the ringer
501 mZenModeHelperSpy.evaluateZenMode("test", true);
503 verify(mZenModeHelperSpy, never()).applyZenToRingerMode();
504 verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
505 mZenModeHelperSpy.TAG);
509 public void testSilentRingerSavedOnZenOff_startsZenOn() {
510 AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
511 mZenModeHelperSpy.mAudioManager = mAudioManager;
512 mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
514 // previously set silent ringer
515 ZenModeHelper.RingerModeDelegate ringerModeDelegate =
516 mZenModeHelperSpy.new RingerModeDelegate();
517 ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
518 AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
519 VolumePolicy.DEFAULT);
520 assertEquals(AudioManager.RINGER_MODE_SILENT, Global.getInt(mContext.getContentResolver(),
521 Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
523 // apply zen off multiple times - verify ringer is not set to normal
524 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
525 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
526 mZenModeHelperSpy.mConfig = null; // will evaluate config to zen mode off
527 for (int i = 0; i < 3; i++) {
528 // if zen doesn't change, zen should not reapply itself to the ringer
529 mZenModeHelperSpy.evaluateZenMode("test", true);
531 verify(mZenModeHelperSpy, times(1)).applyZenToRingerMode();
532 verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
533 mZenModeHelperSpy.TAG);
537 public void testVibrateRingerSavedOnZenOff_startsZenOn() {
538 AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
539 mZenModeHelperSpy.mAudioManager = mAudioManager;
540 mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
542 // previously set silent ringer
543 ZenModeHelper.RingerModeDelegate ringerModeDelegate =
544 mZenModeHelperSpy.new RingerModeDelegate();
545 ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
546 AudioManager.RINGER_MODE_VIBRATE, "test", AudioManager.RINGER_MODE_NORMAL,
547 VolumePolicy.DEFAULT);
548 assertEquals(AudioManager.RINGER_MODE_VIBRATE, Global.getInt(mContext.getContentResolver(),
549 Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
551 // apply zen off multiple times - verify ringer is not set to normal
552 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
553 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
554 mZenModeHelperSpy.mConfig = null; // will evaluate config to zen mode off
555 for (int i = 0; i < 3; i++) {
556 // if zen doesn't change, zen should not reapply itself to the ringer
557 mZenModeHelperSpy.evaluateZenMode("test", true);
559 verify(mZenModeHelperSpy, times(1)).applyZenToRingerMode();
560 verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
561 mZenModeHelperSpy.TAG);
565 public void testParcelConfig() {
566 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
567 mZenModeHelperSpy.mConfig.allowAlarms = false;
568 mZenModeHelperSpy.mConfig.allowMedia = false;
569 mZenModeHelperSpy.mConfig.allowSystem = false;
570 mZenModeHelperSpy.mConfig.allowReminders = true;
571 mZenModeHelperSpy.mConfig.allowCalls = true;
572 mZenModeHelperSpy.mConfig.allowMessages = true;
573 mZenModeHelperSpy.mConfig.allowEvents = true;
574 mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
575 mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
576 mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
577 mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
578 mZenModeHelperSpy.mConfig.manualRule.enabled = true;
579 mZenModeHelperSpy.mConfig.manualRule.snoozing = true;
581 ZenModeConfig actual = mZenModeHelperSpy.mConfig.copy();
583 assertEquals(mZenModeHelperSpy.mConfig, actual);
587 public void testWriteXml() throws Exception {
588 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
589 mZenModeHelperSpy.mConfig.allowAlarms = false;
590 mZenModeHelperSpy.mConfig.allowMedia = false;
591 mZenModeHelperSpy.mConfig.allowSystem = false;
592 mZenModeHelperSpy.mConfig.allowReminders = true;
593 mZenModeHelperSpy.mConfig.allowCalls = true;
594 mZenModeHelperSpy.mConfig.allowMessages = true;
595 mZenModeHelperSpy.mConfig.allowEvents = true;
596 mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
597 mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
598 mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
599 mZenModeHelperSpy.mConfig.manualRule.zenMode =
600 Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
601 mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
602 mZenModeHelperSpy.mConfig.manualRule.enabled = true;
603 mZenModeHelperSpy.mConfig.manualRule.snoozing = true;
605 ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
607 ByteArrayOutputStream baos = writeXmlAndPurge(false, null);
608 XmlPullParser parser = Xml.newPullParser();
609 parser.setInput(new BufferedInputStream(
610 new ByteArrayInputStream(baos.toByteArray())), null);
612 mZenModeHelperSpy.readXml(parser, false);
614 assertEquals(expected, mZenModeHelperSpy.mConfig);
618 public void testReadXml() throws Exception {
621 // automatic zen rule is enabled on upgrade so rules should not be overriden by default
622 ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
623 ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
624 final ScheduleInfo weeknights = new ScheduleInfo();
625 customRule.enabled = true;
626 customRule.name = "Custom Rule";
627 customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
628 customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
629 enabledAutoRule.put("customRule", customRule);
630 mZenModeHelperSpy.mConfig.automaticRules = enabledAutoRule;
632 ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
634 // set previous version
635 ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
636 XmlPullParser parser = Xml.newPullParser();
637 parser.setInput(new BufferedInputStream(
638 new ByteArrayInputStream(baos.toByteArray())), null);
640 mZenModeHelperSpy.readXml(parser, false);
642 assertTrue(mZenModeHelperSpy.mConfig.automaticRules.containsKey("customRule"));
643 setupZenConfigMaintained();
647 public void testMigrateSuppressedVisualEffects_oneExistsButOff() throws Exception {
648 String xml = "<zen version=\"6\" user=\"0\">\n"
649 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
650 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
651 + "visualScreenOff=\"true\" alarms=\"true\" "
652 + "media=\"true\" system=\"false\" />\n"
653 + "<disallow visualEffects=\"511\" />"
656 XmlPullParser parser = Xml.newPullParser();
657 parser.setInput(new BufferedInputStream(
658 new ByteArrayInputStream(xml.getBytes())), null);
660 mZenModeHelperSpy.readXml(parser, false);
662 assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
664 xml = "<zen version=\"6\" user=\"0\">\n"
665 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
666 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
667 + "visualScreenOn=\"true\" alarms=\"true\" "
668 + "media=\"true\" system=\"false\" />\n"
669 + "<disallow visualEffects=\"511\" />"
672 parser = Xml.newPullParser();
673 parser.setInput(new BufferedInputStream(
674 new ByteArrayInputStream(xml.getBytes())), null);
676 mZenModeHelperSpy.readXml(parser, false);
678 assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
682 public void testMigrateSuppressedVisualEffects_bothExistButOff() throws Exception {
683 String xml = "<zen version=\"6\" user=\"0\">\n"
684 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
685 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
686 + "visualScreenOff=\"true\" visualScreenOn=\"true\" alarms=\"true\" "
687 + "media=\"true\" system=\"false\" />\n"
688 + "<disallow visualEffects=\"511\" />"
691 XmlPullParser parser = Xml.newPullParser();
692 parser.setInput(new BufferedInputStream(
693 new ByteArrayInputStream(xml.getBytes())), null);
695 mZenModeHelperSpy.readXml(parser, false);
697 assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
701 public void testMigrateSuppressedVisualEffects_bothExistButOn() throws Exception {
702 String xml = "<zen version=\"6\" user=\"0\">\n"
703 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
704 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
705 + "visualScreenOff=\"false\" visualScreenOn=\"false\" alarms=\"true\" "
706 + "media=\"true\" system=\"false\" />\n"
707 + "<disallow visualEffects=\"511\" />"
710 XmlPullParser parser = Xml.newPullParser();
711 parser.setInput(new BufferedInputStream(
712 new ByteArrayInputStream(xml.getBytes())), null);
714 mZenModeHelperSpy.readXml(parser, false);
716 assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
717 | SUPPRESSED_EFFECT_LIGHTS
718 | SUPPRESSED_EFFECT_PEEK,
719 mZenModeHelperSpy.mConfig.suppressedVisualEffects);
721 xml = "<zen version=\"6\" user=\"0\">\n"
722 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
723 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
724 + "visualScreenOff=\"true\" visualScreenOn=\"false\" alarms=\"true\" "
725 + "media=\"true\" system=\"false\" />\n"
726 + "<disallow visualEffects=\"511\" />"
729 parser = Xml.newPullParser();
730 parser.setInput(new BufferedInputStream(
731 new ByteArrayInputStream(xml.getBytes())), null);
733 mZenModeHelperSpy.readXml(parser, false);
735 assertEquals(SUPPRESSED_EFFECT_PEEK, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
737 xml = "<zen version=\"6\" user=\"0\">\n"
738 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
739 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
740 + "visualScreenOff=\"false\" visualScreenOn=\"true\" alarms=\"true\" "
741 + "media=\"true\" system=\"false\" />\n"
742 + "<disallow visualEffects=\"511\" />"
745 parser = Xml.newPullParser();
746 parser.setInput(new BufferedInputStream(
747 new ByteArrayInputStream(xml.getBytes())), null);
749 mZenModeHelperSpy.readXml(parser, false);
751 assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT | SUPPRESSED_EFFECT_LIGHTS,
752 mZenModeHelperSpy.mConfig.suppressedVisualEffects);
756 public void testReadXmlResetDefaultRules() throws Exception {
759 // no enabled automatic zen rule, so rules should be overriden by default rules
760 mZenModeHelperSpy.mConfig.automaticRules = new ArrayMap<>();
762 // set previous version
763 ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
764 XmlPullParser parser = Xml.newPullParser();
765 parser.setInput(new BufferedInputStream(
766 new ByteArrayInputStream(baos.toByteArray())), null);
768 mZenModeHelperSpy.readXml(parser, false);
770 // check default rules
771 ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
772 assertTrue(rules.size() != 0);
773 for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
774 assertTrue(rules.containsKey(defaultId));
777 setupZenConfigMaintained();
782 public void testReadXmlAllDisabledRulesResetDefaultRules() throws Exception {
785 // all automatic zen rules are diabled on upgrade so rules should be overriden by default
787 ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
788 ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
789 final ScheduleInfo weeknights = new ScheduleInfo();
790 customRule.enabled = false;
791 customRule.name = "Custom Rule";
792 customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
793 customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
794 enabledAutoRule.put("customRule", customRule);
795 mZenModeHelperSpy.mConfig.automaticRules = enabledAutoRule;
797 // set previous version
798 ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
799 XmlPullParser parser = Xml.newPullParser();
800 parser.setInput(new BufferedInputStream(
801 new ByteArrayInputStream(baos.toByteArray())), null);
803 mZenModeHelperSpy.readXml(parser, false);
805 // check default rules
806 ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
807 assertTrue(rules.size() != 0);
808 for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
809 assertTrue(rules.containsKey(defaultId));
811 assertFalse(rules.containsKey("customRule"));
813 setupZenConfigMaintained();
816 private void setupZenConfig() {
817 mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
818 mZenModeHelperSpy.mConfig.allowAlarms = false;
819 mZenModeHelperSpy.mConfig.allowMedia = false;
820 mZenModeHelperSpy.mConfig.allowSystem = false;
821 mZenModeHelperSpy.mConfig.allowReminders = true;
822 mZenModeHelperSpy.mConfig.allowCalls = true;
823 mZenModeHelperSpy.mConfig.allowMessages = true;
824 mZenModeHelperSpy.mConfig.allowEvents = true;
825 mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
826 mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
827 mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
828 mZenModeHelperSpy.mConfig.manualRule.zenMode =
829 Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
830 mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
831 mZenModeHelperSpy.mConfig.manualRule.enabled = true;
832 mZenModeHelperSpy.mConfig.manualRule.snoozing = true;
835 private void setupZenConfigMaintained() {
836 // config is still the same as when it was setup (setupZenConfig)
837 assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
838 assertFalse(mZenModeHelperSpy.mConfig.allowMedia);
839 assertFalse(mZenModeHelperSpy.mConfig.allowSystem);
840 assertTrue(mZenModeHelperSpy.mConfig.allowReminders);
841 assertTrue(mZenModeHelperSpy.mConfig.allowCalls);
842 assertTrue(mZenModeHelperSpy.mConfig.allowMessages);
843 assertTrue(mZenModeHelperSpy.mConfig.allowEvents);
844 assertTrue(mZenModeHelperSpy.mConfig.allowRepeatCallers);
845 assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelperSpy.mConfig.suppressedVisualEffects);