OSDN Git Service

Fix migration of O DND visual effects settings
[android-x86/frameworks-base.git] / services / tests / uiservicestests / src / com / android / server / notification / ZenModeHelperTest.java
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is 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.
15  */
16
17 package com.android.server.notification;
18
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;
23
24 import static junit.framework.Assert.assertFalse;
25 import static junit.framework.Assert.assertEquals;
26 import static junit.framework.TestCase.assertTrue;
27
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;
40
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;
61
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;
67
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;
75
76 import java.io.BufferedInputStream;
77 import java.io.BufferedOutputStream;
78 import java.io.ByteArrayInputStream;
79 import java.io.ByteArrayOutputStream;
80
81 @SmallTest
82 @RunWith(AndroidTestingRunner.class)
83 @TestableLooper.RunWithLooper
84 public class ZenModeHelperTest extends UiServiceTestCase {
85
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;
93
94     @Before
95     public void setUp() {
96         MockitoAnnotations.initMocks(this);
97
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);
105
106         mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(),
107                 mConditionProviders));
108     }
109
110     private ByteArrayOutputStream writeXmlAndPurge(boolean forBackup, Integer version)
111             throws Exception {
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();
118         serializer.flush();
119         mZenModeHelperSpy.setConfig(new ZenModeConfig(), "writing xml");
120         return baos;
121     }
122
123     @Test
124     public void testZenOff_NoMuteApplied() {
125         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_OFF;
126         assertTrue(mZenModeHelperSpy.mConfig.allowAlarms);
127         mZenModeHelperSpy.applyRestrictions();
128
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);
134     }
135
136     @Test
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);
146     }
147
148     @Test
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);
160
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);
166     }
167
168     @Test
169     public void testTotalSilence() {
170         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
171         mZenModeHelperSpy.applyRestrictions();
172
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);
186     }
187
188     @Test
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();
197
198         // Alarms only mode will not silence alarms
199         verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
200                 AudioAttributes.USAGE_ALARM);
201
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);
209
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);
213     }
214
215     @Test
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();
221
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);
227     }
228
229     @Test
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();
249
250         verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
251                 AudioAttributes.USAGE_ALARM);
252     }
253
254     @Test
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();
275
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);
283             } else {
284                 boolean shouldMute = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage)
285                         != AudioAttributes.SUPPRESSIBLE_NEVER;
286                 verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(shouldMute, usage);
287             }
288         }
289     }
290
291     @Test
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);
298
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));
304     }
305
306     @Test
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);
312
313         verify(mZenModeHelperSpy, never()).createZenUpgradeNotification();
314         verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG),
315                 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
316     }
317
318     @Test
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));
324
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;
334
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);
339
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);
346     }
347
348     @Test
349     public void testRingerAffectedStreamsTotalSilence() {
350         // in total silence:
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))
358                 != 0);
359         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0);
360         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) != 0);
361         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) != 0);
362     }
363
364     @Test
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();
374
375         int ringerModeAffectedStreams =
376                 ringerModeDelegateRingerMuted.getRingerModeAffectedStreams(0);
377         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
378         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
379                 != 0);
380         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0);
381         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0);
382         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0);
383
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();
393
394         int ringerMutedRingerModeAffectedStreams =
395                 ringerModeDelegateRingerNotMuted.getRingerModeAffectedStreams(0);
396         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
397         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
398                 != 0);
399         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM))
400                 == 0);
401         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0);
402         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0);
403     }
404
405     @Test
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));
411
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;
416
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);
421
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);
428     }
429
430     @Test
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));
436
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;
441
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);
446
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);
453     }
454
455     @Test
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));
461
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;
467
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);
472
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));
481
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);
488     }
489
490     @Test
491     public void testSilentRingerSavedInZenOff_startsZenOff() {
492         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
493         mZenModeHelperSpy.mAudioManager = mAudioManager;
494
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);
502         }
503         verify(mZenModeHelperSpy, never()).applyZenToRingerMode();
504         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
505                 mZenModeHelperSpy.TAG);
506     }
507
508     @Test
509     public void testSilentRingerSavedOnZenOff_startsZenOn() {
510         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
511         mZenModeHelperSpy.mAudioManager = mAudioManager;
512         mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
513
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));
522
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);
530         }
531         verify(mZenModeHelperSpy, times(1)).applyZenToRingerMode();
532         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
533                 mZenModeHelperSpy.TAG);
534     }
535
536     @Test
537     public void testVibrateRingerSavedOnZenOff_startsZenOn() {
538         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
539         mZenModeHelperSpy.mAudioManager = mAudioManager;
540         mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
541
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));
550
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);
558         }
559         verify(mZenModeHelperSpy, times(1)).applyZenToRingerMode();
560         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
561                 mZenModeHelperSpy.TAG);
562     }
563
564     @Test
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;
580
581         ZenModeConfig actual = mZenModeHelperSpy.mConfig.copy();
582
583         assertEquals(mZenModeHelperSpy.mConfig, actual);
584     }
585
586     @Test
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;
604
605         ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
606
607         ByteArrayOutputStream baos = writeXmlAndPurge(false, null);
608         XmlPullParser parser = Xml.newPullParser();
609         parser.setInput(new BufferedInputStream(
610                 new ByteArrayInputStream(baos.toByteArray())), null);
611         parser.nextTag();
612         mZenModeHelperSpy.readXml(parser, false);
613
614         assertEquals(expected, mZenModeHelperSpy.mConfig);
615     }
616
617     @Test
618     public void testReadXml() throws Exception {
619         setupZenConfig();
620
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;
631
632         ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
633
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);
639         parser.nextTag();
640         mZenModeHelperSpy.readXml(parser, false);
641
642         assertTrue(mZenModeHelperSpy.mConfig.automaticRules.containsKey("customRule"));
643         setupZenConfigMaintained();
644     }
645
646     @Test
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\" />"
654                 + "</zen>";
655
656         XmlPullParser parser = Xml.newPullParser();
657         parser.setInput(new BufferedInputStream(
658                 new ByteArrayInputStream(xml.getBytes())), null);
659         parser.nextTag();
660         mZenModeHelperSpy.readXml(parser, false);
661
662         assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
663
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\" />"
670                 + "</zen>";
671
672         parser = Xml.newPullParser();
673         parser.setInput(new BufferedInputStream(
674                 new ByteArrayInputStream(xml.getBytes())), null);
675         parser.nextTag();
676         mZenModeHelperSpy.readXml(parser, false);
677
678         assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
679     }
680
681     @Test
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\" />"
689                 + "</zen>";
690
691         XmlPullParser parser = Xml.newPullParser();
692         parser.setInput(new BufferedInputStream(
693                 new ByteArrayInputStream(xml.getBytes())), null);
694         parser.nextTag();
695         mZenModeHelperSpy.readXml(parser, false);
696
697         assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
698     }
699
700     @Test
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\" />"
708                 + "</zen>";
709
710         XmlPullParser parser = Xml.newPullParser();
711         parser.setInput(new BufferedInputStream(
712                 new ByteArrayInputStream(xml.getBytes())), null);
713         parser.nextTag();
714         mZenModeHelperSpy.readXml(parser, false);
715
716         assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
717                 | SUPPRESSED_EFFECT_LIGHTS
718                 | SUPPRESSED_EFFECT_PEEK,
719                 mZenModeHelperSpy.mConfig.suppressedVisualEffects);
720
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\" />"
727                 + "</zen>";
728
729         parser = Xml.newPullParser();
730         parser.setInput(new BufferedInputStream(
731                 new ByteArrayInputStream(xml.getBytes())), null);
732         parser.nextTag();
733         mZenModeHelperSpy.readXml(parser, false);
734
735         assertEquals(SUPPRESSED_EFFECT_PEEK, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
736
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\" />"
743                 + "</zen>";
744
745         parser = Xml.newPullParser();
746         parser.setInput(new BufferedInputStream(
747                 new ByteArrayInputStream(xml.getBytes())), null);
748         parser.nextTag();
749         mZenModeHelperSpy.readXml(parser, false);
750
751         assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT | SUPPRESSED_EFFECT_LIGHTS,
752                 mZenModeHelperSpy.mConfig.suppressedVisualEffects);
753     }
754
755     @Test
756     public void testReadXmlResetDefaultRules() throws Exception {
757         setupZenConfig();
758
759         // no enabled automatic zen rule, so rules should be overriden by default rules
760         mZenModeHelperSpy.mConfig.automaticRules = new ArrayMap<>();
761
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);
767         parser.nextTag();
768         mZenModeHelperSpy.readXml(parser, false);
769
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));
775         }
776
777         setupZenConfigMaintained();
778     }
779
780
781     @Test
782     public void testReadXmlAllDisabledRulesResetDefaultRules() throws Exception {
783         setupZenConfig();
784
785         // all automatic zen rules are diabled on upgrade so rules should be overriden by default
786         // rules
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;
796
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);
802         parser.nextTag();
803         mZenModeHelperSpy.readXml(parser, false);
804
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));
810         }
811         assertFalse(rules.containsKey("customRule"));
812
813         setupZenConfigMaintained();
814     }
815
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;
833     }
834
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);
846     }
847 }