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.CONVERSATION_SENDERS_ANYONE;
20 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS;
21 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
22 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
23 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS;
24 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA;
25 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
26 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS;
27 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS;
28 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM;
29 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
30 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
31 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
32 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
33 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
34 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
35 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
36 import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
37 import static android.service.notification.Condition.STATE_FALSE;
38 import static android.service.notification.Condition.STATE_TRUE;
39 import static android.util.StatsLog.ANNOTATION_ID_IS_UID;
40 
41 import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.LOG_DND_STATE_EVENTS;
42 import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
43 import static com.android.os.dnd.DNDModeProto.CHANNELS_BYPASSING_FIELD_NUMBER;
44 import static com.android.os.dnd.DNDModeProto.ENABLED_FIELD_NUMBER;
45 import static com.android.os.dnd.DNDModeProto.ID_FIELD_NUMBER;
46 import static com.android.os.dnd.DNDModeProto.UID_FIELD_NUMBER;
47 import static com.android.os.dnd.DNDModeProto.ZEN_MODE_FIELD_NUMBER;
48 import static com.android.os.dnd.DNDProtoEnums.PEOPLE_STARRED;
49 import static com.android.os.dnd.DNDProtoEnums.ROOT_CONFIG;
50 import static com.android.os.dnd.DNDProtoEnums.STATE_ALLOW;
51 import static com.android.os.dnd.DNDProtoEnums.STATE_DISALLOW;
52 import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE;
53 
54 import static junit.framework.Assert.assertEquals;
55 import static junit.framework.Assert.assertFalse;
56 import static junit.framework.Assert.assertNotNull;
57 import static junit.framework.TestCase.assertTrue;
58 import static junit.framework.TestCase.fail;
59 
60 import static org.junit.Assert.assertNotEquals;
61 import static org.junit.Assert.assertNull;
62 import static org.mockito.ArgumentMatchers.any;
63 import static org.mockito.ArgumentMatchers.anyInt;
64 import static org.mockito.ArgumentMatchers.anyString;
65 import static org.mockito.ArgumentMatchers.eq;
66 import static org.mockito.Mockito.atLeastOnce;
67 import static org.mockito.Mockito.mock;
68 import static org.mockito.Mockito.never;
69 import static org.mockito.Mockito.notNull;
70 import static org.mockito.Mockito.reset;
71 import static org.mockito.Mockito.spy;
72 import static org.mockito.Mockito.times;
73 import static org.mockito.Mockito.verify;
74 import static org.mockito.Mockito.when;
75 
76 import android.app.AppGlobals;
77 import android.app.AppOpsManager;
78 import android.app.AutomaticZenRule;
79 import android.app.NotificationManager;
80 import android.app.NotificationManager.Policy;
81 import android.content.ComponentName;
82 import android.content.ContentResolver;
83 import android.content.pm.ActivityInfo;
84 import android.content.pm.PackageManager;
85 import android.content.pm.ResolveInfo;
86 import android.content.res.Resources;
87 import android.content.res.XmlResourceParser;
88 import android.media.AudioAttributes;
89 import android.media.AudioManager;
90 import android.media.AudioManagerInternal;
91 import android.media.AudioSystem;
92 import android.media.VolumePolicy;
93 import android.net.Uri;
94 import android.os.Process;
95 import android.os.UserHandle;
96 import android.provider.Settings;
97 import android.provider.Settings.Global;
98 import android.service.notification.Condition;
99 import android.service.notification.ZenModeConfig;
100 import android.service.notification.ZenModeConfig.ScheduleInfo;
101 import android.service.notification.ZenModeDiff;
102 import android.service.notification.ZenPolicy;
103 import android.test.suitebuilder.annotation.SmallTest;
104 import android.testing.AndroidTestingRunner;
105 import android.testing.TestableLooper;
106 import android.util.ArrayMap;
107 import android.util.Log;
108 import android.util.StatsEvent;
109 import android.util.Xml;
110 
111 import com.android.internal.R;
112 import com.android.internal.config.sysui.TestableFlagResolver;
113 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
114 import com.android.modules.utils.TypedXmlPullParser;
115 import com.android.modules.utils.TypedXmlSerializer;
116 import com.android.os.dnd.DNDPolicyProto;
117 import com.android.os.dnd.DNDProtoEnums;
118 import com.android.server.UiServiceTestCase;
119 import com.android.server.notification.ManagedServices.UserProfiles;
120 
121 import com.google.common.collect.ImmutableList;
122 
123 import org.junit.Before;
124 import org.junit.Test;
125 import org.junit.runner.RunWith;
126 import org.mockito.Mock;
127 import org.mockito.MockitoAnnotations;
128 import org.xmlpull.v1.XmlPullParserException;
129 
130 import java.io.BufferedInputStream;
131 import java.io.BufferedOutputStream;
132 import java.io.ByteArrayInputStream;
133 import java.io.ByteArrayOutputStream;
134 import java.io.IOException;
135 import java.io.InputStream;
136 import java.io.Reader;
137 import java.util.ArrayList;
138 import java.util.LinkedList;
139 import java.util.List;
140 import java.util.Objects;
141 
142 @SmallTest
143 @RunWith(AndroidTestingRunner.class)
144 @TestableLooper.RunWithLooper
145 public class ZenModeHelperTest extends UiServiceTestCase {
146 
147     private static final String EVENTS_DEFAULT_RULE_ID = "EVENTS_DEFAULT_RULE";
148     private static final String SCHEDULE_DEFAULT_RULE_ID = "EVERY_NIGHT_DEFAULT_RULE";
149     private static final int ZEN_MODE_FOR_TESTING = 99;
150     private static final String CUSTOM_PKG_NAME = "not.android";
151     private static final int CUSTOM_PKG_UID = 1;
152     private static final String CUSTOM_RULE_ID = "custom_rule";
153 
154     ConditionProviders mConditionProviders;
155     @Mock NotificationManager mNotificationManager;
156     @Mock PackageManager mPackageManager;
157     private Resources mResources;
158     private TestableLooper mTestableLooper;
159     private ZenModeHelper mZenModeHelper;
160     private ContentResolver mContentResolver;
161     @Mock AppOpsManager mAppOps;
162     private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory;
163     TestableFlagResolver mTestFlagResolver = new TestableFlagResolver();
164     ZenModeEventLoggerFake mZenModeEventLogger;
165 
166     @Before
setUp()167     public void setUp() throws PackageManager.NameNotFoundException {
168         MockitoAnnotations.initMocks(this);
169 
170         mTestableLooper = TestableLooper.get(this);
171         mContentResolver = mContext.getContentResolver();
172         mResources = spy(mContext.getResources());
173         String pkg = mContext.getPackageName();
174         try {
175             when(mResources.getXml(R.xml.default_zen_mode_config)).thenReturn(
176                     getDefaultConfigParser());
177         } catch (Exception e) {
178             Log.d("ZenModeHelperTest", "Couldn't mock default zen mode config xml file err=" +
179                     e.toString());
180         }
181         mStatsEventBuilderFactory = new WrappedSysUiStatsEvent.WrappedBuilderFactory();
182 
183         when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOps);
184         when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager);
185         mConditionProviders = new ConditionProviders(mContext, new UserProfiles(),
186                 AppGlobals.getPackageManager());
187         mConditionProviders.addSystemProvider(new CountdownConditionProvider());
188         mConditionProviders.addSystemProvider(new ScheduleConditionProvider());
189         mZenModeEventLogger = new ZenModeEventLoggerFake(mPackageManager);
190         mZenModeHelper = new ZenModeHelper(mContext, mTestableLooper.getLooper(),
191                 mConditionProviders, mStatsEventBuilderFactory, mTestFlagResolver,
192                 mZenModeEventLogger);
193 
194         ResolveInfo ri = new ResolveInfo();
195         ri.activityInfo = new ActivityInfo();
196         when(mPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), anyInt())).thenReturn(
197                 ImmutableList.of(ri));
198         when(mPackageManager.getPackageUidAsUser(eq(CUSTOM_PKG_NAME), anyInt()))
199                 .thenReturn(CUSTOM_PKG_UID);
200         when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
201                 new String[] {pkg});
202         mZenModeHelper.mPm = mPackageManager;
203 
204         mZenModeEventLogger.reset();
205     }
206 
getDefaultConfigParser()207     private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException {
208         String xml = "<zen version=\"8\" user=\"0\">\n"
209                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
210                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
211                 + "visualScreenOff=\"true\" alarms=\"true\" "
212                 + "media=\"true\" system=\"false\" conversations=\"true\""
213                 + " conversationsFrom=\"2\"/>\n"
214                 + "<automatic ruleId=\"" + EVENTS_DEFAULT_RULE_ID
215                 + "\" enabled=\"false\" snoozing=\"false\""
216                 + " name=\"Event\" zen=\"1\""
217                 + " component=\"android/com.android.server.notification.EventConditionProvider\""
218                 + " conditionId=\"condition://android/event?userId=-10000&amp;calendar=&amp;"
219                 + "reply=1\"/>\n"
220                 + "<automatic ruleId=\"" + SCHEDULE_DEFAULT_RULE_ID + "\" enabled=\"false\""
221                 + " snoozing=\"false\" name=\"Sleeping\" zen=\"1\""
222                 + " component=\"android/com.android.server.notification.ScheduleConditionProvider\""
223                 + " conditionId=\"condition://android/schedule?days=1.2.3.4.5.6.7 &amp;start=22.0"
224                 + "&amp;end=7.0&amp;exitAtAlarm=true\"/>"
225                 + "<disallow visualEffects=\"511\" />"
226                 + "</zen>";
227         TypedXmlPullParser parser = Xml.newFastPullParser();
228         parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), null);
229         parser.nextTag();
230         return new XmlResourceParserImpl(parser);
231     }
232 
writeXmlAndPurge(Integer version)233     private ByteArrayOutputStream writeXmlAndPurge(Integer version) throws Exception {
234         TypedXmlSerializer serializer = Xml.newFastSerializer();
235         ByteArrayOutputStream baos = new ByteArrayOutputStream();
236         serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
237         serializer.startDocument(null, true);
238         mZenModeHelper.writeXml(serializer, false, version, UserHandle.USER_ALL);
239         serializer.endDocument();
240         serializer.flush();
241         mZenModeHelper.setConfig(new ZenModeConfig(), null, "writing xml", Process.SYSTEM_UID,
242                 true);
243         return baos;
244     }
245 
writeXmlAndPurgeForUser(Integer version, int userId)246     private ByteArrayOutputStream writeXmlAndPurgeForUser(Integer version, int userId)
247             throws Exception {
248         TypedXmlSerializer serializer = Xml.newFastSerializer();
249         ByteArrayOutputStream baos = new ByteArrayOutputStream();
250         serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
251         serializer.startDocument(null, true);
252         mZenModeHelper.writeXml(serializer, true, version, userId);
253         serializer.endDocument();
254         serializer.flush();
255         ZenModeConfig newConfig = new ZenModeConfig();
256         newConfig.user = userId;
257         mZenModeHelper.setConfig(newConfig, null, "writing xml", Process.SYSTEM_UID, true);
258         return baos;
259     }
260 
getParserForByteStream(ByteArrayOutputStream baos)261     private TypedXmlPullParser getParserForByteStream(ByteArrayOutputStream baos) throws Exception {
262         TypedXmlPullParser parser = Xml.newFastPullParser();
263         parser.setInput(
264                 new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null);
265         parser.nextTag();
266         return parser;
267     }
268 
getCustomAutomaticRules()269     private ArrayMap<String, ZenModeConfig.ZenRule> getCustomAutomaticRules() {
270         return getCustomAutomaticRules(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
271     }
272 
getCustomAutomaticRules(int zenMode)273     private ArrayMap<String, ZenModeConfig.ZenRule> getCustomAutomaticRules(int zenMode) {
274         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
275         ZenModeConfig.ZenRule rule = createCustomAutomaticRule(zenMode, CUSTOM_RULE_ID);
276         automaticRules.put(rule.id, rule);
277         return automaticRules;
278     }
279 
createCustomAutomaticRule(int zenMode, String id)280     private ZenModeConfig.ZenRule createCustomAutomaticRule(int zenMode, String id) {
281         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
282         final ScheduleInfo customRuleInfo = new ScheduleInfo();
283         customRule.enabled = true;
284         customRule.creationTime = 0;
285         customRule.id = id;
286         customRule.name = "Custom Rule with id=" + id;
287         customRule.zenMode = zenMode;
288         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
289         customRule.configurationActivity =
290                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider");
291         customRule.pkg = customRule.configurationActivity.getPackageName();
292         return customRule;
293     }
294 
295     // Verify that the appropriate appOpps operations are called for the restrictions requested.
296     // Note that this method assumes that priority only DND exempt packages is set to something
297     // in order to be able to distinguish it from the null case, so callers should make sure
298     // setPriorityOnlyDndExemptPackages has been called bofre this verify statement.
verifyApplyRestrictions(boolean zenPriorityOnly, boolean mute, int usage)299     private void verifyApplyRestrictions(boolean zenPriorityOnly, boolean mute, int usage) {
300         int expectedMode = mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
301         verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_VIBRATE), eq(usage),
302                 eq(expectedMode), zenPriorityOnly ? notNull() : eq(null));
303         verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage),
304                 eq(expectedMode), zenPriorityOnly ? notNull() : eq(null));
305     }
306 
307     @Test
testZenOff_NoMuteApplied()308     public void testZenOff_NoMuteApplied() {
309         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_OFF;
310         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
311         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
312                 | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
313         mZenModeHelper.applyRestrictions();
314 
315         // Check that we call through to applyRestrictions with usages USAGE_ALARM and USAGE_MEDIA
316         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
317         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_MEDIA);
318     }
319 
320     @Test
testZenOn_NotificationApplied()321     public void testZenOn_NotificationApplied() {
322         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
323         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
324         // The most permissive policy
325         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
326                 | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
327                 | PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
328                 | PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
329                 | PRIORITY_CATEGORY_REPEAT_CALLERS | PRIORITY_CATEGORY_SYSTEM, PRIORITY_SENDERS_ANY,
330                 PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
331         mZenModeHelper.applyRestrictions();
332 
333         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_NOTIFICATION);
334         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_NOTIFICATION_EVENT);
335         verifyApplyRestrictions(true, true,
336                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED);
337         verifyApplyRestrictions(true, true,
338                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT);
339     }
340 
341     @Test
testZenOn_StarredCallers_CallTypesBlocked()342     public void testZenOn_StarredCallers_CallTypesBlocked() {
343         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
344         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
345         // The most permissive policy
346         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
347                 | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
348                 | PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
349                 | PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
350                 | PRIORITY_CATEGORY_SYSTEM,
351                 PRIORITY_SENDERS_STARRED,
352                 PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
353         mZenModeHelper.applyRestrictions();
354 
355         verifyApplyRestrictions(true, true,
356                 AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
357         verifyApplyRestrictions(true, true,
358                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
359     }
360 
361     @Test
testZenOn_AllCallers_CallTypesAllowed()362     public void testZenOn_AllCallers_CallTypesAllowed() {
363         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
364         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
365         // The most permissive policy
366         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
367                 | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
368                 | PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
369                 | PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
370                 | PRIORITY_CATEGORY_REPEAT_CALLERS | PRIORITY_CATEGORY_SYSTEM,
371                 PRIORITY_SENDERS_ANY,
372                 PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
373         mZenModeHelper.applyRestrictions();
374 
375         verifyApplyRestrictions(true, false, AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
376         verifyApplyRestrictions(true, false,
377                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
378     }
379 
380     @Test
testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied()381     public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() {
382         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
383         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
384         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
385                 | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
386 
387         mZenModeHelper.applyRestrictions();
388         verifyApplyRestrictions(true, false, AudioAttributes.USAGE_ALARM);
389         verifyApplyRestrictions(true, false, AudioAttributes.USAGE_MEDIA);
390     }
391 
392     @Test
testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied()393     public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() {
394         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
395         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
396         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
397         mZenModeHelper.applyRestrictions();
398         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_ALARM);
399 
400         // Media is a catch-all that includes games
401         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_MEDIA);
402         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_GAME);
403     }
404 
405     @Test
testTotalSilence()406     public void testTotalSilence() {
407         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
408         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
409         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
410                 | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
411         mZenModeHelper.applyRestrictions();
412 
413         // Total silence will silence alarms, media and system noises (but not vibrations)
414         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_ALARM);
415         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_MEDIA);
416         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_GAME);
417         verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_PLAY_AUDIO,
418                 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_IGNORED, null);
419         verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_VIBRATE,
420                 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_ALLOWED, null);
421         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_UNKNOWN);
422     }
423 
424     @Test
testAlarmsOnly_alarmMediaMuteNotApplied()425     public void testAlarmsOnly_alarmMediaMuteNotApplied() {
426         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
427         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
428         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
429         mZenModeHelper.applyRestrictions();
430 
431         // Alarms only mode will not silence alarms
432         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
433 
434         // Alarms only mode will not silence media
435         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_MEDIA);
436         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_GAME);
437         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_UNKNOWN);
438 
439         // Alarms only will silence system noises (but not vibrations)
440         verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_PLAY_AUDIO,
441                 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_IGNORED, null);
442     }
443 
444     @Test
testAlarmsOnly_callsMuteApplied()445     public void testAlarmsOnly_callsMuteApplied() {
446         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
447         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
448         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
449         mZenModeHelper.applyRestrictions();
450 
451         // Alarms only mode will silence calls despite priority-mode config
452         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
453         verifyApplyRestrictions(false, true,
454                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
455     }
456 
457     @Test
testAlarmsOnly_allZenConfigToggledCannotBypass_alarmMuteNotApplied()458     public void testAlarmsOnly_allZenConfigToggledCannotBypass_alarmMuteNotApplied() {
459         // Only audio attributes with SUPPRESIBLE_NEVER can bypass
460         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
461         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
462         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
463         mZenModeHelper.applyRestrictions();
464 
465         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
466     }
467 
468     @Test
testZenAllCannotBypass()469     public void testZenAllCannotBypass() {
470         // Only audio attributes with SUPPRESIBLE_NEVER can bypass
471         // with special case USAGE_ASSISTANCE_SONIFICATION
472         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
473         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
474         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
475         mZenModeHelper.applyRestrictions();
476 
477         for (int usage : AudioAttributes.SDK_USAGES) {
478             if (usage == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) {
479                 // only mute audio, not vibrations
480                 verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_PLAY_AUDIO),
481                         eq(usage), eq(AppOpsManager.MODE_IGNORED), notNull());
482                 verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_VIBRATE),
483                         eq(usage), eq(AppOpsManager.MODE_ALLOWED), notNull());
484             } else {
485                 boolean shouldMute = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage)
486                         != AudioAttributes.SUPPRESSIBLE_NEVER;
487                 verifyApplyRestrictions(true, shouldMute, usage);
488             }
489         }
490     }
491 
492     @Test
testApplyRestrictions_whitelist_priorityOnlyMode()493     public void testApplyRestrictions_whitelist_priorityOnlyMode() {
494         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
495         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
496         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
497         mZenModeHelper.applyRestrictions();
498 
499         for (int usage : AudioAttributes.SDK_USAGES) {
500             verify(mAppOps).setRestriction(
501                     eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage), anyInt(), eq(new String[]{PKG_O}));
502             verify(mAppOps).setRestriction(
503                     eq(AppOpsManager.OP_VIBRATE), eq(usage), anyInt(), eq(new String[]{PKG_O}));
504         }
505     }
506 
507     @Test
testApplyRestrictions_whitelist_alarmsOnlyMode()508     public void testApplyRestrictions_whitelist_alarmsOnlyMode() {
509         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
510         mZenModeHelper.mZenMode = Global.ZEN_MODE_ALARMS;
511         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
512         mZenModeHelper.applyRestrictions();
513 
514         for (int usage : AudioAttributes.SDK_USAGES) {
515             verify(mAppOps).setRestriction(
516                     eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage), anyInt(), eq(null));
517             verify(mAppOps).setRestriction(
518                     eq(AppOpsManager.OP_VIBRATE), eq(usage), anyInt(), eq(null));
519         }
520     }
521 
522     @Test
testApplyRestrictions_whitelist_totalSilenceMode()523     public void testApplyRestrictions_whitelist_totalSilenceMode() {
524         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
525         mZenModeHelper.mZenMode = Global.ZEN_MODE_NO_INTERRUPTIONS;
526         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
527         mZenModeHelper.applyRestrictions();
528 
529         for (int usage : AudioAttributes.SDK_USAGES) {
530             verify(mAppOps).setRestriction(
531                     eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage), anyInt(), eq(null));
532             verify(mAppOps).setRestriction(
533                     eq(AppOpsManager.OP_VIBRATE), eq(usage), anyInt(), eq(null));
534         }
535     }
536 
537     @Test
testZenUpgradeNotification()538     public void testZenUpgradeNotification() {
539         /**
540          * Commit a485ec65b5ba947d69158ad90905abf3310655cf disabled DND status change
541          * notification on watches. So, assume that the device is not watch.
542          */
543         when(mContext.getPackageManager()).thenReturn(mPackageManager);
544         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)).thenReturn(false);
545 
546         // shows zen upgrade notification if stored settings says to shows,
547         // zen has not been updated, boot is completed
548         // and we're setting zen mode on
549         Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);
550         Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 0);
551         mZenModeHelper.mIsBootComplete = true;
552         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
553         mZenModeHelper.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
554 
555         verify(mNotificationManager, times(1)).notify(eq(ZenModeHelper.TAG),
556                 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
557         assertEquals(0, Settings.Secure.getInt(mContentResolver,
558                 Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, -1));
559     }
560 
561     @Test
testNoZenUpgradeNotification()562     public void testNoZenUpgradeNotification() {
563         // doesn't show upgrade notification if stored settings says don't show
564         Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
565         Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 0);
566         mZenModeHelper.mIsBootComplete = true;
567         mZenModeHelper.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
568 
569         verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG),
570                 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
571     }
572 
573     @Test
testNoZenUpgradeNotificationZenUpdated()574     public void testNoZenUpgradeNotificationZenUpdated() {
575         // doesn't show upgrade notification since zen was already updated
576         Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
577         Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 1);
578         mZenModeHelper.mIsBootComplete = true;
579         mZenModeHelper.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
580 
581         verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG),
582                 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
583     }
584 
585     @Test
testZenSetInternalRinger_AllPriorityNotificationSoundsMuted()586     public void testZenSetInternalRinger_AllPriorityNotificationSoundsMuted() {
587         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
588         mZenModeHelper.mAudioManager = mAudioManager;
589         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
590                 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
591 
592         // 1. Current ringer is normal
593         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
594         // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
595         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
596         mZenModeHelper.mConfig.allowReminders = false;
597         mZenModeHelper.mConfig.allowCalls = false;
598         mZenModeHelper.mConfig.allowMessages = false;
599         mZenModeHelper.mConfig.allowEvents = false;
600         mZenModeHelper.mConfig.allowRepeatCallers = false;
601         mZenModeHelper.mConfig.allowConversations = false;
602 
603         // 2. apply priority only zen - verify ringer is unchanged
604         mZenModeHelper.applyZenToRingerMode();
605         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
606                 mZenModeHelper.TAG);
607 
608         // 3. apply zen off - verify zen is set to previous ringer (normal)
609         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
610         mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
611         mZenModeHelper.applyZenToRingerMode();
612         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
613                 mZenModeHelper.TAG);
614     }
615 
616     @Test
testRingerAffectedStreamsTotalSilence()617     public void testRingerAffectedStreamsTotalSilence() {
618         // in total silence:
619         // ringtone, notification, system, alarm, streams, music are affected by ringer mode
620         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
621         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
622                 mZenModeHelper.new RingerModeDelegate();
623         int ringerModeAffectedStreams = ringerModeDelegate.getRingerModeAffectedStreams(0);
624         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
625         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
626                 != 0);
627         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0);
628         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) != 0);
629         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) != 0);
630         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ASSISTANT)) != 0);
631     }
632 
633     @Test
testRingerAffectedStreamsPriorityOnly()634     public void testRingerAffectedStreamsPriorityOnly() {
635         // in priority only mode:
636         // ringtone, notification and system streams are affected by ringer mode
637         mZenModeHelper.mConfig.allowAlarms = true;
638         mZenModeHelper.mConfig.allowReminders = true;
639         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
640         ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerMuted =
641                 mZenModeHelper.new RingerModeDelegate();
642 
643         int ringerModeAffectedStreams =
644                 ringerModeDelegateRingerMuted.getRingerModeAffectedStreams(0);
645         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
646         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
647                 != 0);
648         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0);
649         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0);
650         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0);
651         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ASSISTANT)) == 0);
652 
653         // even when ringer is muted (since all ringer sounds cannot bypass DND),
654         // system stream is still affected by ringer mode
655         mZenModeHelper.mConfig.allowSystem = false;
656         mZenModeHelper.mConfig.allowReminders = false;
657         mZenModeHelper.mConfig.allowCalls = false;
658         mZenModeHelper.mConfig.allowMessages = false;
659         mZenModeHelper.mConfig.allowEvents = false;
660         mZenModeHelper.mConfig.allowRepeatCallers = false;
661         mZenModeHelper.mConfig.allowConversations = false;
662         ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerNotMuted =
663                 mZenModeHelper.new RingerModeDelegate();
664 
665         int ringerMutedRingerModeAffectedStreams =
666                 ringerModeDelegateRingerNotMuted.getRingerModeAffectedStreams(0);
667         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
668         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
669                 != 0);
670         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM))
671                 != 0);
672         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0);
673         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0);
674         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ASSISTANT)) == 0);
675     }
676 
677     @Test
testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartNormal()678     public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartNormal() {
679         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
680         mZenModeHelper.mAudioManager = mAudioManager;
681         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
682                 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
683 
684         // 1. Current ringer is normal
685         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
686         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
687         mZenModeHelper.mConfig.allowReminders = true;
688 
689         // 2. apply priority only zen - verify ringer is normal
690         mZenModeHelper.applyZenToRingerMode();
691         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
692                 mZenModeHelper.TAG);
693 
694         // 3.  apply zen off - verify ringer remains normal
695         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
696         mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
697         mZenModeHelper.applyZenToRingerMode();
698         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
699                 mZenModeHelper.TAG);
700     }
701 
702     @Test
testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartSilent()703     public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartSilent() {
704         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
705         mZenModeHelper.mAudioManager = mAudioManager;
706         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
707                 Integer.toString(AudioManager.RINGER_MODE_SILENT));
708 
709         // 1. Current ringer is silent
710         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
711         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
712         mZenModeHelper.mConfig.allowReminders = true;
713 
714         // 2. apply priority only zen - verify ringer is silent
715         mZenModeHelper.applyZenToRingerMode();
716         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
717                 mZenModeHelper.TAG);
718 
719         // 3. apply zen-off - verify ringer is still silent
720         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
721         mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
722         mZenModeHelper.applyZenToRingerMode();
723         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
724                 mZenModeHelper.TAG);
725     }
726 
727     @Test
testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_RingerChanges()728     public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_RingerChanges() {
729         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
730         mZenModeHelper.mAudioManager = mAudioManager;
731         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
732                 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
733 
734         // 1. Current ringer is normal
735         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
736         // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
737         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
738         mZenModeHelper.mConfig.allowReminders = true;
739 
740         // 2. apply priority only zen - verify zen will still be normal
741         mZenModeHelper.applyZenToRingerMode();
742         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
743                 mZenModeHelper.TAG);
744 
745         // 3. change ringer from normal to silent, verify previous ringer set to new ringer (silent)
746         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
747                 mZenModeHelper.new RingerModeDelegate();
748         ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
749                 AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
750                 VolumePolicy.DEFAULT);
751         assertEquals(AudioManager.RINGER_MODE_SILENT, Global.getInt(mContext.getContentResolver(),
752                 Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
753 
754         // 4.  apply zen off - verify ringer still silenced
755         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
756         mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
757         mZenModeHelper.applyZenToRingerMode();
758         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
759                 mZenModeHelper.TAG);
760     }
761 
762     @Test
testSilentRingerSavedInZenOff_startsZenOff()763     public void testSilentRingerSavedInZenOff_startsZenOff() {
764         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
765         mZenModeHelper.mConfig = new ZenModeConfig();
766         mZenModeHelper.mAudioManager = mAudioManager;
767 
768         // apply zen off multiple times - verify ringer is not set to normal
769         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
770         mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
771         mZenModeHelper.mConfig = null; // will evaluate config to zen mode off
772         for (int i = 0; i < 3; i++) {
773             // if zen doesn't change, zen should not reapply itself to the ringer
774             mZenModeHelper.evaluateZenModeLocked("test", true);
775         }
776         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
777                 mZenModeHelper.TAG);
778     }
779 
780     @Test
testSilentRingerSavedOnZenOff_startsZenOn()781     public void testSilentRingerSavedOnZenOff_startsZenOn() {
782         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
783         mZenModeHelper.mAudioManager = mAudioManager;
784         mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
785         mZenModeHelper.mConfig = new ZenModeConfig();
786 
787         // previously set silent ringer
788         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
789                 mZenModeHelper.new RingerModeDelegate();
790         ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
791                 AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
792                 VolumePolicy.DEFAULT);
793         assertEquals(AudioManager.RINGER_MODE_SILENT, Global.getInt(mContext.getContentResolver(),
794                 Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
795 
796         // apply zen off multiple times - verify ringer is not set to normal
797         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
798         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
799         for (int i = 0; i < 3; i++) {
800             // if zen doesn't change, zen should not reapply itself to the ringer
801             mZenModeHelper.evaluateZenModeLocked("test", true);
802         }
803         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
804                 mZenModeHelper.TAG);
805     }
806 
807     @Test
testVibrateRingerSavedOnZenOff_startsZenOn()808     public void testVibrateRingerSavedOnZenOff_startsZenOn() {
809         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
810         mZenModeHelper.mAudioManager = mAudioManager;
811         mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
812         mZenModeHelper.mConfig = new ZenModeConfig();
813 
814         // previously set silent ringer
815         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
816                 mZenModeHelper.new RingerModeDelegate();
817         ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
818                 AudioManager.RINGER_MODE_VIBRATE, "test", AudioManager.RINGER_MODE_NORMAL,
819                 VolumePolicy.DEFAULT);
820         assertEquals(AudioManager.RINGER_MODE_VIBRATE, Global.getInt(mContext.getContentResolver(),
821                 Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
822 
823         // apply zen off multiple times - verify ringer is not set to normal
824         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
825         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
826         for (int i = 0; i < 3; i++) {
827             // if zen doesn't change, zen should not reapply itself to the ringer
828             mZenModeHelper.evaluateZenModeLocked("test", true);
829         }
830         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
831                 mZenModeHelper.TAG);
832     }
833 
834     @Test
testSetConfig_updatesAudioEventually()835     public void testSetConfig_updatesAudioEventually() {
836         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
837         mZenModeHelper.mAudioManager = mAudioManager;
838         setupZenConfig();
839 
840         // Turn manual zen mode on
841         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null,
842                 "test", CUSTOM_PKG_UID, false);
843 
844         // audio manager shouldn't do anything until the handler processes its messages
845         verify(mAudioManager, never()).updateRingerModeAffectedStreamsInternal();
846 
847         // now process the looper's messages
848         mTestableLooper.processAllMessages();
849 
850         // Expect calls to audio manager
851         verify(mAudioManager, times(1)).updateRingerModeAffectedStreamsInternal();
852 
853         // called during applyZenToRingerMode(), which should be true since zen changed
854         verify(mAudioManager, atLeastOnce()).getRingerModeInternal();
855     }
856 
857     @Test
testParcelConfig()858     public void testParcelConfig() {
859         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
860         mZenModeHelper.mConfig.allowAlarms = false;
861         mZenModeHelper.mConfig.allowMedia = false;
862         mZenModeHelper.mConfig.allowSystem = false;
863         mZenModeHelper.mConfig.allowReminders = true;
864         mZenModeHelper.mConfig.allowCalls = true;
865         mZenModeHelper.mConfig.allowMessages = true;
866         mZenModeHelper.mConfig.allowEvents = true;
867         mZenModeHelper.mConfig.allowRepeatCallers = true;
868         mZenModeHelper.mConfig.allowConversations = true;
869         mZenModeHelper.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
870         mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
871         mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
872         mZenModeHelper.mConfig.manualRule.component = new ComponentName("a", "a");
873         mZenModeHelper.mConfig.manualRule.enabled = true;
874         mZenModeHelper.mConfig.manualRule.snoozing = true;
875 
876         ZenModeConfig actual = mZenModeHelper.mConfig.copy();
877 
878         assertEquals(mZenModeHelper.mConfig, actual);
879     }
880 
881     @Test
testWriteXml()882     public void testWriteXml() throws Exception {
883         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
884         mZenModeHelper.mConfig.allowAlarms = false;
885         mZenModeHelper.mConfig.allowMedia = false;
886         mZenModeHelper.mConfig.allowSystem = false;
887         mZenModeHelper.mConfig.allowReminders = true;
888         mZenModeHelper.mConfig.allowCalls = true;
889         mZenModeHelper.mConfig.allowMessages = true;
890         mZenModeHelper.mConfig.allowEvents = true;
891         mZenModeHelper.mConfig.allowRepeatCallers = true;
892         mZenModeHelper.mConfig.allowConversations = true;
893         mZenModeHelper.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
894         mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
895         mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
896         mZenModeHelper.mConfig.manualRule.zenMode =
897                 ZEN_MODE_IMPORTANT_INTERRUPTIONS;
898         mZenModeHelper.mConfig.manualRule.component = new ComponentName("a", "a");
899         mZenModeHelper.mConfig.manualRule.pkg = "a";
900         mZenModeHelper.mConfig.manualRule.enabled = true;
901 
902         ZenModeConfig expected = mZenModeHelper.mConfig.copy();
903 
904         ByteArrayOutputStream baos = writeXmlAndPurge(null);
905         TypedXmlPullParser parser = getParserForByteStream(baos);
906         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
907 
908         assertEquals("Config mismatch: current vs expected: "
909                 + new ZenModeDiff.ConfigDiff(mZenModeHelper.mConfig, expected), expected,
910                 mZenModeHelper.mConfig);
911     }
912 
913     @Test
testProto()914     public void testProto() {
915         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
916         // existence of manual rule means it should be in output
917         mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
918         mZenModeHelper.mConfig.manualRule.pkg = "android";  // system
919 
920         int n = mZenModeHelper.mConfig.automaticRules.size();
921         List<String> ids = new ArrayList<>(n);
922         for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
923             ids.add(rule.id);
924         }
925         ids.add(ZenModeConfig.MANUAL_RULE_ID);
926         ids.add(""); // for ROOT_CONFIG, logged with empty string as id
927 
928         List<StatsEvent> events = new LinkedList<>();
929         mZenModeHelper.pullRules(events);
930         assertEquals(n + 2, events.size());  // automatic rules + manual rule + root config
931         for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
932             if (builder.getAtomId() == DND_MODE_RULE) {
933                 if (builder.getInt(ZEN_MODE_FIELD_NUMBER) == ROOT_CONFIG) {
934                     assertTrue(builder.getBoolean(ENABLED_FIELD_NUMBER));
935                     assertFalse(builder.getBoolean(CHANNELS_BYPASSING_FIELD_NUMBER));
936                 }
937                 assertEquals(Process.SYSTEM_UID, builder.getInt(UID_FIELD_NUMBER));
938                 assertTrue(builder.getBooleanAnnotation(UID_FIELD_NUMBER, ANNOTATION_ID_IS_UID));
939                 String name = (String) builder.getValue(ID_FIELD_NUMBER);
940                 assertTrue("unexpected rule id", ids.contains(name));
941                 ids.remove(name);
942             } else {
943                 fail("unexpected atom id: " + builder.getAtomId());
944             }
945         }
946         assertEquals("extra rule in output", 0, ids.size());
947     }
948 
949     @Test
testProtoWithAutoRule()950     public void testProtoWithAutoRule() throws Exception {
951         setupZenConfig();
952         // one enabled automatic rule
953         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules(ZEN_MODE_FOR_TESTING);
954 
955         List<StatsEvent> events = new LinkedList<>();
956         mZenModeHelper.pullRules(events);
957 
958         boolean foundCustomEvent = false;
959         for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
960             if (builder.getAtomId() == DND_MODE_RULE) {
961                 if (ZEN_MODE_FOR_TESTING == builder.getInt(ZEN_MODE_FIELD_NUMBER)) {
962                     foundCustomEvent = true;
963                     assertEquals(CUSTOM_PKG_UID, builder.getInt(UID_FIELD_NUMBER));
964                     assertTrue(builder.getBoolean(ENABLED_FIELD_NUMBER));
965                 }
966             } else {
967                 fail("unexpected atom id: " + builder.getAtomId());
968             }
969         }
970         assertTrue("couldn't find custom rule", foundCustomEvent);
971     }
972 
973     @Test
ruleUidsCached()974     public void ruleUidsCached() throws Exception {
975         setupZenConfig();
976         // one enabled automatic rule
977         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
978         List<StatsEvent> events = new LinkedList<>();
979         // first time retrieving uid:
980         mZenModeHelper.pullRules(events);
981         verify(mPackageManager, atLeastOnce()).getPackageUidAsUser(anyString(), anyInt());
982 
983         // second time retrieving uid:
984         reset(mPackageManager);
985         mZenModeHelper.pullRules(events);
986         verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());
987 
988         // new rule from same package + user added
989         reset(mPackageManager);
990         ZenModeConfig.ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS,
991                 CUSTOM_RULE_ID + "2");
992         mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
993         mZenModeHelper.pullRules(events);
994         verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());
995     }
996 
997     @Test
ruleUidAutomaticZenRuleRemovedUpdatesCache()998     public void ruleUidAutomaticZenRuleRemovedUpdatesCache() throws Exception {
999         when(mContext.checkCallingPermission(anyString()))
1000                 .thenReturn(PackageManager.PERMISSION_GRANTED);
1001 
1002         setupZenConfig();
1003         // one enabled automatic rule
1004         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1005         List<StatsEvent> events = new LinkedList<>();
1006 
1007         mZenModeHelper.pullRules(events);
1008         mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, "test", CUSTOM_PKG_UID, false);
1009         assertTrue(-1
1010                 == mZenModeHelper.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
1011     }
1012 
1013     @Test
testProtoRedactsIds()1014     public void testProtoRedactsIds() throws Exception {
1015         setupZenConfig();
1016         // one enabled automatic rule
1017         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1018 
1019         List<StatsEvent> events = new LinkedList<>();
1020         mZenModeHelper.pullRules(events);
1021 
1022         boolean foundCustomEvent = false;
1023         for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
1024             if (builder.getAtomId() == DND_MODE_RULE
1025                     && "customRule".equals(builder.getString(ID_FIELD_NUMBER))) {
1026                 fail("non-default IDs should be redacted");
1027             }
1028         }
1029     }
1030 
1031     @Test
testProtoWithManualRule()1032     public void testProtoWithManualRule() throws Exception {
1033         setupZenConfig();
1034         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1035         mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
1036         mZenModeHelper.mConfig.manualRule.enabled = true;
1037 
1038         List<StatsEvent> events = new LinkedList<>();
1039         mZenModeHelper.pullRules(events);
1040 
1041         boolean foundManualRule = false;
1042         for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
1043             if (builder.getAtomId() == DND_MODE_RULE
1044                     && ZenModeConfig.MANUAL_RULE_ID.equals(builder.getString(ID_FIELD_NUMBER))) {
1045                 assertEquals(0, builder.getInt(UID_FIELD_NUMBER));
1046                 foundManualRule = true;
1047             }
1048         }
1049         assertTrue("couldn't find manual rule", foundManualRule);    }
1050 
1051     @Test
testWriteXml_onlyBackupsTargetUser()1052     public void testWriteXml_onlyBackupsTargetUser() throws Exception {
1053         // Setup configs for user 10 and 11.
1054         setupZenConfig();
1055         ZenModeConfig config10 = mZenModeHelper.mConfig.copy();
1056         config10.user = 10;
1057         config10.allowAlarms = true;
1058         config10.allowMedia = true;
1059         mZenModeHelper.setConfig(config10, null, "writeXml", Process.SYSTEM_UID, true);
1060         ZenModeConfig config11 = mZenModeHelper.mConfig.copy();
1061         config11.user = 11;
1062         config11.allowAlarms = false;
1063         config11.allowMedia = false;
1064         mZenModeHelper.setConfig(config11, null, "writeXml", Process.SYSTEM_UID, true);
1065 
1066         // Backup user 10 and reset values.
1067         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, 10);
1068         ZenModeConfig newConfig11 = new ZenModeConfig();
1069         newConfig11.user = 11;
1070         mZenModeHelper.mConfigs.put(11, newConfig11);
1071 
1072         // Parse backup data.
1073         TypedXmlPullParser parser = getParserForByteStream(baos);
1074         mZenModeHelper.readXml(parser, true, 10);
1075         mZenModeHelper.readXml(parser, true, 11);
1076 
1077         ZenModeConfig actual = mZenModeHelper.mConfigs.get(10);
1078         assertEquals(
1079                 "Config mismatch: current vs expected: "
1080                         + new ZenModeDiff.ConfigDiff(actual, config10), config10, actual);
1081         assertNotEquals("Expected config mismatch", config11, mZenModeHelper.mConfigs.get(11));
1082     }
1083 
1084     @Test
testReadXmlRestore_forSystemUser()1085     public void testReadXmlRestore_forSystemUser() throws Exception {
1086         setupZenConfig();
1087         // one enabled automatic rule
1088         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1089         ZenModeConfig original = mZenModeHelper.mConfig.copy();
1090 
1091         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
1092         TypedXmlPullParser parser = getParserForByteStream(baos);
1093         mZenModeHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
1094 
1095         assertEquals("Config mismatch: current vs original: "
1096                 + new ZenModeDiff.ConfigDiff(mZenModeHelper.mConfig, original),
1097                 original, mZenModeHelper.mConfig);
1098         assertEquals(original.hashCode(), mZenModeHelper.mConfig.hashCode());
1099     }
1100 
1101     /** Restore should ignore the data's user id and restore for the target user. */
1102     @Test
testReadXmlRestore_forNonSystemUser()1103     public void testReadXmlRestore_forNonSystemUser() throws Exception {
1104         // Setup config.
1105         setupZenConfig();
1106         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1107         ZenModeConfig expected = mZenModeHelper.mConfig.copy();
1108 
1109         // Backup data for user 0.
1110         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
1111 
1112         // Restore data for user 10.
1113         TypedXmlPullParser parser = getParserForByteStream(baos);
1114         mZenModeHelper.readXml(parser, true, 10);
1115 
1116         ZenModeConfig actual = mZenModeHelper.mConfigs.get(10);
1117         expected.user = 10;
1118         assertEquals("Config mismatch: current vs original: "
1119                         + new ZenModeDiff.ConfigDiff(actual, expected),
1120                 expected, actual);
1121         assertEquals(expected.hashCode(), actual.hashCode());
1122         expected.user = 0;
1123         assertNotEquals(expected, mZenModeHelper.mConfig);
1124     }
1125 
1126     @Test
testWriteXmlWithZenPolicy()1127     public void testWriteXmlWithZenPolicy() throws Exception {
1128         final String ruleId = "customRule";
1129         setupZenConfig();
1130 
1131         // one enabled automatic rule with zen policy
1132         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
1133         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1134         final ScheduleInfo customRuleInfo = new ScheduleInfo();
1135         customRule.enabled = true;
1136         customRule.creationTime = 0;
1137         customRule.id = "customRule";
1138         customRule.name = "Custom Rule";
1139         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1140         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
1141         customRule.configurationActivity =
1142                 new ComponentName("android", "ScheduleConditionProvider");
1143         customRule.pkg = customRule.configurationActivity.getPackageName();
1144         customRule.zenPolicy = new ZenPolicy.Builder()
1145                 .allowAlarms(false)
1146                 .allowMedia(false)
1147                 .allowRepeatCallers(false)
1148                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)
1149                 .allowMessages(ZenPolicy.PEOPLE_TYPE_CONTACTS)
1150                 .allowEvents(true)
1151                 .allowReminders(false)
1152                 .build();
1153         automaticRules.put("customRule", customRule);
1154         mZenModeHelper.mConfig.automaticRules = automaticRules;
1155 
1156         ZenModeConfig expected = mZenModeHelper.mConfig.copy();
1157 
1158         ByteArrayOutputStream baos = writeXmlAndPurge(null);
1159         TypedXmlPullParser parser = Xml.newFastPullParser();
1160         parser.setInput(new BufferedInputStream(
1161                 new ByteArrayInputStream(baos.toByteArray())), null);
1162         parser.nextTag();
1163         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1164 
1165         ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
1166         ZenModeConfig.ZenRule current = mZenModeHelper.mConfig.automaticRules.get(ruleId);
1167 
1168         assertEquals("Automatic rules mismatch", original, current);
1169     }
1170 
1171     @Test
testReadXmlRestoreWithZenPolicy_forSystemUser()1172     public void testReadXmlRestoreWithZenPolicy_forSystemUser() throws Exception {
1173         final String ruleId = "customRule";
1174         setupZenConfig();
1175 
1176         // one enabled automatic rule with zen policy
1177         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
1178         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1179         final ScheduleInfo customRuleInfo = new ScheduleInfo();
1180         customRule.enabled = true;
1181         customRule.creationTime = 0;
1182         customRule.id = ruleId;
1183         customRule.name = "Custom Rule";
1184         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1185         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
1186         customRule.configurationActivity =
1187                 new ComponentName("android", "ScheduleConditionProvider");
1188         customRule.pkg = customRule.configurationActivity.getPackageName();
1189         customRule.zenPolicy = new ZenPolicy.Builder()
1190                 .allowSystem(true)
1191                 .allowCalls(ZenPolicy.PEOPLE_TYPE_ANYONE)
1192                 .allowReminders(true)
1193                 .build();
1194         automaticRules.put(ruleId, customRule);
1195         mZenModeHelper.mConfig.automaticRules = automaticRules;
1196 
1197         ZenModeConfig expected = mZenModeHelper.mConfig.copy();
1198 
1199         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
1200         TypedXmlPullParser parser = getParserForByteStream(baos);
1201         mZenModeHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
1202 
1203         ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
1204         ZenModeConfig.ZenRule current = mZenModeHelper.mConfig.automaticRules.get(ruleId);
1205 
1206         assertEquals("Automatic rules mismatch", original, current);
1207     }
1208 
1209     @Test
testReadXmlRulesNotOverriden()1210     public void testReadXmlRulesNotOverriden() throws Exception {
1211         setupZenConfig();
1212 
1213         // automatic zen rule is enabled on upgrade so rules should not be overriden to default
1214         ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
1215         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1216         final ScheduleInfo weeknights = new ScheduleInfo();
1217         customRule.enabled = true;
1218         customRule.name = "Custom Rule";
1219         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1220         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
1221         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1222         enabledAutoRule.put("customRule", customRule);
1223         mZenModeHelper.mConfig.automaticRules = enabledAutoRule;
1224 
1225         // set previous version
1226         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1227         TypedXmlPullParser parser = Xml.newFastPullParser();
1228         parser.setInput(new BufferedInputStream(
1229                 new ByteArrayInputStream(baos.toByteArray())), null);
1230         parser.nextTag();
1231         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1232 
1233         assertTrue(mZenModeHelper.mConfig.automaticRules.containsKey("customRule"));
1234         setupZenConfigMaintained();
1235     }
1236 
1237     @Test
testMigrateSuppressedVisualEffects_oneExistsButOff()1238     public void testMigrateSuppressedVisualEffects_oneExistsButOff() throws Exception {
1239         String xml = "<zen version=\"6\" user=\"0\">\n"
1240                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1241                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1242                 + "visualScreenOff=\"true\" alarms=\"true\" "
1243                 + "media=\"true\" system=\"false\" />\n"
1244                 + "<disallow visualEffects=\"511\" />"
1245                 + "</zen>";
1246 
1247         TypedXmlPullParser parser = Xml.newFastPullParser();
1248         parser.setInput(new BufferedInputStream(
1249                 new ByteArrayInputStream(xml.getBytes())), null);
1250         parser.nextTag();
1251         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1252 
1253         assertEquals(0, mZenModeHelper.mConfig.suppressedVisualEffects);
1254 
1255         xml = "<zen version=\"6\" user=\"0\">\n"
1256                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1257                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1258                 + "visualScreenOn=\"true\" alarms=\"true\" "
1259                 + "media=\"true\" system=\"false\" />\n"
1260                 + "<disallow visualEffects=\"511\" />"
1261                 + "</zen>";
1262 
1263         parser = Xml.newFastPullParser();
1264         parser.setInput(new BufferedInputStream(
1265                 new ByteArrayInputStream(xml.getBytes())), null);
1266         parser.nextTag();
1267         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1268 
1269         assertEquals(0, mZenModeHelper.mConfig.suppressedVisualEffects);
1270     }
1271 
1272     @Test
testMigrateSuppressedVisualEffects_bothExistButOff()1273     public void testMigrateSuppressedVisualEffects_bothExistButOff() throws Exception {
1274         String xml = "<zen version=\"6\" user=\"0\">\n"
1275                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1276                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1277                 + "visualScreenOff=\"true\" visualScreenOn=\"true\" alarms=\"true\" "
1278                 + "media=\"true\" system=\"false\" />\n"
1279                 + "<disallow visualEffects=\"511\" />"
1280                 + "</zen>";
1281 
1282         TypedXmlPullParser parser = Xml.newFastPullParser();
1283         parser.setInput(new BufferedInputStream(
1284                 new ByteArrayInputStream(xml.getBytes())), null);
1285         parser.nextTag();
1286         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1287 
1288         assertEquals(0, mZenModeHelper.mConfig.suppressedVisualEffects);
1289     }
1290 
1291     @Test
testMigrateSuppressedVisualEffects_bothExistButOn()1292     public void testMigrateSuppressedVisualEffects_bothExistButOn() throws Exception {
1293         String xml = "<zen version=\"6\" user=\"0\">\n"
1294                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1295                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1296                 + "visualScreenOff=\"false\" visualScreenOn=\"false\" alarms=\"true\" "
1297                 + "media=\"true\" system=\"false\" />\n"
1298                 + "<disallow visualEffects=\"511\" />"
1299                 + "</zen>";
1300 
1301         TypedXmlPullParser parser = Xml.newFastPullParser();
1302         parser.setInput(new BufferedInputStream(
1303                 new ByteArrayInputStream(xml.getBytes())), null);
1304         parser.nextTag();
1305         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1306 
1307         assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
1308                         | SUPPRESSED_EFFECT_LIGHTS
1309                         | SUPPRESSED_EFFECT_AMBIENT
1310                         | SUPPRESSED_EFFECT_PEEK,
1311                 mZenModeHelper.mConfig.suppressedVisualEffects);
1312 
1313         xml = "<zen version=\"6\" user=\"0\">\n"
1314                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1315                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1316                 + "visualScreenOff=\"true\" visualScreenOn=\"false\" alarms=\"true\" "
1317                 + "media=\"true\" system=\"false\" />\n"
1318                 + "<disallow visualEffects=\"511\" />"
1319                 + "</zen>";
1320 
1321         parser = Xml.newFastPullParser();
1322         parser.setInput(new BufferedInputStream(
1323                 new ByteArrayInputStream(xml.getBytes())), null);
1324         parser.nextTag();
1325         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1326 
1327         assertEquals(SUPPRESSED_EFFECT_PEEK, mZenModeHelper.mConfig.suppressedVisualEffects);
1328 
1329         xml = "<zen version=\"6\" user=\"0\">\n"
1330                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1331                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1332                 + "visualScreenOff=\"false\" visualScreenOn=\"true\" alarms=\"true\" "
1333                 + "media=\"true\" system=\"false\" />\n"
1334                 + "<disallow visualEffects=\"511\" />"
1335                 + "</zen>";
1336 
1337         parser = Xml.newFastPullParser();
1338         parser.setInput(new BufferedInputStream(
1339                 new ByteArrayInputStream(xml.getBytes())), null);
1340         parser.nextTag();
1341         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1342 
1343         assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
1344                         | SUPPRESSED_EFFECT_LIGHTS
1345                         | SUPPRESSED_EFFECT_AMBIENT,
1346                 mZenModeHelper.mConfig.suppressedVisualEffects);
1347     }
1348 
1349     @Test
testReadXmlResetDefaultRules()1350     public void testReadXmlResetDefaultRules() throws Exception {
1351         setupZenConfig();
1352 
1353         // no enabled automatic zen rules and no default rules
1354         // so rules should be overriden by default rules
1355         mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();
1356 
1357         // set previous version
1358         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1359         TypedXmlPullParser parser = Xml.newFastPullParser();
1360         parser.setInput(new BufferedInputStream(
1361                 new ByteArrayInputStream(baos.toByteArray())), null);
1362         parser.nextTag();
1363         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1364 
1365         // check default rules
1366         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
1367         assertTrue(rules.size() != 0);
1368         for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
1369             assertTrue(rules.containsKey(defaultId));
1370         }
1371 
1372         setupZenConfigMaintained();
1373     }
1374 
1375 
1376     @Test
testReadXmlAllDisabledRulesResetDefaultRules()1377     public void testReadXmlAllDisabledRulesResetDefaultRules() throws Exception {
1378         setupZenConfig();
1379 
1380         // all automatic zen rules are disabled on upgrade (and default rules don't already exist)
1381         // so rules should be overriden by default rules
1382         ArrayMap<String, ZenModeConfig.ZenRule> disabledAutoRule = new ArrayMap<>();
1383         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1384         final ScheduleInfo weeknights = new ScheduleInfo();
1385         customRule.enabled = false;
1386         customRule.name = "Custom Rule";
1387         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1388         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
1389         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1390         disabledAutoRule.put("customRule", customRule);
1391         mZenModeHelper.mConfig.automaticRules = disabledAutoRule;
1392 
1393         // set previous version
1394         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1395         TypedXmlPullParser parser = Xml.newFastPullParser();
1396         parser.setInput(new BufferedInputStream(
1397                 new ByteArrayInputStream(baos.toByteArray())), null);
1398         parser.nextTag();
1399         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1400 
1401         // check default rules
1402         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
1403         assertTrue(rules.size() != 0);
1404         for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
1405             assertTrue(rules.containsKey(defaultId));
1406         }
1407         assertFalse(rules.containsKey("customRule"));
1408 
1409         setupZenConfigMaintained();
1410     }
1411 
1412     @Test
testReadXmlOnlyOneDefaultRuleExists()1413     public void testReadXmlOnlyOneDefaultRuleExists() throws Exception {
1414         setupZenConfig();
1415 
1416         // all automatic zen rules are disabled on upgrade and only one default rule exists
1417         // so rules should be overriden to the default rules
1418         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
1419         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1420         final ScheduleInfo customRuleInfo = new ScheduleInfo();
1421         customRule.enabled = false;
1422         customRule.name = "Custom Rule";
1423         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1424         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
1425         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1426         customRule.zenPolicy = new ZenPolicy.Builder()
1427                 .allowReminders(true)
1428                 .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE)
1429                 .build();
1430         automaticRules.put("customRule", customRule);
1431 
1432         ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule();
1433         final ScheduleInfo defaultScheduleRuleInfo = new ScheduleInfo();
1434         defaultScheduleRule.enabled = false;
1435         defaultScheduleRule.name = "Default Schedule Rule";
1436         defaultScheduleRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1437         defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId(
1438                 defaultScheduleRuleInfo);
1439         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1440         defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
1441         automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
1442 
1443         mZenModeHelper.mConfig.automaticRules = automaticRules;
1444 
1445         // set previous version
1446         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1447         TypedXmlPullParser parser = Xml.newFastPullParser();
1448         parser.setInput(new BufferedInputStream(
1449                 new ByteArrayInputStream(baos.toByteArray())), null);
1450         parser.nextTag();
1451         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1452 
1453         // check default rules
1454         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
1455         assertTrue(rules.size() != 0);
1456         for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
1457             assertTrue(rules.containsKey(defaultId));
1458         }
1459         assertFalse(rules.containsKey("customRule"));
1460 
1461         setupZenConfigMaintained();
1462     }
1463 
1464     @Test
testReadXmlDefaultRulesExist()1465     public void testReadXmlDefaultRulesExist() throws Exception {
1466         setupZenConfig();
1467 
1468         // Default rules exist so rules should not be overridden by defaults
1469         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
1470         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1471         final ScheduleInfo customRuleInfo = new ScheduleInfo();
1472         customRule.enabled = false;
1473         customRule.name = "Custom Rule";
1474         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1475         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
1476         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1477         customRule.zenPolicy = new ZenPolicy.Builder()
1478                 .allowReminders(true)
1479                 .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE)
1480                 .build();
1481         automaticRules.put("customRule", customRule);
1482 
1483         ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule();
1484         final ScheduleInfo defaultScheduleRuleInfo = new ScheduleInfo();
1485         defaultScheduleRule.enabled = false;
1486         defaultScheduleRule.name = "Default Schedule Rule";
1487         defaultScheduleRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1488         defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId(
1489                 defaultScheduleRuleInfo);
1490         defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
1491         defaultScheduleRule.zenPolicy = new ZenPolicy.Builder()
1492                 .allowEvents(true)
1493                 .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE)
1494                 .build();
1495         automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
1496 
1497         ZenModeConfig.ZenRule defaultEventRule = new ZenModeConfig.ZenRule();
1498         final ScheduleInfo defaultEventRuleInfo = new ScheduleInfo();
1499         defaultEventRule.enabled = false;
1500         defaultEventRule.name = "Default Event Rule";
1501         defaultEventRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1502         defaultEventRule.conditionId = ZenModeConfig.toScheduleConditionId(
1503                 defaultEventRuleInfo);
1504         defaultEventRule.id = ZenModeConfig.EVENTS_DEFAULT_RULE_ID;
1505         defaultScheduleRule.zenPolicy = new ZenPolicy.Builder()
1506                 .allowAlarms(false)
1507                 .allowMedia(false)
1508                 .allowRepeatCallers(false)
1509                 .build();
1510         automaticRules.put(ZenModeConfig.EVENTS_DEFAULT_RULE_ID, defaultEventRule);
1511 
1512         mZenModeHelper.mConfig.automaticRules = automaticRules;
1513 
1514         // set previous version
1515         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1516         TypedXmlPullParser parser = Xml.newFastPullParser();
1517         parser.setInput(new BufferedInputStream(
1518                 new ByteArrayInputStream(baos.toByteArray())), null);
1519         parser.nextTag();
1520         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
1521 
1522         // check default rules
1523         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
1524         assertTrue(rules.size() != 0);
1525         for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
1526             assertTrue(rules.containsKey(defaultId));
1527         }
1528         assertTrue(rules.containsKey("customRule"));
1529 
1530         setupZenConfigMaintained();
1531 
1532         List<StatsEvent> events = new LinkedList<>();
1533         mZenModeHelper.pullRules(events);
1534         assertEquals(4, events.size());
1535     }
1536 
1537     @Test
testCountdownConditionSubscription()1538     public void testCountdownConditionSubscription() throws Exception {
1539         ZenModeConfig config = new ZenModeConfig();
1540         mZenModeHelper.mConfig = config;
1541         mZenModeHelper.mConditions.evaluateConfig(mZenModeHelper.mConfig, null, true);
1542         assertEquals(0, mZenModeHelper.mConditions.mSubscriptions.size());
1543 
1544         mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
1545         Uri conditionId = ZenModeConfig.toCountdownConditionId(9000000, false);
1546         mZenModeHelper.mConfig.manualRule.conditionId = conditionId;
1547         mZenModeHelper.mConfig.manualRule.component = new ComponentName("android",
1548                 CountdownConditionProvider.class.getName());
1549         mZenModeHelper.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0,
1550                 STATE_TRUE, Condition.FLAG_RELEVANT_NOW);
1551         mZenModeHelper.mConfig.manualRule.enabled = true;
1552         ZenModeConfig originalConfig = mZenModeHelper.mConfig.copy();
1553 
1554         mZenModeHelper.mConditions.evaluateConfig(mZenModeHelper.mConfig, null, true);
1555 
1556         assertEquals(true, ZenModeConfig.isValidCountdownConditionId(conditionId));
1557         assertEquals(originalConfig, mZenModeHelper.mConfig);
1558         assertEquals(1, mZenModeHelper.mConditions.mSubscriptions.size());
1559     }
1560 
1561     @Test
testEmptyDefaultRulesMap()1562     public void testEmptyDefaultRulesMap() {
1563         List<StatsEvent> events = new LinkedList<>();
1564         ZenModeConfig config = new ZenModeConfig();
1565         config.automaticRules = new ArrayMap<>();
1566         mZenModeHelper.mConfig = config;
1567         mZenModeHelper.updateDefaultZenRules(
1568                 Process.SYSTEM_UID, true); // shouldn't throw null pointer
1569         mZenModeHelper.pullRules(events); // shouldn't throw null pointer
1570     }
1571 
1572     @Test
testDoNotUpdateModifiedDefaultAutoRule()1573     public void testDoNotUpdateModifiedDefaultAutoRule() {
1574         // mDefaultConfig is set to default config in setup by getDefaultConfigParser
1575         when(mContext.checkCallingPermission(anyString()))
1576                 .thenReturn(PackageManager.PERMISSION_GRANTED);
1577 
1578         // shouldn't update rule that's been modified
1579         ZenModeConfig.ZenRule updatedDefaultRule = new ZenModeConfig.ZenRule();
1580         updatedDefaultRule.modified = true;
1581         updatedDefaultRule.enabled = false;
1582         updatedDefaultRule.creationTime = 0;
1583         updatedDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID;
1584         updatedDefaultRule.name = "Schedule Default Rule";
1585         updatedDefaultRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1586         updatedDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo());
1587         updatedDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider");
1588 
1589         ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
1590         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
1591         mZenModeHelper.mConfig.automaticRules = autoRules;
1592 
1593         mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true);
1594         assertEquals(updatedDefaultRule,
1595                 mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
1596     }
1597 
1598     @Test
testDoNotUpdateEnabledDefaultAutoRule()1599     public void testDoNotUpdateEnabledDefaultAutoRule() {
1600         // mDefaultConfig is set to default config in setup by getDefaultConfigParser
1601         when(mContext.checkCallingPermission(anyString()))
1602                 .thenReturn(PackageManager.PERMISSION_GRANTED);
1603 
1604         // shouldn't update the rule that's enabled
1605         ZenModeConfig.ZenRule updatedDefaultRule = new ZenModeConfig.ZenRule();
1606         updatedDefaultRule.enabled = true;
1607         updatedDefaultRule.modified = false;
1608         updatedDefaultRule.creationTime = 0;
1609         updatedDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID;
1610         updatedDefaultRule.name = "Schedule Default Rule";
1611         updatedDefaultRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1612         updatedDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo());
1613         updatedDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider");
1614 
1615         ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
1616         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
1617         mZenModeHelper.mConfig.automaticRules = autoRules;
1618 
1619         mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true);
1620         assertEquals(updatedDefaultRule,
1621                 mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
1622     }
1623 
1624     @Test
testUpdateDefaultAutoRule()1625     public void testUpdateDefaultAutoRule() {
1626         // mDefaultConfig is set to default config in setup by getDefaultConfigParser
1627         final String defaultRuleName = "rule name test";
1628         when(mContext.checkCallingPermission(anyString()))
1629                 .thenReturn(PackageManager.PERMISSION_GRANTED);
1630 
1631         // will update rule that is not enabled and modified
1632         ZenModeConfig.ZenRule customDefaultRule = new ZenModeConfig.ZenRule();
1633         customDefaultRule.enabled = false;
1634         customDefaultRule.modified = false;
1635         customDefaultRule.creationTime = 0;
1636         customDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID;
1637         customDefaultRule.name = "Schedule Default Rule";
1638         customDefaultRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1639         customDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo());
1640         customDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider");
1641 
1642         ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
1643         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, customDefaultRule);
1644         mZenModeHelper.mConfig.automaticRules = autoRules;
1645 
1646         mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true);
1647         ZenModeConfig.ZenRule ruleAfterUpdating =
1648                 mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID);
1649         assertEquals(customDefaultRule.enabled, ruleAfterUpdating.enabled);
1650         assertEquals(customDefaultRule.modified, ruleAfterUpdating.modified);
1651         assertEquals(customDefaultRule.id, ruleAfterUpdating.id);
1652         assertEquals(customDefaultRule.conditionId, ruleAfterUpdating.conditionId);
1653         assertFalse(Objects.equals(defaultRuleName, ruleAfterUpdating.name)); // update name
1654     }
1655 
1656     @Test
testAddAutomaticZenRule_beyondSystemLimit()1657     public void testAddAutomaticZenRule_beyondSystemLimit() {
1658         for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
1659             ScheduleInfo si = new ScheduleInfo();
1660             si.startHour = i;
1661             AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
1662                     null,
1663                     new ComponentName("android", "ScheduleConditionProvider"),
1664                     ZenModeConfig.toScheduleConditionId(si),
1665                     new ZenPolicy.Builder().build(),
1666                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1667             // We need the package name to be something that's not "android" so there aren't any
1668             // existing rules under that package.
1669             String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
1670                     CUSTOM_PKG_UID, false);
1671             assertNotNull(id);
1672         }
1673         try {
1674             AutomaticZenRule zenRule = new AutomaticZenRule("name",
1675                     null,
1676                     new ComponentName("android", "ScheduleConditionProvider"),
1677                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1678                     new ZenPolicy.Builder().build(),
1679                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1680             String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
1681                     CUSTOM_PKG_UID, false);
1682             fail("allowed too many rules to be created");
1683         } catch (IllegalArgumentException e) {
1684             // yay
1685         }
1686     }
1687 
1688     @Test
testAddAutomaticZenRule_beyondSystemLimit_differentComponents()1689     public void testAddAutomaticZenRule_beyondSystemLimit_differentComponents() {
1690         // Make sure the system limit is enforced per-package even with different component provider
1691         // names.
1692         for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
1693             ScheduleInfo si = new ScheduleInfo();
1694             si.startHour = i;
1695             AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
1696                     null,
1697                     new ComponentName("android", "ScheduleConditionProvider" + i),
1698                     ZenModeConfig.toScheduleConditionId(si),
1699                     new ZenPolicy.Builder().build(),
1700                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1701             String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
1702                     CUSTOM_PKG_UID, false);
1703             assertNotNull(id);
1704         }
1705         try {
1706             AutomaticZenRule zenRule = new AutomaticZenRule("name",
1707                     null,
1708                     new ComponentName("android", "ScheduleConditionProviderFinal"),
1709                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1710                     new ZenPolicy.Builder().build(),
1711                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1712             String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
1713                     CUSTOM_PKG_UID, false);
1714             fail("allowed too many rules to be created");
1715         } catch (IllegalArgumentException e) {
1716             // yay
1717         }
1718     }
1719 
1720     @Test
testAddAutomaticZenRule_claimedSystemOwner()1721     public void testAddAutomaticZenRule_claimedSystemOwner() {
1722         // Make sure anything that claims to have a "system" owner but not actually part of the
1723         // system package still gets limited on number of rules
1724         for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
1725             ScheduleInfo si = new ScheduleInfo();
1726             si.startHour = i;
1727             AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
1728                     new ComponentName("android", "ScheduleConditionProvider" + i),
1729                     null, // configuration activity
1730                     ZenModeConfig.toScheduleConditionId(si),
1731                     new ZenPolicy.Builder().build(),
1732                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1733             String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
1734                     CUSTOM_PKG_UID, false);
1735             assertNotNull(id);
1736         }
1737         try {
1738             AutomaticZenRule zenRule = new AutomaticZenRule("name",
1739                     new ComponentName("android", "ScheduleConditionProviderFinal"),
1740                     null, // configuration activity
1741                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1742                     new ZenPolicy.Builder().build(),
1743                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1744             String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
1745                     CUSTOM_PKG_UID, false);
1746             fail("allowed too many rules to be created");
1747         } catch (IllegalArgumentException e) {
1748             // yay
1749         }
1750     }
1751 
1752     @Test
testAddAutomaticZenRule_CA()1753     public void testAddAutomaticZenRule_CA() {
1754         AutomaticZenRule zenRule = new AutomaticZenRule("name",
1755                 null,
1756                 new ComponentName("android", "ScheduleConditionProvider"),
1757                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1758                 new ZenPolicy.Builder().build(),
1759                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1760         String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
1761                 Process.SYSTEM_UID, true);
1762 
1763         assertTrue(id != null);
1764         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
1765         assertTrue(ruleInConfig != null);
1766         assertEquals(zenRule.isEnabled(), ruleInConfig.enabled);
1767         assertEquals(zenRule.isModified(), ruleInConfig.modified);
1768         assertEquals(zenRule.getConditionId(), ruleInConfig.conditionId);
1769         assertEquals(NotificationManager.zenModeFromInterruptionFilter(
1770                 zenRule.getInterruptionFilter(), -1), ruleInConfig.zenMode);
1771         assertEquals(zenRule.getName(), ruleInConfig.name);
1772         assertEquals("android", ruleInConfig.pkg);
1773     }
1774 
1775     @Test
testAddAutomaticZenRule_CPS()1776     public void testAddAutomaticZenRule_CPS() {
1777         AutomaticZenRule zenRule = new AutomaticZenRule("name",
1778                 new ComponentName("android", "ScheduleConditionProvider"),
1779                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1780                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1781         String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
1782                 Process.SYSTEM_UID, true);
1783 
1784         assertTrue(id != null);
1785         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
1786         assertTrue(ruleInConfig != null);
1787         assertEquals(zenRule.isEnabled(), ruleInConfig.enabled);
1788         assertEquals(zenRule.isModified(), ruleInConfig.modified);
1789         assertEquals(zenRule.getConditionId(), ruleInConfig.conditionId);
1790         assertEquals(NotificationManager.zenModeFromInterruptionFilter(
1791                 zenRule.getInterruptionFilter(), -1), ruleInConfig.zenMode);
1792         assertEquals(zenRule.getName(), ruleInConfig.name);
1793         assertEquals("android", ruleInConfig.pkg);
1794     }
1795 
1796     @Test
testSetAutomaticZenRuleState_nullPkg()1797     public void testSetAutomaticZenRuleState_nullPkg() {
1798         AutomaticZenRule zenRule = new AutomaticZenRule("name",
1799                 null,
1800                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
1801                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1802                 new ZenPolicy.Builder().build(),
1803                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1804 
1805         String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
1806                 CUSTOM_PKG_UID, false);
1807         mZenModeHelper.setAutomaticZenRuleState(zenRule.getConditionId(),
1808                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
1809                 CUSTOM_PKG_UID, false);
1810 
1811         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
1812         assertEquals(STATE_TRUE, ruleInConfig.condition.state);
1813     }
1814 
1815     @Test
testUpdateAutomaticZenRule_nullPkg()1816     public void testUpdateAutomaticZenRule_nullPkg() {
1817         AutomaticZenRule zenRule = new AutomaticZenRule("name",
1818                 null,
1819                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
1820                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1821                 new ZenPolicy.Builder().build(),
1822                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1823 
1824         String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
1825                 CUSTOM_PKG_UID, false);
1826 
1827         AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW",
1828                 null,
1829                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
1830                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1831                 new ZenPolicy.Builder().build(),
1832                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1833 
1834         mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "", CUSTOM_PKG_UID, false);
1835 
1836         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
1837         assertEquals("NEW", ruleInConfig.name);
1838     }
1839 
1840     @Test
testRemoveAutomaticZenRule_nullPkg()1841     public void testRemoveAutomaticZenRule_nullPkg() {
1842         AutomaticZenRule zenRule = new AutomaticZenRule("name",
1843                 null,
1844                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
1845                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1846                 new ZenPolicy.Builder().build(),
1847                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1848 
1849         String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
1850                 CUSTOM_PKG_UID, false);
1851 
1852         assertTrue(id != null);
1853         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
1854         assertTrue(ruleInConfig != null);
1855         assertEquals(zenRule.getName(), ruleInConfig.name);
1856 
1857         mZenModeHelper.removeAutomaticZenRule(id, "test", CUSTOM_PKG_UID, false);
1858         assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
1859     }
1860 
1861     @Test
testRemoveAutomaticZenRules_nullPkg()1862     public void testRemoveAutomaticZenRules_nullPkg() {
1863         AutomaticZenRule zenRule = new AutomaticZenRule("name",
1864                 null,
1865                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
1866                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
1867                 new ZenPolicy.Builder().build(),
1868                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1869         String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
1870                 CUSTOM_PKG_UID, false);
1871 
1872         assertTrue(id != null);
1873         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
1874         assertTrue(ruleInConfig != null);
1875         assertEquals(zenRule.getName(), ruleInConfig.name);
1876 
1877         mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), "test",
1878                 CUSTOM_PKG_UID, false);
1879         assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
1880     }
1881 
1882     @Test
testRulesWithSameUri()1883     public void testRulesWithSameUri() {
1884         // needs to be a valid schedule info object for the subscription to happen properly
1885         ScheduleInfo scheduleInfo = new ScheduleInfo();
1886         scheduleInfo.days = new int[]{1, 2};
1887         scheduleInfo.endHour = 1;
1888         Uri sharedUri = ZenModeConfig.toScheduleConditionId(scheduleInfo);
1889         AutomaticZenRule zenRule = new AutomaticZenRule("name",
1890                 new ComponentName("android", "ScheduleConditionProvider"),
1891                 sharedUri,
1892                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1893         String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
1894                 Process.SYSTEM_UID, true);
1895         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
1896                 new ComponentName("android", "ScheduleConditionProvider"),
1897                 sharedUri,
1898                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
1899         String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, "test",
1900                 Process.SYSTEM_UID, true);
1901 
1902         Condition condition = new Condition(sharedUri, "", STATE_TRUE);
1903         mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, Process.SYSTEM_UID, true);
1904 
1905         for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
1906             if (rule.id.equals(id)) {
1907                 assertNotNull(rule.condition);
1908                 assertTrue(rule.condition.state == STATE_TRUE);
1909             }
1910             if (rule.id.equals(id2)) {
1911                 assertNotNull(rule.condition);
1912                 assertTrue(rule.condition.state == STATE_TRUE);
1913             }
1914         }
1915 
1916         condition = new Condition(sharedUri, "", STATE_FALSE);
1917         mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, Process.SYSTEM_UID, true);
1918 
1919         for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
1920             if (rule.id.equals(id)) {
1921                 assertNotNull(rule.condition);
1922                 assertTrue(rule.condition.state == STATE_FALSE);
1923             }
1924             if (rule.id.equals(id2)) {
1925                 assertNotNull(rule.condition);
1926                 assertTrue(rule.condition.state == STATE_FALSE);
1927             }
1928         }
1929     }
1930 
1931     @Test
testSetManualZenMode()1932     public void testSetManualZenMode() {
1933         setupZenConfig();
1934 
1935         // note that caller=null because that's how it comes in from NMS.setZenMode
1936         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
1937                 Process.SYSTEM_UID, true);
1938 
1939         // confirm that setting zen mode via setManualZenMode changed the zen mode correctly
1940         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode);
1941 
1942         // and also that it works to turn it back off again
1943         mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "",
1944                 Process.SYSTEM_UID, true);
1945 
1946         assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
1947     }
1948 
1949     @Test
testZenModeEventLog_setManualZenMode()1950     public void testZenModeEventLog_setManualZenMode() throws IllegalArgumentException {
1951         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
1952         setupZenConfig();
1953 
1954         // Turn zen mode on (to important_interruptions)
1955         // Need to additionally call the looper in order to finish the post-apply-config process
1956         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
1957                 Process.SYSTEM_UID, true);
1958 
1959         // Now turn zen mode off, but via a different package UID -- this should get registered as
1960         // "not an action by the user" because some other app is changing zen mode
1961         mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "", CUSTOM_PKG_UID,
1962                 false);
1963 
1964         // In total, this should be 2 loggable changes
1965         assertEquals(2, mZenModeEventLogger.numLoggedChanges());
1966 
1967         // we expect the following changes from turning zen mode on:
1968         //   - manual rule added
1969         //   - zen mode -> ZEN_MODE_IMPORTANT_INTERRUPTIONS
1970         // This should combine to 1 log event (zen mode turns on) with the following properties:
1971         //   - event ID: DND_TURNED_ON
1972         //   - new zen mode = important interruptions; prev zen mode = off
1973         //   - changed rule type = manual
1974         //   - rules active = 1
1975         //   - user action = true (system-based turning zen mode on)
1976         //   - package uid = system (as set above)
1977         //   - resulting DNDPolicyProto the same as the values in setupZenConfig()
1978         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
1979                 mZenModeEventLogger.getEventId(0));
1980         assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
1981         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
1982         assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(0));
1983         assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
1984         assertTrue(mZenModeEventLogger.getFromSystemOrSystemUi(0));
1985         assertTrue(mZenModeEventLogger.getIsUserAction(0));
1986         assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(0));
1987         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
1988 
1989         // and from turning zen mode off:
1990         //   - event ID: DND_TURNED_OFF
1991         //   - new zen mode = off; previous = important interruptions
1992         //   - changed rule type = manual
1993         //   - rules active = 0
1994         //   - user action = false
1995         //   - package uid = custom one passed in above
1996         //   - DNDPolicyProto still the same
1997         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
1998                 mZenModeEventLogger.getEventId(1));
1999         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getPrevZenMode(1));
2000         assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getNewZenMode(1));
2001         assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(1));
2002         assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
2003         assertFalse(mZenModeEventLogger.getIsUserAction(1));
2004         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
2005         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
2006     }
2007 
2008     @Test
testZenModeEventLog_automaticRules()2009     public void testZenModeEventLog_automaticRules() throws IllegalArgumentException {
2010         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
2011         setupZenConfig();
2012 
2013         // Add a new automatic zen rule that's enabled
2014         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2015                 null,
2016                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
2017                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2018                 null,
2019                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2020         String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
2021                 "test", Process.SYSTEM_UID, true);
2022 
2023         // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE
2024         mZenModeHelper.setAutomaticZenRuleState(id,
2025                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
2026                 Process.SYSTEM_UID, true);
2027 
2028         // Event 2: "User" turns off the automatic rule (sets it to not enabled)
2029         zenRule.setEnabled(false);
2030         mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, true);
2031 
2032         // Add a new system rule
2033         AutomaticZenRule systemRule = new AutomaticZenRule("systemRule",
2034                 null,
2035                 new ComponentName("android", "ScheduleConditionProvider"),
2036                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2037                 null,
2038                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2039         String systemId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), systemRule,
2040                 "test", Process.SYSTEM_UID, true);
2041 
2042         // Event 3: turn on the system rule
2043         mZenModeHelper.setAutomaticZenRuleState(systemId,
2044                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
2045                 Process.SYSTEM_UID, true);
2046 
2047         // Event 4: "User" deletes the rule
2048         mZenModeHelper.removeAutomaticZenRule(systemId, "", Process.SYSTEM_UID, true);
2049 
2050         // In total, this represents 4 events
2051         assertEquals(4, mZenModeEventLogger.numLoggedChanges());
2052 
2053         // We should see an event from the automatic rule turning on; it should have the following
2054         // properties:
2055         //   - event ID: DND_TURNED_ON
2056         //   - zen mode: OFF -> IMPORTANT_INTERRUPTIONS
2057         //   - automatic rule change
2058         //   - 1 rule (newly) active
2059         //   - automatic (is not a user action)
2060         //   - package UID is written to be the rule *owner* even though it "comes from system"
2061         //   - zen policy is the same as the set-up zen config
2062         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
2063                 mZenModeEventLogger.getEventId(0));
2064         assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
2065         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
2066         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(0));
2067         assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
2068         assertFalse(mZenModeEventLogger.getIsUserAction(0));
2069         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
2070         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
2071 
2072         // When the automatic rule is disabled, this should turn off zen mode and also count as a
2073         // user action.
2074         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
2075                 mZenModeEventLogger.getEventId(1));
2076         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getPrevZenMode(1));
2077         assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getNewZenMode(1));
2078         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1));
2079         assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
2080         assertTrue(mZenModeEventLogger.getIsUserAction(1));
2081         assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
2082         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
2083 
2084         // When the system rule is enabled, this counts as an automatic action that comes from the
2085         // system and turns on DND
2086         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
2087                 mZenModeEventLogger.getEventId(2));
2088         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
2089         assertEquals(1, mZenModeEventLogger.getNumRulesActive(2));
2090         assertFalse(mZenModeEventLogger.getIsUserAction(2));
2091         assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
2092 
2093         // When the system rule is deleted, we consider this a user action that turns DND off
2094         // (again)
2095         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
2096                 mZenModeEventLogger.getEventId(3));
2097         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(3));
2098         assertEquals(0, mZenModeEventLogger.getNumRulesActive(3));
2099         assertTrue(mZenModeEventLogger.getIsUserAction(3));
2100         assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(3));
2101     }
2102 
2103     @Test
testZenModeEventLog_policyChanges()2104     public void testZenModeEventLog_policyChanges() throws IllegalArgumentException {
2105         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
2106         setupZenConfig();
2107 
2108         // First just turn zen mode on
2109         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
2110                 Process.SYSTEM_UID, true);
2111 
2112         // Now change the policy slightly; want to confirm that this'll be reflected in the logs
2113         ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
2114         newConfig.allowAlarms = true;
2115         newConfig.allowRepeatCallers = false;
2116         mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
2117                 true);
2118 
2119         // Turn zen mode off; we want to make sure policy changes do not get logged when zen mode
2120         // is off.
2121         mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "",
2122                 Process.SYSTEM_UID, true);
2123 
2124         // Change the policy again
2125         newConfig.allowMessages = false;
2126         newConfig.allowRepeatCallers = true;
2127         mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
2128                 true);
2129 
2130         // Total events: we only expect ones for turning on, changing policy, and turning off
2131         assertEquals(3, mZenModeEventLogger.numLoggedChanges());
2132 
2133         // The first event is just turning DND on; make sure the policy is what we expect there
2134         // before it changes in the next stage
2135         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
2136                 mZenModeEventLogger.getEventId(0));
2137         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
2138 
2139         // Second message where we change the policy:
2140         //   - DND_POLICY_CHANGED (indicates only the policy changed and nothing else)
2141         //   - rule type: unknown (it's a policy change, not a rule change)
2142         //   - user action (because it comes from a "system" uid)
2143         //   - check the specific things changed above
2144         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
2145                 mZenModeEventLogger.getEventId(1));
2146         assertEquals(DNDProtoEnums.UNKNOWN_RULE, mZenModeEventLogger.getChangedRuleType(1));
2147         assertTrue(mZenModeEventLogger.getIsUserAction(1));
2148         assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
2149         DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(1);
2150         assertEquals(STATE_ALLOW, dndProto.getAlarms().getNumber());
2151         assertEquals(STATE_DISALLOW, dndProto.getRepeatCallers().getNumber());
2152 
2153         // The third and final event should turn DND off
2154         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
2155                 mZenModeEventLogger.getEventId(2));
2156 
2157         // There should be no fourth event for changing the policy the second time.
2158     }
2159 
2160     @Test
testZenModeEventLog_ruleCounts()2161     public void testZenModeEventLog_ruleCounts() throws IllegalArgumentException {
2162         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
2163         setupZenConfig();
2164 
2165         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2166                 null,
2167                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
2168                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2169                 null,
2170                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2171         String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
2172                 Process.SYSTEM_UID, true);
2173 
2174         // Rule 2, same as rule 1
2175         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
2176                 null,
2177                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
2178                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2179                 null,
2180                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2181         String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test",
2182                 Process.SYSTEM_UID, true);
2183 
2184         // Rule 3, has stricter settings than the default settings
2185         ZenModeConfig ruleConfig = mZenModeHelper.mConfig.copy();
2186         ruleConfig.allowReminders = false;
2187         ruleConfig.allowCalls = false;
2188         ruleConfig.allowMessages = false;
2189         AutomaticZenRule zenRule3 = new AutomaticZenRule("name3",
2190                 null,
2191                 new ComponentName("android", "ScheduleConditionProvider"),
2192                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2193                 ruleConfig.toZenPolicy(),
2194                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2195         String id3 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule3, "test",
2196                 Process.SYSTEM_UID, true);
2197 
2198         // First: turn on rule 1
2199         mZenModeHelper.setAutomaticZenRuleState(id,
2200                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
2201                 Process.SYSTEM_UID, true);
2202 
2203         // Second: turn on rule 2
2204         mZenModeHelper.setAutomaticZenRuleState(id2,
2205                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
2206                 Process.SYSTEM_UID, true);
2207 
2208         // Third: turn on rule 3
2209         mZenModeHelper.setAutomaticZenRuleState(id3,
2210                 new Condition(zenRule3.getConditionId(), "", STATE_TRUE),
2211                 Process.SYSTEM_UID, true);
2212 
2213         // Fourth: Turn *off* rule 2
2214         mZenModeHelper.setAutomaticZenRuleState(id2,
2215                 new Condition(zenRule2.getConditionId(), "", STATE_FALSE),
2216                 Process.SYSTEM_UID, true);
2217 
2218         // This should result in a total of four events
2219         assertEquals(4, mZenModeEventLogger.numLoggedChanges());
2220 
2221         // Event 1: rule 1 turns on. We expect this to turn on DND (zen mode) overall, so that's
2222         // what the event should reflect. At this time, the policy is the same as initial setup.
2223         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
2224                 mZenModeEventLogger.getEventId(0));
2225         assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
2226         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
2227         assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
2228         assertFalse(mZenModeEventLogger.getIsUserAction(0));
2229         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
2230         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
2231 
2232         // Event 2: rule 2 turns on. This should not change anything about the policy, so the only
2233         // change is that there are more rules active now.
2234         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
2235                 mZenModeEventLogger.getEventId(1));
2236         assertEquals(2, mZenModeEventLogger.getNumRulesActive(1));
2237         assertFalse(mZenModeEventLogger.getIsUserAction(1));
2238         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
2239         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
2240 
2241         // Event 3: rule 3 turns on. This should trigger a policy change, and be classified as such,
2242         // but meanwhile also change the number of active rules.
2243         // Rule 3 is also set up to be a "system"-owned rule, so the caller UID should remain system
2244         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
2245                 mZenModeEventLogger.getEventId(2));
2246         assertEquals(3, mZenModeEventLogger.getNumRulesActive(2));
2247         assertFalse(mZenModeEventLogger.getIsUserAction(2));
2248         assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
2249         DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(2);
2250         assertEquals(STATE_DISALLOW, dndProto.getReminders().getNumber());
2251         assertEquals(STATE_DISALLOW, dndProto.getCalls().getNumber());
2252         assertEquals(STATE_DISALLOW, dndProto.getMessages().getNumber());
2253 
2254         // Event 4: rule 2 turns off. Because rule 3 is still on and stricter than rule 1 (also
2255         // still on), there should be no policy change as a result of rule 2 going away. Therefore
2256         // this event should again only be an active rule change.
2257         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
2258                 mZenModeEventLogger.getEventId(3));
2259         assertEquals(2, mZenModeEventLogger.getNumRulesActive(3));
2260         assertFalse(mZenModeEventLogger.getIsUserAction(3));
2261     }
2262 
2263     @Test
testZenModeEventLog_noLogWithNoConfigChange()2264     public void testZenModeEventLog_noLogWithNoConfigChange() throws IllegalArgumentException {
2265         // If evaluateZenMode is called independently of a config change, don't log.
2266         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
2267         setupZenConfig();
2268 
2269         // Artificially turn zen mode "on". Re-evaluating zen mode should cause it to turn back off
2270         // given that we don't have any zen rules active.
2271         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2272         mZenModeHelper.evaluateZenModeLocked("test", true);
2273 
2274         // Check that the change actually took: zen mode should be off now
2275         assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
2276 
2277         // but still, nothing should've been logged
2278         assertEquals(0, mZenModeEventLogger.numLoggedChanges());
2279     }
2280 
2281     @Test
testZenModeEventLog_reassignUid()2282     public void testZenModeEventLog_reassignUid() throws IllegalArgumentException {
2283         // Test that, only in specific cases, we reassign the calling UID to one associated with
2284         // the automatic rule owner.
2285         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
2286         setupZenConfig();
2287 
2288         // Rule 1, owned by a package
2289         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2290                 null,
2291                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
2292                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2293                 null,
2294                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2295         String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
2296                 Process.SYSTEM_UID, true);
2297 
2298         // Rule 2, same as rule 1 but owned by the system
2299         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
2300                 null,
2301                 new ComponentName("android", "ScheduleConditionProvider"),
2302                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2303                 null,
2304                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2305         String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test",
2306                 Process.SYSTEM_UID, true);
2307 
2308         // Turn on rule 1; call looks like it's from the system. Because setting a condition is
2309         // typically an automatic (non-user-initiated) action, expect the calling UID to be
2310         // re-evaluated to the one associat.d with CUSTOM_PKG_NAME.
2311         mZenModeHelper.setAutomaticZenRuleState(id,
2312                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
2313                 Process.SYSTEM_UID, true);
2314 
2315         // Second: turn on rule 2. This is a system-owned rule and the UID should not be modified
2316         // (nor even looked up; the mock PackageManager won't handle "android" as input).
2317         mZenModeHelper.setAutomaticZenRuleState(id2,
2318                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
2319                 Process.SYSTEM_UID, true);
2320 
2321         // Disable rule 1. Because this looks like a user action, the UID should not be modified
2322         // from the system-provided one.
2323         zenRule.setEnabled(false);
2324         mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, true);
2325 
2326         // Add a manual rule. Any manual rule changes should not get calling uids reassigned.
2327         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
2328                 CUSTOM_PKG_UID, false);
2329 
2330         // Change rule 2's condition, but from some other UID. Since it doesn't look like it's from
2331         // the system, we keep the UID info.
2332         mZenModeHelper.setAutomaticZenRuleState(id2,
2333                 new Condition(zenRule2.getConditionId(), "", STATE_FALSE),
2334                 12345, false);
2335 
2336         // That was 5 events total
2337         assertEquals(5, mZenModeEventLogger.numLoggedChanges());
2338 
2339         // The first event (activating rule 1) should be of type "zen mode turns on", automatic,
2340         // have a package UID of CUSTOM_PKG_UID
2341         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
2342                 mZenModeEventLogger.getEventId(0));
2343         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(0));
2344         assertFalse(mZenModeEventLogger.getIsUserAction(0));
2345         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
2346 
2347         // The second event (activating rule 2) should have similar other properties but the UID
2348         // should be system.
2349         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
2350                 mZenModeEventLogger.getEventId(1));
2351         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1));
2352         assertFalse(mZenModeEventLogger.getIsUserAction(1));
2353         assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
2354 
2355         // Third event: disable rule 1. This looks like a user action so UID should be left alone.
2356         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
2357                 mZenModeEventLogger.getEventId(2));
2358         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
2359         assertTrue(mZenModeEventLogger.getIsUserAction(2));
2360         assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
2361 
2362         // Fourth event: turns on manual mode. Doesn't change effective policy so this is just a
2363         // change in active rules. Confirm that the package UID is left unchanged.
2364         // Because it's a manual mode change not from the system, isn't considered a user action.
2365         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
2366                 mZenModeEventLogger.getEventId(3));
2367         assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(3));
2368         assertFalse(mZenModeEventLogger.getIsUserAction(3));
2369         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(3));
2370 
2371         // Fourth event: changed condition on rule 2 (turning it off via condition).
2372         // This comes from a random different UID so we expect that to remain untouched.
2373         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
2374                 mZenModeEventLogger.getEventId(4));
2375         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(4));
2376         assertFalse(mZenModeEventLogger.getIsUserAction(4));
2377         assertEquals(12345, mZenModeEventLogger.getPackageUid(4));
2378     }
2379 
2380     @Test
testZenModeEventLog_channelsBypassingChanges()2381     public void testZenModeEventLog_channelsBypassingChanges() {
2382         // Verify that the right thing happens when the canBypassDnd value changes.
2383         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
2384         setupZenConfig();
2385 
2386         // Turn on zen mode with a manual rule with an enabler set. This should *not* count
2387         // as a user action, and *should* get its UID reassigned.
2388         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
2389                 CUSTOM_PKG_NAME, "", Process.SYSTEM_UID, true);
2390 
2391         // Now change apps bypassing to true
2392         ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
2393         newConfig.areChannelsBypassingDnd = true;
2394         mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
2395                 true);
2396 
2397         // and then back to false, all without changing anything else
2398         newConfig.areChannelsBypassingDnd = false;
2399         mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
2400                 true);
2401 
2402         // Turn off manual mode, call from a package: don't reset UID even though enabler is set
2403         mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null,
2404                 CUSTOM_PKG_NAME, "", 12345, false);
2405 
2406         // And likewise when turning it back on again
2407         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
2408                 CUSTOM_PKG_NAME, "", 12345, false);
2409 
2410         // These are 5 events in total.
2411         assertEquals(5, mZenModeEventLogger.numLoggedChanges());
2412 
2413         // First event: turns on, UID reassigned for manual mode
2414         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
2415                 mZenModeEventLogger.getEventId(0));
2416         assertFalse(mZenModeEventLogger.getIsUserAction(0));
2417         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
2418 
2419         // Second event should be a policy-only change with are channels bypassing = true
2420         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
2421                 mZenModeEventLogger.getEventId(1));
2422         assertTrue(mZenModeEventLogger.getAreChannelsBypassing(1));
2423 
2424         // Third event also a policy-only change but with channels bypassing now false
2425         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
2426                 mZenModeEventLogger.getEventId(2));
2427         assertFalse(mZenModeEventLogger.getAreChannelsBypassing(2));
2428 
2429         // Fourth event: should turn DND off, not have UID reassigned
2430         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
2431                 mZenModeEventLogger.getEventId(3));
2432         assertFalse(mZenModeEventLogger.getIsUserAction(3));
2433         assertEquals(12345, mZenModeEventLogger.getPackageUid(3));
2434 
2435         // Fifth event: turn DND back on, not have UID reassigned
2436         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
2437                 mZenModeEventLogger.getEventId(4));
2438         assertFalse(mZenModeEventLogger.getIsUserAction(4));
2439         assertEquals(12345, mZenModeEventLogger.getPackageUid(4));
2440     }
2441 
2442     @Test
testUpdateConsolidatedPolicy_defaultRulesOnly()2443     public void testUpdateConsolidatedPolicy_defaultRulesOnly() {
2444         setupZenConfig();
2445 
2446         // When there's one automatic rule active and it doesn't specify a policy, test that the
2447         // resulting consolidated policy is one that matches the default rule settings.
2448         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2449                 null,
2450                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
2451                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2452                 null,
2453                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2454         String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
2455                 Process.SYSTEM_UID, true);
2456 
2457         // enable the rule
2458         mZenModeHelper.setAutomaticZenRuleState(id,
2459                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
2460                 Process.SYSTEM_UID, true);
2461 
2462         // inspect the consolidated policy. Based on setupZenConfig() values.
2463         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowAlarms());
2464         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowMedia());
2465         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowSystem());
2466         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowReminders());
2467         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowCalls());
2468         assertEquals(PRIORITY_SENDERS_STARRED, mZenModeHelper.mConsolidatedPolicy.allowCallsFrom());
2469         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowMessages());
2470         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowConversations());
2471         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers());
2472         assertFalse(mZenModeHelper.mConsolidatedPolicy.showBadges());
2473     }
2474 
2475     @Test
testUpdateConsolidatedPolicy_customPolicyOnly()2476     public void testUpdateConsolidatedPolicy_customPolicyOnly() {
2477         setupZenConfig();
2478 
2479         // when there's only one automatic rule active and it has a custom policy, make sure that's
2480         // what the consolidated policy reflects whether or not it's stricter than what the default
2481         // would specify.
2482         ZenPolicy customPolicy = new ZenPolicy.Builder()
2483                 .allowAlarms(true)  // more lenient than default
2484                 .allowMedia(true)  // more lenient than default
2485                 .allowRepeatCallers(false)  // more restrictive than default
2486                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)  // more restrictive than default
2487                 .showBadges(true)  // more lenient
2488                 .showPeeking(false)  // more restrictive
2489                 .build();
2490 
2491         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2492                 null,
2493                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
2494                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2495                 customPolicy,
2496                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2497         String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
2498                 Process.SYSTEM_UID, true);
2499 
2500         // enable the rule; this will update the consolidated policy
2501         mZenModeHelper.setAutomaticZenRuleState(id,
2502                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
2503                 Process.SYSTEM_UID, true);
2504 
2505         // since this is the only active rule, the consolidated policy should match the custom
2506         // policy for every field specified, and take default values for unspecified things
2507         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowAlarms());  // custom
2508         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowMedia());  // custom
2509         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowSystem());  // default
2510         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowReminders());  // default
2511         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowCalls());  // custom
2512         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowMessages()); // default
2513         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowConversations());  // default
2514         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers());  // custom
2515         assertTrue(mZenModeHelper.mConsolidatedPolicy.showBadges());  // custom
2516         assertFalse(mZenModeHelper.mConsolidatedPolicy.showPeeking());  // custom
2517     }
2518 
2519     @Test
testUpdateConsolidatedPolicy_defaultAndCustomActive()2520     public void testUpdateConsolidatedPolicy_defaultAndCustomActive() {
2521         setupZenConfig();
2522 
2523         // when there are two rules active, one inheriting the default policy and one setting its
2524         // own custom policy, they should be merged to form the most restrictive combination.
2525 
2526         // rule 1: no custom policy
2527         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2528                 null,
2529                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
2530                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2531                 null,
2532                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2533         String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
2534                 Process.SYSTEM_UID, true);
2535 
2536         // enable rule 1
2537         mZenModeHelper.setAutomaticZenRuleState(id,
2538                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
2539                 Process.SYSTEM_UID, true);
2540 
2541         // custom policy for rule 2
2542         ZenPolicy customPolicy = new ZenPolicy.Builder()
2543                 .allowAlarms(true)  // more lenient than default
2544                 .allowMedia(true)  // more lenient than default
2545                 .allowRepeatCallers(false)  // more restrictive than default
2546                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)  // more restrictive than default
2547                 .showBadges(true)  // more lenient
2548                 .showPeeking(false)  // more restrictive
2549                 .build();
2550 
2551         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
2552                 null,
2553                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
2554                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2555                 customPolicy,
2556                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2557         String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2,
2558                 "test", Process.SYSTEM_UID, true);
2559 
2560         // enable rule 2; this will update the consolidated policy
2561         mZenModeHelper.setAutomaticZenRuleState(id2,
2562                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
2563                 Process.SYSTEM_UID, true);
2564 
2565         // now both rules should be on, and the consolidated policy should reflect the most
2566         // restrictive option of each of the two
2567         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowAlarms());  // default stricter
2568         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowMedia());  // default stricter
2569         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowSystem());  // default, unset in custom
2570         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowReminders());  // default
2571         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowCalls());  // custom stricter
2572         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowMessages()); // default, unset in custom
2573         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowConversations());  // default
2574         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers());  // custom stricter
2575         assertFalse(mZenModeHelper.mConsolidatedPolicy.showBadges());  // default stricter
2576         assertFalse(mZenModeHelper.mConsolidatedPolicy.showPeeking());  // custom stricter
2577     }
2578 
setupZenConfig()2579     private void setupZenConfig() {
2580         mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
2581         mZenModeHelper.mConfig.allowAlarms = false;
2582         mZenModeHelper.mConfig.allowMedia = false;
2583         mZenModeHelper.mConfig.allowSystem = false;
2584         mZenModeHelper.mConfig.allowReminders = true;
2585         mZenModeHelper.mConfig.allowCalls = true;
2586         mZenModeHelper.mConfig.allowCallsFrom = PRIORITY_SENDERS_STARRED;
2587         mZenModeHelper.mConfig.allowMessages = true;
2588         mZenModeHelper.mConfig.allowConversations = true;
2589         mZenModeHelper.mConfig.allowEvents = true;
2590         mZenModeHelper.mConfig.allowRepeatCallers = true;
2591         mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
2592         mZenModeHelper.mConfig.manualRule = null;
2593     }
2594 
setupZenConfigMaintained()2595     private void setupZenConfigMaintained() {
2596         // config is still the same as when it was setup (setupZenConfig)
2597         assertFalse(mZenModeHelper.mConfig.allowAlarms);
2598         assertFalse(mZenModeHelper.mConfig.allowMedia);
2599         assertFalse(mZenModeHelper.mConfig.allowSystem);
2600         assertTrue(mZenModeHelper.mConfig.allowReminders);
2601         assertTrue(mZenModeHelper.mConfig.allowCalls);
2602         assertEquals(PRIORITY_SENDERS_STARRED, mZenModeHelper.mConfig.allowCallsFrom);
2603         assertTrue(mZenModeHelper.mConfig.allowMessages);
2604         assertTrue(mZenModeHelper.mConfig.allowConversations);
2605         assertTrue(mZenModeHelper.mConfig.allowEvents);
2606         assertTrue(mZenModeHelper.mConfig.allowRepeatCallers);
2607         assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelper.mConfig.suppressedVisualEffects);
2608     }
2609 
checkDndProtoMatchesSetupZenConfig(DNDPolicyProto dndProto)2610     private void checkDndProtoMatchesSetupZenConfig(DNDPolicyProto dndProto) {
2611         assertEquals(STATE_DISALLOW, dndProto.getAlarms().getNumber());
2612         assertEquals(STATE_DISALLOW, dndProto.getMedia().getNumber());
2613         assertEquals(STATE_DISALLOW, dndProto.getSystem().getNumber());
2614         assertEquals(STATE_ALLOW, dndProto.getReminders().getNumber());
2615         assertEquals(STATE_ALLOW, dndProto.getCalls().getNumber());
2616         assertEquals(PEOPLE_STARRED, dndProto.getAllowCallsFrom().getNumber());
2617         assertEquals(STATE_ALLOW, dndProto.getMessages().getNumber());
2618         assertEquals(STATE_ALLOW, dndProto.getEvents().getNumber());
2619         assertEquals(STATE_ALLOW, dndProto.getRepeatCallers().getNumber());
2620         assertEquals(STATE_ALLOW, dndProto.getFullscreen().getNumber());
2621         assertEquals(STATE_ALLOW, dndProto.getLights().getNumber());
2622         assertEquals(STATE_ALLOW, dndProto.getPeek().getNumber());
2623         assertEquals(STATE_ALLOW, dndProto.getStatusBar().getNumber());
2624         assertEquals(STATE_DISALLOW, dndProto.getBadge().getNumber());
2625         assertEquals(STATE_ALLOW, dndProto.getAmbient().getNumber());
2626         assertEquals(STATE_ALLOW, dndProto.getNotificationList().getNumber());
2627     }
2628 
2629     /**
2630      * Wrapper to use TypedXmlPullParser as XmlResourceParser for Resources.getXml()
2631      */
2632     final class XmlResourceParserImpl implements XmlResourceParser {
2633         private TypedXmlPullParser parser;
2634 
XmlResourceParserImpl(TypedXmlPullParser parser)2635         public XmlResourceParserImpl(TypedXmlPullParser parser) {
2636             this.parser = parser;
2637         }
2638 
getEventType()2639         public int getEventType() throws XmlPullParserException {
2640             return parser.getEventType();
2641         }
2642 
2643         @Override
setFeature(String name, boolean state)2644         public void setFeature(String name, boolean state) throws XmlPullParserException {
2645             parser.setFeature(name, state);
2646         }
2647 
2648         @Override
getFeature(String name)2649         public boolean getFeature(String name) {
2650             return false;
2651         }
2652 
2653         @Override
setProperty(String name, Object value)2654         public void setProperty(String name, Object value) throws XmlPullParserException {
2655             parser.setProperty(name, value);
2656         }
2657 
2658         @Override
getProperty(String name)2659         public Object getProperty(String name) {
2660             return parser.getProperty(name);
2661         }
2662 
2663         @Override
setInput(Reader in)2664         public void setInput(Reader in) throws XmlPullParserException {
2665             parser.setInput(in);
2666         }
2667 
2668         @Override
setInput(InputStream inputStream, String inputEncoding)2669         public void setInput(InputStream inputStream, String inputEncoding)
2670                 throws XmlPullParserException {
2671             parser.setInput(inputStream, inputEncoding);
2672         }
2673 
2674         @Override
getInputEncoding()2675         public String getInputEncoding() {
2676             return parser.getInputEncoding();
2677         }
2678 
2679         @Override
defineEntityReplacementText(String entityName, String replacementText)2680         public void defineEntityReplacementText(String entityName, String replacementText)
2681                 throws XmlPullParserException {
2682             parser.defineEntityReplacementText(entityName, replacementText);
2683         }
2684 
2685         @Override
getNamespaceCount(int depth)2686         public int getNamespaceCount(int depth) throws XmlPullParserException {
2687             return parser.getNamespaceCount(depth);
2688         }
2689 
2690         @Override
getNamespacePrefix(int pos)2691         public String getNamespacePrefix(int pos) throws XmlPullParserException {
2692             return parser.getNamespacePrefix(pos);
2693         }
2694 
2695         @Override
getNamespaceUri(int pos)2696         public String getNamespaceUri(int pos) throws XmlPullParserException {
2697             return parser.getNamespaceUri(pos);
2698         }
2699 
2700         @Override
getNamespace(String prefix)2701         public String getNamespace(String prefix) {
2702             return parser.getNamespace(prefix);
2703         }
2704 
2705         @Override
getDepth()2706         public int getDepth() {
2707             return parser.getDepth();
2708         }
2709 
2710         @Override
getPositionDescription()2711         public String getPositionDescription() {
2712             return parser.getPositionDescription();
2713         }
2714 
2715         @Override
getLineNumber()2716         public int getLineNumber() {
2717             return parser.getLineNumber();
2718         }
2719 
2720         @Override
getColumnNumber()2721         public int getColumnNumber() {
2722             return parser.getColumnNumber();
2723         }
2724 
2725         @Override
isWhitespace()2726         public boolean isWhitespace() throws XmlPullParserException {
2727             return parser.isWhitespace();
2728         }
2729 
2730         @Override
getText()2731         public String getText() {
2732             return parser.getText();
2733         }
2734 
2735         @Override
getTextCharacters(int[] holderForStartAndLength)2736         public char[] getTextCharacters(int[] holderForStartAndLength) {
2737             return parser.getTextCharacters(holderForStartAndLength);
2738         }
2739 
2740         @Override
getNamespace()2741         public String getNamespace() {
2742             return parser.getNamespace();
2743         }
2744 
2745         @Override
getName()2746         public String getName() {
2747             return parser.getName();
2748         }
2749 
2750         @Override
getPrefix()2751         public String getPrefix() {
2752             return parser.getPrefix();
2753         }
2754 
2755         @Override
isEmptyElementTag()2756         public boolean isEmptyElementTag() throws XmlPullParserException {
2757             return false;
2758         }
2759 
2760         @Override
getAttributeCount()2761         public int getAttributeCount() {
2762             return parser.getAttributeCount();
2763         }
2764 
next()2765         public int next() throws IOException, XmlPullParserException {
2766             return parser.next();
2767         }
2768 
2769         @Override
nextToken()2770         public int nextToken() throws XmlPullParserException, IOException {
2771             return parser.next();
2772         }
2773 
2774         @Override
require(int type, String namespace, String name)2775         public void require(int type, String namespace, String name)
2776                 throws XmlPullParserException, IOException {
2777             parser.require(type, namespace, name);
2778         }
2779 
2780         @Override
nextText()2781         public String nextText() throws XmlPullParserException, IOException {
2782             return parser.nextText();
2783         }
2784 
2785         @Override
getAttributeNamespace(int index)2786         public String getAttributeNamespace(int index) {
2787             return "";
2788         }
2789 
2790         @Override
getAttributeName(int index)2791         public String getAttributeName(int index) {
2792             return parser.getAttributeName(index);
2793         }
2794 
2795         @Override
getAttributePrefix(int index)2796         public String getAttributePrefix(int index) {
2797             return parser.getAttributePrefix(index);
2798         }
2799 
2800         @Override
getAttributeType(int index)2801         public String getAttributeType(int index) {
2802             return parser.getAttributeType(index);
2803         }
2804 
2805         @Override
isAttributeDefault(int index)2806         public boolean isAttributeDefault(int index) {
2807             return parser.isAttributeDefault(index);
2808         }
2809 
2810         @Override
getAttributeValue(int index)2811         public String getAttributeValue(int index) {
2812             return parser.getAttributeValue(index);
2813         }
2814 
2815         @Override
getAttributeValue(String namespace, String name)2816         public String getAttributeValue(String namespace, String name) {
2817             return parser.getAttributeValue(namespace, name);
2818         }
2819 
2820         @Override
getAttributeNameResource(int index)2821         public int getAttributeNameResource(int index) {
2822             return 0;
2823         }
2824 
2825         @Override
getAttributeListValue(String namespace, String attribute, String[] options, int defaultValue)2826         public int getAttributeListValue(String namespace, String attribute, String[] options,
2827                 int defaultValue) {
2828             return 0;
2829         }
2830 
2831         @Override
getAttributeBooleanValue(String namespace, String attribute, boolean defaultValue)2832         public boolean getAttributeBooleanValue(String namespace, String attribute,
2833                 boolean defaultValue) {
2834             return false;
2835         }
2836 
2837         @Override
getAttributeResourceValue(String namespace, String attribute, int defaultValue)2838         public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
2839             return 0;
2840         }
2841 
2842         @Override
getAttributeIntValue(String namespace, String attribute, int defaultValue)2843         public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
2844             return 0;
2845         }
2846 
2847         @Override
getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue)2848         public int getAttributeUnsignedIntValue(String namespace, String attribute,
2849                 int defaultValue) {
2850             return 0;
2851         }
2852 
2853         @Override
getAttributeFloatValue(String namespace, String attribute, float defaultValue)2854         public float getAttributeFloatValue(String namespace, String attribute,
2855                 float defaultValue) {
2856             return 0;
2857         }
2858 
2859         @Override
getAttributeListValue(int index, String[] options, int defaultValue)2860         public int getAttributeListValue(int index, String[] options, int defaultValue) {
2861             return 0;
2862         }
2863 
2864         @Override
getAttributeBooleanValue(int index, boolean defaultValue)2865         public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
2866             return false;
2867         }
2868 
2869         @Override
getAttributeResourceValue(int index, int defaultValue)2870         public int getAttributeResourceValue(int index, int defaultValue) {
2871             return 0;
2872         }
2873 
2874         @Override
getAttributeIntValue(int index, int defaultValue)2875         public int getAttributeIntValue(int index, int defaultValue) {
2876             return 0;
2877         }
2878 
2879         @Override
getAttributeUnsignedIntValue(int index, int defaultValue)2880         public int getAttributeUnsignedIntValue(int index, int defaultValue) {
2881             return 0;
2882         }
2883 
2884         @Override
getAttributeFloatValue(int index, float defaultValue)2885         public float getAttributeFloatValue(int index, float defaultValue) {
2886             return 0;
2887         }
2888 
2889         @Override
getIdAttribute()2890         public String getIdAttribute() {
2891             return null;
2892         }
2893 
2894         @Override
getClassAttribute()2895         public String getClassAttribute() {
2896             return null;
2897         }
2898 
2899         @Override
getIdAttributeResourceValue(int defaultValue)2900         public int getIdAttributeResourceValue(int defaultValue) {
2901             return 0;
2902         }
2903 
2904         @Override
getStyleAttribute()2905         public int getStyleAttribute() {
2906             return 0;
2907         }
2908 
2909         @Override
close()2910         public void close() {
2911         }
2912 
2913         @Override
nextTag()2914         public int nextTag() throws IOException, XmlPullParserException {
2915             return parser.nextTag();
2916         }
2917     }
2918 }
2919