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.AutomaticZenRule.TYPE_BEDTIME;
20 import static android.app.AutomaticZenRule.TYPE_IMMERSIVE;
21 import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME;
22 import static android.app.AutomaticZenRule.TYPE_UNKNOWN;
23 import static android.app.Flags.FLAG_BACKUP_RESTORE_LOGGING;
24 import static android.app.Flags.FLAG_MODES_API;
25 import static android.app.Flags.FLAG_MODES_MULTIUSER;
26 import static android.app.Flags.FLAG_MODES_UI;
27 import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ACTIVATED;
28 import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_DEACTIVATED;
29 import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_DISABLED;
30 import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ENABLED;
31 import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_UNKNOWN;
32 import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
33 import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
34 import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
35 import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
36 import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
37 import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
38 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS;
39 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
40 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
41 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS;
42 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA;
43 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
44 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS;
45 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS;
46 import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM;
47 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
48 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS;
49 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
50 import static android.app.NotificationManager.Policy.STATE_PRIORITY_CHANNELS_BLOCKED;
51 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
52 import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG;
53 import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_RULES;
54 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
55 import static android.os.Process.SYSTEM_UID;
56 import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
57 import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
58 import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
59 import static android.provider.Settings.Global.ZEN_MODE_OFF;
60 import static android.service.notification.Condition.SOURCE_CONTEXT;
61 import static android.service.notification.Condition.SOURCE_SCHEDULE;
62 import static android.service.notification.Condition.SOURCE_USER_ACTION;
63 import static android.service.notification.Condition.STATE_FALSE;
64 import static android.service.notification.Condition.STATE_TRUE;
65 import static android.service.notification.ZenModeConfig.ORIGIN_APP;
66 import static android.service.notification.ZenModeConfig.ORIGIN_INIT;
67 import static android.service.notification.ZenModeConfig.ORIGIN_INIT_USER;
68 import static android.service.notification.ZenModeConfig.ORIGIN_SYSTEM;
69 import static android.service.notification.ZenModeConfig.ORIGIN_UNKNOWN;
70 import static android.service.notification.ZenModeConfig.ORIGIN_USER_IN_APP;
71 import static android.service.notification.ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI;
72 import static android.service.notification.ZenModeConfig.ZenRule.OVERRIDE_ACTIVATE;
73 import static android.service.notification.ZenModeConfig.ZenRule.OVERRIDE_DEACTIVATE;
74 import static android.service.notification.ZenModeConfig.ZenRule.OVERRIDE_NONE;
75 import static android.service.notification.ZenModeConfig.implicitRuleId;
76 import static android.service.notification.ZenPolicy.PEOPLE_TYPE_CONTACTS;
77 import static android.service.notification.ZenPolicy.PEOPLE_TYPE_NONE;
78 import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED;
79 import static android.service.notification.ZenPolicy.VISUAL_EFFECT_AMBIENT;
80 import static android.service.notification.ZenPolicy.VISUAL_EFFECT_BADGE;
81 import static android.service.notification.ZenPolicy.VISUAL_EFFECT_FULL_SCREEN_INTENT;
82 import static android.service.notification.ZenPolicy.VISUAL_EFFECT_LIGHTS;
83 import static android.service.notification.ZenPolicy.VISUAL_EFFECT_PEEK;
84 
85 import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.LOG_DND_STATE_EVENTS;
86 import static com.android.os.dnd.DNDProtoEnums.PEOPLE_STARRED;
87 import static com.android.os.dnd.DNDProtoEnums.ROOT_CONFIG;
88 import static com.android.os.dnd.DNDProtoEnums.STATE_ALLOW;
89 import static com.android.os.dnd.DNDProtoEnums.STATE_DISALLOW;
90 import static com.android.server.notification.ZenModeEventLogger.ACTIVE_RULE_TYPE_MANUAL;
91 import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE;
92 
93 import static com.google.common.base.Preconditions.checkNotNull;
94 import static com.google.common.collect.Iterables.getOnlyElement;
95 import static com.google.common.truth.Truth.assertThat;
96 import static com.google.common.truth.Truth.assertWithMessage;
97 
98 import static junit.framework.Assert.assertEquals;
99 import static junit.framework.Assert.assertFalse;
100 import static junit.framework.Assert.assertNotNull;
101 import static junit.framework.TestCase.assertTrue;
102 import static junit.framework.TestCase.fail;
103 
104 import static org.junit.Assert.assertNotEquals;
105 import static org.junit.Assert.assertNull;
106 import static org.junit.Assert.assertThrows;
107 import static org.mockito.ArgumentMatchers.any;
108 import static org.mockito.ArgumentMatchers.anyInt;
109 import static org.mockito.ArgumentMatchers.anyString;
110 import static org.mockito.ArgumentMatchers.eq;
111 import static org.mockito.Mockito.atLeastOnce;
112 import static org.mockito.Mockito.doNothing;
113 import static org.mockito.Mockito.mock;
114 import static org.mockito.Mockito.never;
115 import static org.mockito.Mockito.notNull;
116 import static org.mockito.Mockito.reset;
117 import static org.mockito.Mockito.spy;
118 import static org.mockito.Mockito.times;
119 import static org.mockito.Mockito.verify;
120 import static org.mockito.Mockito.verifyNoMoreInteractions;
121 import static org.mockito.Mockito.when;
122 import static org.mockito.Mockito.withSettings;
123 
124 import android.Manifest;
125 import android.annotation.Nullable;
126 import android.annotation.SuppressLint;
127 import android.app.AlarmManager;
128 import android.app.AppGlobals;
129 import android.app.AppOpsManager;
130 import android.app.AutomaticZenRule;
131 import android.app.Flags;
132 import android.app.NotificationManager;
133 import android.app.NotificationManager.Policy;
134 import android.app.backup.BackupRestoreEventLogger;
135 import android.app.compat.CompatChanges;
136 import android.content.ComponentName;
137 import android.content.Context;
138 import android.content.pm.ActivityInfo;
139 import android.content.pm.ApplicationInfo;
140 import android.content.pm.PackageInfo;
141 import android.content.pm.PackageManager;
142 import android.content.pm.ResolveInfo;
143 import android.content.res.Resources;
144 import android.content.res.XmlResourceParser;
145 import android.media.AudioAttributes;
146 import android.media.AudioManager;
147 import android.media.AudioManagerInternal;
148 import android.media.AudioSystem;
149 import android.media.VolumePolicy;
150 import android.net.Uri;
151 import android.os.Parcel;
152 import android.os.SimpleClock;
153 import android.os.UserHandle;
154 import android.platform.test.annotations.DisableFlags;
155 import android.platform.test.annotations.EnableFlags;
156 import android.platform.test.flag.junit.FlagsParameterization;
157 import android.platform.test.flag.junit.SetFlagsRule;
158 import android.provider.Settings;
159 import android.provider.Settings.Global;
160 import android.service.notification.Condition;
161 import android.service.notification.DeviceEffectsApplier;
162 import android.service.notification.SystemZenRules;
163 import android.service.notification.ZenAdapters;
164 import android.service.notification.ZenDeviceEffects;
165 import android.service.notification.ZenModeConfig;
166 import android.service.notification.ZenModeConfig.ScheduleInfo;
167 import android.service.notification.ZenModeConfig.ZenRule;
168 import android.service.notification.ZenModeDiff;
169 import android.service.notification.ZenPolicy;
170 import android.testing.TestWithLooperRule;
171 import android.testing.TestableLooper;
172 import android.util.ArrayMap;
173 import android.util.Log;
174 import android.util.StatsEvent;
175 import android.util.StatsEventTestUtils;
176 import android.util.Xml;
177 
178 import androidx.test.filters.SmallTest;
179 
180 import com.android.internal.R;
181 import com.android.internal.config.sysui.TestableFlagResolver;
182 import com.android.modules.utils.TypedXmlPullParser;
183 import com.android.modules.utils.TypedXmlSerializer;
184 import com.android.os.AtomsProto;
185 import com.android.os.dnd.DNDModeProto;
186 import com.android.os.dnd.DNDPolicyProto;
187 import com.android.os.dnd.DNDProtoEnums;
188 import com.android.server.UiServiceTestCase;
189 import com.android.server.notification.ManagedServices.UserProfiles;
190 
191 import com.google.common.collect.ImmutableList;
192 import com.google.common.collect.ImmutableSet;
193 import com.google.common.truth.Correspondence;
194 import com.google.common.util.concurrent.SettableFuture;
195 import com.google.protobuf.InvalidProtocolBufferException;
196 
197 import org.junit.Before;
198 import org.junit.Rule;
199 import org.junit.Test;
200 import org.junit.runner.RunWith;
201 import org.mockito.Mock;
202 import org.mockito.MockitoAnnotations;
203 import org.xmlpull.v1.XmlPullParserException;
204 
205 import java.io.BufferedInputStream;
206 import java.io.BufferedOutputStream;
207 import java.io.ByteArrayInputStream;
208 import java.io.ByteArrayOutputStream;
209 import java.io.IOException;
210 import java.io.InputStream;
211 import java.io.Reader;
212 import java.time.Instant;
213 import java.time.ZoneOffset;
214 import java.time.temporal.ChronoUnit;
215 import java.util.ArrayList;
216 import java.util.Calendar;
217 import java.util.LinkedList;
218 import java.util.List;
219 import java.util.Objects;
220 import java.util.concurrent.CountDownLatch;
221 import java.util.concurrent.TimeUnit;
222 import java.util.stream.Collectors;
223 
224 import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
225 import platform.test.runner.parameterized.Parameters;
226 
227 @SmallTest
228 @SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the service.
229 @RunWith(ParameterizedAndroidJunit4.class)
230 @TestableLooper.RunWithLooper
231 public class ZenModeHelperTest extends UiServiceTestCase {
232 
233     private static final String EVENTS_DEFAULT_RULE_ID = ZenModeConfig.EVENTS_OBSOLETE_RULE_ID;
234     private static final String SCHEDULE_DEFAULT_RULE_ID =
235             ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
236     private static final String CUSTOM_PKG_NAME = "not.android";
237     private static final String CUSTOM_APP_LABEL = "This is not Android";
238     private static final int CUSTOM_PKG_UID = 1;
239     private static final String CUSTOM_RULE_ID = "custom_rule";
240 
241     private static final String NAME = "name";
242     private static final ComponentName OWNER = new ComponentName("pkg", "cls");
243     private static final ComponentName CONFIG_ACTIVITY = new ComponentName("pkg", "act");
244     private static final ZenPolicy POLICY = new ZenPolicy.Builder().allowAlarms(true).build();
245     private static final Uri CONDITION_ID = new Uri.Builder().scheme("scheme")
246             .authority("authority")
247             .appendPath("path")
248             .appendPath("test")
249             .build();
250 
251     private static final Condition CONDITION_TRUE = new Condition(CONDITION_ID, "",
252             Condition.STATE_TRUE);
253     private static final Condition CONDITION_FALSE = new Condition(CONDITION_ID, "",
254             Condition.STATE_FALSE);
255     private static final String TRIGGER_DESC = "Every Night, 10pm to 6am";
256     private static final int TYPE = TYPE_BEDTIME;
257     private static final boolean ALLOW_MANUAL = true;
258     private static final String ICON_RES_NAME = "com.android.server.notification:drawable/res_name";
259     private static final int ICON_RES_ID = 123;
260     private static final int INTERRUPTION_FILTER_ZR = Settings.Global.ZEN_MODE_ALARMS;
261 
262     private static final int INTERRUPTION_FILTER_AZR
263             = NotificationManager.INTERRUPTION_FILTER_ALARMS;
264     private static final boolean ENABLED = true;
265     private static final int CREATION_TIME = 123;
266     private static final ZenDeviceEffects NO_EFFECTS = new ZenDeviceEffects.Builder().build();
267 
268     @Rule
269     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(
270             SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
271 
272     @Rule(order = Integer.MAX_VALUE) // set the highest order so it's the innermost rule
273     public TestWithLooperRule mLooperRule = new TestWithLooperRule();
274 
275     ConditionProviders mConditionProviders;
276     @Mock
277     NotificationManager mNotificationManager;
278     @Mock
279     PackageManager mPackageManager;
280     private Resources mResources;
281     private TestableLooper mTestableLooper;
282     private final TestClock mTestClock = new TestClock();
283     private ZenModeHelper mZenModeHelper;
284     @Mock
285     DeviceEffectsApplier mDeviceEffectsApplier;
286     @Mock
287     AppOpsManager mAppOps;
288     TestableFlagResolver mTestFlagResolver = new TestableFlagResolver();
289     ZenModeEventLoggerFake mZenModeEventLogger;
290     private String mPkg;
291 
292     @Parameters(name = "{0}")
getParams()293     public static List<FlagsParameterization> getParams() {
294         return FlagsParameterization.allCombinationsOf(FLAG_MODES_UI, FLAG_BACKUP_RESTORE_LOGGING);
295     }
296 
ZenModeHelperTest(FlagsParameterization flags)297     public ZenModeHelperTest(FlagsParameterization flags) {
298         mSetFlagsRule.setFlagsParameterization(flags);
299     }
300 
301     @Before
setUp()302     public void setUp() throws PackageManager.NameNotFoundException {
303         MockitoAnnotations.initMocks(this);
304 
305         mTestableLooper = TestableLooper.get(this);
306         mContext.ensureTestableResources();
307         mResources = mock(Resources.class, withSettings()
308                 .spiedInstance(mContext.getResources()));
309         mPkg = mContext.getPackageName();
310         try {
311             when(mResources.getXml(R.xml.default_zen_mode_config)).thenReturn(
312                     getDefaultConfigParser());
313         } catch (Exception e) {
314             Log.d("ZenModeHelperTest", "Couldn't mock default zen mode config xml file err=" +
315                     e.toString());
316         }
317         when(mResources.getIdentifier(ICON_RES_NAME, null, null)).thenReturn(ICON_RES_ID);
318         when(mResources.getResourceName(ICON_RES_ID)).thenReturn(ICON_RES_NAME);
319         when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(
320                 mResources);
321 
322         mContext.addMockSystemService(AppOpsManager.class, mAppOps);
323         mContext.addMockSystemService(NotificationManager.class, mNotificationManager);
324         mContext.addMockSystemService(Context.ALARM_SERVICE, mock(AlarmManager.class));
325 
326         mConditionProviders = new ConditionProviders(mContext, new UserProfiles(),
327                 AppGlobals.getPackageManager());
328         CountdownConditionProvider countdown = spy(new CountdownConditionProvider());
329         ScheduleConditionProvider schedule = spy(new ScheduleConditionProvider());
330         doNothing().when(countdown).notifyConditions(any());
331         doNothing().when(schedule).notifyConditions(any());
332         mConditionProviders.addSystemProvider(countdown);
333         mConditionProviders.addSystemProvider(schedule);
334         mZenModeEventLogger = new ZenModeEventLoggerFake(mPackageManager);
335         mZenModeHelper = new ZenModeHelper(mContext, mTestableLooper.getLooper(), mTestClock,
336                 mConditionProviders, mTestFlagResolver, mZenModeEventLogger);
337 
338         ResolveInfo ri = new ResolveInfo();
339         ri.activityInfo = new ActivityInfo();
340         when(mPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), anyInt())).thenReturn(
341                 ImmutableList.of(ri));
342         when(mPackageManager.getPackageUidAsUser(eq(CUSTOM_PKG_NAME), anyInt()))
343                 .thenReturn(CUSTOM_PKG_UID);
344         when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
345                 new String[]{mPkg});
346 
347         ApplicationInfo appInfoSpy = spy(new ApplicationInfo());
348         appInfoSpy.icon = ICON_RES_ID;
349         when(appInfoSpy.loadLabel(any())).thenReturn(CUSTOM_APP_LABEL);
350         when(mPackageManager.getApplicationInfo(eq(CUSTOM_PKG_NAME), anyInt()))
351                 .thenReturn(appInfoSpy);
352         when(mPackageManager.getApplicationInfo(eq(mPkg), anyInt()))
353                 .thenReturn(appInfoSpy);
354         mZenModeHelper.mPm = mPackageManager;
355 
356         mZenModeEventLogger.reset();
357     }
358 
getDefaultConfigParser()359     private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException {
360         String xml = "<zen version=\"10\">\n"
361                 + "<allow alarms=\"true\" media=\"true\" system=\"false\" calls=\"true\" "
362                 + "callsFrom=\"2\" messages=\"true\"\n"
363                 + "messagesFrom=\"2\" reminders=\"false\" events=\"false\" "
364                 + "repeatCallers=\"true\" convos=\"true\"\n"
365                 + "convosFrom=\"2\"/>\n"
366                 + "<automatic ruleId=" + EVENTS_DEFAULT_RULE_ID
367                 + " enabled=\"false\" snoozing=\"false\""
368                 + " name=\"Event\" zen=\"1\"\n"
369                 + "  component=\"android/com.android.server.notification.EventConditionProvider\"\n"
370                 + "  conditionId=\"condition://android/event?userId=-10000&amp;calendar=&amp;"
371                 + "reply=1\"/>\n"
372                 + "<automatic ruleId=" + SCHEDULE_DEFAULT_RULE_ID + " enabled=\"false\""
373                 + " snoozing=\"false\" name=\"Sleeping\"\n zen=\"1\""
374                 + " component=\"android/com.android.server.notification"
375                 + ".ScheduleConditionProvider\"\n"
376                 + " conditionId=\"condition://android/schedule?days=1.2.3.4.5.6.7&amp;start=22.0"
377                 + "&amp;end=7.0&amp;exitAtAlarm=true\"/>\n"
378                 + "<disallow visualEffects=\"157\" />\n"
379                 + "<state areChannelsBypassingDnd=\"false\" />\n"
380                 + "</zen>";
381         TypedXmlPullParser parser = Xml.newFastPullParser();
382         parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), null);
383         parser.nextTag();
384         return new XmlResourceParserImpl(parser);
385     }
386 
writeXmlAndPurge(Integer version)387     private ByteArrayOutputStream writeXmlAndPurge(Integer version) throws Exception {
388         TypedXmlSerializer serializer = Xml.newFastSerializer();
389         ByteArrayOutputStream baos = new ByteArrayOutputStream();
390         serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
391         serializer.startDocument(null, true);
392         mZenModeHelper.writeXml(serializer, false, version, UserHandle.USER_ALL, null);
393         serializer.endDocument();
394         serializer.flush();
395         mZenModeHelper.setConfig(new ZenModeConfig(), null, ORIGIN_INIT, "writing xml",
396                 SYSTEM_UID);
397         return baos;
398     }
399 
writeXmlAndPurgeForUser(Integer version, int userId, boolean forBackup, BackupRestoreEventLogger logger)400     private ByteArrayOutputStream writeXmlAndPurgeForUser(Integer version, int userId,
401             boolean forBackup, BackupRestoreEventLogger logger)
402             throws Exception {
403         TypedXmlSerializer serializer = Xml.newFastSerializer();
404         ByteArrayOutputStream baos = new ByteArrayOutputStream();
405         serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
406         serializer.startDocument(null, true);
407         mZenModeHelper.writeXml(serializer, forBackup, version, userId, logger);
408         serializer.endDocument();
409         serializer.flush();
410         ZenModeConfig newConfig = new ZenModeConfig();
411         newConfig.user = userId;
412         mZenModeHelper.setConfig(newConfig, null, ORIGIN_INIT, "writing xml",
413                 SYSTEM_UID);
414         return baos;
415     }
416 
getParserForByteStream(ByteArrayOutputStream baos)417     private TypedXmlPullParser getParserForByteStream(ByteArrayOutputStream baos) throws Exception {
418         TypedXmlPullParser parser = Xml.newFastPullParser();
419         parser.setInput(
420                 new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null);
421         parser.nextTag();
422         return parser;
423     }
424 
getCustomAutomaticRules()425     private ArrayMap<String, ZenModeConfig.ZenRule> getCustomAutomaticRules() {
426         return getCustomAutomaticRules(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
427     }
428 
getCustomAutomaticRules(int zenMode)429     private ArrayMap<String, ZenModeConfig.ZenRule> getCustomAutomaticRules(int zenMode) {
430         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
431         ZenModeConfig.ZenRule rule = createCustomAutomaticRule(zenMode, CUSTOM_RULE_ID);
432         automaticRules.put(rule.id, rule);
433         return automaticRules;
434     }
435 
createCustomAutomaticRule(int zenMode, String id)436     private ZenModeConfig.ZenRule createCustomAutomaticRule(int zenMode, String id) {
437         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
438         final ScheduleInfo customRuleInfo = new ScheduleInfo();
439         customRule.enabled = true;
440         customRule.creationTime = 0;
441         customRule.id = id;
442         customRule.name = "Custom Rule with id=" + id;
443         customRule.zenMode = zenMode;
444         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
445         customRule.configurationActivity =
446                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider");
447         customRule.pkg = customRule.configurationActivity.getPackageName();
448         return customRule;
449     }
450 
451     // Verify that the appropriate appOpps operations are called for the restrictions requested.
452     // Note that this method assumes that priority only DND exempt packages is set to something
453     // in order to be able to distinguish it from the null case, so callers should make sure
454     // setPriorityOnlyDndExemptPackages has been called bofre this verify statement.
verifyApplyRestrictions(boolean zenPriorityOnly, boolean mute, int usage)455     private void verifyApplyRestrictions(boolean zenPriorityOnly, boolean mute, int usage) {
456         int expectedMode = mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
457         verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_VIBRATE), eq(usage),
458                 eq(expectedMode), zenPriorityOnly ? notNull() : eq(null));
459         verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage),
460                 eq(expectedMode), zenPriorityOnly ? notNull() : eq(null));
461     }
462 
463     @Test
testZenOff_NoMuteApplied()464     public void testZenOff_NoMuteApplied() {
465         mZenModeHelper.mZenMode = ZEN_MODE_OFF;
466         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
467         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
468                 | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
469         mZenModeHelper.applyRestrictions();
470 
471         // Check that we call through to applyRestrictions with usages USAGE_ALARM and USAGE_MEDIA
472         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
473         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_MEDIA);
474     }
475 
476     @Test
testZenOn_NotificationApplied()477     public void testZenOn_NotificationApplied() {
478         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
479         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
480         // The most permissive policy
481         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
482                 | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
483                 | PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
484                 | PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
485                 | PRIORITY_CATEGORY_REPEAT_CALLERS | PRIORITY_CATEGORY_SYSTEM, PRIORITY_SENDERS_ANY,
486                 PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
487         mZenModeHelper.applyRestrictions();
488 
489         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_NOTIFICATION);
490         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_NOTIFICATION_EVENT);
491         verifyApplyRestrictions(true, true,
492                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED);
493         verifyApplyRestrictions(true, true,
494                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT);
495     }
496 
497     @Test
testZenOn_RepeatCallers_CallTypesBlocked()498     public void testZenOn_RepeatCallers_CallTypesBlocked() {
499         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
500         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
501         // Any call allowed but no repeat callers
502         mZenModeHelper.mConsolidatedPolicy = new Policy(PRIORITY_CATEGORY_CALLS,
503                 PRIORITY_SENDERS_ANY, 0, 0, 0);
504         mZenModeHelper.applyRestrictions();
505 
506         verifyApplyRestrictions(true, true,
507                 AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
508         verifyApplyRestrictions(true, true,
509                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
510     }
511 
512 
513     @Test
testZenOn_StarredCallers_CallTypesBlocked()514     public void testZenOn_StarredCallers_CallTypesBlocked() {
515         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
516         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
517         // The most permissive policy
518         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
519                 | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
520                 | PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
521                 | PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
522                 | PRIORITY_CATEGORY_SYSTEM | PRIORITY_CATEGORY_REPEAT_CALLERS,
523                 PRIORITY_SENDERS_STARRED,
524                 PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
525         mZenModeHelper.applyRestrictions();
526 
527         verifyApplyRestrictions(true, true,
528                 AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
529         verifyApplyRestrictions(true, true,
530                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
531     }
532 
533     @Test
testZenOn_AllCallers_CallTypesAllowed()534     public void testZenOn_AllCallers_CallTypesAllowed() {
535         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
536         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
537         // The most permissive policy
538         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
539                 | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
540                 | PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
541                 | PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
542                 | PRIORITY_CATEGORY_REPEAT_CALLERS | PRIORITY_CATEGORY_SYSTEM,
543                 PRIORITY_SENDERS_ANY,
544                 PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
545         mZenModeHelper.applyRestrictions();
546 
547         verifyApplyRestrictions(true, false, AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
548         verifyApplyRestrictions(true, false,
549                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
550     }
551 
552     @Test
testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied()553     public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() {
554         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
555         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
556         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
557                 | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
558 
559         mZenModeHelper.applyRestrictions();
560         verifyApplyRestrictions(true, false, AudioAttributes.USAGE_ALARM);
561         verifyApplyRestrictions(true, false, AudioAttributes.USAGE_MEDIA);
562     }
563 
564     @Test
testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied()565     public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() {
566         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
567         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
568         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
569         mZenModeHelper.applyRestrictions();
570         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_ALARM);
571 
572         // Media is a catch-all that includes games
573         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_MEDIA);
574         verifyApplyRestrictions(true, true, AudioAttributes.USAGE_GAME);
575     }
576 
577     @Test
testTotalSilence()578     public void testTotalSilence() {
579         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
580         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
581         mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
582                 | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
583         mZenModeHelper.applyRestrictions();
584 
585         // Total silence will silence alarms, media and system noises (but not vibrations)
586         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_ALARM);
587         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_MEDIA);
588         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_GAME);
589         verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_PLAY_AUDIO,
590                 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_IGNORED, null);
591         verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_VIBRATE,
592                 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_ALLOWED, null);
593         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_UNKNOWN);
594     }
595 
596     @Test
testAlarmsOnly_alarmMediaMuteNotApplied()597     public void testAlarmsOnly_alarmMediaMuteNotApplied() {
598         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
599         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
600         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
601         mZenModeHelper.applyRestrictions();
602 
603         // Alarms only mode will not silence alarms
604         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
605 
606         // Alarms only mode will not silence media
607         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_MEDIA);
608         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_GAME);
609         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_UNKNOWN);
610 
611         // Alarms only will silence system noises (but not vibrations)
612         verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_PLAY_AUDIO,
613                 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_IGNORED, null);
614     }
615 
616     @Test
testAlarmsOnly_callsMuteApplied()617     public void testAlarmsOnly_callsMuteApplied() {
618         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
619         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
620         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
621         mZenModeHelper.applyRestrictions();
622 
623         // Alarms only mode will silence calls despite priority-mode config
624         verifyApplyRestrictions(false, true, AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
625         verifyApplyRestrictions(false, true,
626                 AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
627     }
628 
629     @Test
testAlarmsOnly_allZenConfigToggledCannotBypass_alarmMuteNotApplied()630     public void testAlarmsOnly_allZenConfigToggledCannotBypass_alarmMuteNotApplied() {
631         // Only audio attributes with SUPPRESIBLE_NEVER can bypass
632         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
633         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
634         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
635         mZenModeHelper.applyRestrictions();
636 
637         verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
638     }
639 
640     @Test
testZenAllCannotBypass()641     public void testZenAllCannotBypass() {
642         // Only audio attributes with SUPPRESIBLE_NEVER can bypass
643         // with special case USAGE_ASSISTANCE_SONIFICATION
644         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
645         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
646         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
647         mZenModeHelper.applyRestrictions();
648 
649         for (int usage : AudioAttributes.getSdkUsages()) {
650             if (usage == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) {
651                 // only mute audio, not vibrations
652                 verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_PLAY_AUDIO),
653                         eq(usage), eq(AppOpsManager.MODE_IGNORED), notNull());
654                 verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_VIBRATE),
655                         eq(usage), eq(AppOpsManager.MODE_ALLOWED), notNull());
656             } else {
657                 boolean shouldMute = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage)
658                         != AudioAttributes.SUPPRESSIBLE_NEVER;
659                 verifyApplyRestrictions(true, shouldMute, usage);
660             }
661         }
662     }
663 
664     @Test
testApplyRestrictions_whitelist_priorityOnlyMode()665     public void testApplyRestrictions_whitelist_priorityOnlyMode() {
666         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
667         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
668         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
669         mZenModeHelper.applyRestrictions();
670 
671         for (int usage : AudioAttributes.getSdkUsages()) {
672             verify(mAppOps).setRestriction(
673                     eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage), anyInt(), eq(new String[]{PKG_O}));
674             verify(mAppOps).setRestriction(
675                     eq(AppOpsManager.OP_VIBRATE), eq(usage), anyInt(), eq(new String[]{PKG_O}));
676         }
677     }
678 
679     @Test
testApplyRestrictions_whitelist_alarmsOnlyMode()680     public void testApplyRestrictions_whitelist_alarmsOnlyMode() {
681         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
682         mZenModeHelper.mZenMode = Global.ZEN_MODE_ALARMS;
683         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
684         mZenModeHelper.applyRestrictions();
685 
686         for (int usage : AudioAttributes.getSdkUsages()) {
687             verify(mAppOps).setRestriction(
688                     eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage), anyInt(), eq(null));
689             verify(mAppOps).setRestriction(
690                     eq(AppOpsManager.OP_VIBRATE), eq(usage), anyInt(), eq(null));
691         }
692     }
693 
694     @Test
testApplyRestrictions_whitelist_totalSilenceMode()695     public void testApplyRestrictions_whitelist_totalSilenceMode() {
696         mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[]{PKG_O});
697         mZenModeHelper.mZenMode = Global.ZEN_MODE_NO_INTERRUPTIONS;
698         mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
699         mZenModeHelper.applyRestrictions();
700 
701         for (int usage : AudioAttributes.getSdkUsages()) {
702             verify(mAppOps).setRestriction(
703                     eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage), anyInt(), eq(null));
704             verify(mAppOps).setRestriction(
705                     eq(AppOpsManager.OP_VIBRATE), eq(usage), anyInt(), eq(null));
706         }
707     }
708 
709     @Test
710     @EnableFlags(FLAG_MODES_API)
testTotalSilence_consolidatedPolicyDisallowsAll()711     public void testTotalSilence_consolidatedPolicyDisallowsAll() {
712         // Start with zen mode off just to make sure global/manual mode isn't doing anything.
713         mZenModeHelper.mZenMode = ZEN_MODE_OFF;
714 
715         // Create a zen rule that calls for total silence via zen mode, but does not specify any
716         // particular policy. This confirms that the application of the policy is based only on the
717         // actual zen mode setting.
718         AutomaticZenRule azr = new AutomaticZenRule.Builder("OriginalName", CONDITION_ID)
719                 .setInterruptionFilter(INTERRUPTION_FILTER_NONE)
720                 .build();
721         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
722                 mContext.getPackageName(), azr, ORIGIN_SYSTEM, "reason", SYSTEM_UID);
723 
724         // Enable rule
725         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
726                 new Condition(azr.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM,
727                 SYSTEM_UID);
728 
729         // Confirm that the consolidated policy doesn't allow anything
730         NotificationManager.Policy policy = mZenModeHelper.getConsolidatedNotificationPolicy();
731         assertThat(policy.allowAlarms()).isFalse();
732         assertThat(policy.allowMedia()).isFalse();
733         assertThat(policy.allowCalls()).isFalse();
734         assertThat(policy.allowMessages()).isFalse();
735         assertThat(policy.allowConversations()).isFalse();
736         assertThat(policy.allowEvents()).isFalse();
737         assertThat(policy.allowReminders()).isFalse();
738         assertThat(policy.allowRepeatCallers()).isFalse();
739         assertThat(policy.allowPriorityChannels()).isFalse();
740     }
741 
742     @Test
743     @EnableFlags(FLAG_MODES_API)
testAlarmsOnly_consolidatedPolicyOnlyAllowsAlarmsAndMedia()744     public void testAlarmsOnly_consolidatedPolicyOnlyAllowsAlarmsAndMedia() {
745         // Start with zen mode off just to make sure global/manual mode isn't doing anything.
746         mZenModeHelper.mZenMode = ZEN_MODE_OFF;
747 
748         // Create a zen rule that calls for alarms only via zen mode, but does not specify any
749         // particular policy. This confirms that the application of the policy is based only on the
750         // actual zen mode setting.
751         AutomaticZenRule azr = new AutomaticZenRule.Builder("OriginalName", CONDITION_ID)
752                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
753                 .build();
754         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
755                 mContext.getPackageName(), azr, ORIGIN_SYSTEM, "reason", SYSTEM_UID);
756 
757         // Enable rule
758         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
759                 new Condition(azr.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM,
760                 SYSTEM_UID);
761 
762         // Confirm that the consolidated policy allows only alarms and media and nothing else
763         NotificationManager.Policy policy = mZenModeHelper.getConsolidatedNotificationPolicy();
764         assertThat(policy.allowAlarms()).isTrue();
765         assertThat(policy.allowMedia()).isTrue();
766         assertThat(policy.allowCalls()).isFalse();
767         assertThat(policy.allowMessages()).isFalse();
768         assertThat(policy.allowConversations()).isFalse();
769         assertThat(policy.allowEvents()).isFalse();
770         assertThat(policy.allowReminders()).isFalse();
771         assertThat(policy.allowRepeatCallers()).isFalse();
772         assertThat(policy.allowPriorityChannels()).isFalse();
773     }
774 
775     @Test
testZenSetInternalRinger_AllPriorityNotificationSoundsMuted()776     public void testZenSetInternalRinger_AllPriorityNotificationSoundsMuted() {
777         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
778         mZenModeHelper.mAudioManager = mAudioManager;
779         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
780                 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
781 
782         // 1. Current ringer is normal
783         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
784         // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
785         Policy totalSilence = new Policy(0, 0, 0);
786         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, totalSilence, ORIGIN_APP, 1);
787         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
788 
789         // 2. verify ringer is unchanged
790         mZenModeHelper.applyZenToRingerMode();
791         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
792                 mZenModeHelper.TAG);
793 
794         // 3. apply zen off - verify zen is set to previous ringer (normal)
795         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
796         mZenModeHelper.mZenMode = ZEN_MODE_OFF;
797         mZenModeHelper.applyZenToRingerMode();
798         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
799                 mZenModeHelper.TAG);
800     }
801 
802     @Test
testRingerAffectedStreamsTotalSilence()803     public void testRingerAffectedStreamsTotalSilence() {
804         // in total silence:
805         // ringtone, notification, system, alarm, streams, music are affected by ringer mode
806         mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
807         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
808                 mZenModeHelper.new RingerModeDelegate();
809         int ringerModeAffectedStreams = ringerModeDelegate.getRingerModeAffectedStreams(0);
810         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
811         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
812                 != 0);
813         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0);
814         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) != 0);
815         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) != 0);
816         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ASSISTANT)) != 0);
817     }
818 
819     @Test
testRingerAffectedStreamsPriorityOnly()820     public void testRingerAffectedStreamsPriorityOnly() {
821         // in priority only mode:
822         // ringtone, notification and system streams are affected by ringer mode
823         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
824                 Uri.EMPTY, ORIGIN_APP, "test", "caller", 1);
825         ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerMuted =
826                 mZenModeHelper.new RingerModeDelegate();
827 
828         int ringerModeAffectedStreams =
829                 ringerModeDelegateRingerMuted.getRingerModeAffectedStreams(0);
830         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
831         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
832                 != 0);
833         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM)) != 0);
834         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0);
835         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0);
836         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ASSISTANT)) == 0);
837 
838         // even when ringer is muted (since all ringer sounds cannot bypass DND),
839         // system stream is still affected by ringer mode
840         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, new Policy(0, 0, 0), ORIGIN_APP,
841                 1);
842         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
843                 Uri.EMPTY, ORIGIN_APP, "test", "caller", 1);
844         ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerNotMuted =
845                 mZenModeHelper.new RingerModeDelegate();
846 
847         int ringerMutedRingerModeAffectedStreams =
848                 ringerModeDelegateRingerNotMuted.getRingerModeAffectedStreams(0);
849         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
850         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
851                 != 0);
852         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_SYSTEM))
853                 != 0);
854         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_ALARM)) == 0);
855         assertTrue((ringerMutedRingerModeAffectedStreams & (1 << AudioSystem.STREAM_MUSIC)) == 0);
856         assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_ASSISTANT)) == 0);
857     }
858 
859     @Test
applyZenToRingerMode_ZEN_MODE_IMPORTANT_INTERRUPTIONS()860     public void applyZenToRingerMode_ZEN_MODE_IMPORTANT_INTERRUPTIONS() {
861         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
862         mZenModeHelper.mAudioManager = mAudioManager;
863         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
864                 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
865 
866         // 1. Current ringer is normal
867         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
868         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
869 
870         // 2. apply priority only zen - verify ringer is normal
871         mZenModeHelper.applyZenToRingerMode();
872         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
873                 mZenModeHelper.TAG);
874 
875         // 3.  apply zen off - verify ringer remains normal
876         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
877         mZenModeHelper.mZenMode = ZEN_MODE_OFF;
878         mZenModeHelper.applyZenToRingerMode();
879         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
880                 mZenModeHelper.TAG);
881     }
882 
883     @Test
testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartSilent()884     public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartSilent() {
885         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
886         mZenModeHelper.mAudioManager = mAudioManager;
887         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
888                 Integer.toString(AudioManager.RINGER_MODE_SILENT));
889 
890         // 1. Current ringer is silent
891         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
892         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
893 
894         // 2. apply priority only zen - verify ringer is silent
895         mZenModeHelper.applyZenToRingerMode();
896         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
897                 mZenModeHelper.TAG);
898 
899         // 3. apply zen-off - verify ringer is still silent
900         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
901         mZenModeHelper.mZenMode = ZEN_MODE_OFF;
902         mZenModeHelper.applyZenToRingerMode();
903         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
904                 mZenModeHelper.TAG);
905     }
906 
907     @Test
testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_RingerChanges()908     public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_RingerChanges() {
909         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
910         mZenModeHelper.mAudioManager = mAudioManager;
911         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
912                 Integer.toString(AudioManager.RINGER_MODE_NORMAL));
913 
914         // 1. Current ringer is normal
915         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
916         // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
917         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
918 
919         // 2. apply priority only zen - verify zen will still be normal
920         mZenModeHelper.applyZenToRingerMode();
921         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
922                 mZenModeHelper.TAG);
923 
924         // 3. change ringer from normal to silent, verify previous ringer set to new ringer (silent)
925         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
926                 mZenModeHelper.new RingerModeDelegate();
927         ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
928                 AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
929                 VolumePolicy.DEFAULT);
930         assertEquals(AudioManager.RINGER_MODE_SILENT, Global.getInt(mContext.getContentResolver(),
931                 Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
932 
933         // 4.  apply zen off - verify ringer still silenced
934         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
935         mZenModeHelper.mZenMode = ZEN_MODE_OFF;
936         mZenModeHelper.applyZenToRingerMode();
937         verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
938                 mZenModeHelper.TAG);
939     }
940 
941     @Test
testSilentRingerSavedInZenOff_startsZenOff()942     public void testSilentRingerSavedInZenOff_startsZenOff() {
943         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
944         mZenModeHelper.mConfig = new ZenModeConfig();
945         mZenModeHelper.mAudioManager = mAudioManager;
946 
947         // apply zen off multiple times - verify ringer is not set to normal
948         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
949         for (int i = 0; i < 3; i++) {
950             mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, Uri.EMPTY,
951                     ORIGIN_APP, "test", "caller", 1);
952         }
953         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
954                 mZenModeHelper.TAG);
955     }
956 
957     @Test
testSilentRingerSavedOnZenOff_startsZenOn()958     public void testSilentRingerSavedOnZenOff_startsZenOn() {
959         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
960         mZenModeHelper.mAudioManager = mAudioManager;
961 
962         // previously set silent ringer
963         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
964                 mZenModeHelper.new RingerModeDelegate();
965         ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
966                 AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
967                 VolumePolicy.DEFAULT);
968         assertEquals(AudioManager.RINGER_MODE_SILENT, Global.getInt(mContext.getContentResolver(),
969                 Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
970 
971         // apply zen on multiple times - verify ringer is not set to normal
972         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
973         for (int i = 0; i < 3; i++) {
974             // if zen doesn't change, zen should not reapply itself to the ringer
975             mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, Uri.EMPTY,
976                     ORIGIN_APP, "test", "caller", 1);
977         }
978         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
979                 mZenModeHelper.TAG);
980     }
981 
982     @Test
testVibrateRingerSavedOnZenOff_startsZenOn()983     public void testVibrateRingerSavedOnZenOff_startsZenOn() {
984         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
985         mZenModeHelper.mAudioManager = mAudioManager;
986 
987         // previously set silent ringer
988         ZenModeHelper.RingerModeDelegate ringerModeDelegate =
989                 mZenModeHelper.new RingerModeDelegate();
990         ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
991                 AudioManager.RINGER_MODE_VIBRATE, "test", AudioManager.RINGER_MODE_NORMAL,
992                 VolumePolicy.DEFAULT);
993         assertEquals(AudioManager.RINGER_MODE_VIBRATE, Global.getInt(mContext.getContentResolver(),
994                 Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
995 
996         // apply zen off multiple times - verify ringer is not set to normal
997         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
998         for (int i = 0; i < 3; i++) {
999             // if zen doesn't change, zen should not reapply itself to the ringer
1000             mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, Uri.EMPTY,
1001                     ORIGIN_APP, "test", "caller", 1);
1002         }
1003         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
1004                 mZenModeHelper.TAG);
1005     }
1006 
1007     @Test
testSetConfig_updatesAudioEventually()1008     public void testSetConfig_updatesAudioEventually() {
1009         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
1010         mZenModeHelper.mAudioManager = mAudioManager;
1011         setupZenConfig();
1012         mTestableLooper.processAllMessages();
1013         reset(mAudioManager);
1014 
1015         // Turn manual zen mode on
1016         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
1017                 ORIGIN_APP, null, "test", CUSTOM_PKG_UID);
1018 
1019         // audio manager shouldn't do anything until the handler processes its messages
1020         verify(mAudioManager, never()).updateRingerModeAffectedStreamsInternal();
1021 
1022         // now process the looper's messages
1023         mTestableLooper.processAllMessages();
1024 
1025         // Expect calls to audio manager
1026         verify(mAudioManager, times(1)).updateRingerModeAffectedStreamsInternal();
1027 
1028         // called during applyZenToRingerMode(), which should be true since zen changed
1029         verify(mAudioManager, atLeastOnce()).getRingerModeInternal();
1030     }
1031 
1032     @Test
testSetConfig_updatesAudioForSequentialChangesToZenMode()1033     public void testSetConfig_updatesAudioForSequentialChangesToZenMode() {
1034         AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
1035         mZenModeHelper.mAudioManager = mAudioManager;
1036         setupZenConfig();
1037         mTestableLooper.processAllMessages();
1038         reset(mAudioManager);
1039 
1040         // Turn manual zen mode on
1041         mZenModeHelper.setManualZenMode(
1042                 UserHandle.CURRENT,
1043                 ZEN_MODE_IMPORTANT_INTERRUPTIONS,
1044                 null,
1045                 ORIGIN_APP,
1046                 null,
1047                 "test",
1048                 CUSTOM_PKG_UID);
1049         mZenModeHelper.setManualZenMode(
1050                 UserHandle.CURRENT,
1051                 ZEN_MODE_IMPORTANT_INTERRUPTIONS,
1052                 null,
1053                 ORIGIN_APP,
1054                 null,
1055                 "test",
1056                 CUSTOM_PKG_UID);
1057 
1058         // audio manager shouldn't do anything until the handler processes its messages
1059         verify(mAudioManager, never()).updateRingerModeAffectedStreamsInternal();
1060 
1061         // now process the looper's messages
1062         mTestableLooper.processAllMessages();
1063 
1064         // Expect calls to audio manager
1065         verify(mAudioManager, times(2)).updateRingerModeAffectedStreamsInternal();
1066         verify(mAudioManager, times(1)).setRingerModeInternal(anyInt(), anyString());
1067 
1068         // called during applyZenToRingerMode(), which should be true since zen changed
1069         verify(mAudioManager, atLeastOnce()).getRingerModeInternal();
1070     }
1071 
1072     @Test
testParcelConfig()1073     public void testParcelConfig() {
1074         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT,
1075                 new Policy(PRIORITY_CATEGORY_EVENTS
1076                         | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_REPEAT_CALLERS
1077                         | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED,
1078                         PRIORITY_SENDERS_STARRED, 0, CONVERSATION_SENDERS_ANYONE),
1079                 ORIGIN_UNKNOWN,
1080                 1);
1081         mZenModeHelper.setManualZenRuleDeviceEffects(UserHandle.CURRENT,
1082                 new ZenDeviceEffects.Builder()
1083                         .setShouldDimWallpaper(true)
1084                         .setShouldDisplayGrayscale(true)
1085                         .setShouldUseNightMode(true)
1086                         .build(),
1087                 ORIGIN_UNKNOWN, "test", 1);
1088         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
1089                 Uri.EMPTY, ORIGIN_UNKNOWN, "test", "me", 1);
1090 
1091         ZenModeConfig actual = mZenModeHelper.mConfig.copy();
1092 
1093         assertEquals(mZenModeHelper.mConfig, actual);
1094     }
1095 
1096     @Test
testWriteXml()1097     public void testWriteXml() throws Exception {
1098         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT,
1099                 new Policy(PRIORITY_CATEGORY_EVENTS
1100                         | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_REPEAT_CALLERS
1101                         | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED,
1102                         PRIORITY_SENDERS_STARRED, SUPPRESSED_EFFECT_BADGE,
1103                         CONVERSATION_SENDERS_ANYONE),
1104                 ORIGIN_UNKNOWN, 1);
1105         mZenModeHelper.setManualZenRuleDeviceEffects(UserHandle.CURRENT,
1106                 new ZenDeviceEffects.Builder()
1107                         .setShouldDimWallpaper(true)
1108                         .setShouldDisplayGrayscale(true)
1109                         .build(),
1110                 ORIGIN_UNKNOWN, "test", 1);
1111         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
1112                 Uri.EMPTY, ORIGIN_UNKNOWN, "test", "me", 1);
1113 
1114         ZenModeConfig expected = mZenModeHelper.mConfig.copy();
1115         if (Flags.modesUi()) {
1116             // Reading the configuration will upgrade it, so for equality comparison also upgrade
1117             // the expected value.
1118             SystemZenRules.maybeUpgradeRules(mContext, expected);
1119         }
1120 
1121         ByteArrayOutputStream baos = writeXmlAndPurge(null);
1122         TypedXmlPullParser parser = getParserForByteStream(baos);
1123         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1124 
1125         assertEquals("Config mismatch: current vs expected: "
1126                         + new ZenModeDiff.ConfigDiff(mZenModeHelper.mConfig, expected), expected,
1127                 mZenModeHelper.mConfig);
1128     }
1129 
1130     @Test
testProto()1131     public void testProto() throws InvalidProtocolBufferException {
1132         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
1133                 Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ORIGIN_SYSTEM, null,
1134                 "test", CUSTOM_PKG_UID);
1135 
1136         mZenModeHelper.mConfig.automaticRules = new ArrayMap<>(); // no automatic rules
1137 
1138         List<String> ids = new ArrayList<>();
1139         ids.add(ZenModeConfig.MANUAL_RULE_ID);
1140         ids.add(""); // for ROOT_CONFIG, logged with empty string as id
1141 
1142         List<StatsEvent> events = new LinkedList<>();
1143         mZenModeHelper.pullRules(events);
1144         assertEquals(2, events.size());  // manual rule + root config
1145         for (StatsEvent ev : events) {
1146             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
1147             assertTrue(atom.hasDndModeRule());
1148             DNDModeProto cfg = atom.getDndModeRule();
1149             // Additional check for ID to clearly identify the root config because there's some
1150             // odd behavior in the test util around enum value of 0 (the usual default, but not in
1151             // this case).
1152             if (cfg.getZenMode().getNumber() == ROOT_CONFIG && cfg.getId().equals("")) {
1153                 assertTrue(cfg.getEnabled());
1154                 assertFalse(cfg.getChannelsBypassing());
1155             }
1156             String name = cfg.getId();
1157             assertTrue("unexpected rule id", ids.contains(name));
1158             ids.remove(name);
1159         }
1160         assertEquals("extra rule in output", 0, ids.size());
1161     }
1162 
1163     @Test
testProtoWithAutoRule()1164     public void testProtoWithAutoRule() throws Exception {
1165         setupZenConfig();
1166         // one enabled automatic rule. we use a non-usual zen mode value (though it has to be
1167         // a real one in the enum because non-valid enum values are reverted to default).
1168         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules(ZEN_MODE_ALARMS);
1169 
1170         List<StatsEvent> events = new LinkedList<>();
1171         mZenModeHelper.pullRules(events);
1172 
1173         boolean foundCustomEvent = false;
1174         for (StatsEvent ev : events) {
1175             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
1176             assertTrue(atom.hasDndModeRule());
1177             DNDModeProto cfg = atom.getDndModeRule();
1178             if (cfg.getZenMode().getNumber() == ZEN_MODE_ALARMS) {
1179                 foundCustomEvent = true;
1180                 assertEquals(CUSTOM_PKG_UID, cfg.getUid());
1181                 assertTrue(cfg.getEnabled());
1182             }
1183         }
1184         assertTrue("couldn't find custom rule", foundCustomEvent);
1185     }
1186 
1187     @Test
testProtoWithDefaultAutoRules()1188     public void testProtoWithDefaultAutoRules() throws Exception {
1189         setupZenConfig();
1190         // clear the automatic rules so we can reset to only the default rules
1191         mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();
1192 
1193         // read in XML to restore the default rules
1194         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1195         TypedXmlPullParser parser = Xml.newFastPullParser();
1196         parser.setInput(new BufferedInputStream(
1197                 new ByteArrayInputStream(baos.toByteArray())), null);
1198         parser.nextTag();
1199         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1200         List<StatsEvent> events = new LinkedList<>();
1201         mZenModeHelper.pullRules(events);
1202 
1203         // list for tracking which ids we've seen in the pulled atom output
1204         List<String> ids = new ArrayList<>();
1205         ids.addAll(ZenModeConfig.getDefaultRuleIds());
1206         ids.add("");  // empty string for root config
1207 
1208         for (StatsEvent ev : events) {
1209             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
1210             assertTrue(atom.hasDndModeRule());
1211             DNDModeProto cfg = atom.getDndModeRule();
1212             if (!ids.contains(cfg.getId())) {
1213                 fail("unexpected ID found: " + cfg.getId());
1214             }
1215             ids.remove(cfg.getId());
1216         }
1217         assertEquals("default ID(s) not found", 0, ids.size());
1218     }
1219 
1220     @Test
testProtoWithAutoRuleCustomPolicy_classic()1221     public void testProtoWithAutoRuleCustomPolicy_classic() throws Exception {
1222         setupZenConfig();
1223         // clear any automatic rules just to make sure
1224         mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();
1225 
1226         // Add an automatic rule with a custom policy
1227         ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS, CUSTOM_RULE_ID);
1228         rule.zenPolicy = new ZenPolicy.Builder()
1229                 .allowAlarms(true)
1230                 .allowRepeatCallers(false)
1231                 .allowCalls(PEOPLE_TYPE_STARRED)
1232                 .build();
1233         mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
1234         List<StatsEvent> events = new LinkedList<>();
1235         mZenModeHelper.pullRules(events);
1236 
1237         boolean foundCustomEvent = false;
1238         for (StatsEvent ev : events) {
1239             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
1240             assertTrue(atom.hasDndModeRule());
1241             DNDModeProto cfg = atom.getDndModeRule();
1242             if (cfg.getUid() == CUSTOM_PKG_UID) {
1243                 foundCustomEvent = true;
1244                 // Check that the pieces of the policy are applied.
1245                 assertThat(cfg.hasPolicy()).isTrue();
1246                 DNDPolicyProto policy = cfg.getPolicy();
1247                 assertThat(policy.getAlarms().getNumber()).isEqualTo(DNDProtoEnums.STATE_ALLOW);
1248                 assertThat(policy.getRepeatCallers().getNumber())
1249                         .isEqualTo(DNDProtoEnums.STATE_DISALLOW);
1250                 assertThat(policy.getCalls().getNumber()).isEqualTo(DNDProtoEnums.STATE_ALLOW);
1251                 assertThat(policy.getAllowCallsFrom().getNumber())
1252                         .isEqualTo(DNDProtoEnums.PEOPLE_STARRED);
1253             }
1254         }
1255         assertTrue("couldn't find custom rule", foundCustomEvent);
1256     }
1257 
1258     @Test
1259     @EnableFlags(FLAG_MODES_API)
testProtoWithAutoRuleCustomPolicy()1260     public void testProtoWithAutoRuleCustomPolicy() throws Exception {
1261         setupZenConfig();
1262         // clear any automatic rules just to make sure
1263         mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();
1264 
1265         // Add an automatic rule with a custom policy
1266         ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS, CUSTOM_RULE_ID);
1267         rule.zenPolicy = new ZenPolicy.Builder()
1268                 .allowAlarms(true)
1269                 .allowRepeatCallers(false)
1270                 .allowCalls(PEOPLE_TYPE_STARRED)
1271                 .allowPriorityChannels(false)
1272                 .build();
1273         mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
1274         List<StatsEvent> events = new LinkedList<>();
1275         mZenModeHelper.pullRules(events);
1276 
1277         boolean foundCustomEvent = false;
1278         for (StatsEvent ev : events) {
1279             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
1280             assertTrue(atom.hasDndModeRule());
1281             DNDModeProto cfg = atom.getDndModeRule();
1282             if (cfg.getUid() == CUSTOM_PKG_UID) {
1283                 foundCustomEvent = true;
1284                 // Check that the pieces of the policy are applied.
1285                 assertThat(cfg.hasPolicy()).isTrue();
1286                 DNDPolicyProto policy = cfg.getPolicy();
1287                 assertThat(policy.getAlarms().getNumber()).isEqualTo(DNDProtoEnums.STATE_ALLOW);
1288                 assertThat(policy.getRepeatCallers().getNumber())
1289                         .isEqualTo(DNDProtoEnums.STATE_DISALLOW);
1290                 assertThat(policy.getCalls().getNumber()).isEqualTo(DNDProtoEnums.STATE_ALLOW);
1291                 assertThat(policy.getAllowCallsFrom().getNumber())
1292                         .isEqualTo(DNDProtoEnums.PEOPLE_STARRED);
1293                 assertThat(policy.getAllowChannels().getNumber())
1294                         .isEqualTo(DNDProtoEnums.CHANNEL_POLICY_NONE);
1295             }
1296         }
1297         assertTrue("couldn't find custom rule", foundCustomEvent);
1298     }
1299 
1300     @Test
1301     @EnableFlags(FLAG_MODES_API)
testProtoWithAutoRuleWithModifiedFields()1302     public void testProtoWithAutoRuleWithModifiedFields() throws Exception {
1303         setupZenConfig();
1304         mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();
1305         ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS, CUSTOM_RULE_ID);
1306         rule.userModifiedFields = AutomaticZenRule.FIELD_NAME;
1307         rule.zenPolicyUserModifiedFields = ZenPolicy.FIELD_PRIORITY_CATEGORY_MEDIA;
1308         rule.zenDeviceEffectsUserModifiedFields = ZenDeviceEffects.FIELD_GRAYSCALE;
1309         mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
1310 
1311         List<StatsEvent> events = new ArrayList<>();
1312         mZenModeHelper.pullRules(events);
1313 
1314         assertThat(events).hasSize(2); // Global config + 1 automatic rule
1315         DNDModeProto ruleProto = StatsEventTestUtils.convertToAtom(events.get(1)).getDndModeRule();
1316         assertThat(ruleProto.getRuleModifiedFields()).isEqualTo(rule.userModifiedFields);
1317         assertThat(ruleProto.getPolicyModifiedFields()).isEqualTo(rule.zenPolicyUserModifiedFields);
1318         assertThat(ruleProto.getDeviceEffectsModifiedFields()).isEqualTo(
1319                 rule.zenDeviceEffectsUserModifiedFields);
1320     }
1321 
1322     @Test
ruleUidsCached()1323     public void ruleUidsCached() throws Exception {
1324         setupZenConfig();
1325         // one enabled automatic rule
1326         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1327         List<StatsEvent> events = new LinkedList<>();
1328         // first time retrieving uid:
1329         mZenModeHelper.pullRules(events);
1330         verify(mPackageManager, atLeastOnce()).getPackageUidAsUser(anyString(), anyInt());
1331 
1332         // second time retrieving uid:
1333         reset(mPackageManager);
1334         mZenModeHelper.pullRules(events);
1335         verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());
1336 
1337         // new rule from same package + user added
1338         reset(mPackageManager);
1339         ZenModeConfig.ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS,
1340                 CUSTOM_RULE_ID + "2");
1341         mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
1342         mZenModeHelper.pullRules(events);
1343         verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());
1344     }
1345 
1346     @Test
ruleUidAutomaticZenRuleRemovedUpdatesCache()1347     public void ruleUidAutomaticZenRuleRemovedUpdatesCache() throws Exception {
1348         when(mContext.checkCallingPermission(anyString()))
1349                 .thenReturn(PERMISSION_GRANTED);
1350 
1351         setupZenConfig();
1352         // one enabled automatic rule
1353         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1354         List<StatsEvent> events = new LinkedList<>();
1355 
1356         mZenModeHelper.pullRules(events);
1357         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, CUSTOM_RULE_ID, ORIGIN_APP,
1358                 "test", CUSTOM_PKG_UID);
1359         assertTrue(-1
1360                 == mZenModeHelper.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
1361     }
1362 
1363     @Test
testProtoRedactsIds()1364     public void testProtoRedactsIds() throws Exception {
1365         setupZenConfig();
1366         // one enabled automatic rule
1367         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1368 
1369         List<StatsEvent> events = new LinkedList<>();
1370         mZenModeHelper.pullRules(events);
1371 
1372         for (StatsEvent ev : events) {
1373             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
1374             assertTrue(atom.hasDndModeRule());
1375             DNDModeProto cfg = atom.getDndModeRule();
1376             if ("customRule".equals(cfg.getId())) {
1377                 fail("non-default IDs should be redacted");
1378             }
1379         }
1380     }
1381 
1382     @Test
testProtoWithManualRule()1383     public void testProtoWithManualRule() throws Exception {
1384         setupZenConfig();
1385         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1386         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, INTERRUPTION_FILTER_PRIORITY, Uri.EMPTY,
1387                 ORIGIN_APP, "test", "me", 1);
1388 
1389         List<StatsEvent> events = new LinkedList<>();
1390         mZenModeHelper.pullRules(events);
1391 
1392         boolean foundManualRule = false;
1393         for (StatsEvent ev : events) {
1394             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
1395             assertTrue(atom.hasDndModeRule());
1396             DNDModeProto cfg = atom.getDndModeRule();
1397             if (ZenModeConfig.MANUAL_RULE_ID.equals(cfg.getId())) {
1398                 assertEquals(0, cfg.getUid());
1399                 foundManualRule = true;
1400             }
1401         }
1402         assertTrue("couldn't find manual rule", foundManualRule);
1403     }
1404 
1405     @Test
testWriteXml_onlyBackupsTargetUser()1406     public void testWriteXml_onlyBackupsTargetUser() throws Exception {
1407         BackupRestoreEventLogger logger = null;
1408         if (android.app.Flags.backupRestoreLogging()) {
1409             logger = mock(BackupRestoreEventLogger.class);
1410         }
1411         // Setup configs for user 10 and 11.
1412         setupZenConfig();
1413         ZenModeConfig config10 = mZenModeHelper.mConfig.copy();
1414         Policy policy = new Policy(PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_ALARMS, 0, 0);
1415         config10.applyNotificationPolicy(policy);
1416         config10.user = 10;
1417         mZenModeHelper.setConfig(config10, null, ORIGIN_INIT, "writeXml",
1418                 SYSTEM_UID);
1419         ZenModeConfig config11 = mZenModeHelper.mConfig.copy();
1420         config11.user = 11;
1421         policy = new Policy(0, 0, 0);
1422         config11.applyNotificationPolicy(policy);
1423         mZenModeHelper.setConfig(config11, null, ORIGIN_INIT, "writeXml",
1424                 SYSTEM_UID);
1425 
1426         // Backup user 10 and reset values.
1427         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, 10, true, logger);
1428         ZenModeConfig newConfig11 = new ZenModeConfig();
1429         newConfig11.user = 11;
1430         mZenModeHelper.mConfigs.put(11, newConfig11);
1431 
1432         // Parse backup data.
1433         TypedXmlPullParser parser = getParserForByteStream(baos);
1434         mZenModeHelper.readXml(parser, true, 10, logger);
1435         parser = getParserForByteStream(baos);
1436         mZenModeHelper.readXml(parser, true, 11, logger);
1437 
1438         ZenModeConfig actual = mZenModeHelper.mConfigs.get(10);
1439         if (Flags.modesUi()) {
1440             // Reading the configuration will upgrade it, so for equality comparison also upgrade
1441             // the expected value.
1442             SystemZenRules.maybeUpgradeRules(mContext, config10);
1443             SystemZenRules.maybeUpgradeRules(mContext, config11);
1444         }
1445 
1446         assertEquals(
1447                 "Config mismatch: current vs expected: "
1448                         + new ZenModeDiff.ConfigDiff(actual, config10), config10, actual);
1449         assertNotEquals("Expected config mismatch", config11, mZenModeHelper.mConfigs.get(11));
1450 
1451         if (android.app.Flags.backupRestoreLogging()) {
1452             verify(logger).logItemsBackedUp(DATA_TYPE_ZEN_CONFIG, 1);
1453             // If this is modes_ui, this is manual + single default rule
1454             // If not modes_ui, it's two default automatic rules + manual policy
1455             verify(logger).logItemsBackedUp(DATA_TYPE_ZEN_RULES, Flags.modesUi() ? 2 : 3);
1456             verify(logger, never())
1457                     .logItemsBackupFailed(anyString(), anyInt(), anyString());
1458 
1459             verify(logger, times(2)).logItemsRestored(DATA_TYPE_ZEN_RULES, Flags.modesUi() ? 2 : 3);
1460             verify(logger, never())
1461                     .logItemsRestoreFailed(anyString(), anyInt(), anyString());
1462         }
1463     }
1464 
1465     @Test
testReadXmlRestore_forSystemUser()1466     public void testReadXmlRestore_forSystemUser() throws Exception {
1467         BackupRestoreEventLogger logger = null;
1468         if (android.app.Flags.backupRestoreLogging()) {
1469             logger = mock(BackupRestoreEventLogger.class);
1470         }
1471         setupZenConfig();
1472         // one enabled automatic rule
1473         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1474         ZenModeConfig original = mZenModeHelper.mConfig.copy();
1475 
1476         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(
1477                 null, UserHandle.USER_SYSTEM, true, logger);
1478         TypedXmlPullParser parser = getParserForByteStream(baos);
1479         mZenModeHelper.readXml(parser, true, UserHandle.USER_SYSTEM, logger);
1480 
1481         assertEquals("Config mismatch: current vs original: "
1482                         + new ZenModeDiff.ConfigDiff(mZenModeHelper.mConfig, original),
1483                 original, mZenModeHelper.mConfig);
1484         assertEquals(original.hashCode(), mZenModeHelper.mConfig.hashCode());
1485 
1486         if (android.app.Flags.backupRestoreLogging()) {
1487             verify(logger).logItemsBackedUp(DATA_TYPE_ZEN_CONFIG, 1);
1488             verify(logger).logItemsBackedUp(DATA_TYPE_ZEN_RULES, 2);
1489             verify(logger, never())
1490                     .logItemsBackupFailed(anyString(), anyInt(), anyString());
1491             verify(logger).logItemsRestored(DATA_TYPE_ZEN_RULES, 2);
1492             verify(logger, never())
1493                     .logItemsRestoreFailed(anyString(), anyInt(), anyString());
1494         }
1495     }
1496 
1497     /** Restore should ignore the data's user id and restore for the target user. */
1498     @Test
testReadXmlRestore_forNonSystemUser()1499     public void testReadXmlRestore_forNonSystemUser() throws Exception {
1500         BackupRestoreEventLogger logger = null;
1501         if (android.app.Flags.backupRestoreLogging()) {
1502             logger = mock(BackupRestoreEventLogger.class);
1503         }
1504         // Setup config.
1505         setupZenConfig();
1506         mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
1507         ZenModeConfig expected = mZenModeHelper.mConfig.copy();
1508 
1509         // Backup data for user 0.
1510         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(
1511                 null, UserHandle.USER_SYSTEM, true, logger);
1512 
1513         // Restore data for user 10.
1514         TypedXmlPullParser parser = getParserForByteStream(baos);
1515         mZenModeHelper.readXml(parser, true, 10, logger);
1516 
1517         ZenModeConfig actual = mZenModeHelper.mConfigs.get(10);
1518         expected.user = 10;
1519         assertEquals("Config mismatch: current vs original: "
1520                         + new ZenModeDiff.ConfigDiff(actual, expected),
1521                 expected, actual);
1522         assertEquals(expected.hashCode(), actual.hashCode());
1523         expected.user = 0;
1524         assertNotEquals(expected, mZenModeHelper.mConfig);
1525     }
1526 
1527     @Test
testReadXmlRestore_doesNotEnableManualRule()1528     public void testReadXmlRestore_doesNotEnableManualRule() throws Exception {
1529         BackupRestoreEventLogger logger = null;
1530         if (android.app.Flags.backupRestoreLogging()) {
1531             logger = mock(BackupRestoreEventLogger.class);
1532         }
1533         setupZenConfig();
1534 
1535         // Turn on manual zen mode
1536         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
1537                 ORIGIN_USER_IN_SYSTEMUI, "", "someCaller", SYSTEM_UID);
1538         ZenModeConfig original = mZenModeHelper.mConfig.copy();
1539         assertThat(original.isManualActive()).isTrue();
1540 
1541         ByteArrayOutputStream baos = writeXmlAndPurge(null);
1542         TypedXmlPullParser parser = getParserForByteStream(baos);
1543         mZenModeHelper.readXml(parser, true, UserHandle.USER_ALL, logger);
1544 
1545         ZenModeConfig result = mZenModeHelper.getConfig();
1546         assertThat(result.isManualActive()).isFalse();
1547 
1548         // confirm that we do still keep policy information, modes_ui only; prior to modes_ui the
1549         // entire rule is intentionally cleared
1550         if (Flags.modesUi()) {
1551             assertThat(result.manualRule.zenPolicy).isNotNull();
1552         }
1553     }
1554 
1555     @Test
testWriteXmlWithZenPolicy()1556     public void testWriteXmlWithZenPolicy() throws Exception {
1557         final String ruleId = "customRule";
1558         setupZenConfig();
1559 
1560         // one enabled automatic rule with zen policy
1561         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
1562         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1563         final ScheduleInfo customRuleInfo = new ScheduleInfo();
1564         customRule.enabled = true;
1565         customRule.creationTime = 0;
1566         customRule.id = "customRule";
1567         customRule.name = "Custom Rule";
1568         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1569         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
1570         customRule.configurationActivity =
1571                 new ComponentName("android", "ScheduleConditionProvider");
1572         customRule.pkg = customRule.configurationActivity.getPackageName();
1573         customRule.zenPolicy = new ZenPolicy.Builder()
1574                 .allowAlarms(false)
1575                 .allowMedia(false)
1576                 .allowRepeatCallers(false)
1577                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)
1578                 .allowMessages(PEOPLE_TYPE_CONTACTS)
1579                 .allowEvents(true)
1580                 .allowReminders(false)
1581                 .build();
1582         automaticRules.put("customRule", customRule);
1583         mZenModeHelper.mConfig.automaticRules = automaticRules;
1584 
1585         ZenModeConfig expected = mZenModeHelper.mConfig.copy();
1586         if (Flags.modesUi()) {
1587             // Reading the configuration will upgrade it, so for equality comparison also upgrade
1588             // the expected value.
1589             SystemZenRules.maybeUpgradeRules(mContext, expected);
1590         }
1591 
1592         ByteArrayOutputStream baos = writeXmlAndPurge(null);
1593         TypedXmlPullParser parser = Xml.newFastPullParser();
1594         parser.setInput(new BufferedInputStream(
1595                 new ByteArrayInputStream(baos.toByteArray())), null);
1596         parser.nextTag();
1597         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1598 
1599         ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
1600         ZenModeConfig.ZenRule current = mZenModeHelper.mConfig.automaticRules.get(ruleId);
1601 
1602         assertEquals("Automatic rules mismatch: current vs expected: "
1603                 + new ZenModeDiff.RuleDiff(original, current), original, current);
1604     }
1605 
1606     @Test
testReadXmlRestoreWithZenPolicy_forSystemUser()1607     public void testReadXmlRestoreWithZenPolicy_forSystemUser() throws Exception {
1608         BackupRestoreEventLogger logger = null;
1609         if (android.app.Flags.backupRestoreLogging()) {
1610             logger = mock(BackupRestoreEventLogger.class);
1611         }
1612         final String ruleId = "customRule";
1613         setupZenConfig();
1614 
1615         // one enabled automatic rule with zen policy
1616         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
1617         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1618         final ScheduleInfo customRuleInfo = new ScheduleInfo();
1619         customRule.enabled = true;
1620         customRule.creationTime = 0;
1621         customRule.id = ruleId;
1622         customRule.name = "Custom Rule";
1623         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1624         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
1625         customRule.configurationActivity =
1626                 new ComponentName("android", "ScheduleConditionProvider");
1627         customRule.pkg = customRule.configurationActivity.getPackageName();
1628         customRule.zenPolicy = new ZenPolicy.Builder()
1629                 .allowSystem(true)
1630                 .allowCalls(ZenPolicy.PEOPLE_TYPE_ANYONE)
1631                 .allowReminders(true)
1632                 .build();
1633         automaticRules.put(ruleId, customRule);
1634         mZenModeHelper.mConfig.automaticRules = automaticRules;
1635 
1636         ZenModeConfig expected = mZenModeHelper.mConfig.copy();
1637         if (Flags.modesUi()) {
1638             // Reading the configuration will upgrade it, so for equality comparison also upgrade
1639             // the expected value.
1640             SystemZenRules.maybeUpgradeRules(mContext, expected);
1641         }
1642 
1643         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(
1644                 null, UserHandle.USER_SYSTEM, true, logger);
1645         TypedXmlPullParser parser = getParserForByteStream(baos);
1646         mZenModeHelper.readXml(parser, true, UserHandle.USER_SYSTEM, logger);
1647 
1648         ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
1649         ZenModeConfig.ZenRule current = mZenModeHelper.mConfig.automaticRules.get(ruleId);
1650 
1651         assertEquals("Automatic rules mismatch: current vs expected: "
1652                 + new ZenModeDiff.RuleDiff(original, current), original, current);
1653     }
1654 
1655     @Test
testReadXmlRulesNotOverridden()1656     public void testReadXmlRulesNotOverridden() throws Exception {
1657         setupZenConfig();
1658         Policy originalPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT);
1659 
1660         // automatic zen rule is enabled on upgrade so rules should not be overriden to default
1661         ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
1662         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1663         final ScheduleInfo weeknights = new ScheduleInfo();
1664         customRule.enabled = true;
1665         customRule.name = "Custom Rule";
1666         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1667         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
1668         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1669         enabledAutoRule.put("customRule", customRule);
1670         mZenModeHelper.mConfig.automaticRules = enabledAutoRule;
1671 
1672         // set previous version
1673         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1674         TypedXmlPullParser parser = Xml.newFastPullParser();
1675         parser.setInput(new BufferedInputStream(
1676                 new ByteArrayInputStream(baos.toByteArray())), null);
1677         parser.nextTag();
1678         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1679 
1680         assertTrue(mZenModeHelper.mConfig.automaticRules.containsKey("customRule"));
1681         assertEquals(originalPolicy, mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT));
1682     }
1683 
1684     @Test
testMigrateSuppressedVisualEffects_oneExistsButOff()1685     public void testMigrateSuppressedVisualEffects_oneExistsButOff() throws Exception {
1686         String xml = "<zen version=\"6\" user=\"0\">\n"
1687                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1688                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1689                 + "visualScreenOff=\"true\" alarms=\"true\" "
1690                 + "media=\"true\" system=\"false\" />\n"
1691                 + "<disallow visualEffects=\"511\" />"
1692                 + "</zen>";
1693 
1694         TypedXmlPullParser parser = Xml.newFastPullParser();
1695         parser.setInput(new BufferedInputStream(
1696                 new ByteArrayInputStream(xml.getBytes())), null);
1697         parser.nextTag();
1698         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1699 
1700         assertTrue(mZenModeHelper.mConfig.getZenPolicy().shouldShowAllVisualEffects());
1701 
1702         xml = "<zen version=\"6\" user=\"0\">\n"
1703                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1704                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1705                 + "visualScreenOn=\"true\" alarms=\"true\" "
1706                 + "media=\"true\" system=\"false\" />\n"
1707                 + "<disallow visualEffects=\"511\" />"
1708                 + "</zen>";
1709 
1710         parser = Xml.newFastPullParser();
1711         parser.setInput(new BufferedInputStream(
1712                 new ByteArrayInputStream(xml.getBytes())), null);
1713         parser.nextTag();
1714         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1715 
1716         assertTrue(mZenModeHelper.mConfig.getZenPolicy().shouldShowAllVisualEffects());
1717     }
1718 
1719     @Test
testMigrateSuppressedVisualEffects_bothExistButOff()1720     public void testMigrateSuppressedVisualEffects_bothExistButOff() throws Exception {
1721         String xml = "<zen version=\"6\" user=\"0\">\n"
1722                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1723                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1724                 + "visualScreenOff=\"true\" visualScreenOn=\"true\" alarms=\"true\" "
1725                 + "media=\"true\" system=\"false\" />\n"
1726                 + "<disallow visualEffects=\"511\" />"
1727                 + "</zen>";
1728 
1729         TypedXmlPullParser parser = Xml.newFastPullParser();
1730         parser.setInput(new BufferedInputStream(
1731                 new ByteArrayInputStream(xml.getBytes())), null);
1732         parser.nextTag();
1733         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1734 
1735         assertTrue(mZenModeHelper.mConfig.getZenPolicy().shouldShowAllVisualEffects());
1736     }
1737 
1738     @Test
testMigrateSuppressedVisualEffects_bothExistButOn()1739     public void testMigrateSuppressedVisualEffects_bothExistButOn() throws Exception {
1740         String xml = "<zen version=\"6\" user=\"0\">\n"
1741                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1742                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1743                 + "visualScreenOff=\"false\" visualScreenOn=\"false\" alarms=\"true\" "
1744                 + "media=\"true\" system=\"false\" />\n"
1745                 + "<disallow visualEffects=\"511\" />"
1746                 + "</zen>";
1747 
1748         TypedXmlPullParser parser = Xml.newFastPullParser();
1749         parser.setInput(new BufferedInputStream(
1750                 new ByteArrayInputStream(xml.getBytes())), null);
1751         parser.nextTag();
1752         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1753 
1754         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1755                 .isVisualEffectAllowed(VISUAL_EFFECT_FULL_SCREEN_INTENT, true)).isFalse();
1756         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1757                 .isVisualEffectAllowed(VISUAL_EFFECT_LIGHTS, true)).isFalse();
1758         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1759                 .isVisualEffectAllowed(VISUAL_EFFECT_PEEK, true)).isFalse();
1760         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1761                 .isVisualEffectAllowed(VISUAL_EFFECT_AMBIENT, true)).isFalse();
1762         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1763                 .isVisualEffectAllowed(VISUAL_EFFECT_BADGE, true)).isTrue();
1764 
1765         xml = "<zen version=\"6\" user=\"0\">\n"
1766                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1767                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1768                 + "visualScreenOff=\"true\" visualScreenOn=\"false\" alarms=\"true\" "
1769                 + "media=\"true\" system=\"false\" />\n"
1770                 + "<disallow visualEffects=\"511\" />"
1771                 + "</zen>";
1772 
1773         parser = Xml.newFastPullParser();
1774         parser.setInput(new BufferedInputStream(
1775                 new ByteArrayInputStream(xml.getBytes())), null);
1776         parser.nextTag();
1777         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1778 
1779         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1780                 .isVisualEffectAllowed(VISUAL_EFFECT_PEEK, true)).isFalse();
1781         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1782                 .isVisualEffectAllowed(VISUAL_EFFECT_AMBIENT, true)).isTrue();
1783 
1784         xml = "<zen version=\"6\" user=\"0\">\n"
1785                 + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
1786                 + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
1787                 + "visualScreenOff=\"false\" visualScreenOn=\"true\" alarms=\"true\" "
1788                 + "media=\"true\" system=\"false\" />\n"
1789                 + "<disallow visualEffects=\"511\" />"
1790                 + "</zen>";
1791 
1792         parser = Xml.newFastPullParser();
1793         parser.setInput(new BufferedInputStream(
1794                 new ByteArrayInputStream(xml.getBytes())), null);
1795         parser.nextTag();
1796         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1797 
1798         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1799                 .isVisualEffectAllowed(VISUAL_EFFECT_FULL_SCREEN_INTENT, true)).isFalse();
1800         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1801                 .isVisualEffectAllowed(VISUAL_EFFECT_LIGHTS, true)).isFalse();
1802         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1803                 .isVisualEffectAllowed(VISUAL_EFFECT_AMBIENT, true)).isFalse();
1804         assertThat(mZenModeHelper.mConfig.getZenPolicy()
1805                 .isVisualEffectAllowed(VISUAL_EFFECT_BADGE, true)).isTrue();
1806     }
1807 
1808     @Test
testReadXmlResetDefaultRules()1809     public void testReadXmlResetDefaultRules() throws Exception {
1810         setupZenConfig();
1811         Policy originalPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT);
1812 
1813         // no enabled automatic zen rules and no default rules
1814         // so rules should be overridden by default rules
1815         mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();
1816 
1817         // set previous version
1818         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1819         TypedXmlPullParser parser = Xml.newFastPullParser();
1820         parser.setInput(new BufferedInputStream(
1821                 new ByteArrayInputStream(baos.toByteArray())), null);
1822         parser.nextTag();
1823         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1824 
1825         // check default rules
1826         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
1827         assertTrue(rules.size() != 0);
1828         for (String defaultId : ZenModeConfig.getDefaultRuleIds()) {
1829             assertTrue(rules.containsKey(defaultId));
1830         }
1831 
1832         assertEquals(originalPolicy, mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT));
1833     }
1834 
1835     @Test
testReadXmlAllDisabledRulesResetDefaultRules()1836     public void testReadXmlAllDisabledRulesResetDefaultRules() throws Exception {
1837         setupZenConfig();
1838         Policy originalPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT);
1839 
1840         // all automatic zen rules are disabled on upgrade (and default rules don't already exist)
1841         // so rules should be overriden by default rules
1842         ArrayMap<String, ZenModeConfig.ZenRule> disabledAutoRule = new ArrayMap<>();
1843         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1844         final ScheduleInfo weeknights = new ScheduleInfo();
1845         customRule.enabled = false;
1846         customRule.name = "Custom Rule";
1847         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1848         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
1849         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1850         disabledAutoRule.put("customRule", customRule);
1851         mZenModeHelper.mConfig.automaticRules = disabledAutoRule;
1852 
1853         // set previous version
1854         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1855         TypedXmlPullParser parser = Xml.newFastPullParser();
1856         parser.setInput(new BufferedInputStream(
1857                 new ByteArrayInputStream(baos.toByteArray())), null);
1858         parser.nextTag();
1859         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1860 
1861         // check default rules
1862         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
1863         assertTrue(rules.size() != 0);
1864         for (String defaultId : ZenModeConfig.getDefaultRuleIds()) {
1865             assertTrue(rules.containsKey(defaultId));
1866         }
1867         assertFalse(rules.containsKey("customRule"));
1868 
1869         assertEquals(originalPolicy, mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT));
1870     }
1871 
1872     @Test
1873     @DisableFlags(FLAG_MODES_UI) // modes_ui has only 1 default rule
testReadXmlOnlyOneDefaultRuleExists()1874     public void testReadXmlOnlyOneDefaultRuleExists() throws Exception {
1875         setupZenConfig();
1876         Policy originalPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT);
1877 
1878         // all automatic zen rules are disabled on upgrade and only one default rule exists
1879         // so rules should be overriden to the default rules
1880         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
1881         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1882         final ScheduleInfo customRuleInfo = new ScheduleInfo();
1883         customRule.enabled = false;
1884         customRule.name = "Custom Rule";
1885         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1886         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
1887         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1888         customRule.zenPolicy = new ZenPolicy.Builder()
1889                 .allowReminders(true)
1890                 .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE)
1891                 .build();
1892         automaticRules.put("customRule", customRule);
1893 
1894         ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule();
1895         final ScheduleInfo defaultScheduleRuleInfo = new ScheduleInfo();
1896         defaultScheduleRule.enabled = false;
1897         defaultScheduleRule.name = "Default Schedule Rule";
1898         defaultScheduleRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1899         defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId(
1900                 defaultScheduleRuleInfo);
1901         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1902         defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
1903         automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
1904 
1905         mZenModeHelper.mConfig.automaticRules = automaticRules;
1906 
1907         // set previous version
1908         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1909         TypedXmlPullParser parser = Xml.newFastPullParser();
1910         parser.setInput(new BufferedInputStream(
1911                 new ByteArrayInputStream(baos.toByteArray())), null);
1912         parser.nextTag();
1913         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1914 
1915         // check default rules
1916         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
1917         assertThat(rules).isNotEmpty();
1918         for (String defaultId : ZenModeConfig.getDefaultRuleIds()) {
1919             assertThat(rules).containsKey(defaultId);
1920         }
1921         assertThat(rules).doesNotContainKey("customRule");
1922 
1923         assertEquals(originalPolicy, mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT));
1924     }
1925 
1926     @Test
testReadXmlDefaultRulesExist()1927     public void testReadXmlDefaultRulesExist() throws Exception {
1928         setupZenConfig();
1929         Policy originalPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT);
1930 
1931         // Default rules exist so rules should not be overridden by defaults
1932         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
1933         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
1934         final ScheduleInfo customRuleInfo = new ScheduleInfo();
1935         customRule.enabled = false;
1936         customRule.name = "Custom Rule";
1937         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1938         customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
1939         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
1940         customRule.zenPolicy = new ZenPolicy.Builder()
1941                 .allowReminders(true)
1942                 .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE)
1943                 .build();
1944         automaticRules.put("customRule", customRule);
1945 
1946         ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule();
1947         final ScheduleInfo defaultScheduleRuleInfo = new ScheduleInfo();
1948         defaultScheduleRule.enabled = false;
1949         defaultScheduleRule.name = "Default Schedule Rule";
1950         defaultScheduleRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1951         defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId(
1952                 defaultScheduleRuleInfo);
1953         defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
1954         defaultScheduleRule.zenPolicy = new ZenPolicy.Builder()
1955                 .allowEvents(true)
1956                 .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE)
1957                 .build();
1958         automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
1959 
1960         ZenModeConfig.ZenRule defaultEventRule = new ZenModeConfig.ZenRule();
1961         final ScheduleInfo defaultEventRuleInfo = new ScheduleInfo();
1962         defaultEventRule.enabled = false;
1963         defaultEventRule.name = "Default Event Rule";
1964         defaultEventRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1965         defaultEventRule.conditionId = ZenModeConfig.toScheduleConditionId(
1966                 defaultEventRuleInfo);
1967         defaultEventRule.id = ZenModeConfig.EVENTS_OBSOLETE_RULE_ID;
1968         defaultScheduleRule.zenPolicy = new ZenPolicy.Builder()
1969                 .allowAlarms(false)
1970                 .allowMedia(false)
1971                 .allowRepeatCallers(false)
1972                 .build();
1973         automaticRules.put(ZenModeConfig.EVENTS_OBSOLETE_RULE_ID, defaultEventRule);
1974 
1975         mZenModeHelper.mConfig.automaticRules = automaticRules;
1976 
1977         // set previous version
1978         ByteArrayOutputStream baos = writeXmlAndPurge(5);
1979         TypedXmlPullParser parser = Xml.newFastPullParser();
1980         parser.setInput(new BufferedInputStream(
1981                 new ByteArrayInputStream(baos.toByteArray())), null);
1982         parser.nextTag();
1983         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
1984 
1985         // check default rules
1986         int expectedNumAutoRules = 1 + ZenModeConfig.getDefaultRuleIds().size(); // custom + default
1987         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
1988         assertThat(rules).hasSize(expectedNumAutoRules);
1989         for (String defaultId : ZenModeConfig.getDefaultRuleIds()) {
1990             assertThat(rules).containsKey(defaultId);
1991         }
1992         assertThat(rules).containsKey("customRule");
1993 
1994         assertEquals(originalPolicy, mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT));
1995 
1996         List<StatsEvent> events = new LinkedList<>();
1997         mZenModeHelper.pullRules(events);
1998         assertThat(events).hasSize(expectedNumAutoRules + 1); // auto + manual
1999     }
2000 
2001     @Test
2002     @EnableFlags(FLAG_MODES_API)
testReadXml_onModesApi_noUpgrade()2003     public void testReadXml_onModesApi_noUpgrade() throws Exception {
2004         // When reading XML for something that is already on the modes API system, make sure no
2005         // rules' policies get changed.
2006         setupZenConfig();
2007         Policy originalPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT);
2008 
2009         // Shared for rules
2010         ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRules = new ArrayMap<>();
2011         final ScheduleInfo weeknights = new ScheduleInfo();
2012 
2013         // Custom rule with a custom policy
2014         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
2015         customRule.enabled = true;
2016         customRule.name = "Custom Rule";
2017         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2018         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
2019         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
2020         ZenPolicy policy = new ZenPolicy.Builder()
2021                 .allowCalls(PEOPLE_TYPE_CONTACTS)
2022                 .allowAlarms(true)
2023                 .allowRepeatCallers(false)
2024                 .build();
2025         // Fill in policy fields, since on modes api we do not expect any rules to have unset fields
2026         customRule.zenPolicy = mZenModeHelper.getDefaultZenPolicy().overwrittenWith(policy);
2027         enabledAutoRules.put("customRule", customRule);
2028         mZenModeHelper.mConfig.automaticRules = enabledAutoRules;
2029 
2030         // set version to post-modes-API = 11
2031         ByteArrayOutputStream baos = writeXmlAndPurge(11);
2032         TypedXmlPullParser parser = Xml.newFastPullParser();
2033         parser.setInput(new BufferedInputStream(
2034                 new ByteArrayInputStream(baos.toByteArray())), null);
2035         parser.nextTag();
2036         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
2037 
2038         // basic check: global config maintained
2039         assertEquals(originalPolicy, mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT));
2040 
2041         // Find our automatic rules.
2042         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
2043         assertThat(rules).hasSize(1);
2044         assertThat(rules).containsKey("customRule");
2045         ZenRule rule = rules.get("customRule");
2046         assertThat(rule.zenPolicy).isEqualTo(customRule.zenPolicy);
2047     }
2048 
2049     @Test
2050     @EnableFlags(FLAG_MODES_API)
testReadXml_upgradeToModesApi_makesCustomPolicies()2051     public void testReadXml_upgradeToModesApi_makesCustomPolicies() throws Exception {
2052         // When reading in an XML file written from a pre-modes-API version, confirm that we create
2053         // a custom policy matching the global config for any automatic rule with no specified
2054         // policy.
2055         setupZenConfig();
2056         Policy originalPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT);
2057 
2058         ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
2059         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
2060         final ScheduleInfo weeknights = new ScheduleInfo();
2061         customRule.enabled = true;
2062         customRule.name = "Custom Rule";
2063         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2064         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
2065         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
2066         enabledAutoRule.put("customRule", customRule);  // no custom policy set
2067         mZenModeHelper.mConfig.automaticRules = enabledAutoRule;
2068 
2069         // set version to pre-modes-API = 10
2070         ByteArrayOutputStream baos = writeXmlAndPurge(10);
2071         TypedXmlPullParser parser = Xml.newFastPullParser();
2072         parser.setInput(new BufferedInputStream(
2073                 new ByteArrayInputStream(baos.toByteArray())), null);
2074         parser.nextTag();
2075         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
2076 
2077         // basic check: global config maintained
2078         assertEquals(originalPolicy, mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT));
2079 
2080         // Find our automatic rule and check that it has a policy set now
2081         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
2082         assertThat(rules).hasSize(1);
2083         assertThat(rules).containsKey("customRule");
2084         ZenRule rule = rules.get("customRule");
2085         assertThat(rule.zenPolicy).isNotNull();
2086 
2087         // Check policy values as set up in setupZenConfig() to confirm they match
2088         assertThat(rule.zenPolicy.getPriorityCategoryAlarms()).isEqualTo(STATE_DISALLOW);
2089         assertThat(rule.zenPolicy.getPriorityCategoryMedia()).isEqualTo(STATE_DISALLOW);
2090         assertThat(rule.zenPolicy.getPriorityCategorySystem()).isEqualTo(STATE_DISALLOW);
2091         assertThat(rule.zenPolicy.getPriorityCategoryReminders()).isEqualTo(STATE_ALLOW);
2092         assertThat(rule.zenPolicy.getPriorityCategoryCalls()).isEqualTo(STATE_ALLOW);
2093         assertThat(rule.zenPolicy.getPriorityCallSenders()).isEqualTo(PEOPLE_TYPE_STARRED);
2094         assertThat(rule.zenPolicy.getPriorityCategoryMessages()).isEqualTo(STATE_ALLOW);
2095         assertThat(rule.zenPolicy.getPriorityCategoryConversations()).isEqualTo(STATE_ALLOW);
2096         assertThat(rule.zenPolicy.getPriorityCategoryEvents()).isEqualTo(STATE_ALLOW);
2097         assertThat(rule.zenPolicy.getPriorityCategoryRepeatCallers()).isEqualTo(STATE_ALLOW);
2098         assertThat(rule.zenPolicy.getVisualEffectBadge()).isEqualTo(STATE_DISALLOW);
2099     }
2100 
2101     @Test
2102     @EnableFlags(FLAG_MODES_API)
testReadXml_upgradeToModesApi_fillsInCustomPolicies()2103     public void testReadXml_upgradeToModesApi_fillsInCustomPolicies() throws Exception {
2104         // When reading in an XML file written from a pre-modes-API version, confirm that for an
2105         // underspecified ZenPolicy, we fill in all of the gaps with things from the global config
2106         // in order to maintain consistency of behavior.
2107         setupZenConfig();
2108         Policy originalPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT);
2109 
2110         ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
2111         ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
2112         final ScheduleInfo weeknights = new ScheduleInfo();
2113         customRule.enabled = true;
2114         customRule.name = "Custom Rule";
2115         customRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2116         customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
2117         customRule.component = new ComponentName("android", "ScheduleConditionProvider");
2118         customRule.zenPolicy = new ZenPolicy.Builder()
2119                 .allowAlarms(true)
2120                 .allowMedia(true)
2121                 .allowRepeatCallers(false)
2122                 .build();
2123         enabledAutoRule.put("customRule", customRule);
2124         mZenModeHelper.mConfig.automaticRules = enabledAutoRule;
2125 
2126         // set version to pre-modes-API = 10
2127         ByteArrayOutputStream baos = writeXmlAndPurge(10);
2128         TypedXmlPullParser parser = Xml.newFastPullParser();
2129         parser.setInput(new BufferedInputStream(
2130                 new ByteArrayInputStream(baos.toByteArray())), null);
2131         parser.nextTag();
2132         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
2133 
2134         // basic check: global config maintained
2135         assertEquals(originalPolicy, mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT));
2136 
2137         // Find our automatic rule and check that it has a policy set now
2138         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
2139         assertThat(rules).hasSize(1);
2140         assertThat(rules).containsKey("customRule");
2141         ZenRule rule = rules.get("customRule");
2142         assertThat(rule.zenPolicy).isNotNull();
2143 
2144         // Check unset policy values match values in setupZenConfig().
2145         // Check that set policy values match the values set in the policy.
2146         assertThat(rule.zenPolicy.getPriorityCategoryAlarms()).isEqualTo(STATE_ALLOW);
2147         assertThat(rule.zenPolicy.getPriorityCategoryMedia()).isEqualTo(STATE_ALLOW);
2148         assertThat(rule.zenPolicy.getPriorityCategoryRepeatCallers()).isEqualTo(STATE_DISALLOW);
2149 
2150         // Check that the rest is filled in from the default
2151         assertThat(rule.zenPolicy.getPriorityCategorySystem()).isEqualTo(STATE_DISALLOW);
2152         assertThat(rule.zenPolicy.getPriorityCategoryReminders()).isEqualTo(STATE_ALLOW);
2153         assertThat(rule.zenPolicy.getPriorityCategoryCalls()).isEqualTo(STATE_ALLOW);
2154         assertThat(rule.zenPolicy.getPriorityCallSenders()).isEqualTo(PEOPLE_TYPE_STARRED);
2155         assertThat(rule.zenPolicy.getPriorityCategoryMessages()).isEqualTo(STATE_ALLOW);
2156         assertThat(rule.zenPolicy.getPriorityCategoryConversations()).isEqualTo(STATE_ALLOW);
2157         assertThat(rule.zenPolicy.getPriorityCategoryEvents()).isEqualTo(STATE_ALLOW);
2158         assertThat(rule.zenPolicy.getVisualEffectBadge()).isEqualTo(STATE_DISALLOW);
2159     }
2160 
2161     @Test
2162     @EnableFlags(FLAG_MODES_API)
testReadXml_upgradeToModesApi_existingDefaultRulesGetCustomPolicy()2163     public void testReadXml_upgradeToModesApi_existingDefaultRulesGetCustomPolicy()
2164             throws Exception {
2165         setupZenConfig();
2166 
2167         // Default rules, if they exist and have no policies, should get a snapshot of the global
2168         // policy, even if they are disabled upon upgrade.
2169         ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
2170         ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule();
2171         final ScheduleInfo defaultScheduleRuleInfo = new ScheduleInfo();
2172         defaultScheduleRule.enabled = false;
2173         defaultScheduleRule.name = "Default Schedule Rule";
2174         defaultScheduleRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2175         defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId(
2176                 defaultScheduleRuleInfo);
2177         defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
2178         automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
2179 
2180         ZenModeConfig.ZenRule defaultEventRule = new ZenModeConfig.ZenRule();
2181         final ScheduleInfo defaultEventRuleInfo = new ScheduleInfo();
2182         defaultEventRule.enabled = false;
2183         defaultEventRule.name = "Default Event Rule";
2184         defaultEventRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2185         defaultEventRule.conditionId = ZenModeConfig.toScheduleConditionId(
2186                 defaultEventRuleInfo);
2187         defaultEventRule.id = ZenModeConfig.EVENTS_OBSOLETE_RULE_ID;
2188         automaticRules.put(ZenModeConfig.EVENTS_OBSOLETE_RULE_ID, defaultEventRule);
2189 
2190         mZenModeHelper.mConfig.automaticRules = automaticRules;
2191 
2192         // set previous version
2193         ByteArrayOutputStream baos = writeXmlAndPurge(10);
2194         TypedXmlPullParser parser = Xml.newFastPullParser();
2195         parser.setInput(new BufferedInputStream(
2196                 new ByteArrayInputStream(baos.toByteArray())), null);
2197         parser.nextTag();
2198         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
2199 
2200         // check default rules
2201         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
2202         assertThat(rules.size()).isGreaterThan(0);
2203         for (String defaultId : ZenModeConfig.getDefaultRuleIds()) {
2204             assertThat(rules).containsKey(defaultId);
2205             ZenRule rule = rules.get(defaultId);
2206             assertThat(rule.zenPolicy).isNotNull();
2207 
2208             // Check policy values as set up in setupZenConfig() to confirm they match
2209             assertThat(rule.zenPolicy.getPriorityCategoryAlarms()).isEqualTo(STATE_DISALLOW);
2210             assertThat(rule.zenPolicy.getPriorityCategoryMedia()).isEqualTo(STATE_DISALLOW);
2211             assertThat(rule.zenPolicy.getPriorityCategorySystem()).isEqualTo(STATE_DISALLOW);
2212             assertThat(rule.zenPolicy.getPriorityCategoryReminders()).isEqualTo(STATE_ALLOW);
2213             assertThat(rule.zenPolicy.getPriorityCategoryCalls()).isEqualTo(STATE_ALLOW);
2214             assertThat(rule.zenPolicy.getPriorityCallSenders()).isEqualTo(PEOPLE_TYPE_STARRED);
2215             assertThat(rule.zenPolicy.getPriorityCategoryMessages()).isEqualTo(STATE_ALLOW);
2216             assertThat(rule.zenPolicy.getPriorityCategoryConversations()).isEqualTo(STATE_ALLOW);
2217             assertThat(rule.zenPolicy.getPriorityCategoryEvents()).isEqualTo(STATE_ALLOW);
2218             assertThat(rule.zenPolicy.getPriorityCategoryRepeatCallers()).isEqualTo(STATE_ALLOW);
2219             assertThat(rule.zenPolicy.getVisualEffectBadge()).isEqualTo(STATE_DISALLOW);
2220         }
2221     }
2222 
2223     @Test
2224     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
testReadXml_upgradeToModesUi_resetsImplicitRuleIcon()2225     public void testReadXml_upgradeToModesUi_resetsImplicitRuleIcon() throws Exception {
2226         setupZenConfig();
2227         mZenModeHelper.mConfig.automaticRules.clear();
2228 
2229         ZenRule implicitRuleWithModesUi = expectedImplicitRule("pkg",
2230                 ZEN_MODE_IMPORTANT_INTERRUPTIONS, POLICY, null);
2231 
2232         // Add one implicit rule in the pre-MODES_UI configuration.
2233         ZenRule implicitRuleBeforeModesUi = implicitRuleWithModesUi.copy();
2234         implicitRuleBeforeModesUi.iconResName = "pkg_icon";
2235         mZenModeHelper.mConfig.automaticRules.put(implicitRuleBeforeModesUi.id,
2236                 implicitRuleBeforeModesUi);
2237         // Plus one other normal rule.
2238         ZenRule anotherRule = newZenRule("other_pkg", Instant.now(), null);
2239         anotherRule.id = "other_rule";
2240         anotherRule.iconResName = "other_icon";
2241         anotherRule.type = TYPE_IMMERSIVE;
2242         mZenModeHelper.mConfig.automaticRules.put(anotherRule.id, anotherRule);
2243 
2244         // Write with pre-modes-ui = (modes_api) version, then re-read.
2245         ByteArrayOutputStream baos = writeXmlAndPurge(ZenModeConfig.XML_VERSION_MODES_API);
2246         TypedXmlPullParser parser = Xml.newFastPullParser();
2247         parser.setInput(new BufferedInputStream(
2248                 new ByteArrayInputStream(baos.toByteArray())), null);
2249         parser.nextTag();
2250         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
2251 
2252         // Implicit rule was updated.
2253         assertThat(mZenModeHelper.mConfig.automaticRules.get(implicitRuleBeforeModesUi.id))
2254                 .isEqualTo(implicitRuleWithModesUi);
2255 
2256         // The other rule was untouched.
2257         assertThat(mZenModeHelper.mConfig.automaticRules.get(anotherRule.id))
2258                 .isEqualTo(anotherRule);
2259     }
2260 
2261     @Test
2262     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
testReadXml_onModesUi_implicitRulesUntouched()2263     public void testReadXml_onModesUi_implicitRulesUntouched() throws Exception {
2264         setupZenConfig();
2265         mZenModeHelper.mConfig.automaticRules.clear();
2266 
2267         // Add one implicit rule already in its post-modes-UI configuration, also customized with
2268         // an icon;
2269         ZenRule implicitRuleWithModesUi = expectedImplicitRule("pkg",
2270                 ZEN_MODE_IMPORTANT_INTERRUPTIONS, POLICY, null);
2271         implicitRuleWithModesUi.iconResName = "icon_chosen_by_user";
2272         mZenModeHelper.mConfig.automaticRules.put(implicitRuleWithModesUi.id,
2273                 implicitRuleWithModesUi);
2274 
2275         // Plus one other normal rule.
2276         ZenRule anotherRule = newZenRule("other_pkg", Instant.now(), null);
2277         anotherRule.id = "other_rule";
2278         anotherRule.iconResName = "other_icon";
2279         anotherRule.type = TYPE_IMMERSIVE;
2280         mZenModeHelper.mConfig.automaticRules.put(anotherRule.id, anotherRule);
2281 
2282         // Write with modes_ui version, then re-read.
2283         ByteArrayOutputStream baos = writeXmlAndPurge(ZenModeConfig.XML_VERSION_MODES_UI);
2284         TypedXmlPullParser parser = Xml.newFastPullParser();
2285         parser.setInput(new BufferedInputStream(
2286                 new ByteArrayInputStream(baos.toByteArray())), null);
2287         parser.nextTag();
2288         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
2289 
2290         // Both rules were untouched
2291         assertThat(mZenModeHelper.mConfig.automaticRules.get(implicitRuleWithModesUi.id))
2292                 .isEqualTo(implicitRuleWithModesUi);
2293         assertThat(mZenModeHelper.mConfig.automaticRules.get(anotherRule.id))
2294                 .isEqualTo(anotherRule);
2295     }
2296 
2297     @Test
testCountdownConditionSubscription()2298     public void testCountdownConditionSubscription() throws Exception {
2299         ZenModeConfig config = new ZenModeConfig();
2300         mZenModeHelper.mConfig = config;
2301         mZenModeHelper.mConditions.evaluateConfig(mZenModeHelper.mConfig, null, true);
2302         assertEquals(0, mZenModeHelper.mConditions.mSubscriptions.size());
2303 
2304         mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
2305         Uri conditionId = ZenModeConfig.toCountdownConditionId(9000000, false);
2306         mZenModeHelper.mConfig.manualRule.conditionId = conditionId;
2307         mZenModeHelper.mConfig.manualRule.component = new ComponentName("android",
2308                 CountdownConditionProvider.class.getName());
2309         mZenModeHelper.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0,
2310                 STATE_TRUE, Condition.FLAG_RELEVANT_NOW);
2311         mZenModeHelper.mConfig.manualRule.enabled = true;
2312         ZenModeConfig originalConfig = mZenModeHelper.mConfig.copy();
2313 
2314         mZenModeHelper.mConditions.evaluateConfig(mZenModeHelper.mConfig, null, true);
2315 
2316         assertEquals(true, ZenModeConfig.isValidCountdownConditionId(conditionId));
2317         assertEquals(originalConfig, mZenModeHelper.mConfig);
2318         assertEquals(1, mZenModeHelper.mConditions.mSubscriptions.size());
2319     }
2320 
2321     @Test
testEmptyDefaultRulesMap()2322     public void testEmptyDefaultRulesMap() {
2323         List<StatsEvent> events = new LinkedList<>();
2324         ZenModeConfig config = new ZenModeConfig();
2325         config.automaticRules = new ArrayMap<>();
2326         mZenModeHelper.mConfig = config;
2327         mZenModeHelper.updateZenRulesOnLocaleChange(); // shouldn't throw null pointer
2328         mZenModeHelper.pullRules(events); // shouldn't throw null pointer
2329     }
2330 
2331     @Test
testDoNotUpdateModifiedDefaultAutoRule()2332     public void testDoNotUpdateModifiedDefaultAutoRule() {
2333         // mDefaultConfig is set to default config in setup by getDefaultConfigParser
2334         when(mContext.checkCallingPermission(anyString()))
2335                 .thenReturn(PERMISSION_GRANTED);
2336 
2337         // shouldn't update rule that's been modified
2338         ZenModeConfig.ZenRule updatedDefaultRule = new ZenModeConfig.ZenRule();
2339         updatedDefaultRule.modified = true;
2340         updatedDefaultRule.enabled = false;
2341         updatedDefaultRule.creationTime = 0;
2342         updatedDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID;
2343         updatedDefaultRule.name = "Schedule Default Rule";
2344         updatedDefaultRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2345         updatedDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo());
2346         updatedDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider");
2347 
2348         ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
2349         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
2350         mZenModeHelper.mConfig.automaticRules = autoRules;
2351 
2352         mZenModeHelper.updateZenRulesOnLocaleChange();
2353         assertEquals(updatedDefaultRule,
2354                 mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
2355     }
2356 
2357     @Test
testUpdateDefaultAutoRule()2358     public void testUpdateDefaultAutoRule() {
2359         // mDefaultConfig is set to default config in setup by getDefaultConfigParser
2360         final String defaultRuleName = "rule name test";
2361         when(mContext.checkCallingPermission(anyString()))
2362                 .thenReturn(PERMISSION_GRANTED);
2363 
2364         // will update rule that is not enabled and modified
2365         ZenModeConfig.ZenRule customDefaultRule = new ZenModeConfig.ZenRule();
2366         customDefaultRule.pkg = SystemZenRules.PACKAGE_ANDROID;
2367         customDefaultRule.enabled = false;
2368         customDefaultRule.modified = false;
2369         customDefaultRule.creationTime = 0;
2370         customDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID;
2371         customDefaultRule.name = "Schedule Default Rule";
2372         customDefaultRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2373         ScheduleInfo scheduleInfo = new ScheduleInfo();
2374         scheduleInfo.days = new int[]{Calendar.SUNDAY};
2375         scheduleInfo.startHour = 18;
2376         scheduleInfo.endHour = 19;
2377         customDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(scheduleInfo);
2378         customDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider");
2379 
2380         ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
2381         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, customDefaultRule);
2382         mZenModeHelper.mConfig.automaticRules = autoRules;
2383 
2384         mZenModeHelper.updateZenRulesOnLocaleChange();
2385         ZenModeConfig.ZenRule ruleAfterUpdating =
2386                 mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID);
2387         assertEquals(customDefaultRule.enabled, ruleAfterUpdating.enabled);
2388         assertEquals(customDefaultRule.modified, ruleAfterUpdating.modified);
2389         assertEquals(customDefaultRule.id, ruleAfterUpdating.id);
2390         assertEquals(customDefaultRule.conditionId, ruleAfterUpdating.conditionId);
2391         assertNotEquals(defaultRuleName, ruleAfterUpdating.name); // update name
2392         if (Flags.modesUi()) {
2393             assertThat(ruleAfterUpdating.triggerDescription).isNotEmpty(); // update trigger desc
2394         }
2395     }
2396 
2397     @Test
2398     @EnableFlags(FLAG_MODES_API)
testDefaultRulesFromConfig_modesApi_getPolicies()2399     public void testDefaultRulesFromConfig_modesApi_getPolicies() {
2400         // After mZenModeHelper was created, set some things in the policy so it's changed from
2401         // default.
2402         setupZenConfig();
2403 
2404         // Find default rules; check they have non-null policies; check that they match the default
2405         // and not whatever has been set up in setupZenConfig.
2406         ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
2407         for (String defaultId : ZenModeConfig.getDefaultRuleIds()) {
2408             assertThat(rules).containsKey(defaultId);
2409             ZenRule rule = rules.get(defaultId);
2410             assertThat(rule.zenPolicy).isNotNull();
2411 
2412             assertThat(rule.zenPolicy).isEqualTo(mZenModeHelper.getDefaultZenPolicy());
2413         }
2414     }
2415 
2416     @Test
testAddAutomaticZenRule_beyondSystemLimit()2417     public void testAddAutomaticZenRule_beyondSystemLimit() {
2418         for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
2419             ScheduleInfo si = new ScheduleInfo();
2420             si.startHour = i;
2421             AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
2422                     null,
2423                     new ComponentName("android", "ScheduleConditionProvider"),
2424                     ZenModeConfig.toScheduleConditionId(si),
2425                     new ZenPolicy.Builder().build(),
2426                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2427             // We need the package name to be something that's not "android" so there aren't any
2428             // existing rules under that package.
2429             String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkgname", zenRule,
2430                     ORIGIN_APP, "test", CUSTOM_PKG_UID);
2431             assertNotNull(id);
2432         }
2433         try {
2434             AutomaticZenRule zenRule = new AutomaticZenRule("name",
2435                     null,
2436                     new ComponentName("android", "ScheduleConditionProvider"),
2437                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2438                     new ZenPolicy.Builder().build(),
2439                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2440             String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkgname", zenRule,
2441                     ORIGIN_APP, "test", CUSTOM_PKG_UID);
2442             fail("allowed too many rules to be created");
2443         } catch (IllegalArgumentException e) {
2444             // yay
2445         }
2446     }
2447 
2448     @Test
testAddAutomaticZenRule_beyondSystemLimit_differentComponents()2449     public void testAddAutomaticZenRule_beyondSystemLimit_differentComponents() {
2450         // Make sure the system limit is enforced per-package even with different component provider
2451         // names.
2452         for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
2453             ScheduleInfo si = new ScheduleInfo();
2454             si.startHour = i;
2455             AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
2456                     null,
2457                     new ComponentName("android", "ScheduleConditionProvider" + i),
2458                     ZenModeConfig.toScheduleConditionId(si),
2459                     new ZenPolicy.Builder().build(),
2460                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2461             String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkgname", zenRule,
2462                     ORIGIN_APP, "test", CUSTOM_PKG_UID);
2463             assertNotNull(id);
2464         }
2465         try {
2466             AutomaticZenRule zenRule = new AutomaticZenRule("name",
2467                     null,
2468                     new ComponentName("android", "ScheduleConditionProviderFinal"),
2469                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2470                     new ZenPolicy.Builder().build(),
2471                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2472             String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkgname", zenRule,
2473                     ORIGIN_APP, "test", CUSTOM_PKG_UID);
2474             fail("allowed too many rules to be created");
2475         } catch (IllegalArgumentException e) {
2476             // yay
2477         }
2478     }
2479 
2480     @Test
testAddAutomaticZenRule_claimedSystemOwner()2481     public void testAddAutomaticZenRule_claimedSystemOwner() {
2482         // Make sure anything that claims to have a "system" owner but not actually part of the
2483         // system package still gets limited on number of rules
2484         for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
2485             ScheduleInfo si = new ScheduleInfo();
2486             si.startHour = i;
2487             AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
2488                     new ComponentName("android", "ScheduleConditionProvider" + i),
2489                     null, // configuration activity
2490                     ZenModeConfig.toScheduleConditionId(si),
2491                     new ZenPolicy.Builder().build(),
2492                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2493             String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkgname", zenRule,
2494                     ORIGIN_APP, "test", CUSTOM_PKG_UID);
2495             assertNotNull(id);
2496         }
2497         try {
2498             AutomaticZenRule zenRule = new AutomaticZenRule("name",
2499                     new ComponentName("android", "ScheduleConditionProviderFinal"),
2500                     null, // configuration activity
2501                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2502                     new ZenPolicy.Builder().build(),
2503                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2504             String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkgname", zenRule,
2505                     ORIGIN_APP, "test", CUSTOM_PKG_UID);
2506             fail("allowed too many rules to be created");
2507         } catch (IllegalArgumentException e) {
2508             // yay
2509         }
2510     }
2511 
2512     @Test
testAddAutomaticZenRule_CA()2513     public void testAddAutomaticZenRule_CA() {
2514         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2515                 null,
2516                 new ComponentName("android", "ScheduleConditionProvider"),
2517                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2518                 new ZenPolicy.Builder().build(),
2519                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2520         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "android", zenRule,
2521                 ORIGIN_SYSTEM, "test", SYSTEM_UID);
2522 
2523         assertTrue(id != null);
2524         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
2525         assertTrue(ruleInConfig != null);
2526         assertEquals(zenRule.isEnabled(), ruleInConfig.enabled);
2527         assertEquals(zenRule.isModified(), ruleInConfig.modified);
2528         assertEquals(zenRule.getConditionId(), ruleInConfig.conditionId);
2529         assertEquals(NotificationManager.zenModeFromInterruptionFilter(
2530                 zenRule.getInterruptionFilter(), -1), ruleInConfig.zenMode);
2531         assertEquals(zenRule.getName(), ruleInConfig.name);
2532         assertEquals("android", ruleInConfig.pkg);
2533     }
2534 
2535     @Test
testAddAutomaticZenRule_CPS()2536     public void testAddAutomaticZenRule_CPS() {
2537         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2538                 new ComponentName("android", "ScheduleConditionProvider"),
2539                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2540                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2541         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "android", zenRule,
2542                 ORIGIN_SYSTEM, "test", SYSTEM_UID);
2543 
2544         assertTrue(id != null);
2545         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
2546         assertTrue(ruleInConfig != null);
2547         assertEquals(zenRule.isEnabled(), ruleInConfig.enabled);
2548         assertEquals(zenRule.isModified(), ruleInConfig.modified);
2549         assertEquals(zenRule.getConditionId(), ruleInConfig.conditionId);
2550         assertEquals(NotificationManager.zenModeFromInterruptionFilter(
2551                 zenRule.getInterruptionFilter(), -1), ruleInConfig.zenMode);
2552         assertEquals(zenRule.getName(), ruleInConfig.name);
2553         assertEquals("android", ruleInConfig.pkg);
2554     }
2555 
2556     @Test
2557     @EnableFlags(FLAG_MODES_API)
testAddAutomaticZenRule_modesApi_fillsInDefaultValues()2558     public void testAddAutomaticZenRule_modesApi_fillsInDefaultValues() {
2559         // When a new automatic zen rule is added with only some fields filled in, ensure that
2560         // all unset fields are filled in with device defaults.
2561 
2562         // Zen rule with null policy: should get entirely the default state
2563         AutomaticZenRule zenRule1 = new AutomaticZenRule("name",
2564                 new ComponentName("android", "ScheduleConditionProvider"),
2565                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2566                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2567         String id1 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "android", zenRule1,
2568                 ORIGIN_SYSTEM, "test", SYSTEM_UID);
2569 
2570         // Zen rule with partially-filled policy: should get all of the filled fields set, and the
2571         // rest filled with default state
2572         AutomaticZenRule zenRule2 = new AutomaticZenRule("name",
2573                 null,
2574                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
2575                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2576                 new ZenPolicy.Builder()
2577                         .allowCalls(PEOPLE_TYPE_NONE)
2578                         .allowMessages(PEOPLE_TYPE_CONTACTS)
2579                         .showFullScreenIntent(true)
2580                         .build(),
2581                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2582         String id2 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "android", zenRule2,
2583                 ORIGIN_SYSTEM, "test", SYSTEM_UID);
2584 
2585         // rule 1 should exist
2586         assertThat(id1).isNotNull();
2587         ZenModeConfig.ZenRule rule1InConfig = mZenModeHelper.mConfig.automaticRules.get(id1);
2588         assertThat(rule1InConfig).isNotNull();
2589         assertThat(rule1InConfig.zenPolicy).isNotNull();  // we passed in null; it should now not be
2590 
2591         // all of rule 1 should be the device default's policy
2592         assertThat(rule1InConfig.zenPolicy).isEqualTo(mZenModeHelper.getDefaultZenPolicy());
2593 
2594         // rule 2 should exist
2595         assertThat(id2).isNotNull();
2596         ZenModeConfig.ZenRule rule2InConfig = mZenModeHelper.mConfig.automaticRules.get(id2);
2597         assertThat(rule2InConfig).isNotNull();
2598 
2599         // rule 2: values set from the policy itself
2600         assertThat(rule2InConfig.zenPolicy.getPriorityCallSenders()).isEqualTo(PEOPLE_TYPE_NONE);
2601         assertThat(rule2InConfig.zenPolicy.getPriorityMessageSenders())
2602                 .isEqualTo(PEOPLE_TYPE_CONTACTS);
2603         assertThat(rule2InConfig.zenPolicy.getVisualEffectFullScreenIntent())
2604                 .isEqualTo(STATE_ALLOW);
2605 
2606         // the rest of rule 2's settings should be the device defaults
2607         assertThat(rule2InConfig.zenPolicy.getPriorityConversationSenders())
2608                 .isEqualTo(CONVERSATION_SENDERS_IMPORTANT);
2609         assertThat(rule2InConfig.zenPolicy.getPriorityCategorySystem())
2610                 .isEqualTo(STATE_DISALLOW);
2611         assertThat(rule2InConfig.zenPolicy.getPriorityCategoryAlarms())
2612                 .isEqualTo(STATE_ALLOW);
2613         assertThat(rule2InConfig.zenPolicy.getVisualEffectPeek())
2614                 .isEqualTo(STATE_DISALLOW);
2615         assertThat(rule2InConfig.zenPolicy.getVisualEffectNotificationList())
2616                 .isEqualTo(STATE_ALLOW);
2617     }
2618 
2619     @Test
testSetAutomaticZenRuleState_nullPkg()2620     public void testSetAutomaticZenRuleState_nullPkg() {
2621         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2622                 null,
2623                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
2624                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2625                 new ZenPolicy.Builder().build(),
2626                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2627 
2628         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, null, zenRule,
2629                 ORIGIN_APP, "test", CUSTOM_PKG_UID);
2630         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, zenRule.getConditionId(),
2631                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
2632                 ORIGIN_APP,
2633                 CUSTOM_PKG_UID);
2634 
2635         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
2636         assertEquals(STATE_TRUE, ruleInConfig.condition.state);
2637     }
2638 
2639     @Test
testUpdateAutomaticZenRule_nullPkg()2640     public void testUpdateAutomaticZenRule_nullPkg() {
2641         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2642                 null,
2643                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
2644                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2645                 new ZenPolicy.Builder().build(),
2646                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2647 
2648         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, null, zenRule,
2649                 ORIGIN_APP, "test", CUSTOM_PKG_UID);
2650 
2651         AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW",
2652                 null,
2653                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
2654                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2655                 new ZenPolicy.Builder().build(),
2656                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2657 
2658         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, id, zenRule2, ORIGIN_APP, "",
2659                 CUSTOM_PKG_UID);
2660 
2661         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
2662         assertEquals("NEW", ruleInConfig.name);
2663     }
2664 
2665     @Test
testRemoveAutomaticZenRule_nullPkg()2666     public void testRemoveAutomaticZenRule_nullPkg() {
2667         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2668                 null,
2669                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
2670                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2671                 new ZenPolicy.Builder().build(),
2672                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2673 
2674         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, null, zenRule,
2675                 ORIGIN_APP, "test", CUSTOM_PKG_UID);
2676 
2677         assertTrue(id != null);
2678         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
2679         assertTrue(ruleInConfig != null);
2680         assertEquals(zenRule.getName(), ruleInConfig.name);
2681 
2682         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, id, ORIGIN_APP, "test",
2683                 CUSTOM_PKG_UID);
2684         assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
2685     }
2686 
2687     @Test
testRemoveAutomaticZenRules_nullPkg()2688     public void testRemoveAutomaticZenRules_nullPkg() {
2689         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2690                 null,
2691                 new ComponentName(mContext.getPackageName(), "ScheduleConditionProvider"),
2692                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
2693                 new ZenPolicy.Builder().build(),
2694                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2695         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, null, zenRule,
2696                 ORIGIN_APP, "test", CUSTOM_PKG_UID);
2697 
2698         assertTrue(id != null);
2699         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
2700         assertTrue(ruleInConfig != null);
2701         assertEquals(zenRule.getName(), ruleInConfig.name);
2702 
2703         mZenModeHelper.removeAutomaticZenRules(UserHandle.CURRENT, mContext.getPackageName(),
2704                 ORIGIN_APP, "test", CUSTOM_PKG_UID);
2705         assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
2706     }
2707 
2708     @Test
testRulesWithSameUri()2709     public void testRulesWithSameUri() {
2710         // needs to be a valid schedule info object for the subscription to happen properly
2711         ScheduleInfo scheduleInfo = new ScheduleInfo();
2712         scheduleInfo.days = new int[]{1, 2};
2713         scheduleInfo.endHour = 1;
2714         Uri sharedUri = ZenModeConfig.toScheduleConditionId(scheduleInfo);
2715         AutomaticZenRule zenRule = new AutomaticZenRule("name",
2716                 new ComponentName(mPkg, "ScheduleConditionProvider"),
2717                 sharedUri,
2718                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2719         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, zenRule,
2720                 ORIGIN_SYSTEM, "test", SYSTEM_UID);
2721         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
2722                 new ComponentName(mPkg, "ScheduleConditionProvider"),
2723                 sharedUri,
2724                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
2725         String id2 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, zenRule2,
2726                 ORIGIN_SYSTEM, "test", SYSTEM_UID);
2727 
2728         Condition condition = new Condition(sharedUri, "", STATE_TRUE);
2729         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, sharedUri, condition,
2730                 ORIGIN_SYSTEM, SYSTEM_UID);
2731 
2732         for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
2733             if (rule.id.equals(id)) {
2734                 assertNotNull(rule.condition);
2735                 assertEquals(STATE_TRUE, rule.condition.state);
2736             }
2737             if (rule.id.equals(id2)) {
2738                 assertNotNull(rule.condition);
2739                 assertEquals(STATE_TRUE, rule.condition.state);
2740             }
2741         }
2742 
2743         condition = new Condition(sharedUri, "", STATE_FALSE);
2744         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, sharedUri, condition,
2745                 ORIGIN_SYSTEM, SYSTEM_UID);
2746 
2747         for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
2748             if (rule.id.equals(id)) {
2749                 assertNotNull(rule.condition);
2750                 assertEquals(STATE_FALSE, rule.condition.state);
2751             }
2752             if (rule.id.equals(id2)) {
2753                 assertNotNull(rule.condition);
2754                 assertEquals(STATE_FALSE, rule.condition.state);
2755             }
2756         }
2757     }
2758 
2759     @Test
2760     @EnableFlags(FLAG_MODES_API)
addAutomaticZenRule_fromApp_ignoresHiddenEffects()2761     public void addAutomaticZenRule_fromApp_ignoresHiddenEffects() {
2762         ZenDeviceEffects zde = new ZenDeviceEffects.Builder()
2763                 .setShouldDisplayGrayscale(true)
2764                 .setShouldSuppressAmbientDisplay(true)
2765                 .setShouldDimWallpaper(true)
2766                 .setShouldUseNightMode(true)
2767                 .setShouldDisableAutoBrightness(true)
2768                 .setShouldDisableTapToWake(true)
2769                 .setShouldDisableTiltToWake(true)
2770                 .setShouldDisableTouch(true)
2771                 .setShouldMinimizeRadioUsage(true)
2772                 .setShouldMaximizeDoze(true)
2773                 .build();
2774 
2775         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
2776                 mContext.getPackageName(),
2777                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2778                         .setOwner(OWNER)
2779                         .setDeviceEffects(zde)
2780                         .build(),
2781                 ORIGIN_APP, "reasons", 0);
2782 
2783         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
2784         assertThat(savedRule.getDeviceEffects()).isEqualTo(
2785                 new ZenDeviceEffects.Builder()
2786                         .setShouldDisplayGrayscale(true)
2787                         .setShouldSuppressAmbientDisplay(true)
2788                         .setShouldDimWallpaper(true)
2789                         .setShouldUseNightMode(true)
2790                         .build());
2791     }
2792 
2793     @Test
2794     @EnableFlags(FLAG_MODES_API)
addAutomaticZenRule_fromSystem_respectsHiddenEffects()2795     public void addAutomaticZenRule_fromSystem_respectsHiddenEffects() {
2796         ZenDeviceEffects zde = new ZenDeviceEffects.Builder()
2797                 .setShouldDisplayGrayscale(true)
2798                 .setShouldSuppressAmbientDisplay(true)
2799                 .setShouldDimWallpaper(true)
2800                 .setShouldUseNightMode(true)
2801                 .setShouldDisableAutoBrightness(true)
2802                 .setShouldDisableTapToWake(true)
2803                 .setShouldDisableTiltToWake(true)
2804                 .setShouldDisableTouch(true)
2805                 .setShouldMinimizeRadioUsage(true)
2806                 .setShouldMaximizeDoze(true)
2807                 .build();
2808 
2809         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
2810                 mContext.getPackageName(),
2811                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2812                         .setOwner(OWNER)
2813                         .setDeviceEffects(zde)
2814                         .build(),
2815                 ORIGIN_SYSTEM, "reasons", 0);
2816 
2817         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
2818         assertThat(savedRule.getDeviceEffects()).isEqualTo(zde);
2819     }
2820 
2821     @Test
2822     @EnableFlags(FLAG_MODES_API)
addAutomaticZenRule_fromUser_respectsHiddenEffects()2823     public void addAutomaticZenRule_fromUser_respectsHiddenEffects() throws Exception {
2824         ZenDeviceEffects zde = new ZenDeviceEffects.Builder()
2825                 .setShouldDisplayGrayscale(true)
2826                 .setShouldSuppressAmbientDisplay(true)
2827                 .setShouldDimWallpaper(true)
2828                 .setShouldUseNightMode(true)
2829                 .setShouldDisableAutoBrightness(true)
2830                 .setShouldDisableTapToWake(true)
2831                 .setShouldDisableTiltToWake(true)
2832                 .setShouldDisableTouch(true)
2833                 .setShouldMinimizeRadioUsage(true)
2834                 .setShouldMaximizeDoze(true)
2835                 .build();
2836 
2837         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
2838                 mContext.getPackageName(),
2839                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2840                         .setOwner(OWNER)
2841                         .setDeviceEffects(zde)
2842                         .build(),
2843                 ORIGIN_USER_IN_SYSTEMUI,
2844                 "reasons", 0);
2845 
2846         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
2847 
2848         assertThat(savedRule.getDeviceEffects()).isEqualTo(zde);
2849     }
2850 
2851     @Test
2852     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_fromApp_preservesPreviousHiddenEffects()2853     public void updateAutomaticZenRule_fromApp_preservesPreviousHiddenEffects() {
2854         ZenDeviceEffects original = new ZenDeviceEffects.Builder()
2855                 .setShouldDisableTapToWake(true)
2856                 .addExtraEffect("extra")
2857                 .build();
2858         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
2859                 mContext.getPackageName(),
2860                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2861                         .setOwner(OWNER)
2862                         .setDeviceEffects(original)
2863                         .build(),
2864                 ORIGIN_SYSTEM, "reasons", 0);
2865 
2866         ZenDeviceEffects updateFromApp = new ZenDeviceEffects.Builder()
2867                 .setShouldUseNightMode(true) // Good
2868                 .setShouldMaximizeDoze(true) // Bad
2869                 .addExtraEffect("should be rejected") // Bad
2870                 .build();
2871         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
2872                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2873                         .setOwner(OWNER)
2874                         .setDeviceEffects(updateFromApp)
2875                         .build(),
2876                 ORIGIN_APP, "reasons", 0);
2877 
2878         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
2879         assertThat(savedRule.getDeviceEffects()).isEqualTo(
2880                 new ZenDeviceEffects.Builder()
2881                         .setShouldUseNightMode(true) // From update.
2882                         .setShouldDisableTapToWake(true) // From original.
2883                         .addExtraEffect("extra")
2884                         .build());
2885     }
2886 
2887     @Test
2888     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_fromSystem_updatesHiddenEffects()2889     public void updateAutomaticZenRule_fromSystem_updatesHiddenEffects() {
2890         ZenDeviceEffects original = new ZenDeviceEffects.Builder()
2891                 .setShouldDisableTapToWake(true)
2892                 .build();
2893         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
2894                 mContext.getPackageName(),
2895                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2896                         .setOwner(OWNER)
2897                         .setDeviceEffects(original)
2898                         .build(),
2899                 ORIGIN_SYSTEM, "reasons", 0);
2900 
2901         ZenDeviceEffects updateFromSystem = new ZenDeviceEffects.Builder()
2902                 .setShouldUseNightMode(true) // Good
2903                 .setShouldMaximizeDoze(true) // Also good
2904                 .build();
2905         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
2906                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2907                         .setDeviceEffects(updateFromSystem)
2908                         .build(),
2909                 ORIGIN_SYSTEM, "reasons", 0);
2910 
2911         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
2912         assertThat(savedRule.getDeviceEffects()).isEqualTo(updateFromSystem);
2913     }
2914 
2915     @Test
2916     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_fromUser_updatesHiddenEffects()2917     public void updateAutomaticZenRule_fromUser_updatesHiddenEffects() {
2918         ZenDeviceEffects original = new ZenDeviceEffects.Builder()
2919                 .setShouldDisableTapToWake(true)
2920                 .build();
2921         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
2922                 mContext.getPackageName(),
2923                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2924                         .setOwner(OWNER)
2925                         .setDeviceEffects(original)
2926                         .build(),
2927                 ORIGIN_SYSTEM, "reasons", 0);
2928 
2929         ZenDeviceEffects updateFromUser = new ZenDeviceEffects.Builder()
2930                 .setShouldUseNightMode(true)
2931                 .setShouldMaximizeDoze(true)
2932                 // Just to emphasize that unset values default to false;
2933                 // even with this line removed, tap to wake would be set to false.
2934                 .setShouldDisableTapToWake(false)
2935                 .build();
2936         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
2937                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2938                         .setDeviceEffects(updateFromUser)
2939                         .build(),
2940                 ORIGIN_USER_IN_SYSTEMUI, "reasons", 0);
2941 
2942         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
2943 
2944         assertThat(savedRule.getDeviceEffects()).isEqualTo(updateFromUser);
2945     }
2946 
2947     @Test
2948     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_nullPolicy_doesNothing()2949     public void updateAutomaticZenRule_nullPolicy_doesNothing() {
2950         // Test that when updateAutomaticZenRule is called with a null policy, nothing changes
2951         // about the existing policy.
2952         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
2953                 mContext.getPackageName(),
2954                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2955                         .setOwner(OWNER)
2956                         .setZenPolicy(new ZenPolicy.Builder()
2957                                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE) // default is stars
2958                                 .build())
2959                         .build(),
2960                 ORIGIN_APP, "reasons", 0);
2961 
2962         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
2963                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2964                         // no zen policy
2965                         .build(),
2966                 ORIGIN_APP, "reasons", 0);
2967 
2968         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
2969         assertThat(savedRule.getZenPolicy().getPriorityCategoryCalls())
2970                 .isEqualTo(STATE_DISALLOW);
2971     }
2972 
2973     @Test
2974     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_overwritesExistingPolicy()2975     public void updateAutomaticZenRule_overwritesExistingPolicy() {
2976         // Test that when updating an automatic zen rule with an existing policy, the newly set
2977         // fields overwrite those from the previous policy, but unset fields in the new policy
2978         // keep values from the previous one.
2979         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
2980                 mContext.getPackageName(),
2981                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2982                         .setOwner(OWNER)
2983                         .setZenPolicy(new ZenPolicy.Builder()
2984                                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE) // default is stars
2985                                 .allowAlarms(false)
2986                                 .allowReminders(true)
2987                                 .build())
2988                         .build(),
2989                 ORIGIN_SYSTEM, "reasons", 0);
2990 
2991         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
2992                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
2993                         .setZenPolicy(new ZenPolicy.Builder()
2994                                 .allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
2995                                 .build())
2996                         .build(),
2997                 ORIGIN_APP, "reasons", 0);
2998 
2999         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
3000         assertThat(savedRule.getZenPolicy().getPriorityCategoryCalls())
3001                 .isEqualTo(STATE_ALLOW);  // from update
3002         assertThat(savedRule.getZenPolicy().getPriorityCallSenders())
3003                 .isEqualTo(ZenPolicy.PEOPLE_TYPE_CONTACTS);  // from update
3004         assertThat(savedRule.getZenPolicy().getPriorityCategoryAlarms())
3005                 .isEqualTo(STATE_DISALLOW);  // from original
3006         assertThat(savedRule.getZenPolicy().getPriorityCategoryReminders())
3007                 .isEqualTo(STATE_ALLOW);  // from original
3008     }
3009 
3010 
3011     @Test
3012     @EnableFlags(FLAG_MODES_API)
addAutomaticZenRule_withTypeBedtime_replacesDisabledSleeping()3013     public void addAutomaticZenRule_withTypeBedtime_replacesDisabledSleeping() {
3014         ZenRule sleepingRule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS,
3015                 ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID);
3016         sleepingRule.enabled = false;
3017         sleepingRule.userModifiedFields = 0;
3018         sleepingRule.name = "ZZZZZZZ...";
3019         mZenModeHelper.mConfig.automaticRules.clear();
3020         mZenModeHelper.mConfig.automaticRules.put(sleepingRule.id, sleepingRule);
3021 
3022         AutomaticZenRule bedtime = new AutomaticZenRule.Builder("Bedtime Mode (TM)", CONDITION_ID)
3023                 .setType(TYPE_BEDTIME)
3024                 .build();
3025         String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkg",
3026                 bedtime, ORIGIN_APP, "reason", CUSTOM_PKG_UID);
3027 
3028         assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly(bedtimeRuleId);
3029     }
3030 
3031     @Test
3032     @EnableFlags(FLAG_MODES_API)
addAutomaticZenRule_withTypeBedtime_keepsEnabledSleeping()3033     public void addAutomaticZenRule_withTypeBedtime_keepsEnabledSleeping() {
3034         ZenRule sleepingRule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS,
3035                 ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID);
3036         sleepingRule.enabled = true;
3037         sleepingRule.userModifiedFields = 0;
3038         sleepingRule.name = "ZZZZZZZ...";
3039         mZenModeHelper.mConfig.automaticRules.clear();
3040         mZenModeHelper.mConfig.automaticRules.put(sleepingRule.id, sleepingRule);
3041 
3042         AutomaticZenRule bedtime = new AutomaticZenRule.Builder("Bedtime Mode (TM)", CONDITION_ID)
3043                 .setType(TYPE_BEDTIME)
3044                 .build();
3045         String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkg",
3046                 bedtime, ORIGIN_APP, "reason", CUSTOM_PKG_UID);
3047 
3048         assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly(
3049                 ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, bedtimeRuleId);
3050     }
3051 
3052     @Test
3053     @EnableFlags(FLAG_MODES_API)
addAutomaticZenRule_withTypeBedtime_keepsCustomizedSleeping()3054     public void addAutomaticZenRule_withTypeBedtime_keepsCustomizedSleeping() {
3055         ZenRule sleepingRule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS,
3056                 ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID);
3057         sleepingRule.enabled = false;
3058         sleepingRule.userModifiedFields = AutomaticZenRule.FIELD_INTERRUPTION_FILTER;
3059         sleepingRule.name = "ZZZZZZZ...";
3060         mZenModeHelper.mConfig.automaticRules.clear();
3061         mZenModeHelper.mConfig.automaticRules.put(sleepingRule.id, sleepingRule);
3062 
3063         AutomaticZenRule bedtime = new AutomaticZenRule.Builder("Bedtime Mode (TM)", CONDITION_ID)
3064                 .setType(TYPE_BEDTIME)
3065                 .build();
3066         String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkg",
3067                 bedtime, ORIGIN_APP, "reason", CUSTOM_PKG_UID);
3068 
3069         assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly(
3070                 ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, bedtimeRuleId);
3071     }
3072 
3073     @Test
3074     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
updateAutomaticZenRule_withTypeBedtime_replacesDisabledSleeping()3075     public void updateAutomaticZenRule_withTypeBedtime_replacesDisabledSleeping() {
3076         ZenRule sleepingRule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS,
3077                 ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID);
3078         sleepingRule.enabled = false;
3079         sleepingRule.userModifiedFields = 0;
3080         sleepingRule.name = "ZZZZZZZ...";
3081         mZenModeHelper.mConfig.automaticRules.clear();
3082         mZenModeHelper.mConfig.automaticRules.put(sleepingRule.id, sleepingRule);
3083 
3084         AutomaticZenRule futureBedtime = new AutomaticZenRule.Builder("Bedtime (?)", CONDITION_ID)
3085                 .build();
3086         String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg,
3087                 futureBedtime, ORIGIN_APP, "reason", CUSTOM_PKG_UID);
3088         assertThat(mZenModeHelper.mConfig.automaticRules.keySet())
3089                 .containsExactly(sleepingRule.id, bedtimeRuleId);
3090 
3091         AutomaticZenRule bedtime = new AutomaticZenRule.Builder("Bedtime (!)", CONDITION_ID)
3092                 .setType(TYPE_BEDTIME)
3093                 .build();
3094         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, bedtimeRuleId, bedtime,
3095                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
3096 
3097         assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly(bedtimeRuleId);
3098     }
3099 
3100     @Test
3101     @EnableFlags(FLAG_MODES_API)
testSetManualZenMode()3102     public void testSetManualZenMode() {
3103         setupZenConfig();
3104 
3105         // note that caller=null because that's how it comes in from NMS.setZenMode
3106         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
3107                 ORIGIN_SYSTEM, "", null, SYSTEM_UID);
3108 
3109         // confirm that setting zen mode via setManualZenMode changed the zen mode correctly
3110         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode);
3111         assertEquals(true, mZenModeHelper.mConfig.manualRule.allowManualInvocation);
3112 
3113         // and also that it works to turn it back off again
3114         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, Global.ZEN_MODE_OFF, null,
3115                 ORIGIN_SYSTEM, "", null, SYSTEM_UID);
3116 
3117         assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
3118     }
3119 
3120     @Test
3121     @EnableFlags(FLAG_MODES_API)
3122     @DisableFlags(FLAG_MODES_UI)
setManualZenMode_off_snoozesActiveRules()3123     public void setManualZenMode_off_snoozesActiveRules() {
3124         for (ZenChangeOrigin origin : ZenChangeOrigin.values()) {
3125             // Start with an active rule and an inactive rule.
3126             mZenModeHelper.mConfig.automaticRules.clear();
3127             AutomaticZenRule activeRule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
3128                     .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
3129                     .build();
3130             String activeRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3131                     mContext.getPackageName(), activeRule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
3132             mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, activeRuleId,
3133                     CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID);
3134             AutomaticZenRule inactiveRule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
3135                     .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
3136                     .build();
3137             String inactiveRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3138                     mContext.getPackageName(), inactiveRule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
3139 
3140             assertWithMessage("Failure for origin " + origin.name())
3141                     .that(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
3142 
3143             // User turns DND off.
3144             mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, null, origin.value(),
3145                     "snoozing", "systemui", SYSTEM_UID);
3146             assertWithMessage("Failure for origin " + origin.name())
3147                     .that(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
3148             assertWithMessage("Failure for origin " + origin.name())
3149                     .that(mZenModeHelper.mConfig.automaticRules
3150                             .get(activeRuleId).getConditionOverride())
3151                     .isEqualTo(OVERRIDE_DEACTIVATE);
3152             assertWithMessage("Failure for origin " + origin.name())
3153                     .that(mZenModeHelper.mConfig.automaticRules
3154                             .get(inactiveRuleId).getConditionOverride())
3155                     .isEqualTo(OVERRIDE_NONE);
3156         }
3157     }
3158 
3159     @Test
3160     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setManualZenMode_off_doesNotSnoozeRulesIfFromUserInSystemUi()3161     public void setManualZenMode_off_doesNotSnoozeRulesIfFromUserInSystemUi() {
3162         for (ZenChangeOrigin origin : ZenChangeOrigin.values()) {
3163             // Start with an active rule and an inactive rule
3164             mZenModeHelper.mConfig.automaticRules.clear();
3165             AutomaticZenRule activeRule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
3166                     .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
3167                     .build();
3168             String activeRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3169                     mContext.getPackageName(), activeRule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
3170             mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, activeRuleId,
3171                     CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID);
3172             AutomaticZenRule inactiveRule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
3173                     .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
3174                     .build();
3175             String inactiveRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3176                     mContext.getPackageName(), inactiveRule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
3177 
3178             assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
3179 
3180             // User turns DND off.
3181             mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, null, origin.value(),
3182                     "snoozing", "systemui", SYSTEM_UID);
3183             ZenModeConfig config = mZenModeHelper.mConfig;
3184             if (origin == ZenChangeOrigin.ORIGIN_USER_IN_SYSTEMUI) {
3185                 // Other rule was unaffected.
3186                 assertWithMessage("Failure for origin " + origin.name()).that(
3187                         mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
3188                 assertWithMessage("Failure for origin " + origin.name()).that(
3189                         config.automaticRules.get(activeRuleId).getConditionOverride())
3190                         .isEqualTo(OVERRIDE_NONE);
3191                 assertWithMessage("Failure for origin " + origin.name()).that(
3192                         config.automaticRules.get(inactiveRuleId).getConditionOverride())
3193                         .isEqualTo(OVERRIDE_NONE);
3194             } else {
3195                 assertWithMessage("Failure for origin " + origin.name()).that(
3196                         mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
3197                 assertWithMessage("Failure for origin " + origin.name()).that(
3198                         config.automaticRules.get(activeRuleId).getConditionOverride())
3199                         .isEqualTo(OVERRIDE_DEACTIVATE);
3200                 assertWithMessage("Failure for origin " + origin.name()).that(
3201                         config.automaticRules.get(inactiveRuleId).getConditionOverride())
3202                         .isEqualTo(OVERRIDE_NONE);
3203             }
3204         }
3205     }
3206 
3207     @Test
testSetManualZenMode_legacy()3208     public void testSetManualZenMode_legacy() {
3209         setupZenConfig();
3210 
3211         // note that caller=null because that's how it comes in from NMS.setZenMode
3212         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
3213                 ORIGIN_SYSTEM, "", null, SYSTEM_UID);
3214 
3215         // confirm that setting zen mode via setManualZenMode changed the zen mode correctly
3216         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode);
3217 
3218         // and also that it works to turn it back off again
3219         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, null,
3220                 ORIGIN_SYSTEM, "", null, SYSTEM_UID);
3221 
3222         assertEquals(ZEN_MODE_OFF, mZenModeHelper.mZenMode);
3223     }
3224 
3225     @Test
testZenModeEventLog_setManualZenMode()3226     public void testZenModeEventLog_setManualZenMode()
3227             throws IllegalArgumentException {
3228         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3229         setupZenConfig();
3230 
3231         // Turn zen mode on (to important_interruptions)
3232         // Need to additionally call the looper in order to finish the post-apply-config process
3233         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
3234                 Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ORIGIN_SYSTEM, "", null, SYSTEM_UID);
3235 
3236         // Now turn zen mode off, but via a different package UID -- this should get registered as
3237         // "not an action by the user" because some other app is changing zen mode
3238         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, null, ORIGIN_APP, "",
3239                 null, CUSTOM_PKG_UID);
3240 
3241         // In total, this should be 2 loggable changes
3242         assertEquals(2, mZenModeEventLogger.numLoggedChanges());
3243 
3244         // we expect the following changes from turning zen mode on:
3245         //   - manual rule added
3246         //   - zen mode -> ZEN_MODE_IMPORTANT_INTERRUPTIONS
3247         // This should combine to 1 log event (zen mode turns on) with the following properties:
3248         //   - event ID: DND_TURNED_ON
3249         //   - new zen mode = important interruptions; prev zen mode = off
3250         //   - changed rule type = manual
3251         //   - rules active = 1
3252         //   - user action = true (system-based turning zen mode on)
3253         //   - package uid = system (as set above)
3254         //   - resulting DNDPolicyProto the same as the values in setupZenConfig() (global policy)
3255         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3256                 mZenModeEventLogger.getEventId(0));
3257         assertEquals(ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
3258         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
3259         assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(0));
3260         assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
3261         assertThat(mZenModeEventLogger.getFromSystemOrSystemUi(0)).isEqualTo(
3262                 !(Flags.modesUi() || Flags.modesApi()));
3263         assertTrue(mZenModeEventLogger.getIsUserAction(0));
3264         assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(0));
3265         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
3266         // change origin should be populated only under modes_ui
3267         assertThat(mZenModeEventLogger.getChangeOrigin(0)).isEqualTo(
3268                 (Flags.modesApi() && Flags.modesUi()) ? ORIGIN_USER_IN_SYSTEMUI : 0);
3269 
3270         // and from turning zen mode off:
3271         //   - event ID: DND_TURNED_OFF
3272         //   - new zen mode = off; previous = important interruptions
3273         //   - changed rule type = manual
3274         //   - rules active = 0
3275         //   - user action = false
3276         //   - package uid = custom one passed in above
3277         //   - DNDPolicyProto still the same
3278         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
3279                 mZenModeEventLogger.getEventId(1));
3280         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getPrevZenMode(1));
3281         assertEquals(ZEN_MODE_OFF, mZenModeEventLogger.getNewZenMode(1));
3282         assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(1));
3283         assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
3284         assertFalse(mZenModeEventLogger.getIsUserAction(1));
3285         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
3286         if (Flags.modesApi()) {
3287             assertThat(mZenModeEventLogger.getPolicyProto(1)).isNull();
3288         } else {
3289             checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
3290         }
3291         assertThat(mZenModeEventLogger.getChangeOrigin(1)).isEqualTo(
3292                 Flags.modesUi() ? ORIGIN_APP : 0);
3293     }
3294 
3295     @Test
testZenModeEventLog_automaticRules()3296     public void testZenModeEventLog_automaticRules()
3297             throws IllegalArgumentException {
3298         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3299         setupZenConfig();
3300 
3301         // Add a new automatic zen rule that's enabled
3302         AutomaticZenRule zenRule = new AutomaticZenRule("name",
3303                 null,
3304                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
3305                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
3306                 null,
3307                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
3308         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3309                 mContext.getPackageName(), zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID);
3310 
3311         // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE
3312         // Note that pre-modes_ui, this event serves as a test that automatic changes to an app's
3313         // that look like they're coming from the system are attributed to the app, but when
3314         // modes_ui is true, we opt to trust the provided change origin.
3315         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
3316                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
3317                 Flags.modesUi() ? ORIGIN_APP : ORIGIN_SYSTEM, CUSTOM_PKG_UID);
3318 
3319         // Event 2: "User" turns off the automatic rule (sets it to not enabled)
3320         zenRule.setEnabled(false);
3321         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, id, zenRule,
3322                 Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ORIGIN_SYSTEM, "",
3323                 SYSTEM_UID);
3324 
3325         AutomaticZenRule systemRule = new AutomaticZenRule("systemRule",
3326                 null,
3327                 new ComponentName("android", "ScheduleConditionProvider"),
3328                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
3329                 null,
3330                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
3331         String systemId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3332                 mContext.getPackageName(), systemRule,
3333                 Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ORIGIN_SYSTEM, "test",
3334                 SYSTEM_UID);
3335 
3336         // Event 3: turn on the system rule
3337         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, systemId,
3338                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
3339                 ORIGIN_SYSTEM, SYSTEM_UID);
3340 
3341         // Event 4: "User" deletes the rule
3342         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, systemId,
3343                 Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ORIGIN_SYSTEM, "",
3344                 SYSTEM_UID);
3345         // In total, this represents 4 events
3346         assertEquals(4, mZenModeEventLogger.numLoggedChanges());
3347 
3348         // We should see an event from the automatic rule turning on; it should have the following
3349         // properties:
3350         //   - event ID: DND_TURNED_ON
3351         //   - zen mode: OFF -> IMPORTANT_INTERRUPTIONS
3352         //   - automatic rule change
3353         //   - 1 rule (newly) active
3354         //   - automatic (is not a user action)
3355         //   - package UID is written to be the rule *owner* even though it "comes from system"
3356         //   - zen policy is the default as it's unspecified
3357         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3358                 mZenModeEventLogger.getEventId(0));
3359         assertEquals(ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
3360         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
3361         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(0));
3362         assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
3363         assertFalse(mZenModeEventLogger.getIsUserAction(0));
3364         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
3365         checkDndProtoMatchesDefaultZenConfig(mZenModeEventLogger.getPolicyProto(0));
3366         assertThat(mZenModeEventLogger.getChangeOrigin(0)).isEqualTo(
3367                 Flags.modesUi() ? ORIGIN_APP : 0);
3368 
3369         // When the automatic rule is disabled, this should turn off zen mode and also count as a
3370         // user action. We don't care what the consolidated policy is when DND turns off.
3371         // When modes_ui is true, this event should look like a user action attributed to the
3372         // specific app.
3373         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
3374                 mZenModeEventLogger.getEventId(1));
3375         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getPrevZenMode(1));
3376         assertEquals(ZEN_MODE_OFF, mZenModeEventLogger.getNewZenMode(1));
3377         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1));
3378         assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
3379         assertTrue(mZenModeEventLogger.getIsUserAction(1));
3380         assertThat(mZenModeEventLogger.getPackageUid(1)).isEqualTo(
3381                 Flags.modesUi() ? CUSTOM_PKG_UID : SYSTEM_UID);
3382         if (Flags.modesApi()) {
3383             assertThat(mZenModeEventLogger.getPolicyProto(1)).isNull();
3384         } else {
3385             checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
3386         }
3387         assertThat(mZenModeEventLogger.getChangeOrigin(1)).isEqualTo(
3388                 Flags.modesUi() ? ORIGIN_USER_IN_SYSTEMUI : 0);
3389 
3390         // When the system rule is enabled, this counts as an automatic action that comes from the
3391         // system and turns on DND
3392         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3393                 mZenModeEventLogger.getEventId(2));
3394         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
3395         assertEquals(1, mZenModeEventLogger.getNumRulesActive(2));
3396         assertFalse(mZenModeEventLogger.getIsUserAction(2));
3397         assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
3398         assertThat(mZenModeEventLogger.getChangeOrigin(2)).isEqualTo(
3399                 Flags.modesUi() ? ORIGIN_SYSTEM : 0);
3400 
3401         // When the system rule is deleted, we consider this a user action that turns DND off
3402         // (again)
3403         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
3404                 mZenModeEventLogger.getEventId(3));
3405         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(3));
3406         assertEquals(0, mZenModeEventLogger.getNumRulesActive(3));
3407         assertTrue(mZenModeEventLogger.getIsUserAction(3));
3408         assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(3));
3409         assertThat(mZenModeEventLogger.getChangeOrigin(3)).isEqualTo(
3410                 Flags.modesUi() ? ORIGIN_USER_IN_SYSTEMUI : 0);
3411     }
3412 
3413     @Test
3414     @EnableFlags(FLAG_MODES_API)
testZenModeEventLog_automaticRuleActivatedFromAppByAppAndUser()3415     public void testZenModeEventLog_automaticRuleActivatedFromAppByAppAndUser()
3416             throws IllegalArgumentException {
3417         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3418         setupZenConfig();
3419 
3420         // Ann app adds an automatic zen rule
3421         AutomaticZenRule zenRule = new AutomaticZenRule("name",
3422                 null,
3423                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
3424                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
3425                 null,
3426                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
3427         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3428                 mContext.getPackageName(), zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID);
3429 
3430         // Event 1: Mimic the rule coming on manually when the user turns it on in the app
3431         // ("Turn on bedtime now" because user goes to bed earlier).
3432         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
3433                 new Condition(zenRule.getConditionId(), "", STATE_TRUE, SOURCE_USER_ACTION),
3434                 ORIGIN_USER_IN_APP, CUSTOM_PKG_UID);
3435 
3436         // Event 2: App deactivates the rule automatically (it's 8 AM, bedtime schedule ends)
3437         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
3438                 new Condition(zenRule.getConditionId(), "", STATE_FALSE, SOURCE_SCHEDULE),
3439                 ORIGIN_APP, CUSTOM_PKG_UID);
3440 
3441         // Event 3: App activates the rule automatically (it's now 11 PM, bedtime schedule starts)
3442         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
3443                 new Condition(zenRule.getConditionId(), "", STATE_TRUE, SOURCE_SCHEDULE),
3444                 ORIGIN_APP, CUSTOM_PKG_UID);
3445 
3446         // Event 4: User deactivates the rule manually (they get up before 8 AM on the next day)
3447         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
3448                 new Condition(zenRule.getConditionId(), "", STATE_FALSE, SOURCE_USER_ACTION),
3449                 ORIGIN_USER_IN_APP, CUSTOM_PKG_UID);
3450 
3451         // In total, this represents 4 events
3452         assertEquals(4, mZenModeEventLogger.numLoggedChanges());
3453 
3454         // Automatic rule turning on manually:
3455         //   - event ID: DND_TURNED_ON
3456         //   - 1 rule (newly) active
3457         //   - is a user action
3458         //   - package UID is the calling package
3459         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3460                 mZenModeEventLogger.getEventId(0));
3461         assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
3462         assertTrue(mZenModeEventLogger.getIsUserAction(0));
3463         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
3464         assertThat(mZenModeEventLogger.getChangeOrigin(0)).isEqualTo(
3465                 Flags.modesUi() ? ORIGIN_USER_IN_APP : 0);
3466 
3467         // Automatic rule turned off automatically by app:
3468         //   - event ID: DND_TURNED_OFF
3469         //   - 0 rules active
3470         //   - is not a user action
3471         //   - package UID is the calling package
3472         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
3473                 mZenModeEventLogger.getEventId(1));
3474         assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
3475         assertFalse(mZenModeEventLogger.getIsUserAction(1));
3476         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
3477         assertThat(mZenModeEventLogger.getChangeOrigin(1)).isEqualTo(
3478                 Flags.modesUi() ? ORIGIN_APP : 0);
3479 
3480         // Automatic rule turned on automatically by app:
3481         //   - event ID: DND_TURNED_ON
3482         //   - 1 rule (newly) active
3483         //   - is not a user action
3484         //   - package UID is the calling package
3485         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3486                 mZenModeEventLogger.getEventId(2));
3487         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
3488         assertEquals(1, mZenModeEventLogger.getNumRulesActive(2));
3489         assertFalse(mZenModeEventLogger.getIsUserAction(2));
3490         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(2));
3491         assertThat(mZenModeEventLogger.getChangeOrigin(2)).isEqualTo(
3492                 Flags.modesUi() ? ORIGIN_APP : 0);
3493 
3494         // Automatic rule turned off automatically by the user:
3495         //   - event ID: DND_TURNED_ON
3496         //   - 0 rules active
3497         //   - is a user action
3498         //   - package UID is the calling package
3499         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
3500                 mZenModeEventLogger.getEventId(3));
3501         assertEquals(0, mZenModeEventLogger.getNumRulesActive(3));
3502         assertTrue(mZenModeEventLogger.getIsUserAction(3));
3503         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(3));
3504         assertThat(mZenModeEventLogger.getChangeOrigin(3)).isEqualTo(
3505                 Flags.modesUi() ? ORIGIN_USER_IN_APP : 0);
3506     }
3507 
3508     @Test
testZenModeEventLog_policyChanges()3509     public void testZenModeEventLog_policyChanges()
3510             throws IllegalArgumentException {
3511         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3512         setupZenConfig();
3513 
3514         // First just turn zen mode on
3515         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
3516                 ORIGIN_USER_IN_SYSTEMUI, "", null, SYSTEM_UID);
3517 
3518         // Now change the policy slightly; want to confirm that this'll be reflected in the logs
3519         ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
3520         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT,
3521                 new Policy(PRIORITY_CATEGORY_ALARMS, 0, 0),
3522                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
3523 
3524         // Turn zen mode off; we want to make sure policy changes do not get logged when zen mode
3525         // is off.
3526         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, null,
3527                 ORIGIN_SYSTEM, "", null, SYSTEM_UID);
3528 
3529         // Change the policy again
3530         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT,
3531                 new Policy(PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0),
3532                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
3533 
3534         // Total events: we only expect ones for turning on, changing policy, and turning off
3535         assertEquals(3, mZenModeEventLogger.numLoggedChanges());
3536 
3537         // The first event is just turning DND on; make sure the policy is what we expect there
3538         // before it changes in the next stage
3539         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3540                 mZenModeEventLogger.getEventId(0));
3541         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
3542 
3543         // Second message where we change the policy:
3544         //   - DND_POLICY_CHANGED (indicates only the policy changed and nothing else)
3545         //   - rule type: unknown (it's a policy change, not a rule change)
3546         //   - user action (because it comes from a "system" uid)
3547         //   - check the specific things changed above
3548         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
3549                 mZenModeEventLogger.getEventId(1));
3550         assertEquals(DNDProtoEnums.UNKNOWN_RULE, mZenModeEventLogger.getChangedRuleType(1));
3551         assertTrue(mZenModeEventLogger.getIsUserAction(1));
3552         assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
3553         DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(1);
3554         assertEquals(STATE_ALLOW, dndProto.getAlarms().getNumber());
3555         assertEquals(STATE_DISALLOW, dndProto.getRepeatCallers().getNumber());
3556 
3557         // The third and final event should turn DND off
3558         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
3559                 mZenModeEventLogger.getEventId(2));
3560 
3561         // There should be no fourth event for changing the policy the second time.
3562     }
3563 
3564     @Test
testZenModeEventLog_ruleCounts()3565     public void testZenModeEventLog_ruleCounts() throws IllegalArgumentException {
3566         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3567         setupZenConfig();
3568 
3569         AutomaticZenRule zenRule = new AutomaticZenRule("name",
3570                 null,
3571                 new ComponentName("android", "ScheduleConditionProvider"),
3572                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
3573                 null,
3574                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
3575         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3576                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
3577 
3578         // Rule 2, same as rule 1
3579         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
3580                 null,
3581                 new ComponentName("android", "ScheduleConditionProvider"),
3582                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
3583                 null,
3584                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
3585         String id2 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3586                 mContext.getPackageName(), zenRule2, ORIGIN_SYSTEM, "test", SYSTEM_UID);
3587 
3588         // Rule 3, has stricter settings than the default settings
3589         ZenModeConfig ruleConfig = mZenModeHelper.mConfig.copy();
3590         ruleConfig.applyNotificationPolicy(new Policy(0, 0, 0));
3591         AutomaticZenRule zenRule3 = new AutomaticZenRule("name3",
3592                 null,
3593                 new ComponentName("android", "ScheduleConditionProvider"),
3594                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
3595                 ruleConfig.getZenPolicy(),
3596                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
3597         String id3 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3598                 mContext.getPackageName(), zenRule3, ORIGIN_SYSTEM, "test", SYSTEM_UID);
3599 
3600         // First: turn on rule 1
3601         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
3602                 new Condition(zenRule.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM, SYSTEM_UID);
3603 
3604         // Second: turn on rule 2
3605         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id2,
3606                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM,
3607                 SYSTEM_UID);
3608 
3609         // Third: turn on rule 3
3610         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id3,
3611                 new Condition(zenRule3.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM,
3612                 SYSTEM_UID);
3613 
3614         // Fourth: Turn *off* rule 2
3615         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id2,
3616                 new Condition(zenRule2.getConditionId(), "", STATE_FALSE), ORIGIN_SYSTEM,
3617                 SYSTEM_UID);
3618 
3619         // This should result in a total of four events
3620         assertEquals(4, mZenModeEventLogger.numLoggedChanges());
3621 
3622         // Event 1: rule 1 turns on. We expect this to turn on DND (zen mode) overall, so that's
3623         // what the event should reflect. At this time, the policy is the default.
3624         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3625                 mZenModeEventLogger.getEventId(0));
3626         assertEquals(ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
3627         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
3628         assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
3629         assertFalse(mZenModeEventLogger.getIsUserAction(0));
3630         assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(0));
3631         checkDndProtoMatchesDefaultZenConfig(mZenModeEventLogger.getPolicyProto(0));
3632 
3633         // Event 2: rule 2 turns on. This should not change anything about the policy, so the only
3634         // change is that there are more rules active now.
3635         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
3636                 mZenModeEventLogger.getEventId(1));
3637         assertEquals(2, mZenModeEventLogger.getNumRulesActive(1));
3638         assertFalse(mZenModeEventLogger.getIsUserAction(1));
3639         assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
3640         checkDndProtoMatchesDefaultZenConfig(mZenModeEventLogger.getPolicyProto(1));
3641 
3642         // Event 3: rule 3 turns on. This should trigger a policy change, and be classified as such,
3643         // but meanwhile also change the number of active rules.
3644         // Rule 3 is also set up to be a "system"-owned rule, so the caller UID should remain system
3645         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
3646                 mZenModeEventLogger.getEventId(2));
3647         assertEquals(3, mZenModeEventLogger.getNumRulesActive(2));
3648         assertFalse(mZenModeEventLogger.getIsUserAction(2));
3649         assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
3650         DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(2);
3651         assertEquals(STATE_DISALLOW, dndProto.getReminders().getNumber());
3652         assertEquals(STATE_DISALLOW, dndProto.getCalls().getNumber());
3653         assertEquals(STATE_DISALLOW, dndProto.getMessages().getNumber());
3654 
3655         // Event 4: rule 2 turns off. Because rule 3 is still on and stricter than rule 1 (also
3656         // still on), there should be no policy change as a result of rule 2 going away. Therefore
3657         // this event should again only be an active rule change.
3658         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
3659                 mZenModeEventLogger.getEventId(3));
3660         assertEquals(2, mZenModeEventLogger.getNumRulesActive(3));
3661         assertFalse(mZenModeEventLogger.getIsUserAction(3));
3662     }
3663 
3664     @Test
testZenModeEventLog_noLogWithNoConfigChange()3665     public void testZenModeEventLog_noLogWithNoConfigChange() throws IllegalArgumentException {
3666         // If evaluateZenMode is called independently of a config change, don't log.
3667         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3668         setupZenConfig();
3669 
3670         // Artificially turn zen mode "on". Re-evaluating zen mode should cause it to turn back off
3671         // given that we don't have any zen rules active.
3672         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
3673         mZenModeHelper.evaluateZenModeLocked(ORIGIN_UNKNOWN, "test", true);
3674 
3675         // Check that the change actually took: zen mode should be off now
3676         assertEquals(ZEN_MODE_OFF, mZenModeHelper.mZenMode);
3677 
3678         // but still, nothing should've been logged
3679         assertEquals(0, mZenModeEventLogger.numLoggedChanges());
3680     }
3681 
3682     @Test
testZenModeEventLog_reassignUid()3683     public void testZenModeEventLog_reassignUid()
3684             throws IllegalArgumentException {
3685         // Test that, only in specific cases, we reassign the calling UID to one associated with
3686         // the automatic rule owner.
3687         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3688         setupZenConfig();
3689 
3690         // Explicitly set up all rules with the same policy as the manual rule so there will be
3691         // no policy changes in this test case.
3692         ZenPolicy manualRulePolicy = mZenModeHelper.mConfig.getZenPolicy();
3693 
3694         // Rule 1, owned by a package
3695         AutomaticZenRule zenRule = new AutomaticZenRule("name",
3696                 null,
3697                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
3698                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
3699                 manualRulePolicy,
3700                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
3701         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3702                 mContext.getPackageName(), zenRule, ORIGIN_APP, "test", SYSTEM_UID);
3703 
3704         // Rule 2, same as rule 1 but owned by the system
3705         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
3706                 null,
3707                 new ComponentName("android", "ScheduleConditionProvider"),
3708                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
3709                 manualRulePolicy,
3710                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
3711         String id2 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3712                 mContext.getPackageName(), zenRule2, ORIGIN_USER_IN_SYSTEMUI, "test", SYSTEM_UID);
3713 
3714         // Turn on rule 1; call looks like it's from the system. Because setting a condition is
3715         // typically an automatic (non-user-initiated) action, expect the calling UID to be
3716         // re-evaluated to the one associated with CUSTOM_PKG_NAME.
3717         // When modes_ui is true: we expect the change origin to be the source of truth.
3718         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
3719                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
3720                 Flags.modesUi() ? ORIGIN_APP : ORIGIN_SYSTEM, SYSTEM_UID);
3721 
3722         // Second: turn on rule 2. This is a system-owned rule and the UID should not be modified
3723         // (nor even looked up; the mock PackageManager won't handle "android" as input).
3724         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id2,
3725                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM,
3726                 SYSTEM_UID);
3727 
3728         // Disable rule 1. Because this looks like a user action, the UID should not be modified
3729         // from the system-provided one unless modes_ui is true.
3730         zenRule.setEnabled(false);
3731         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, id, zenRule,
3732                 ORIGIN_USER_IN_SYSTEMUI, "", SYSTEM_UID);
3733 
3734         // Add a manual rule. Any manual rule changes should not get calling uids reassigned.
3735         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
3736                 ORIGIN_APP, "", null, CUSTOM_PKG_UID);
3737 
3738         // Change rule 2's condition, but from some other UID. Since it doesn't look like it's from
3739         // the system, we keep the UID info.
3740         // Note that this probably shouldn't be able to occur in real scenarios.
3741         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id2,
3742                 new Condition(zenRule2.getConditionId(), "", STATE_FALSE), ORIGIN_APP, 12345);
3743 
3744         // That was 5 events total
3745         assertEquals(5, mZenModeEventLogger.numLoggedChanges());
3746 
3747         // The first event (activating rule 1) should be of type "zen mode turns on", automatic,
3748         // have a package UID of CUSTOM_PKG_UID
3749         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3750                 mZenModeEventLogger.getEventId(0));
3751         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(0));
3752         assertFalse(mZenModeEventLogger.getIsUserAction(0));
3753         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
3754 
3755         // The second event (activating rule 2) should have similar other properties but the UID
3756         // should be system.
3757         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
3758                 mZenModeEventLogger.getEventId(1));
3759         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1));
3760         assertFalse(mZenModeEventLogger.getIsUserAction(1));
3761         assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
3762 
3763         // Third event: disable rule 1. This looks like a user action so UID should be left alone.
3764         // When modes_ui is true, we assign log this user action with the app that owns the rule.
3765         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
3766                 mZenModeEventLogger.getEventId(2));
3767         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
3768         assertTrue(mZenModeEventLogger.getIsUserAction(2));
3769         assertThat(mZenModeEventLogger.getPackageUid(2)).isEqualTo(
3770                 Flags.modesUi() ? CUSTOM_PKG_UID : SYSTEM_UID);
3771 
3772         // Fourth event: turns on manual mode. Doesn't change effective policy so this is just a
3773         // change in active rules. Confirm that the package UID is left unchanged.
3774         // Because it's a manual mode change not from the system, isn't considered a user action.
3775         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
3776                 mZenModeEventLogger.getEventId(3));
3777         assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(3));
3778         assertFalse(mZenModeEventLogger.getIsUserAction(3));
3779         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(3));
3780 
3781         // Fourth event: changed condition on rule 2 (turning it off via condition).
3782         // This comes from a random different UID so we expect that to remain untouched.
3783         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
3784                 mZenModeEventLogger.getEventId(4));
3785         assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(4));
3786         assertFalse(mZenModeEventLogger.getIsUserAction(4));
3787         assertEquals(12345, mZenModeEventLogger.getPackageUid(4));
3788     }
3789 
3790     @Test
testZenModeEventLog_channelsBypassingChanges()3791     public void testZenModeEventLog_channelsBypassingChanges() {
3792         // Verify that the right thing happens when the canBypassDnd value changes.
3793         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3794         setupZenConfig();
3795 
3796         // Turn on zen mode with a manual rule with an enabler set. This should *not* count
3797         // as a user action, and *should* get its UID reassigned.
3798         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
3799                 ORIGIN_SYSTEM, "", CUSTOM_PKG_NAME, SYSTEM_UID);
3800         assertEquals(1, mZenModeEventLogger.numLoggedChanges());
3801 
3802         // Now change apps bypassing to true
3803         ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
3804         newConfig.areChannelsBypassingDnd = true;
3805         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, newConfig.toNotificationPolicy(),
3806                 ORIGIN_SYSTEM, SYSTEM_UID);
3807         assertEquals(2, mZenModeEventLogger.numLoggedChanges());
3808 
3809         // and then back to false, all without changing anything else
3810         newConfig.areChannelsBypassingDnd = false;
3811         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, newConfig.toNotificationPolicy(),
3812                 ORIGIN_SYSTEM, SYSTEM_UID);
3813         assertEquals(3, mZenModeEventLogger.numLoggedChanges());
3814 
3815         // Turn off manual mode, call from a package: don't reset UID even though enabler is set
3816         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, null, ORIGIN_APP, "",
3817                 CUSTOM_PKG_NAME, 12345);
3818         assertEquals(4, mZenModeEventLogger.numLoggedChanges());
3819 
3820         // And likewise when turning it back on again
3821         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
3822                 ORIGIN_APP, "", CUSTOM_PKG_NAME, 12345);
3823 
3824         // These are 5 events in total.
3825         assertEquals(5, mZenModeEventLogger.numLoggedChanges());
3826 
3827         // First event: turns on, UID reassigned for manual mode
3828         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3829                 mZenModeEventLogger.getEventId(0));
3830         assertFalse(mZenModeEventLogger.getIsUserAction(0));
3831         assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
3832 
3833         // Second event should be a policy-only change with are channels bypassing = true
3834         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
3835                 mZenModeEventLogger.getEventId(1));
3836         assertTrue(mZenModeEventLogger.getAreChannelsBypassing(1));
3837 
3838         // Third event also a policy-only change but with channels bypassing now false
3839         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
3840                 mZenModeEventLogger.getEventId(2));
3841         assertFalse(mZenModeEventLogger.getAreChannelsBypassing(2));
3842 
3843         // Fourth event: should turn DND off, not have UID reassigned
3844         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
3845                 mZenModeEventLogger.getEventId(3));
3846         assertFalse(mZenModeEventLogger.getIsUserAction(3));
3847         assertEquals(12345, mZenModeEventLogger.getPackageUid(3));
3848 
3849         // Fifth event: turn DND back on, not have UID reassigned
3850         assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
3851                 mZenModeEventLogger.getEventId(4));
3852         assertFalse(mZenModeEventLogger.getIsUserAction(4));
3853         assertEquals(12345, mZenModeEventLogger.getPackageUid(4));
3854     }
3855 
3856     @Test
3857     @EnableFlags(FLAG_MODES_API)
testZenModeEventLog_policyAllowChannels()3858     public void testZenModeEventLog_policyAllowChannels() {
3859         // when modes_api flag is on, ensure that any change in allow_channels gets logged,
3860         // even when there are no other changes.
3861         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3862 
3863         // Default zen config has allow channels = priority (aka on)
3864         setupZenConfig();
3865 
3866         // First just turn zen mode on
3867         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
3868                 ORIGIN_SYSTEM, "", null, SYSTEM_UID);
3869 
3870         // Now change only the channels part of the policy; want to confirm that this'll be
3871         // reflected in the logs
3872         ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
3873         Policy oldPolicy = newConfig.toNotificationPolicy();
3874         Policy newPolicy = new Policy(oldPolicy.priorityCategories, oldPolicy.priorityCallSenders,
3875                 oldPolicy.priorityMessageSenders, oldPolicy.suppressedVisualEffects,
3876                 STATE_PRIORITY_CHANNELS_BLOCKED,
3877                 oldPolicy.priorityConversationSenders);
3878         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, newPolicy, ORIGIN_SYSTEM,
3879                 SYSTEM_UID);
3880 
3881         // Total events: one for turning on, one for changing policy
3882         assertThat(mZenModeEventLogger.numLoggedChanges()).isEqualTo(2);
3883 
3884         // The first event is just turning DND on; make sure the policy is what we expect there
3885         // before it changes in the next stage
3886         assertThat(mZenModeEventLogger.getEventId(0))
3887                 .isEqualTo(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId());
3888         DNDPolicyProto origDndProto = mZenModeEventLogger.getPolicyProto(0);
3889         checkDndProtoMatchesSetupZenConfig(origDndProto);
3890         assertThat(origDndProto.getAllowChannels().getNumber())
3891                 .isEqualTo(DNDProtoEnums.CHANNEL_POLICY_PRIORITY);
3892 
3893         // Second message where we change the policy:
3894         //   - DND_POLICY_CHANGED (indicates only the policy changed and nothing else)
3895         //   - rule type: unknown (it's a policy change, not a rule change)
3896         //   - change is in allow channels, and final policy
3897         assertThat(mZenModeEventLogger.getEventId(1))
3898                 .isEqualTo(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId());
3899         assertThat(mZenModeEventLogger.getChangedRuleType(1))
3900                 .isEqualTo(DNDProtoEnums.UNKNOWN_RULE);
3901         DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(1);
3902         assertThat(dndProto.getAllowChannels().getNumber())
3903                 .isEqualTo(DNDProtoEnums.CHANNEL_POLICY_NONE);
3904     }
3905 
3906     @Test
3907     @EnableFlags(FLAG_MODES_API)
testZenModeEventLog_ruleWithInterruptionFilterAll_notLoggedAsDndChange()3908     public void testZenModeEventLog_ruleWithInterruptionFilterAll_notLoggedAsDndChange() {
3909         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3910         setupZenConfig();
3911 
3912         // An app adds an automatic zen rule
3913         AutomaticZenRule zenRule = new AutomaticZenRule("name",
3914                 null,
3915                 new ComponentName(CUSTOM_PKG_NAME, "cls"),
3916                 Uri.parse("condition"),
3917                 null,
3918                 NotificationManager.INTERRUPTION_FILTER_ALL, true);
3919         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
3920                 mContext.getPackageName(), zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID);
3921 
3922         // Event 1: App activates the rule automatically.
3923         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
3924                 new Condition(zenRule.getConditionId(), "", STATE_TRUE, SOURCE_SCHEDULE),
3925                 ORIGIN_APP, CUSTOM_PKG_UID);
3926 
3927         // Event 2: App deactivates the rule automatically.
3928         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
3929                 new Condition(zenRule.getConditionId(), "", STATE_FALSE, SOURCE_SCHEDULE),
3930                 ORIGIN_APP, CUSTOM_PKG_UID);
3931 
3932         // In total, this represents 2 events.
3933         assertEquals(2, mZenModeEventLogger.numLoggedChanges());
3934 
3935         // However, they are not DND_TURNED_ON/_OFF (no notification filtering is taking place).
3936         // Also, no consolidated ZenPolicy is logged (because of the same reason).
3937         assertThat(mZenModeEventLogger.getEventId(0)).isEqualTo(
3938                 ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId());
3939         assertThat(mZenModeEventLogger.getNumRulesActive(0)).isEqualTo(1);
3940         assertThat(mZenModeEventLogger.getPolicyProto(0)).isNull();
3941 
3942         assertThat(mZenModeEventLogger.getEventId(1)).isEqualTo(
3943                 ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId());
3944         assertThat(mZenModeEventLogger.getNumRulesActive(1)).isEqualTo(0);
3945         assertThat(mZenModeEventLogger.getPolicyProto(1)).isNull();
3946     }
3947 
3948     @Test
3949     @EnableFlags(FLAG_MODES_API)
testZenModeEventLog_activeRuleTypes()3950     public void testZenModeEventLog_activeRuleTypes() {
3951         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
3952         setupZenConfig();
3953 
3954         // Create bedtime rule
3955         // This one has INTERRUPTION_FILTER_ALL to make sure active rules still count when zen mode
3956         // (in the notification filtering sense) is not on
3957         AutomaticZenRule bedtime = new AutomaticZenRule.Builder("Bedtime Mode (TM)", CONDITION_ID)
3958                 .setInterruptionFilter(INTERRUPTION_FILTER_ALL)
3959                 .setType(TYPE_BEDTIME)
3960                 .build();
3961         String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, bedtime,
3962                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
3963 
3964         // Create immersive rule
3965         AutomaticZenRule immersive = new AutomaticZenRule.Builder("Immersed", CONDITION_ID)
3966                 .setType(TYPE_IMMERSIVE)
3967                 .setZenPolicy(mZenModeHelper.mConfig.getZenPolicy()) // same as the manual rule
3968                 .build();
3969         String immersiveId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, immersive,
3970                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
3971 
3972         // Event 1: Activate bedtime rule. This doesn't turn on notification filtering
3973         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, bedtimeRuleId,
3974                 new Condition(bedtime.getConditionId(), "", STATE_TRUE, SOURCE_SCHEDULE),
3975                 ORIGIN_APP, CUSTOM_PKG_UID);
3976 
3977         // Event 2: turn on manual zen mode. Manual rule will have ACTIVE_RULE_TYPE_MANUAL
3978         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
3979                 ORIGIN_SYSTEM, "", null, SYSTEM_UID);
3980 
3981         // Event 3: Turn immersive on
3982         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, immersiveId,
3983                 new Condition(immersive.getConditionId(), "", STATE_TRUE, SOURCE_SCHEDULE),
3984                 ORIGIN_APP, CUSTOM_PKG_UID);
3985 
3986         // Event 4: Turn off bedtime mode, leaving just manual + immersive
3987         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, bedtimeRuleId,
3988                 new Condition(bedtime.getConditionId(), "", STATE_FALSE, SOURCE_SCHEDULE),
3989                 ORIGIN_APP, CUSTOM_PKG_UID);
3990 
3991         // Total of 4 events
3992         assertEquals(4, mZenModeEventLogger.numLoggedChanges());
3993 
3994         // First event: active rules changed; active rules: 1; type is ACTIVE_RULE_TYPE_MANUAL
3995         assertThat(mZenModeEventLogger.getEventId(0)).isEqualTo(
3996                 ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId());
3997         assertThat(mZenModeEventLogger.getChangedRuleType(0)).isEqualTo(
3998                 DNDProtoEnums.AUTOMATIC_RULE);
3999         assertThat(mZenModeEventLogger.getNumRulesActive(0)).isEqualTo(1);
4000         int[] ruleTypes0 = mZenModeEventLogger.getActiveRuleTypes(0);
4001         assertThat(ruleTypes0.length).isEqualTo(1);
4002         assertThat(ruleTypes0[0]).isEqualTo(TYPE_BEDTIME);
4003 
4004         // Second event: active rules: 2; types are TYPE_MANUAL and TYPE_BEDTIME
4005         assertThat(mZenModeEventLogger.getEventId(1)).isEqualTo(
4006                 ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId());
4007         assertThat(mZenModeEventLogger.getChangedRuleType(1)).isEqualTo(
4008                 DNDProtoEnums.MANUAL_RULE);
4009         assertThat(mZenModeEventLogger.getNumRulesActive(1)).isEqualTo(2);
4010         int[] ruleTypes1 = mZenModeEventLogger.getActiveRuleTypes(1);
4011         assertThat(ruleTypes1.length).isEqualTo(2);
4012         assertThat(ruleTypes1[0]).isEqualTo(TYPE_BEDTIME);
4013         assertThat(ruleTypes1[1]).isEqualTo(ACTIVE_RULE_TYPE_MANUAL);
4014 
4015         // Third event: active rules: 3
4016         assertThat(mZenModeEventLogger.getEventId(2)).isEqualTo(
4017                 ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId());
4018         assertThat(mZenModeEventLogger.getChangedRuleType(2)).isEqualTo(
4019                 DNDProtoEnums.AUTOMATIC_RULE);
4020         int[] ruleTypes2 = mZenModeEventLogger.getActiveRuleTypes(2);
4021         assertThat(ruleTypes2.length).isEqualTo(3);
4022         assertThat(ruleTypes2[0]).isEqualTo(TYPE_BEDTIME);
4023         assertThat(ruleTypes2[1]).isEqualTo(TYPE_IMMERSIVE);
4024         assertThat(ruleTypes2[2]).isEqualTo(ACTIVE_RULE_TYPE_MANUAL);
4025 
4026         // Fourth event: active rules 2, types are TYPE_MANUAL and TYPE_IMMERSIVE
4027         assertThat(mZenModeEventLogger.getEventId(3)).isEqualTo(
4028                 ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId());
4029         assertThat(mZenModeEventLogger.getChangedRuleType(3)).isEqualTo(
4030                 DNDProtoEnums.AUTOMATIC_RULE);
4031         int[] ruleTypes3 = mZenModeEventLogger.getActiveRuleTypes(3);
4032         assertThat(ruleTypes3.length).isEqualTo(2);
4033         assertThat(ruleTypes3[0]).isEqualTo(TYPE_IMMERSIVE);
4034         assertThat(ruleTypes3[1]).isEqualTo(ACTIVE_RULE_TYPE_MANUAL);
4035     }
4036 
4037     @Test
4038     @DisableFlags(FLAG_MODES_API)
testUpdateConsolidatedPolicy_preModesApiDefaultRulesOnly_takesGlobalDefault()4039     public void testUpdateConsolidatedPolicy_preModesApiDefaultRulesOnly_takesGlobalDefault() {
4040         setupZenConfig();
4041         // When there's one automatic rule active and it doesn't specify a policy, test that the
4042         // resulting consolidated policy is one that matches the default rule settings.
4043         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4044                 null,
4045                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4046                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4047                 null,
4048                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4049         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4050                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4051 
4052         // enable the rule
4053         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
4054                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
4055                 ORIGIN_SYSTEM, SYSTEM_UID);
4056 
4057         assertEquals(mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT),
4058                 mZenModeHelper.getConsolidatedNotificationPolicy());
4059 
4060         // inspect the consolidated policy. Based on setupZenConfig() values.
4061         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowAlarms());
4062         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowMedia());
4063         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowSystem());
4064         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowReminders());
4065         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowCalls());
4066         assertEquals(PRIORITY_SENDERS_STARRED, mZenModeHelper.mConsolidatedPolicy.allowCallsFrom());
4067         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowMessages());
4068         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowConversations());
4069         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers());
4070         assertFalse(mZenModeHelper.mConsolidatedPolicy.showBadges());
4071     }
4072 
4073     @Test
testUpdateConsolidatedPolicy_modesApiDefaultRulesOnly_takesDefault()4074     public void testUpdateConsolidatedPolicy_modesApiDefaultRulesOnly_takesDefault() {
4075         setupZenConfig();
4076 
4077         // When there's one automatic rule active and it doesn't specify a policy, test that the
4078         // resulting consolidated policy is one that matches the default *device* settings.
4079         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4080                 null,
4081                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4082                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4083                 null,  // null policy
4084                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4085         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4086                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4087 
4088         // enable the rule
4089         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
4090                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
4091                 ORIGIN_SYSTEM, SYSTEM_UID);
4092 
4093         // inspect the consolidated policy, which should match the device default settings.
4094         assertThat(ZenAdapters.notificationPolicyToZenPolicy(mZenModeHelper.mConsolidatedPolicy))
4095                 .isEqualTo(Flags.modesUi()
4096                         ? mZenModeHelper.getDefaultZenPolicy()
4097                         : mZenModeHelper.mConfig.getZenPolicy());
4098     }
4099 
4100     @Test
4101     @DisableFlags(FLAG_MODES_API)
testUpdateConsolidatedPolicy_preModesApiCustomPolicyOnly_fillInWithGlobal()4102     public void testUpdateConsolidatedPolicy_preModesApiCustomPolicyOnly_fillInWithGlobal() {
4103         setupZenConfig();
4104 
4105         // when there's only one automatic rule active and it has a custom policy, make sure that's
4106         // what the consolidated policy reflects whether or not it's stricter than what the global
4107         // config would specify.
4108         ZenPolicy customPolicy = new ZenPolicy.Builder()
4109                 .allowAlarms(true)  // more lenient than default
4110                 .allowMedia(true)  // more lenient than default
4111                 .allowRepeatCallers(false)  // more restrictive than default
4112                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)  // more restrictive than default
4113                 .showBadges(true)  // more lenient
4114                 .showPeeking(false)  // more restrictive
4115                 .build();
4116 
4117         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4118                 null,
4119                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4120                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4121                 customPolicy,
4122                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4123         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4124                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4125 
4126         // enable the rule; this will update the consolidated policy
4127         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
4128                 new Condition(zenRule.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM, SYSTEM_UID);
4129 
4130         // since this is the only active rule, the consolidated policy should match the custom
4131         // policy for every field specified, and take default values (from device default or
4132         // manual policy) for unspecified things
4133         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowAlarms());  // custom
4134         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowMedia());  // custom
4135         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowSystem());  // default
4136         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowReminders());  // default
4137         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowCalls());  // custom
4138         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowMessages()); // default
4139         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowConversations());  // default
4140         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers());  // custom
4141         assertTrue(mZenModeHelper.mConsolidatedPolicy.showBadges());  // custom
4142         assertFalse(mZenModeHelper.mConsolidatedPolicy.showPeeking());  // custom
4143     }
4144 
4145     @Test
4146     @EnableFlags(FLAG_MODES_API)
testUpdateConsolidatedPolicy_modesApiCustomPolicyOnly_fillInWithDefault()4147     public void testUpdateConsolidatedPolicy_modesApiCustomPolicyOnly_fillInWithDefault() {
4148         setupZenConfig();
4149 
4150         // when there's only one automatic rule active and it has a custom policy, make sure that's
4151         // what the consolidated policy reflects whether or not it's stricter than what the default
4152         // would specify.
4153         ZenPolicy customPolicy = new ZenPolicy.Builder()
4154                 .allowSystem(true)  // more lenient than default
4155                 .allowRepeatCallers(false)  // more restrictive than default
4156                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)  // more restrictive than default
4157                 .showFullScreenIntent(true)  // more lenient
4158                 .showBadges(false)  // more restrictive
4159                 .build();
4160 
4161         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4162                 null,
4163                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4164                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4165                 customPolicy,
4166                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4167         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4168                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4169 
4170         // enable the rule; this will update the consolidated policy
4171         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
4172                 new Condition(zenRule.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM, SYSTEM_UID);
4173 
4174         // since this is the only active rule, the consolidated policy should match the custom
4175         // policy for every field specified, and take default values (from either device default
4176         // policy or manual rule) for unspecified things
4177         assertThat(mZenModeHelper.mConsolidatedPolicy.allowAlarms()).isEqualTo(
4178                 Flags.modesUi() ? true : false);  // default
4179         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMedia()).isEqualTo(
4180                 Flags.modesUi() ? true : false);  // default
4181         assertThat(mZenModeHelper.mConsolidatedPolicy.allowSystem()).isTrue();  // custom
4182         assertThat(mZenModeHelper.mConsolidatedPolicy.allowReminders()).isEqualTo(
4183                 Flags.modesUi() ? false : true);  // default
4184         assertThat(mZenModeHelper.mConsolidatedPolicy.allowCalls()).isFalse();  // custom
4185         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMessages()).isTrue(); // default
4186         assertThat(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers()).isFalse();  // custom
4187         assertThat(mZenModeHelper.mConsolidatedPolicy.showBadges()).isFalse();  // custom
4188         assertThat(mZenModeHelper.mConsolidatedPolicy.showFullScreenIntents()).isTrue();  // custom
4189     }
4190 
4191     @Test
4192     @DisableFlags(FLAG_MODES_API)
testUpdateConsolidatedPolicy_preModesApiDefaultAndCustomActive_mergesWithGlobal()4193     public void testUpdateConsolidatedPolicy_preModesApiDefaultAndCustomActive_mergesWithGlobal() {
4194         setupZenConfig();
4195 
4196         // when there are two rules active, one inheriting the default policy and one setting its
4197         // own custom policy, they should be merged to form the most restrictive combination.
4198 
4199         // rule 1: no custom policy
4200         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4201                 null,
4202                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4203                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4204                 null,
4205                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4206         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4207                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4208 
4209         // enable rule 1
4210         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
4211                 new Condition(zenRule.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM, SYSTEM_UID);
4212 
4213         // custom policy for rule 2
4214         ZenPolicy customPolicy = new ZenPolicy.Builder()
4215                 .allowAlarms(true)  // more lenient than default
4216                 .allowMedia(true)  // more lenient than default
4217                 .allowRepeatCallers(false)  // more restrictive than default
4218                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)  // more restrictive than default
4219                 .showBadges(true)  // more lenient
4220                 .showPeeking(false)  // more restrictive
4221                 .build();
4222 
4223         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
4224                 null,
4225                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4226                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4227                 customPolicy,
4228                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4229         String id2 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4230                 mContext.getPackageName(), zenRule2, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4231 
4232         // enable rule 2; this will update the consolidated policy
4233         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id2,
4234                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
4235                 ORIGIN_SYSTEM, SYSTEM_UID);
4236 
4237         // now both rules should be on, and the consolidated policy should reflect the most
4238         // restrictive option of each of the two
4239         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowAlarms());  // default stricter
4240         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowMedia());  // default stricter
4241         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowSystem());  // default, unset in custom
4242         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowReminders());  // default
4243         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowCalls());  // custom stricter
4244         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowMessages()); // default, unset in custom
4245         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowConversations());  // default
4246         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers());  // custom stricter
4247         assertFalse(mZenModeHelper.mConsolidatedPolicy.showBadges());  // default stricter
4248         assertFalse(mZenModeHelper.mConsolidatedPolicy.showPeeking());  // custom stricter
4249     }
4250 
4251     @Test
4252     @EnableFlags(FLAG_MODES_API)
testUpdateConsolidatedPolicy_modesApiDefaultAndCustomActive_mergesWithDefault()4253     public void testUpdateConsolidatedPolicy_modesApiDefaultAndCustomActive_mergesWithDefault() {
4254         setupZenConfig();
4255 
4256         // when there are two rules active, one inheriting the default policy and one setting its
4257         // own custom policy, they should be merged to form the most restrictive combination.
4258 
4259         // rule 1: no custom policy
4260         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4261                 null,
4262                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4263                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4264                 null,
4265                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4266         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4267                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4268 
4269         // enable rule 1
4270         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
4271                 new Condition(zenRule.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM, SYSTEM_UID);
4272 
4273         // custom policy for rule 2
4274         ZenPolicy customPolicy = new ZenPolicy.Builder()
4275                 .allowAlarms(false) // more restrictive than default
4276                 .allowSystem(true)  // more lenient than default
4277                 .allowRepeatCallers(false)  // more restrictive than default
4278                 .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)  // more restrictive than default
4279                 .showBadges(false)  // more restrictive
4280                 .showPeeking(true)  // more lenient
4281                 .build();
4282 
4283         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
4284                 null,
4285                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4286                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4287                 customPolicy,
4288                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4289         String id2 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4290                 mContext.getPackageName(), zenRule2, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4291 
4292         // enable rule 2; this will update the consolidated policy
4293         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id2,
4294                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM,
4295                 SYSTEM_UID);
4296 
4297         // now both rules should be on, and the consolidated policy should reflect the most
4298         // restrictive option of each of the two
4299         assertThat(mZenModeHelper.mConsolidatedPolicy.allowAlarms()).isFalse();  // custom stricter
4300         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMedia()).isEqualTo(
4301                 Flags.modesUi() ? true : false);  // default
4302         assertThat(mZenModeHelper.mConsolidatedPolicy.allowSystem()).isFalse();  // default stricter
4303         assertThat(mZenModeHelper.mConsolidatedPolicy.allowReminders()).isEqualTo(
4304                 Flags.modesUi() ? false : true);  // default
4305         assertThat(mZenModeHelper.mConsolidatedPolicy.allowCalls()).isFalse();  // custom stricter
4306         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMessages()).isTrue(); // default
4307         assertThat(mZenModeHelper.mConsolidatedPolicy.allowConversations()).isTrue();  // default
4308         assertThat(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers())
4309                 .isFalse();  // custom stricter
4310         assertThat(mZenModeHelper.mConsolidatedPolicy.showBadges()).isFalse();  // custom stricter
4311         assertThat(mZenModeHelper.mConsolidatedPolicy.showPeeking()).isEqualTo(
4312                 Flags.modesUi() ? false : true);  // default
4313     }
4314 
4315     @Test
4316     @EnableFlags(FLAG_MODES_API)
testUpdateConsolidatedPolicy_allowChannels()4317     public void testUpdateConsolidatedPolicy_allowChannels() {
4318         setupZenConfig();
4319 
4320         // one rule, custom policy, allows channels
4321         ZenPolicy customPolicy = new ZenPolicy.Builder()
4322                 .allowPriorityChannels(true)
4323                 .build();
4324 
4325         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4326                 null,
4327                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4328                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4329                 customPolicy,
4330                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4331         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4332                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4333 
4334         // enable the rule; this will update the consolidated policy
4335         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id,
4336                 new Condition(zenRule.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM, SYSTEM_UID);
4337 
4338         // confirm that channels make it through
4339         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowPriorityChannels());
4340 
4341         // add new rule with policy that disallows channels
4342         ZenPolicy strictPolicy = new ZenPolicy.Builder()
4343                 .allowPriorityChannels(false)
4344                 .build();
4345 
4346         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
4347                 null,
4348                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4349                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4350                 strictPolicy,
4351                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4352         String id2 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4353                 mContext.getPackageName(), zenRule2, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4354 
4355         // enable rule 2; this will update the consolidated policy
4356         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id2,
4357                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM,
4358                 SYSTEM_UID);
4359 
4360         // rule 2 should override rule 1
4361         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowPriorityChannels());
4362     }
4363 
4364     @Test
4365     @EnableFlags(FLAG_MODES_API)
testUpdateConsolidatedPolicy_ignoresActiveRulesWithInterruptionFilterAll()4366     public void testUpdateConsolidatedPolicy_ignoresActiveRulesWithInterruptionFilterAll() {
4367         setupZenConfig();
4368 
4369         // Rules with INTERRUPTION_FILTER_ALL are skipped when calculating consolidated policy.
4370         // Note: rules with filter != PRIORITY should not have a custom policy. However, as of V
4371         // this is only validated on rule addition, but not on rule update. :/
4372 
4373         // Rule 1: PRIORITY, custom policy but not very strict (in fact, less strict than default).
4374         AutomaticZenRule zenRuleWithPriority = new AutomaticZenRule("Priority",
4375                 null,
4376                 new ComponentName(CUSTOM_PKG_NAME, "cls"),
4377                 Uri.parse("priority"),
4378                 new ZenPolicy.Builder()
4379                         .allowMedia(true)
4380                         .allowSystem(true)
4381                         .build(),
4382                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4383         String rule1Id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4384                 mContext.getPackageName(), zenRuleWithPriority, ORIGIN_APP, "test", CUSTOM_PKG_UID);
4385         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, rule1Id,
4386                 new Condition(zenRuleWithPriority.getConditionId(), "", STATE_TRUE),
4387                 ORIGIN_APP, CUSTOM_PKG_UID);
4388 
4389         // Rule 2: ALL, but somehow with a super strict ZenPolicy.
4390         AutomaticZenRule zenRuleWithAll = new AutomaticZenRule("All",
4391                 null,
4392                 new ComponentName(CUSTOM_PKG_NAME, "cls"),
4393                 Uri.parse("priority"),
4394                 new ZenPolicy.Builder().disallowAllSounds().build(),
4395                 NotificationManager.INTERRUPTION_FILTER_ALL, true);
4396         String rule2Id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4397                 mContext.getPackageName(), zenRuleWithAll, ORIGIN_APP, "test", CUSTOM_PKG_UID);
4398         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, rule2Id,
4399                 new Condition(zenRuleWithPriority.getConditionId(), "", STATE_TRUE),
4400                 ORIGIN_APP, CUSTOM_PKG_UID);
4401 
4402         // Consolidated Policy should be default + rule1.
4403         assertThat(mZenModeHelper.mConsolidatedPolicy.allowAlarms()).isEqualTo(
4404                 Flags.modesUi() ? true : false);  // default
4405         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMedia()).isTrue(); // priority rule
4406         assertThat(mZenModeHelper.mConsolidatedPolicy.allowSystem()).isTrue();  // priority rule
4407         assertThat(mZenModeHelper.mConsolidatedPolicy.allowReminders()).isEqualTo(
4408                 Flags.modesUi() ? false : true);  // default
4409         assertThat(mZenModeHelper.mConsolidatedPolicy.allowCalls()).isTrue();  // default
4410         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMessages()).isTrue(); // default
4411         assertThat(mZenModeHelper.mConsolidatedPolicy.allowConversations()).isTrue();  // default
4412         assertThat(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers()).isTrue(); // default
4413     }
4414 
4415     @Test
4416     @EnableFlags(FLAG_MODES_API)
zenRuleToAutomaticZenRule_allFields()4417     public void zenRuleToAutomaticZenRule_allFields() {
4418         when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
4419                 new String[]{OWNER.getPackageName()});
4420 
4421         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
4422         rule.configurationActivity = CONFIG_ACTIVITY;
4423         rule.component = OWNER;
4424         rule.conditionId = CONDITION_ID;
4425         rule.condition = CONDITION_TRUE;
4426         rule.enabled = ENABLED;
4427         rule.creationTime = 123;
4428         rule.id = "id";
4429         rule.zenMode = INTERRUPTION_FILTER_ZR;
4430         rule.modified = true;
4431         rule.name = NAME;
4432         rule.setConditionOverride(OVERRIDE_DEACTIVATE);
4433         rule.pkg = OWNER.getPackageName();
4434         rule.zenPolicy = POLICY;
4435 
4436         rule.allowManualInvocation = ALLOW_MANUAL;
4437         rule.type = TYPE;
4438         rule.iconResName = ICON_RES_NAME;
4439         rule.triggerDescription = TRIGGER_DESC;
4440 
4441         mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
4442         AutomaticZenRule actual = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, rule.id);
4443 
4444         assertEquals(NAME, actual.getName());
4445         assertEquals(OWNER, actual.getOwner());
4446         assertEquals(CONDITION_ID, actual.getConditionId());
4447         assertEquals(INTERRUPTION_FILTER_AZR, actual.getInterruptionFilter());
4448         assertEquals(ENABLED, actual.isEnabled());
4449         assertEquals(POLICY, actual.getZenPolicy());
4450         assertEquals(CONFIG_ACTIVITY, actual.getConfigurationActivity());
4451         assertEquals(TYPE, actual.getType());
4452         assertEquals(ALLOW_MANUAL, actual.isManualInvocationAllowed());
4453         assertEquals(CREATION_TIME, actual.getCreationTime());
4454         assertEquals(OWNER.getPackageName(), actual.getPackageName());
4455         assertEquals(ICON_RES_ID, actual.getIconResId());
4456         assertEquals(TRIGGER_DESC, actual.getTriggerDescription());
4457     }
4458 
4459     @Test
4460     @EnableFlags(FLAG_MODES_API)
automaticZenRuleToZenRule_allFields()4461     public void automaticZenRuleToZenRule_allFields() {
4462         when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
4463                 new String[]{OWNER.getPackageName()});
4464 
4465         AutomaticZenRule azr = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
4466                 .setEnabled(true)
4467                 .setConfigurationActivity(CONFIG_ACTIVITY)
4468                 .setTriggerDescription(TRIGGER_DESC)
4469                 .setCreationTime(CREATION_TIME)
4470                 .setIconResId(ICON_RES_ID)
4471                 .setZenPolicy(POLICY)
4472                 .setInterruptionFilter(INTERRUPTION_FILTER_AZR)
4473                 .setType(TYPE)
4474                 .setOwner(OWNER)
4475                 .setManualInvocationAllowed(ALLOW_MANUAL)
4476                 .build();
4477 
4478         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4479                 OWNER.getPackageName(), azr, ORIGIN_APP, "add", CUSTOM_PKG_UID);
4480 
4481         ZenModeConfig.ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
4482 
4483         assertThat(storedRule).isNotNull();
4484         assertEquals(NAME, storedRule.name);
4485         assertEquals(OWNER, storedRule.component);
4486         assertEquals(CONDITION_ID, storedRule.conditionId);
4487         assertEquals(INTERRUPTION_FILTER_ZR, storedRule.zenMode);
4488         assertEquals(ENABLED, storedRule.enabled);
4489         assertEquals(mZenModeHelper.getDefaultZenPolicy().overwrittenWith(POLICY),
4490                 storedRule.zenPolicy);
4491         assertEquals(CONFIG_ACTIVITY, storedRule.configurationActivity);
4492         assertEquals(TYPE, storedRule.type);
4493         assertEquals(ALLOW_MANUAL, storedRule.allowManualInvocation);
4494         assertEquals(OWNER.getPackageName(), storedRule.getPkg());
4495         assertEquals(ICON_RES_NAME, storedRule.iconResName);
4496         // Because the origin of the update is the app, we don't expect the bitmask to change.
4497         assertEquals(0, storedRule.userModifiedFields);
4498         assertEquals(TRIGGER_DESC, storedRule.triggerDescription);
4499     }
4500 
4501     @Test
4502     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_fromApp_updatesNameUnlessUserModified()4503     public void updateAutomaticZenRule_fromApp_updatesNameUnlessUserModified() {
4504         // Add a starting rule with the name OriginalName.
4505         AutomaticZenRule azrBase = new AutomaticZenRule.Builder("OriginalName", CONDITION_ID)
4506                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
4507                 .build();
4508         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4509                 mContext.getPackageName(), azrBase, ORIGIN_APP, "reason", SYSTEM_UID);
4510         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4511 
4512         // Checks the name can be changed by the app because the user has not modified it.
4513         AutomaticZenRule azrUpdate = new AutomaticZenRule.Builder(rule)
4514                 .setName("NewName")
4515                 .build();
4516         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azrUpdate, ORIGIN_APP,
4517                 "reason", SYSTEM_UID);
4518         rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4519         assertThat(rule.getName()).isEqualTo("NewName");
4520 
4521         // The user modifies some other field in the rule, which makes the rule as a whole not
4522         // app modifiable.
4523         azrUpdate = new AutomaticZenRule.Builder(rule)
4524                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
4525                 .build();
4526         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azrUpdate,
4527                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
4528 
4529         // ...but the app can still modify the name, because the name itself hasn't been modified
4530         // by the user.
4531         azrUpdate = new AutomaticZenRule.Builder(rule)
4532                 .setName("NewAppName")
4533                 .build();
4534         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azrUpdate, ORIGIN_APP,
4535                 "reason", SYSTEM_UID);
4536         rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4537         assertThat(rule.getName()).isEqualTo("NewAppName");
4538 
4539         // The user modifies the name.
4540         azrUpdate = new AutomaticZenRule.Builder(rule)
4541                 .setName("UserProvidedName")
4542                 .build();
4543         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azrUpdate,
4544                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
4545         rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4546         assertThat(rule.getName()).isEqualTo("UserProvidedName");
4547 
4548         // The app is no longer able to modify the name.
4549         azrUpdate = new AutomaticZenRule.Builder(rule)
4550                 .setName("NewAppName")
4551                 .build();
4552         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azrUpdate, ORIGIN_APP,
4553                 "reason", SYSTEM_UID);
4554         rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4555         assertThat(rule.getName()).isEqualTo("UserProvidedName");
4556     }
4557 
4558     @Test
4559     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_fromUser_updatesBitmaskAndValue()4560     public void updateAutomaticZenRule_fromUser_updatesBitmaskAndValue() {
4561         // Adds a starting rule with empty zen policies and device effects
4562         AutomaticZenRule azrBase = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
4563                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
4564                 .setZenPolicy(new ZenPolicy.Builder().build())
4565                 .setDeviceEffects(new ZenDeviceEffects.Builder().build())
4566                 .build();
4567         // Adds the rule using the app, to avoid having any user modified bits set.
4568         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4569                 mContext.getPackageName(), azrBase, ORIGIN_APP, "reason", SYSTEM_UID);
4570         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4571 
4572         // Modifies the filter, icon, zen policy, and device effects
4573         ZenPolicy policy = new ZenPolicy.Builder(rule.getZenPolicy())
4574                 .allowPriorityChannels(false)
4575                 .build();
4576         ZenDeviceEffects deviceEffects =
4577                 new ZenDeviceEffects.Builder(rule.getDeviceEffects())
4578                         .setShouldDisplayGrayscale(true)
4579                         .build();
4580         AutomaticZenRule azrUpdate = new AutomaticZenRule.Builder(rule)
4581                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
4582                 .setIconResId(ICON_RES_ID)
4583                 .setZenPolicy(policy)
4584                 .setDeviceEffects(deviceEffects)
4585                 .build();
4586 
4587         // Update the rule with the AZR from origin user.
4588         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azrUpdate,
4589                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
4590         rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4591 
4592         // UPDATE_ORIGIN_USER should change the bitmask and change the values.
4593         assertThat(rule.getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_PRIORITY);
4594         assertThat(rule.getIconResId()).isEqualTo(ICON_RES_ID);
4595         assertThat(rule.getZenPolicy().getPriorityChannelsAllowed()).isEqualTo(
4596                 STATE_DISALLOW);
4597 
4598         assertThat(rule.getDeviceEffects().shouldDisplayGrayscale()).isTrue();
4599 
4600         ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
4601         assertThat(storedRule.userModifiedFields)
4602                 .isEqualTo(Flags.modesUi()
4603                         ? AutomaticZenRule.FIELD_INTERRUPTION_FILTER | AutomaticZenRule.FIELD_ICON
4604                         : AutomaticZenRule.FIELD_INTERRUPTION_FILTER);
4605         assertThat(storedRule.zenPolicyUserModifiedFields)
4606                 .isEqualTo(ZenPolicy.FIELD_ALLOW_CHANNELS);
4607         assertThat(storedRule.zenDeviceEffectsUserModifiedFields)
4608                 .isEqualTo(ZenDeviceEffects.FIELD_GRAYSCALE);
4609     }
4610 
4611     @Test
4612     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_fromSystemUi_updatesValues()4613     public void updateAutomaticZenRule_fromSystemUi_updatesValues() {
4614         // Adds a starting rule with empty zen policies and device effects
4615         AutomaticZenRule azrBase = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
4616                 .setInterruptionFilter(INTERRUPTION_FILTER_ALL)
4617                 .setZenPolicy(new ZenPolicy.Builder()
4618                         .allowReminders(false)
4619                         .build())
4620                 .setDeviceEffects(new ZenDeviceEffects.Builder()
4621                         .setShouldDisplayGrayscale(false)
4622                         .build())
4623                 .build();
4624         // Adds the rule using the app, to avoid having any user modified bits set.
4625         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4626                 mContext.getPackageName(), azrBase, ORIGIN_APP, "reason", SYSTEM_UID);
4627         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4628 
4629         // Modifies the icon, zen policy and device effects
4630         ZenPolicy policy = new ZenPolicy.Builder(rule.getZenPolicy())
4631                 .allowReminders(true)
4632                 .build();
4633         ZenDeviceEffects deviceEffects =
4634                 new ZenDeviceEffects.Builder(rule.getDeviceEffects())
4635                         .setShouldDisplayGrayscale(true)
4636                         .build();
4637         AutomaticZenRule azrUpdate = new AutomaticZenRule.Builder(rule)
4638                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
4639                 .setIconResId(ICON_RES_ID)
4640                 .setZenPolicy(policy)
4641                 .setDeviceEffects(deviceEffects)
4642                 .build();
4643 
4644         // Update the rule with the AZR from origin systemUI.
4645         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azrUpdate, ORIGIN_SYSTEM,
4646                 "reason", SYSTEM_UID);
4647         rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4648 
4649         // UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI should change the value but NOT update the bitmask.
4650         assertThat(rule.getIconResId()).isEqualTo(ICON_RES_ID);
4651         assertThat(rule.getZenPolicy().getPriorityCategoryReminders())
4652                 .isEqualTo(STATE_ALLOW);
4653         assertThat(rule.getDeviceEffects().shouldDisplayGrayscale()).isTrue();
4654 
4655         ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
4656         assertThat(storedRule.userModifiedFields).isEqualTo(0);
4657         assertThat(storedRule.zenPolicyUserModifiedFields).isEqualTo(0);
4658         assertThat(storedRule.zenDeviceEffectsUserModifiedFields).isEqualTo(0);
4659     }
4660 
4661     @Test
4662     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_fromApp_updatesValuesIfRuleNotUserModified()4663     public void updateAutomaticZenRule_fromApp_updatesValuesIfRuleNotUserModified() {
4664         // Adds a starting rule with empty zen policies and device effects
4665         AutomaticZenRule azrBase = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
4666                 .setInterruptionFilter(INTERRUPTION_FILTER_ALL)
4667                 .setZenPolicy(new ZenPolicy.Builder()
4668                         .allowReminders(false)
4669                         .build())
4670                 .setDeviceEffects(new ZenDeviceEffects.Builder()
4671                         .setShouldDisplayGrayscale(false)
4672                         .build())
4673                 .build();
4674         // Adds the rule using the app, to avoid having any user modified bits set.
4675         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4676                 mContext.getPackageName(), azrBase, ORIGIN_APP, "reason", SYSTEM_UID);
4677         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4678 
4679         ZenPolicy policy = new ZenPolicy.Builder()
4680                 .allowReminders(true)
4681                 .build();
4682         ZenDeviceEffects deviceEffects = new ZenDeviceEffects.Builder()
4683                 .setShouldDisplayGrayscale(true)
4684                 .build();
4685         AutomaticZenRule azrUpdate = new AutomaticZenRule.Builder(rule)
4686                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
4687                 .setZenPolicy(policy)
4688                 .setDeviceEffects(deviceEffects)
4689                 .build();
4690 
4691         // Since the rule is not already user modified, UPDATE_ORIGIN_APP can modify the rule.
4692         // The bitmask is not modified.
4693         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azrUpdate, ORIGIN_APP,
4694                 "reason", SYSTEM_UID);
4695 
4696         ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
4697         assertThat(storedRule.userModifiedFields).isEqualTo(0);
4698 
4699         assertThat(storedRule.zenMode).isEqualTo(ZEN_MODE_ALARMS);
4700         assertThat(storedRule.zenPolicy.getPriorityCategoryReminders())
4701                 .isEqualTo(STATE_ALLOW);
4702         assertThat(storedRule.zenDeviceEffects.shouldDisplayGrayscale()).isTrue();
4703         assertThat(storedRule.userModifiedFields).isEqualTo(0);
4704         assertThat(storedRule.zenPolicyUserModifiedFields).isEqualTo(0);
4705         assertThat(storedRule.zenDeviceEffectsUserModifiedFields).isEqualTo(0);
4706 
4707         // Creates another rule, this time from user. This will have user modified bits set.
4708         String ruleIdUser = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4709                 mContext.getPackageName(), azrBase, ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
4710         storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleIdUser);
4711         int ruleModifiedFields = storedRule.userModifiedFields;
4712         int rulePolicyModifiedFields = storedRule.zenPolicyUserModifiedFields;
4713         int ruleDeviceEffectsModifiedFields = storedRule.zenDeviceEffectsUserModifiedFields;
4714 
4715         // Zen rule update coming from the app again. This cannot fully update the rule, because
4716         // the rule is already considered user modified.
4717         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleIdUser, azrUpdate, ORIGIN_APP,
4718                 "reason", SYSTEM_UID);
4719         AutomaticZenRule ruleUser = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT,
4720                 ruleIdUser);
4721 
4722         // The app can only change the value if the rule is not already user modified,
4723         // so the rule is not changed, and neither is the bitmask.
4724         assertThat(ruleUser.getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALL);
4725         assertThat(ruleUser.getZenPolicy().getPriorityCategoryReminders())
4726                 .isEqualTo(STATE_DISALLOW);
4727         assertThat(ruleUser.getDeviceEffects().shouldDisplayGrayscale()).isFalse();
4728 
4729         storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleIdUser);
4730         assertThat(storedRule.userModifiedFields).isEqualTo(ruleModifiedFields);
4731         assertThat(storedRule.zenPolicyUserModifiedFields).isEqualTo(rulePolicyModifiedFields);
4732         assertThat(storedRule.zenDeviceEffectsUserModifiedFields).isEqualTo(
4733                 ruleDeviceEffectsModifiedFields);
4734     }
4735 
4736     @Test
4737     @EnableFlags(FLAG_MODES_API)
addAutomaticZenRule_updatesValues()4738     public void addAutomaticZenRule_updatesValues() {
4739         // Adds a starting rule with empty zen policies and device effects
4740         AutomaticZenRule azrBase = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
4741                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
4742                 .setZenPolicy(new ZenPolicy.Builder()
4743                         .allowReminders(true)
4744                         .build())
4745                 .setDeviceEffects(new ZenDeviceEffects.Builder()
4746                         .setShouldDisplayGrayscale(true)
4747                         .build())
4748                 .build();
4749         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4750                 mContext.getPackageName(), azrBase, ORIGIN_APP, "reason", SYSTEM_UID);
4751         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4752 
4753         // The values are modified but the bitmask is not.
4754         assertThat(rule.getZenPolicy().getPriorityCategoryReminders())
4755                 .isEqualTo(STATE_ALLOW);
4756         assertThat(rule.getDeviceEffects().shouldDisplayGrayscale()).isTrue();
4757 
4758         ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
4759         assertThat(storedRule.canBeUpdatedByApp()).isTrue();
4760     }
4761 
4762     @Test
4763     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_nullDeviceEffectsUpdate()4764     public void updateAutomaticZenRule_nullDeviceEffectsUpdate() {
4765         // Adds a starting rule with empty zen policies and device effects
4766         ZenDeviceEffects zde = new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build();
4767         AutomaticZenRule azrBase = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
4768                 .setDeviceEffects(zde)
4769                 .build();
4770         // Adds the rule using the app, to avoid having any user modified bits set.
4771         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4772                 mContext.getPackageName(), azrBase, ORIGIN_APP, "reason", SYSTEM_UID);
4773 
4774         AutomaticZenRule azr = new AutomaticZenRule.Builder(azrBase)
4775                 // Sets Device Effects to null
4776                 .setDeviceEffects(null)
4777                 .build();
4778 
4779         // Zen rule update coming from app, but since the rule isn't already
4780         // user modified, it can be updated.
4781         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azr, ORIGIN_APP, "reason",
4782                 SYSTEM_UID);
4783         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4784 
4785         // When AZR's ZenDeviceEffects is null, the updated rule's device effects are kept.
4786         assertThat(rule.getDeviceEffects()).isEqualTo(zde);
4787     }
4788 
4789     @Test
4790     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_nullPolicyUpdate()4791     public void updateAutomaticZenRule_nullPolicyUpdate() {
4792         // Adds a starting rule with set zen policy and empty device effects
4793         AutomaticZenRule azrBase = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
4794                 .setZenPolicy(POLICY)
4795                 .build();
4796         // Adds the rule using the app, to avoid having any user modified bits set.
4797         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4798                 mContext.getPackageName(), azrBase, ORIGIN_APP, "reason", SYSTEM_UID);
4799         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4800 
4801         AutomaticZenRule azr = new AutomaticZenRule.Builder(azrBase)
4802                 // Set zen policy to null
4803                 .setZenPolicy(null)
4804                 .build();
4805 
4806         // Zen rule update coming from app, but since the rule isn't already
4807         // user modified, it can be updated.
4808         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azr, ORIGIN_APP, "reason",
4809                 SYSTEM_UID);
4810         rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4811 
4812         // When AZR's ZenPolicy is null, we expect the updated rule's policy to be unchanged
4813         // (equivalent to the provided policy, with additional fields filled in with defaults).
4814         assertThat(rule.getZenPolicy()).isEqualTo(
4815                 mZenModeHelper.getDefaultZenPolicy().overwrittenWith(POLICY));
4816     }
4817 
4818     @Test
4819     @EnableFlags(FLAG_MODES_API)
automaticZenRuleToZenRule_nullToNonNullPolicyUpdate()4820     public void automaticZenRuleToZenRule_nullToNonNullPolicyUpdate() {
4821         when(mContext.checkCallingPermission(anyString()))
4822                 .thenReturn(PackageManager.PERMISSION_GRANTED);
4823         // Adds a starting rule with empty zen policies and device effects
4824         AutomaticZenRule azrBase = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
4825                 .setZenPolicy(null)
4826                 // .setDeviceEffects(new ZenDeviceEffects.Builder().build())
4827                 .build();
4828         // Adds the rule using the app, to avoid having any user modified bits set.
4829         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4830                 mContext.getPackageName(), azrBase, ORIGIN_APP, "reason", SYSTEM_UID);
4831         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4832 
4833         // Create a fully populated ZenPolicy.
4834         ZenPolicy policy = new ZenPolicy.Builder()
4835                 .allowPriorityChannels(false) // Differs from the default
4836                 .allowReminders(true) // Differs from the default
4837                 .allowEvents(true) // Differs from the default
4838                 .allowConversations(ZenPolicy.CONVERSATION_SENDERS_IMPORTANT)
4839                 .allowMessages(PEOPLE_TYPE_STARRED)
4840                 .allowCalls(PEOPLE_TYPE_STARRED)
4841                 .allowRepeatCallers(true)
4842                 .allowAlarms(true)
4843                 .allowMedia(true)
4844                 .allowSystem(true) // Differs from the default
4845                 .showFullScreenIntent(true) // Differs from the default
4846                 .showLights(true) // Differs from the default
4847                 .showPeeking(true) // Differs from the default
4848                 .showStatusBarIcons(true)
4849                 .showBadges(true)
4850                 .showInAmbientDisplay(true) // Differs from the default
4851                 .showInNotificationList(true)
4852                 .build();
4853         AutomaticZenRule azr = new AutomaticZenRule.Builder(azrBase)
4854                 .setZenPolicy(policy)
4855                 .build();
4856 
4857         // Applies the update to the rule.
4858         // Default config defined in getDefaultConfigParser() is used as the original rule.
4859         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azr,
4860                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
4861         rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4862 
4863         // New ZenPolicy differs from the default config
4864         assertThat(rule.getZenPolicy()).isNotNull();
4865         assertThat(rule.getZenPolicy().getPriorityChannelsAllowed()).isEqualTo(
4866                 STATE_DISALLOW);
4867 
4868         ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
4869         assertThat(storedRule.canBeUpdatedByApp()).isFalse();
4870         assertThat(storedRule.zenPolicyUserModifiedFields).isEqualTo(
4871                 ZenPolicy.FIELD_ALLOW_CHANNELS
4872                         | ZenPolicy.FIELD_PRIORITY_CATEGORY_REMINDERS
4873                         | ZenPolicy.FIELD_PRIORITY_CATEGORY_EVENTS
4874                         | ZenPolicy.FIELD_PRIORITY_CATEGORY_SYSTEM
4875                         | ZenPolicy.FIELD_VISUAL_EFFECT_FULL_SCREEN_INTENT
4876                         | ZenPolicy.FIELD_VISUAL_EFFECT_LIGHTS
4877                         | ZenPolicy.FIELD_VISUAL_EFFECT_PEEK
4878                         | ZenPolicy.FIELD_VISUAL_EFFECT_AMBIENT
4879         );
4880     }
4881 
4882     @Test
4883     @EnableFlags(FLAG_MODES_API)
automaticZenRuleToZenRule_nullToNonNullDeviceEffectsUpdate()4884     public void automaticZenRuleToZenRule_nullToNonNullDeviceEffectsUpdate() {
4885         // Adds a starting rule with empty zen policies and device effects
4886         AutomaticZenRule azrBase = new AutomaticZenRule.Builder(NAME, CONDITION_ID)
4887                 .setDeviceEffects(null)
4888                 .build();
4889         // Adds the rule using the app, to avoid having any user modified bits set.
4890         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4891                 mContext.getPackageName(), azrBase, ORIGIN_APP, "reason", SYSTEM_UID);
4892         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4893 
4894         ZenDeviceEffects deviceEffects = new ZenDeviceEffects.Builder()
4895                 .setShouldDisplayGrayscale(true)
4896                 .build();
4897         AutomaticZenRule azr = new AutomaticZenRule.Builder(rule)
4898                 .setDeviceEffects(deviceEffects)
4899                 .build();
4900 
4901         // Applies the update to the rule.
4902         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, azr,
4903                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
4904         rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
4905 
4906         // New ZenDeviceEffects is used; all fields considered set, since previously were null.
4907         assertThat(rule.getDeviceEffects()).isNotNull();
4908         assertThat(rule.getDeviceEffects().shouldDisplayGrayscale()).isTrue();
4909 
4910         ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
4911         assertThat(storedRule.canBeUpdatedByApp()).isFalse();
4912         assertThat(storedRule.zenDeviceEffectsUserModifiedFields).isEqualTo(
4913                 ZenDeviceEffects.FIELD_GRAYSCALE);
4914     }
4915 
4916     @Test
testUpdateAutomaticRule_disabled_triggersBroadcast()4917     public void testUpdateAutomaticRule_disabled_triggersBroadcast() throws Exception {
4918         setupZenConfig();
4919 
4920         // Add a new automatic zen rule that's enabled
4921         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4922                 null,
4923                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4924                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4925                 null,
4926                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4927         final String createdId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4928                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4929 
4930         CountDownLatch latch = new CountDownLatch(1);
4931         final int[] actualStatus = new int[1];
4932         ZenModeHelper.Callback callback = new ZenModeHelper.Callback() {
4933             @Override
4934             void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) {
4935                 if (Objects.equals(createdId, id)) {
4936                     actualStatus[0] = status;
4937                     latch.countDown();
4938                 }
4939             }
4940         };
4941         mZenModeHelper.addCallback(callback);
4942 
4943         zenRule.setEnabled(false);
4944         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, createdId, zenRule, ORIGIN_SYSTEM,
4945                 "", SYSTEM_UID);
4946 
4947         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
4948         assertEquals(AUTOMATIC_RULE_STATUS_DISABLED, actualStatus[0]);
4949     }
4950 
4951     @Test
testUpdateAutomaticRule_enabled_triggersBroadcast()4952     public void testUpdateAutomaticRule_enabled_triggersBroadcast() throws Exception {
4953         setupZenConfig();
4954 
4955         // Add a new automatic zen rule that's enabled
4956         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4957                 null,
4958                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4959                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4960                 null,
4961                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, false);
4962         final String createdId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4963                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
4964 
4965         CountDownLatch latch = new CountDownLatch(1);
4966         final int[] actualStatus = new int[1];
4967         ZenModeHelper.Callback callback = new ZenModeHelper.Callback() {
4968             @Override
4969             void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) {
4970                 if (Objects.equals(createdId, id)) {
4971                     actualStatus[0] = status;
4972                     latch.countDown();
4973                 }
4974             }
4975         };
4976         mZenModeHelper.addCallback(callback);
4977 
4978         zenRule.setEnabled(true);
4979         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, createdId, zenRule, ORIGIN_SYSTEM,
4980                 "", SYSTEM_UID);
4981 
4982         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
4983         assertEquals(AUTOMATIC_RULE_STATUS_ENABLED, actualStatus[0]);
4984     }
4985 
4986     @Test
4987     @EnableFlags(FLAG_MODES_API)
testUpdateAutomaticRule_activated_triggersBroadcast()4988     public void testUpdateAutomaticRule_activated_triggersBroadcast() throws Exception {
4989         setupZenConfig();
4990 
4991         // Add a new automatic zen rule that's enabled
4992         AutomaticZenRule zenRule = new AutomaticZenRule("name",
4993                 null,
4994                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
4995                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
4996                 null,
4997                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
4998         final String createdId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
4999                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
5000 
5001         CountDownLatch latch = new CountDownLatch(1);
5002         final int[] actualStatus = new int[1];
5003         ZenModeHelper.Callback callback = new ZenModeHelper.Callback() {
5004             @Override
5005             void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) {
5006                 if (Objects.equals(createdId, id)) {
5007                     actualStatus[0] = status;
5008                     latch.countDown();
5009                 }
5010             }
5011         };
5012         mZenModeHelper.addCallback(callback);
5013 
5014         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, createdId,
5015                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
5016                 ORIGIN_SYSTEM, SYSTEM_UID);
5017 
5018         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
5019         if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) {
5020             assertEquals(AUTOMATIC_RULE_STATUS_ACTIVATED, actualStatus[0]);
5021         } else {
5022             assertEquals(AUTOMATIC_RULE_STATUS_UNKNOWN, actualStatus[0]);
5023         }
5024     }
5025 
5026     @Test
5027     @EnableFlags(FLAG_MODES_API)
testUpdateAutomaticRule_deactivatedByUser_triggersBroadcast()5028     public void testUpdateAutomaticRule_deactivatedByUser_triggersBroadcast() throws Exception {
5029         setupZenConfig();
5030 
5031         // Add a new automatic zen rule that's enabled
5032         AutomaticZenRule zenRule = new AutomaticZenRule("name",
5033                 null,
5034                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
5035                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
5036                 null,
5037                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
5038         final String createdId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5039                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
5040 
5041         CountDownLatch latch = new CountDownLatch(1);
5042         final int[] actualStatus = new int[2];
5043         ZenModeHelper.Callback callback = new ZenModeHelper.Callback() {
5044             int i = 0;
5045 
5046             @Override
5047             void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) {
5048                 if (Objects.equals(createdId, id)) {
5049                     actualStatus[i++] = status;
5050                     latch.countDown();
5051                 }
5052             }
5053         };
5054         mZenModeHelper.addCallback(callback);
5055 
5056         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, createdId,
5057                 new Condition(zenRule.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM, SYSTEM_UID);
5058 
5059         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, Global.ZEN_MODE_OFF, null,
5060                 ORIGIN_SYSTEM, null, "", SYSTEM_UID);
5061 
5062         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
5063         if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) {
5064             assertEquals(AUTOMATIC_RULE_STATUS_DEACTIVATED, actualStatus[1]);
5065         } else {
5066             assertEquals(AUTOMATIC_RULE_STATUS_UNKNOWN, actualStatus[1]);
5067         }
5068     }
5069 
5070     @Test
5071     @EnableFlags(FLAG_MODES_API)
testUpdateAutomaticRule_deactivatedByApp_triggersBroadcast()5072     public void testUpdateAutomaticRule_deactivatedByApp_triggersBroadcast() throws Exception {
5073         setupZenConfig();
5074 
5075         // Add a new automatic zen rule that's enabled
5076         AutomaticZenRule zenRule = new AutomaticZenRule("name",
5077                 null,
5078                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
5079                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
5080                 null,
5081                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
5082         final String createdId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5083                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
5084 
5085         CountDownLatch latch = new CountDownLatch(1);
5086         final int[] actualStatus = new int[2];
5087         ZenModeHelper.Callback callback = new ZenModeHelper.Callback() {
5088             int i = 0;
5089 
5090             @Override
5091             void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) {
5092                 if (Objects.equals(createdId, id)) {
5093                     actualStatus[i++] = status;
5094                     latch.countDown();
5095                 }
5096             }
5097         };
5098         mZenModeHelper.addCallback(callback);
5099 
5100         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, createdId,
5101                 new Condition(zenRule.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM, SYSTEM_UID);
5102 
5103         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, createdId,
5104                 new Condition(zenRule.getConditionId(), "", STATE_FALSE), ORIGIN_APP,
5105                 CUSTOM_PKG_UID);
5106 
5107         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
5108         if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) {
5109             assertEquals(AUTOMATIC_RULE_STATUS_DEACTIVATED, actualStatus[1]);
5110         } else {
5111             assertEquals(AUTOMATIC_RULE_STATUS_UNKNOWN, actualStatus[1]);
5112         }
5113     }
5114 
5115     @Test
testUpdateAutomaticRule_unsnoozes()5116     public void testUpdateAutomaticRule_unsnoozes() throws IllegalArgumentException {
5117         setupZenConfig();
5118 
5119         // Add a new automatic zen rule that's enabled
5120         AutomaticZenRule zenRule = new AutomaticZenRule("name",
5121                 null,
5122                 new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
5123                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
5124                 null,
5125                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
5126         final String createdId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5127                 mContext.getPackageName(), zenRule, ORIGIN_SYSTEM, "test", SYSTEM_UID);
5128 
5129         // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE
5130         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, createdId,
5131                 new Condition(zenRule.getConditionId(), "", STATE_TRUE), ORIGIN_SYSTEM, SYSTEM_UID);
5132 
5133         // Event 2: Snooze rule by turning off DND
5134         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, Global.ZEN_MODE_OFF, null,
5135                 ORIGIN_SYSTEM, "", null, SYSTEM_UID);
5136 
5137         // Event 3: "User" turns off the automatic rule (sets it to not enabled)
5138         zenRule.setEnabled(false);
5139         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, createdId, zenRule, ORIGIN_SYSTEM,
5140                 "", SYSTEM_UID);
5141 
5142         assertEquals(OVERRIDE_NONE,
5143                 mZenModeHelper.mConfig.automaticRules.get(createdId).getConditionOverride());
5144     }
5145 
5146     @Test
5147     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_ruleChanged_deactivatesRule()5148     public void updateAutomaticZenRule_ruleChanged_deactivatesRule() {
5149         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5150         AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", CONDITION_ID)
5151                 .setConfigurationActivity(new ComponentName(mPkg, "cls"))
5152                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5153                 .build();
5154         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
5155                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
5156         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5157                 ORIGIN_APP, CUSTOM_PKG_UID);
5158         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
5159 
5160         AutomaticZenRule updateWithDiff = new AutomaticZenRule.Builder(rule)
5161                 .setTriggerDescription("Whenever")
5162                 .build();
5163         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, updateWithDiff,
5164                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
5165 
5166         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5167         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).condition).isNull();
5168     }
5169 
5170     @Test
5171     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_ruleNotChanged_doesNotDeactivateRule()5172     public void updateAutomaticZenRule_ruleNotChanged_doesNotDeactivateRule() {
5173         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5174         AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", CONDITION_ID)
5175                 .setConfigurationActivity(new ComponentName(mPkg, "cls"))
5176                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5177                 .build();
5178         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
5179                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
5180         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5181                 ORIGIN_APP, CUSTOM_PKG_UID);
5182         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
5183 
5184         AutomaticZenRule updateUnchanged = new AutomaticZenRule.Builder(rule).build();
5185         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, updateUnchanged,
5186                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
5187 
5188         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
5189         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).condition).isEqualTo(
5190                 CONDITION_TRUE);
5191     }
5192 
5193     @Test
5194     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
updateAutomaticZenRule_ruleChangedByUser_doesNotDeactivateRule()5195     public void updateAutomaticZenRule_ruleChangedByUser_doesNotDeactivateRule() {
5196         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5197         AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", CONDITION_ID)
5198                 .setConfigurationActivity(new ComponentName(mPkg, "cls"))
5199                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5200                 .build();
5201         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
5202                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
5203         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5204                 ORIGIN_APP, CUSTOM_PKG_UID);
5205         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
5206 
5207         AutomaticZenRule updateWithDiff = new AutomaticZenRule.Builder(rule)
5208                 .setTriggerDescription("Whenever")
5209                 .build();
5210         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, updateWithDiff,
5211                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
5212 
5213         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
5214         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).condition).isEqualTo(
5215                 CONDITION_TRUE);
5216     }
5217 
5218     @Test
5219     @EnableFlags(FLAG_MODES_API)
updateAutomaticZenRule_ruleChangedByUser_doesNotDeactivateRule_forWatch()5220     public void updateAutomaticZenRule_ruleChangedByUser_doesNotDeactivateRule_forWatch() {
5221         when(mContext.getPackageManager()).thenReturn(mPackageManager);
5222         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)).thenReturn(true);
5223         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5224         AutomaticZenRule rule =
5225                 new AutomaticZenRule.Builder("rule", CONDITION_ID)
5226                         .setConfigurationActivity(new ComponentName(mPkg, "cls"))
5227                         .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5228                         .build();
5229         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
5230                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
5231         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5232                 ORIGIN_APP, CUSTOM_PKG_UID);
5233         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
5234 
5235         AutomaticZenRule updateWithDiff =
5236                 new AutomaticZenRule.Builder(rule).setTriggerDescription("Whenever").build();
5237         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, updateWithDiff,
5238                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
5239 
5240         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
5241         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).condition).isEqualTo(
5242                 CONDITION_TRUE);
5243     }
5244 
5245     @Test
5246     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
updateAutomaticZenRule_ruleDisabledByUser_doesNotReactivateOnReenable()5247     public void updateAutomaticZenRule_ruleDisabledByUser_doesNotReactivateOnReenable() {
5248         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5249         AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", CONDITION_ID)
5250                 .setConfigurationActivity(new ComponentName(mPkg, "cls"))
5251                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5252                 .build();
5253         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
5254                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
5255         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5256                 ORIGIN_APP, CUSTOM_PKG_UID);
5257         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
5258 
5259         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
5260                 new AutomaticZenRule.Builder(rule).setEnabled(false).build(),
5261                 ORIGIN_USER_IN_SYSTEMUI, "disable", SYSTEM_UID);
5262         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
5263                 new AutomaticZenRule.Builder(rule).setEnabled(true).build(),
5264                 ORIGIN_USER_IN_SYSTEMUI, "enable", SYSTEM_UID);
5265 
5266         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5267         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).condition).isNull();
5268     }
5269 
5270     @Test
5271     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
updateAutomaticZenRule_changeOwnerForSystemRule_allowed()5272     public void updateAutomaticZenRule_changeOwnerForSystemRule_allowed() {
5273         when(mContext.checkCallingPermission(anyString()))
5274                 .thenReturn(PackageManager.PERMISSION_GRANTED);
5275         AutomaticZenRule original = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
5276                 .setOwner(new ComponentName("android", "some.old.cps"))
5277                 .build();
5278         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "android", original,
5279                 ORIGIN_SYSTEM, "reason", SYSTEM_UID);
5280 
5281         AutomaticZenRule update = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
5282                 .setOwner(new ComponentName("android", "brand.new.cps"))
5283                 .build();
5284         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, update,
5285                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
5286 
5287         AutomaticZenRule result = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
5288         assertThat(result).isNotNull();
5289         assertThat(result.getOwner().getClassName()).isEqualTo("brand.new.cps");
5290     }
5291 
5292     @Test
5293     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
updateAutomaticZenRule_changeOwnerForAppOwnedRule_ignored()5294     public void updateAutomaticZenRule_changeOwnerForAppOwnedRule_ignored() {
5295         AutomaticZenRule original = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
5296                 .setOwner(new ComponentName(mContext.getPackageName(), "old.third.party.cps"))
5297                 .build();
5298         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5299                 mContext.getPackageName(), original, ORIGIN_APP, "reason", CUSTOM_PKG_UID);
5300 
5301         AutomaticZenRule update = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
5302                 .setOwner(new ComponentName(mContext.getPackageName(), "new.third.party.cps"))
5303                 .build();
5304         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, update,
5305                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
5306 
5307         AutomaticZenRule result = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
5308         assertThat(result).isNotNull();
5309         assertThat(result.getOwner().getClassName()).isEqualTo("old.third.party.cps");
5310     }
5311 
5312     @Test
5313     @EnableFlags(FLAG_MODES_API)
removeAutomaticZenRule_propagatesOriginToEffectsApplier()5314     public void removeAutomaticZenRule_propagatesOriginToEffectsApplier() {
5315         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
5316         reset(mDeviceEffectsApplier);
5317 
5318         String ruleId = addRuleWithEffects(new ZenDeviceEffects.Builder()
5319                 .setShouldSuppressAmbientDisplay(true)
5320                 .setShouldDimWallpaper(true)
5321                 .build());
5322         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5323                 ORIGIN_APP, CUSTOM_PKG_UID);
5324         mTestableLooper.processAllMessages();
5325         verify(mDeviceEffectsApplier).apply(any(), eq(ORIGIN_APP));
5326 
5327         // Now delete the (currently active!) rule. For example, assume this is done from settings.
5328         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, ruleId, ORIGIN_USER_IN_SYSTEMUI,
5329                 "remove", SYSTEM_UID);
5330         mTestableLooper.processAllMessages();
5331 
5332         verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_USER_IN_SYSTEMUI));
5333     }
5334 
5335     @Test
5336     @EnableFlags(FLAG_MODES_API)
testDeviceEffects_applied()5337     public void testDeviceEffects_applied() {
5338         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
5339         verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_INIT));
5340 
5341         ZenDeviceEffects effects = new ZenDeviceEffects.Builder()
5342                 .setShouldSuppressAmbientDisplay(true)
5343                 .setShouldDimWallpaper(true)
5344                 .build();
5345         String ruleId = addRuleWithEffects(effects);
5346         verifyNoMoreInteractions(mDeviceEffectsApplier);
5347 
5348         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5349                 ORIGIN_APP, CUSTOM_PKG_UID);
5350         mTestableLooper.processAllMessages();
5351 
5352         verify(mDeviceEffectsApplier).apply(eq(effects), eq(ORIGIN_APP));
5353         assertTrue(mZenModeHelper.hasDeviceEffectsApplier());
5354     }
5355 
5356     @Test
testHasDeviceEffectsApplier_returnsFalseIfNotSet()5357     public void testHasDeviceEffectsApplier_returnsFalseIfNotSet() {
5358         assertFalse(mZenModeHelper.hasDeviceEffectsApplier());
5359     }
5360 
5361     @Test
5362     @EnableFlags(FLAG_MODES_API)
testSettingDeviceEffects_throwsExceptionIfAlreadySet()5363     public void testSettingDeviceEffects_throwsExceptionIfAlreadySet() {
5364         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
5365 
5366         assertThrows(
5367                 IllegalStateException.class,
5368                 () -> mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier));
5369     }
5370 
5371     @Test
5372     @EnableFlags(FLAG_MODES_API)
testDeviceEffects_onDeactivateRule_applied()5373     public void testDeviceEffects_onDeactivateRule_applied() {
5374         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
5375 
5376         ZenDeviceEffects zde = new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build();
5377         String ruleId = addRuleWithEffects(zde);
5378         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5379                 ORIGIN_APP, CUSTOM_PKG_UID);
5380         mTestableLooper.processAllMessages();
5381         verify(mDeviceEffectsApplier).apply(eq(zde), eq(ORIGIN_APP));
5382 
5383         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_FALSE,
5384                 ORIGIN_APP, CUSTOM_PKG_UID);
5385         mTestableLooper.processAllMessages();
5386 
5387         verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_APP));
5388     }
5389 
5390     @Test
5391     @EnableFlags(FLAG_MODES_API)
testDeviceEffects_changeToConsolidatedEffects_applied()5392     public void testDeviceEffects_changeToConsolidatedEffects_applied() {
5393         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
5394         verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_INIT));
5395 
5396         String ruleId = addRuleWithEffects(
5397                 new ZenDeviceEffects.Builder()
5398                         .setShouldDisplayGrayscale(true)
5399                         .addExtraEffect("ONE")
5400                         .build());
5401         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5402                 ORIGIN_APP, CUSTOM_PKG_UID);
5403         mTestableLooper.processAllMessages();
5404         verify(mDeviceEffectsApplier).apply(
5405                 eq(new ZenDeviceEffects.Builder()
5406                         .setShouldDisplayGrayscale(true)
5407                         .addExtraEffect("ONE")
5408                         .build()),
5409                 eq(ORIGIN_APP));
5410 
5411         // Now create and activate a second rule that adds more effects.
5412         String secondRuleId = addRuleWithEffects(
5413                 new ZenDeviceEffects.Builder()
5414                         .setShouldDimWallpaper(true)
5415                         .addExtraEffect("TWO")
5416                         .build());
5417         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, secondRuleId, CONDITION_TRUE,
5418                 ORIGIN_APP, CUSTOM_PKG_UID);
5419         mTestableLooper.processAllMessages();
5420 
5421         verify(mDeviceEffectsApplier).apply(
5422                 eq(new ZenDeviceEffects.Builder()
5423                         .setShouldDisplayGrayscale(true)
5424                         .setShouldDimWallpaper(true)
5425                         .setExtraEffects(ImmutableSet.of("ONE", "TWO"))
5426                         .build()),
5427                 eq(ORIGIN_APP));
5428     }
5429 
5430     @Test
5431     @EnableFlags(FLAG_MODES_API)
testDeviceEffects_noChangeToConsolidatedEffects_notApplied()5432     public void testDeviceEffects_noChangeToConsolidatedEffects_notApplied() {
5433         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
5434         verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_INIT));
5435 
5436         ZenDeviceEffects zde = new ZenDeviceEffects.Builder()
5437                 .setShouldUseNightMode(true)
5438                 .addExtraEffect("extra_effect")
5439                 .build();
5440         String ruleId = addRuleWithEffects(zde);
5441         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5442                 ORIGIN_APP, CUSTOM_PKG_UID);
5443         mTestableLooper.processAllMessages();
5444         verify(mDeviceEffectsApplier).apply(eq(zde), eq(ORIGIN_APP));
5445 
5446         // Now create and activate a second rule that doesn't add any more effects.
5447         String secondRuleId = addRuleWithEffects(zde);
5448         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, secondRuleId, CONDITION_TRUE,
5449                 ORIGIN_APP, CUSTOM_PKG_UID);
5450         mTestableLooper.processAllMessages();
5451 
5452         verifyNoMoreInteractions(mDeviceEffectsApplier);
5453     }
5454 
5455     @Test
5456     @EnableFlags(FLAG_MODES_API)
testDeviceEffects_activeBeforeApplierProvided_appliedWhenProvided()5457     public void testDeviceEffects_activeBeforeApplierProvided_appliedWhenProvided() {
5458         ZenDeviceEffects zde = new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build();
5459         String ruleId = addRuleWithEffects(zde);
5460         verify(mDeviceEffectsApplier, never()).apply(any(), anyInt());
5461 
5462         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5463                 ORIGIN_APP, CUSTOM_PKG_UID);
5464         mTestableLooper.processAllMessages();
5465         verify(mDeviceEffectsApplier, never()).apply(any(), anyInt());
5466 
5467         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
5468         verify(mDeviceEffectsApplier).apply(eq(zde), eq(ORIGIN_INIT));
5469     }
5470 
5471     @Test
5472     @EnableFlags(FLAG_MODES_API)
testDeviceEffects_onUserSwitch_appliedImmediately()5473     public void testDeviceEffects_onUserSwitch_appliedImmediately() {
5474         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
5475         verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_INIT));
5476 
5477         // Initialize default configurations (default rules) for both users.
5478         mZenModeHelper.onUserSwitched(1);
5479         mZenModeHelper.onUserSwitched(2);
5480 
5481         // Current user is now 2. Tweak a rule for user 1 so it's active and has effects.
5482         ZenRule user1Rule = mZenModeHelper.mConfigs.get(1).automaticRules.valueAt(0);
5483         user1Rule.enabled = true;
5484         user1Rule.condition = new Condition(user1Rule.conditionId, "on", STATE_TRUE);
5485         user1Rule.zenDeviceEffects = new ZenDeviceEffects.Builder()
5486                 .setShouldDimWallpaper(true)
5487                 .setShouldUseNightMode(true)
5488                 .build();
5489         user1Rule.zenPolicy = new ZenPolicy();
5490         verifyNoMoreInteractions(mDeviceEffectsApplier);
5491 
5492         mZenModeHelper.onUserSwitched(1);
5493         mTestableLooper.processAllMessages();
5494 
5495         verify(mDeviceEffectsApplier).apply(eq(user1Rule.zenDeviceEffects),
5496                 eq(ORIGIN_INIT_USER));
5497     }
5498 
addRuleWithEffects(ZenDeviceEffects effects)5499     private String addRuleWithEffects(ZenDeviceEffects effects) {
5500         AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
5501                 .setDeviceEffects(effects)
5502                 .build();
5503         return mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mContext.getPackageName(),
5504                 rule, ORIGIN_SYSTEM, "reasons", SYSTEM_UID);
5505     }
5506 
5507     @Test
5508     @EnableFlags(FLAG_MODES_API)
removeAndAddAutomaticZenRule_wasCustomized_isRestored()5509     public void removeAndAddAutomaticZenRule_wasCustomized_isRestored() {
5510         // Start with a rule.
5511         mZenModeHelper.mConfig.automaticRules.clear();
5512         mTestClock.setNowMillis(1000);
5513         AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
5514                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5515                 .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(false).build())
5516                 .build();
5517         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5518                 mContext.getPackageName(), rule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
5519         assertThat(mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId).getCreationTime())
5520                 .isEqualTo(1000);
5521 
5522         // User customizes it.
5523         AutomaticZenRule userUpdate = new AutomaticZenRule.Builder(rule)
5524                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
5525                 .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(true).build())
5526                 .build();
5527         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdate,
5528                 ORIGIN_USER_IN_SYSTEMUI, "userUpdate", SYSTEM_UID);
5529 
5530         // App deletes it.
5531         mTestClock.advanceByMillis(1000);
5532         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, ruleId, ORIGIN_APP, "delete it",
5533                 CUSTOM_PKG_UID);
5534         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0);
5535         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1);
5536 
5537         // App adds it again.
5538         mTestClock.advanceByMillis(1000);
5539         String newRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5540                 mContext.getPackageName(), rule, ORIGIN_APP, "add it again", CUSTOM_PKG_UID);
5541 
5542         // Verify that the rule was restored:
5543         // - id and creation time is the same as the original one.
5544         // - ZenPolicy is the one that the user had set.
5545         // - rule still has the user-modified fields.
5546         AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT,
5547                 newRuleId);
5548         assertThat(finalRule.getCreationTime()).isEqualTo(1000); // And not 3000.
5549         assertThat(newRuleId).isEqualTo(ruleId);
5550         assertThat(finalRule.getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALARMS);
5551         assertThat(finalRule.getZenPolicy().getPriorityCategoryRepeatCallers()).isEqualTo(
5552                 STATE_ALLOW);
5553 
5554         ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
5555         assertThat(storedRule.userModifiedFields).isEqualTo(
5556                 AutomaticZenRule.FIELD_INTERRUPTION_FILTER);
5557         assertThat(storedRule.zenPolicyUserModifiedFields).isEqualTo(
5558                 ZenPolicy.FIELD_PRIORITY_CATEGORY_REPEAT_CALLERS);
5559 
5560         // Also, we discarded the "deleted rule" since we already used it for restoration.
5561         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(0);
5562     }
5563 
5564     @Test
5565     @EnableFlags(FLAG_MODES_API)
removeAndAddAutomaticZenRule_wasNotCustomized_isNotRestored()5566     public void removeAndAddAutomaticZenRule_wasNotCustomized_isNotRestored() {
5567         // Start with a single rule.
5568         mZenModeHelper.mConfig.automaticRules.clear();
5569         mTestClock.setNowMillis(1000);
5570         AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
5571                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5572                 .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(false).build())
5573                 .build();
5574         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5575                 mContext.getPackageName(), rule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
5576         assertThat(mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId).getCreationTime())
5577                 .isEqualTo(1000);
5578 
5579         // App deletes it.
5580         mTestClock.advanceByMillis(1000);
5581         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, ruleId, ORIGIN_APP, "delete it",
5582                 CUSTOM_PKG_UID);
5583         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0);
5584         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(0);
5585 
5586         // App adds it again.
5587         mTestClock.advanceByMillis(1000);
5588         String newRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5589                 mContext.getPackageName(), rule, ORIGIN_APP, "add it again", CUSTOM_PKG_UID);
5590 
5591         // Verify that the rule was recreated. This means id and creation time are new.
5592         AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT,
5593                 newRuleId);
5594         assertThat(finalRule.getCreationTime()).isEqualTo(3000);
5595         assertThat(newRuleId).isNotEqualTo(ruleId);
5596     }
5597 
5598     @Test
5599     @EnableFlags(FLAG_MODES_API)
removeAndAddAutomaticZenRule_recreatedButNotByApp_isNotRestored()5600     public void removeAndAddAutomaticZenRule_recreatedButNotByApp_isNotRestored() {
5601         // Start with a single rule.
5602         mZenModeHelper.mConfig.automaticRules.clear();
5603         mTestClock.setNowMillis(1000);
5604         AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
5605                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5606                 .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(false).build())
5607                 .build();
5608         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5609                 mContext.getPackageName(), rule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
5610         assertThat(mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId).getCreationTime())
5611                 .isEqualTo(1000);
5612 
5613         // User customizes it.
5614         mTestClock.advanceByMillis(1000);
5615         AutomaticZenRule userUpdate = new AutomaticZenRule.Builder(rule)
5616                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
5617                 .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(true).build())
5618                 .build();
5619         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdate,
5620                 ORIGIN_USER_IN_SYSTEMUI, "userUpdate", SYSTEM_UID);
5621 
5622         // App deletes it.
5623         mTestClock.advanceByMillis(1000);
5624         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, ruleId, ORIGIN_APP, "delete it",
5625                 CUSTOM_PKG_UID);
5626         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0);
5627         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1);
5628 
5629         // User creates it again (unusual case, but ok).
5630         mTestClock.advanceByMillis(1000);
5631         String newRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5632                 mContext.getPackageName(), rule, ORIGIN_USER_IN_SYSTEMUI, "add it anew",
5633                 SYSTEM_UID);
5634 
5635         // Verify that the rule was recreated. This means id and creation time are new, and the rule
5636         // matches the latest data supplied to addAZR.
5637         AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT,
5638                 newRuleId);
5639         assertThat(finalRule.getCreationTime()).isEqualTo(4000);
5640         assertThat(newRuleId).isNotEqualTo(ruleId);
5641         assertThat(finalRule.getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_PRIORITY);
5642         assertThat(finalRule.getZenPolicy().getPriorityCategoryRepeatCallers()).isEqualTo(
5643                 STATE_DISALLOW);
5644 
5645         // Also, we discarded the "deleted rule" since we're not interested in recreating it.
5646         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(0);
5647     }
5648 
5649     @Test
5650     @EnableFlags(FLAG_MODES_API)
removeAndAddAutomaticZenRule_removedByUser_isNotRestored()5651     public void removeAndAddAutomaticZenRule_removedByUser_isNotRestored() {
5652         // Start with a single rule.
5653         mZenModeHelper.mConfig.automaticRules.clear();
5654         mTestClock.setNowMillis(1000);
5655         AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
5656                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5657                 .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(false).build())
5658                 .build();
5659         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5660                 mContext.getPackageName(), rule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
5661         assertThat(mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId).getCreationTime())
5662                 .isEqualTo(1000);
5663 
5664         // User customizes it.
5665         mTestClock.advanceByMillis(1000);
5666         AutomaticZenRule userUpdate = new AutomaticZenRule.Builder(rule)
5667                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
5668                 .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(true).build())
5669                 .build();
5670         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdate,
5671                 ORIGIN_USER_IN_SYSTEMUI, "userUpdate", SYSTEM_UID);
5672 
5673         // User deletes it.
5674         mTestClock.advanceByMillis(1000);
5675         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, ruleId, ORIGIN_USER_IN_SYSTEMUI,
5676                 "delete it", SYSTEM_UID);
5677         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0);
5678         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(0);
5679 
5680         // App creates it again.
5681         mTestClock.advanceByMillis(1000);
5682         String newRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5683                 mContext.getPackageName(), rule, ORIGIN_APP, "add it again", CUSTOM_PKG_UID);
5684 
5685         // Verify that the rule was recreated. This means id and creation time are new.
5686         AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT,
5687                 newRuleId);
5688         assertThat(finalRule.getCreationTime()).isEqualTo(4000);
5689         assertThat(newRuleId).isNotEqualTo(ruleId);
5690     }
5691 
5692     @Test
5693     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
removeAndAddAutomaticZenRule_ifChangingComponent_isAllowedAndDoesNotRestore()5694     public void removeAndAddAutomaticZenRule_ifChangingComponent_isAllowedAndDoesNotRestore() {
5695         // Start with a rule.
5696         mZenModeHelper.mConfig.automaticRules.clear();
5697         AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
5698                 .setOwner(new ComponentName("first", "owner"))
5699                 .setInterruptionFilter(INTERRUPTION_FILTER_ALL)
5700                 .build();
5701         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5702                 mContext.getPackageName(), rule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
5703 
5704         // User customizes it.
5705         AutomaticZenRule userUpdate = new AutomaticZenRule.Builder(rule)
5706                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5707                 .build();
5708         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdate,
5709                 ORIGIN_USER_IN_SYSTEMUI, "userUpdate", SYSTEM_UID);
5710 
5711         // App deletes it. It's preserved for a possible restoration.
5712         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, ruleId, ORIGIN_APP, "delete it",
5713                 CUSTOM_PKG_UID);
5714         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0);
5715         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1);
5716 
5717         // App adds it again, but this time with a different owner!
5718         AutomaticZenRule readdingWithDifferentOwner = new AutomaticZenRule.Builder(rule)
5719                 .setOwner(new ComponentName("second", "owner"))
5720                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
5721                 .build();
5722         String newRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5723                 mContext.getPackageName(), readdingWithDifferentOwner, ORIGIN_APP, "add it again",
5724                 CUSTOM_PKG_UID);
5725 
5726         // Verify that the rule was NOT restored:
5727         assertThat(newRuleId).isNotEqualTo(ruleId);
5728         AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT,
5729                 newRuleId);
5730         assertThat(finalRule.getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALARMS);
5731         assertThat(finalRule.getOwner()).isEqualTo(new ComponentName("second", "owner"));
5732 
5733         // Also, we discarded the "deleted rule" since we found it but decided not to use it.
5734         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(0);
5735     }
5736 
5737     @Test
5738     @EnableFlags(FLAG_MODES_API)
removeAutomaticZenRule_preservedForRestoringByPackageAndConditionId()5739     public void removeAutomaticZenRule_preservedForRestoringByPackageAndConditionId() {
5740         mContext.getTestablePermissions().setPermission(Manifest.permission.MANAGE_NOTIFICATIONS,
5741                 PERMISSION_GRANTED); // So that canManageAZR passes although packages don't match.
5742         mZenModeHelper.mConfig.automaticRules.clear();
5743 
5744         // Start with a bunch of customized rules where conditionUris are not unique.
5745         String id1 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkg1",
5746                 new AutomaticZenRule.Builder("Test1", Uri.parse("uri1")).build(),
5747                 ORIGIN_APP,
5748                 "add it", CUSTOM_PKG_UID);
5749         String id2 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkg1",
5750                 new AutomaticZenRule.Builder("Test2", Uri.parse("uri2")).build(),
5751                 ORIGIN_APP,
5752                 "add it", CUSTOM_PKG_UID);
5753         String id3 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkg1",
5754                 new AutomaticZenRule.Builder("Test3", Uri.parse("uri2")).build(),
5755                 ORIGIN_APP,
5756                 "add it", CUSTOM_PKG_UID);
5757         String id4 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkg2",
5758                 new AutomaticZenRule.Builder("Test4", Uri.parse("uri1")).build(),
5759                 ORIGIN_APP,
5760                 "add it", CUSTOM_PKG_UID);
5761         String id5 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "pkg2",
5762                 new AutomaticZenRule.Builder("Test5", Uri.parse("uri1")).build(),
5763                 ORIGIN_APP,
5764                 "add it", CUSTOM_PKG_UID);
5765         for (ZenRule zenRule : mZenModeHelper.mConfig.automaticRules.values()) {
5766             zenRule.userModifiedFields = AutomaticZenRule.FIELD_INTERRUPTION_FILTER;
5767         }
5768 
5769         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, id1, ORIGIN_APP, "begone",
5770                 CUSTOM_PKG_UID);
5771         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, id2, ORIGIN_APP, "begone",
5772                 CUSTOM_PKG_UID);
5773         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, id3, ORIGIN_APP, "begone",
5774                 CUSTOM_PKG_UID);
5775         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, id4, ORIGIN_APP, "begone",
5776                 CUSTOM_PKG_UID);
5777         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, id5, ORIGIN_APP, "begone",
5778                 CUSTOM_PKG_UID);
5779 
5780         assertThat(mZenModeHelper.mConfig.deletedRules.keySet())
5781                 .containsExactly("pkg1|uri1", "pkg1|uri2", "pkg2|uri1");
5782         assertThat(mZenModeHelper.mConfig.deletedRules.values().stream().map(zr -> zr.name)
5783                 .collect(Collectors.toList()))
5784                 .containsExactly("Test1", "Test3", "Test5");
5785     }
5786 
5787     @Test
5788     @EnableFlags(FLAG_MODES_API)
removeAllZenRules_preservedForRestoring()5789     public void removeAllZenRules_preservedForRestoring() {
5790         mZenModeHelper.mConfig.automaticRules.clear();
5791 
5792         mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mContext.getPackageName(),
5793                 new AutomaticZenRule.Builder("Test1", Uri.parse("uri1")).build(),
5794                 ORIGIN_APP,
5795                 "add it", CUSTOM_PKG_UID);
5796         mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mContext.getPackageName(),
5797                 new AutomaticZenRule.Builder("Test2", Uri.parse("uri2")).build(),
5798                 ORIGIN_APP,
5799                 "add it", CUSTOM_PKG_UID);
5800 
5801         for (ZenRule zenRule : mZenModeHelper.mConfig.automaticRules.values()) {
5802             zenRule.userModifiedFields = AutomaticZenRule.FIELD_INTERRUPTION_FILTER;
5803         }
5804 
5805         mZenModeHelper.removeAutomaticZenRules(UserHandle.CURRENT, mContext.getPackageName(),
5806                 ORIGIN_APP, "begone", CUSTOM_PKG_UID);
5807 
5808         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(2);
5809     }
5810 
5811     @Test
5812     @EnableFlags(FLAG_MODES_API)
removeAllZenRules_fromSystem_deletesPreservedRulesToo()5813     public void removeAllZenRules_fromSystem_deletesPreservedRulesToo() {
5814         mZenModeHelper.mConfig.automaticRules.clear();
5815 
5816         // Start with deleted rules from 2 different packages.
5817         Instant now = Instant.ofEpochMilli(1701796461000L);
5818         ZenRule pkg1Rule = newZenRule("pkg1", now.minus(1, ChronoUnit.DAYS), now);
5819         ZenRule pkg2Rule = newZenRule("pkg2", now.minus(2, ChronoUnit.DAYS), now);
5820         mZenModeHelper.mConfig.deletedRules.put(ZenModeConfig.deletedRuleKey(pkg1Rule), pkg1Rule);
5821         mZenModeHelper.mConfig.deletedRules.put(ZenModeConfig.deletedRuleKey(pkg2Rule), pkg2Rule);
5822 
5823         mZenModeHelper.removeAutomaticZenRules(UserHandle.CURRENT, "pkg1",
5824                 ORIGIN_SYSTEM, "goodbye pkg1", SYSTEM_UID);
5825 
5826         // Preserved rules from pkg1 are gone; those from pkg2 are still there.
5827         assertThat(mZenModeHelper.mConfig.deletedRules.values().stream().map(r -> r.pkg)
5828                 .collect(Collectors.toSet())).containsExactly("pkg2");
5829     }
5830 
5831     @Test
5832     @EnableFlags(FLAG_MODES_API)
removeAndAddAutomaticZenRule_wasActive_isRestoredAsInactive()5833     public void removeAndAddAutomaticZenRule_wasActive_isRestoredAsInactive() {
5834         // Start with a rule.
5835         mZenModeHelper.mConfig.automaticRules.clear();
5836         AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
5837                 .setConditionId(CONDITION_ID)
5838                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5839                 .build();
5840         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5841                 mContext.getPackageName(), rule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
5842 
5843         // User customizes it.
5844         AutomaticZenRule userUpdate = new AutomaticZenRule.Builder(rule)
5845                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
5846                 .build();
5847         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdate,
5848                 ORIGIN_USER_IN_SYSTEMUI, "userUpdate", SYSTEM_UID);
5849         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5850 
5851         // App activates it.
5852         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5853                 ORIGIN_APP, CUSTOM_PKG_UID);
5854         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
5855 
5856         // App deletes it.
5857         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, ruleId, ORIGIN_APP, "delete it",
5858                 CUSTOM_PKG_UID);
5859         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0);
5860         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1);
5861         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5862 
5863         // App adds it again.
5864         String newRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5865                 mContext.getPackageName(), rule, ORIGIN_APP, "add it again", CUSTOM_PKG_UID);
5866 
5867         // The rule is restored...
5868         assertThat(newRuleId).isEqualTo(ruleId);
5869         AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT,
5870                 newRuleId);
5871         assertThat(finalRule.getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALARMS);
5872 
5873         // ... but it is NOT active
5874         ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(newRuleId);
5875         assertThat(storedRule.isActive()).isFalse();
5876         assertThat(storedRule.isTrueOrUnknown()).isFalse();
5877         assertThat(storedRule.condition).isNull();
5878         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5879     }
5880 
5881     @Test
5882     @EnableFlags(FLAG_MODES_API)
removeAndAddAutomaticZenRule_wasSnoozed_isRestoredAsInactive()5883     public void removeAndAddAutomaticZenRule_wasSnoozed_isRestoredAsInactive() {
5884         // Start with a rule.
5885         mZenModeHelper.mConfig.automaticRules.clear();
5886         AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
5887                 .setConditionId(CONDITION_ID)
5888                 .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
5889                 .build();
5890         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5891                 mContext.getPackageName(), rule, ORIGIN_APP, "add it", CUSTOM_PKG_UID);
5892 
5893         // User customizes it.
5894         AutomaticZenRule userUpdate = new AutomaticZenRule.Builder(rule)
5895                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
5896                 .build();
5897         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdate,
5898                 ORIGIN_USER_IN_SYSTEMUI, "userUpdate", SYSTEM_UID);
5899         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5900 
5901         // App activates it.
5902         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, CONDITION_TRUE,
5903                 ORIGIN_APP, CUSTOM_PKG_UID);
5904         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
5905 
5906         // User snoozes it.
5907         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, null, ORIGIN_SYSTEM,
5908                 "snoozing", "systemui", SYSTEM_UID);
5909         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5910 
5911         // App deletes it.
5912         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, ruleId, ORIGIN_APP, "delete it",
5913                 CUSTOM_PKG_UID);
5914         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0);
5915         assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1);
5916 
5917         // App adds it again.
5918         String newRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5919                 mContext.getPackageName(), rule, ORIGIN_APP, "add it again", CUSTOM_PKG_UID);
5920 
5921         // The rule is restored...
5922         assertThat(newRuleId).isEqualTo(ruleId);
5923         AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT,
5924                 newRuleId);
5925         assertThat(finalRule.getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALARMS);
5926 
5927         // ... but it is NEITHER active NOR snoozed.
5928         ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(newRuleId);
5929         assertThat(storedRule.isActive()).isFalse();
5930         assertThat(storedRule.isTrueOrUnknown()).isFalse();
5931         assertThat(storedRule.condition).isNull();
5932         assertThat(storedRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
5933         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
5934     }
5935 
5936     @Test
5937     @EnableFlags(FLAG_MODES_API)
testRuleCleanup()5938     public void testRuleCleanup() throws Exception {
5939         Instant now = Instant.ofEpochMilli(1701796461000L);
5940         Instant yesterday = now.minus(1, ChronoUnit.DAYS);
5941         Instant aWeekAgo = now.minus(7, ChronoUnit.DAYS);
5942         Instant twoMonthsAgo = now.minus(60, ChronoUnit.DAYS);
5943         mTestClock.setNowMillis(now.toEpochMilli());
5944 
5945         when(mPackageManager.getPackageInfo(eq("good_pkg"), anyInt()))
5946                 .thenReturn(new PackageInfo());
5947         when(mPackageManager.getPackageInfo(eq("bad_pkg"), anyInt()))
5948                 .thenThrow(new PackageManager.NameNotFoundException("bad_pkg is not here"));
5949 
5950         // Set up a config for another user containing:
5951         ZenModeConfig config = new ZenModeConfig();
5952         config.user = 42;
5953         mZenModeHelper.mConfigs.put(42, config);
5954         // okay rules (not deleted, package exists, with a range of creation dates).
5955         config.automaticRules.put("ar1", newZenRule("good_pkg", now, null));
5956         config.automaticRules.put("ar2", newZenRule("good_pkg", yesterday, null));
5957         config.automaticRules.put("ar3", newZenRule("good_pkg", twoMonthsAgo, null));
5958         // newish rules for a missing package
5959         config.automaticRules.put("ar4", newZenRule("bad_pkg", yesterday, null));
5960         // oldish rules belonging to a missing package
5961         config.automaticRules.put("ar5", newZenRule("bad_pkg", aWeekAgo, null));
5962         // rules deleted recently
5963         config.deletedRules.put("del1", newZenRule("good_pkg", twoMonthsAgo, yesterday));
5964         config.deletedRules.put("del2", newZenRule("good_pkg", twoMonthsAgo, aWeekAgo));
5965         // rules deleted a long time ago
5966         config.deletedRules.put("del3", newZenRule("good_pkg", twoMonthsAgo, twoMonthsAgo));
5967         // rules for a missing package, created recently and deleted recently
5968         config.deletedRules.put("del4", newZenRule("bad_pkg", yesterday, now));
5969         // rules for a missing package, created a long time ago and deleted recently
5970         config.deletedRules.put("del5", newZenRule("bad_pkg", twoMonthsAgo, now));
5971         // rules for a missing package, created a long time ago and deleted a long time ago
5972         config.deletedRules.put("del6", newZenRule("bad_pkg", twoMonthsAgo, twoMonthsAgo));
5973 
5974         mZenModeHelper.onUserSwitched(42); // copies config and cleans it up.
5975 
5976         assertThat(mZenModeHelper.mConfig.automaticRules.keySet())
5977                 .containsExactly("ar1", "ar2", "ar3", "ar4");
5978         assertThat(mZenModeHelper.mConfig.deletedRules.keySet())
5979                 .containsExactly("del1", "del2", "del4");
5980     }
5981 
newZenRule(String pkg, Instant createdAt, @Nullable Instant deletedAt)5982     private static ZenRule newZenRule(String pkg, Instant createdAt, @Nullable Instant deletedAt) {
5983         ZenRule rule = new ZenRule();
5984         rule.pkg = pkg;
5985         rule.creationTime = createdAt.toEpochMilli();
5986         rule.enabled = true;
5987         rule.deletionInstant = deletedAt;
5988         // Plus stuff so that isValidAutomaticRule() passes
5989         rule.name = "A rule from " + pkg + " created on " + createdAt;
5990         rule.conditionId = Uri.parse(rule.name);
5991         return rule;
5992     }
5993 
5994     @Test
5995     @EnableFlags(FLAG_MODES_API)
getAutomaticZenRuleState_ownedRule_returnsRuleState()5996     public void getAutomaticZenRuleState_ownedRule_returnsRuleState() {
5997         String id = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
5998                 mContext.getPackageName(),
5999                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
6000                         .setConfigurationActivity(
6001                                 new ComponentName(mContext.getPackageName(), "Blah"))
6002                         .build(),
6003                 ORIGIN_APP, "reasons", CUSTOM_PKG_UID);
6004 
6005         // Null condition -> STATE_FALSE
6006         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, id))
6007                 .isEqualTo(Condition.STATE_FALSE);
6008 
6009         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id, CONDITION_TRUE, ORIGIN_APP,
6010                 CUSTOM_PKG_UID);
6011         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, id))
6012                 .isEqualTo(Condition.STATE_TRUE);
6013 
6014         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, id, CONDITION_FALSE, ORIGIN_APP,
6015                 CUSTOM_PKG_UID);
6016         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, id))
6017                 .isEqualTo(Condition.STATE_FALSE);
6018 
6019         mZenModeHelper.removeAutomaticZenRule(UserHandle.CURRENT, id, ORIGIN_APP, "",
6020                 CUSTOM_PKG_UID);
6021         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, id))
6022                 .isEqualTo(Condition.STATE_UNKNOWN);
6023     }
6024 
6025     @Test
6026     @EnableFlags(FLAG_MODES_API)
getAutomaticZenRuleState_notOwnedRule_returnsStateUnknown()6027     public void getAutomaticZenRuleState_notOwnedRule_returnsStateUnknown() {
6028         // Assume existence of a system-owned rule that is currently ACTIVE.
6029         ZenRule systemRule = newZenRule("android", Instant.now(), null);
6030         systemRule.zenMode = ZEN_MODE_ALARMS;
6031         systemRule.condition = new Condition(systemRule.conditionId, "on", Condition.STATE_TRUE);
6032         ZenModeConfig config = mZenModeHelper.mConfig.copy();
6033         config.automaticRules.put("systemRule", systemRule);
6034         mZenModeHelper.setConfig(config, null, ORIGIN_INIT, "", SYSTEM_UID);
6035         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
6036 
6037         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, "systemRule"))
6038                 .isEqualTo(Condition.STATE_UNKNOWN);
6039     }
6040 
6041     @Test
6042     @EnableFlags(FLAG_MODES_API)
setAutomaticZenRuleState_idForNotOwnedRule_ignored()6043     public void setAutomaticZenRuleState_idForNotOwnedRule_ignored() {
6044         // Assume existence of an other-package-owned rule that is currently ACTIVE.
6045         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
6046         ZenRule otherRule = newZenRule("another.package", Instant.now(), null);
6047         otherRule.zenMode = ZEN_MODE_ALARMS;
6048         otherRule.condition = new Condition(otherRule.conditionId, "on", Condition.STATE_TRUE);
6049         ZenModeConfig config = mZenModeHelper.mConfig.copy();
6050         config.automaticRules.put("otherRule", otherRule);
6051         mZenModeHelper.setConfig(config, null, ORIGIN_INIT, "", SYSTEM_UID);
6052         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
6053 
6054         // Should be ignored.
6055         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, "otherRule",
6056                 new Condition(otherRule.conditionId, "off", Condition.STATE_FALSE),
6057                 ORIGIN_APP, CUSTOM_PKG_UID);
6058 
6059         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
6060     }
6061 
6062     @Test
6063     @EnableFlags(FLAG_MODES_API)
setAutomaticZenRuleState_conditionForNotOwnedRule_ignored()6064     public void setAutomaticZenRuleState_conditionForNotOwnedRule_ignored() {
6065         // Assume existence of an other-package-owned rule that is currently ACTIVE.
6066         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF);
6067         ZenRule otherRule = newZenRule("another.package", Instant.now(), null);
6068         otherRule.zenMode = ZEN_MODE_ALARMS;
6069         otherRule.condition = new Condition(otherRule.conditionId, "on", Condition.STATE_TRUE);
6070         ZenModeConfig config = mZenModeHelper.mConfig.copy();
6071         config.automaticRules.put("otherRule", otherRule);
6072         mZenModeHelper.setConfig(config, null, ORIGIN_INIT, "", SYSTEM_UID);
6073         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
6074 
6075         // Should be ignored.
6076         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, otherRule.conditionId,
6077                 new Condition(otherRule.conditionId, "off", Condition.STATE_FALSE),
6078                 ORIGIN_APP, CUSTOM_PKG_UID);
6079 
6080         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
6081     }
6082 
6083     @Test
6084     @EnableFlags(FLAG_MODES_API)
testCallbacks_policy()6085     public void testCallbacks_policy() throws Exception {
6086         setupZenConfig();
6087         assertThat(mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT).allowReminders())
6088                 .isTrue();
6089         SettableFuture<Policy> futurePolicy = SettableFuture.create();
6090         mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
6091             @Override
6092             void onPolicyChanged(Policy newPolicy) {
6093                 futurePolicy.set(newPolicy);
6094             }
6095         });
6096 
6097         Policy totalSilencePolicy = new Policy(0, 0, 0);
6098         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, totalSilencePolicy, ORIGIN_APP,
6099                 CUSTOM_PKG_UID);
6100 
6101         Policy callbackPolicy = futurePolicy.get(1, TimeUnit.SECONDS);
6102         assertThat(callbackPolicy.allowReminders()).isFalse();
6103     }
6104 
6105     @Test
6106     @EnableFlags(FLAG_MODES_API)
testCallbacks_consolidatedPolicy()6107     public void testCallbacks_consolidatedPolicy() throws Exception {
6108         assertThat(mZenModeHelper.getConsolidatedNotificationPolicy().allowMedia()).isTrue();
6109         SettableFuture<Policy> futureConsolidatedPolicy = SettableFuture.create();
6110         mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
6111             @Override
6112             void onConsolidatedPolicyChanged(Policy newConsolidatedPolicy) {
6113                 futureConsolidatedPolicy.set(newConsolidatedPolicy);
6114             }
6115         });
6116 
6117         String totalSilenceRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
6118                 mContext.getPackageName(),
6119                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
6120                         .setOwner(OWNER)
6121                         .setInterruptionFilter(INTERRUPTION_FILTER_NONE)
6122                         .build(),
6123                 ORIGIN_APP, "reasons", 0);
6124         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, totalSilenceRuleId,
6125                 new Condition(CONDITION_ID, "", STATE_TRUE), ORIGIN_APP, CUSTOM_PKG_UID);
6126 
6127         Policy callbackPolicy = futureConsolidatedPolicy.get(1, TimeUnit.SECONDS);
6128         assertThat(callbackPolicy.allowMedia()).isFalse();
6129     }
6130 
6131     @Test
6132     @EnableFlags(FLAG_MODES_API)
applyGlobalZenModeAsImplicitZenRule_createsImplicitRuleAndActivatesIt()6133     public void applyGlobalZenModeAsImplicitZenRule_createsImplicitRuleAndActivatesIt() {
6134         mZenModeHelper.mConfig.automaticRules.clear();
6135 
6136         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6137                 CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6138 
6139         assertThat(mZenModeHelper.mConfig.automaticRules.values())
6140                 .comparingElementsUsing(IGNORE_METADATA)
6141                 .containsExactly(
6142                         expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
6143                                 mZenModeHelper.mConfig.getZenPolicy(), // copy of global config
6144                                 true));
6145     }
6146 
6147     @Test
6148     @EnableFlags(FLAG_MODES_API)
applyGlobalZenModeAsImplicitZenRule_updatesImplicitRuleAndActivatesIt()6149     public void applyGlobalZenModeAsImplicitZenRule_updatesImplicitRuleAndActivatesIt() {
6150         mZenModeHelper.mConfig.automaticRules.clear();
6151 
6152         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6153                 CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6154         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, null, ORIGIN_APP, "test",
6155                 "test", 0);
6156         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1);
6157 
6158         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6159                 CUSTOM_PKG_UID, ZEN_MODE_ALARMS);
6160 
6161         assertThat(mZenModeHelper.mConfig.automaticRules.values())
6162                 .comparingElementsUsing(IGNORE_METADATA)
6163                 .containsExactly(
6164                         expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_ALARMS,
6165                                 mZenModeHelper.mConfig.getZenPolicy(), // copy of global config
6166                                 true));
6167     }
6168 
6169     @Test
6170     @EnableFlags(FLAG_MODES_API)
applyGlobalZenModeAsImplicitZenRule_ruleCustomized_doesNotUpdateRule()6171     public void applyGlobalZenModeAsImplicitZenRule_ruleCustomized_doesNotUpdateRule() {
6172         mZenModeHelper.mConfig.automaticRules.clear();
6173         String pkg = mContext.getPackageName();
6174 
6175         // From app, call "setInterruptionFilter" and create and implicit rule.
6176         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, pkg, CUSTOM_PKG_UID,
6177                 ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6178         String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet());
6179         assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode)
6180                 .isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6181 
6182         // From user, update that rule's interruption filter.
6183         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
6184         AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule)
6185                 .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
6186                 .build();
6187         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdateRule,
6188                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
6189 
6190         // From app, call "setInterruptionFilter" again.
6191         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, pkg, CUSTOM_PKG_UID,
6192                 ZEN_MODE_NO_INTERRUPTIONS);
6193 
6194         // The app's update was ignored, and the user's update is still current, and the current
6195         // mode is the one they chose.
6196         assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode)
6197                 .isEqualTo(ZEN_MODE_ALARMS);
6198         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS);
6199     }
6200 
6201     @Test
6202     @EnableFlags(FLAG_MODES_API)
applyGlobalZenModeAsImplicitZenRule_ruleCustomizedButNotFilter_updatesRule()6203     public void applyGlobalZenModeAsImplicitZenRule_ruleCustomizedButNotFilter_updatesRule() {
6204         mZenModeHelper.mConfig.automaticRules.clear();
6205         String pkg = mContext.getPackageName();
6206 
6207         // From app, call "setInterruptionFilter" and create and implicit rule.
6208         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, pkg, CUSTOM_PKG_UID,
6209                 ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6210         String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet());
6211         assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode)
6212                 .isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6213 
6214         // From user, update something in that rule, but not the interruption filter.
6215         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
6216         AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule)
6217                 .setName("Renamed")
6218                 .build();
6219         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdateRule,
6220                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
6221 
6222         // From app, call "setInterruptionFilter" again.
6223         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, pkg, CUSTOM_PKG_UID,
6224                 ZEN_MODE_NO_INTERRUPTIONS);
6225 
6226         // The app's update was accepted, and the current mode is the one that they wanted.
6227         assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenMode)
6228                 .isEqualTo(ZEN_MODE_NO_INTERRUPTIONS);
6229         assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_NO_INTERRUPTIONS);
6230     }
6231 
6232     @Test
6233     @EnableFlags(FLAG_MODES_API)
applyGlobalZenModeAsImplicitZenRule_modeOff_deactivatesImplicitRule()6234     public void applyGlobalZenModeAsImplicitZenRule_modeOff_deactivatesImplicitRule() {
6235         mZenModeHelper.mConfig.automaticRules.clear();
6236         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, mPkg, CUSTOM_PKG_UID,
6237                 ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6238         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1);
6239         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).condition.state)
6240                 .isEqualTo(STATE_TRUE);
6241 
6242         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, mPkg, CUSTOM_PKG_UID,
6243                 ZEN_MODE_OFF);
6244 
6245         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).condition.state)
6246                 .isEqualTo(STATE_FALSE);
6247     }
6248 
6249     @Test
6250     @EnableFlags(FLAG_MODES_API)
applyGlobalZenModeAsImplicitZenRule_modeOffButNoPreviousRule_ignored()6251     public void applyGlobalZenModeAsImplicitZenRule_modeOffButNoPreviousRule_ignored() {
6252         mZenModeHelper.mConfig.automaticRules.clear();
6253 
6254         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6255                 CUSTOM_PKG_UID, ZEN_MODE_OFF);
6256 
6257         assertThat(mZenModeHelper.mConfig.automaticRules).isEmpty();
6258     }
6259 
6260     @Test
6261     @EnableFlags(FLAG_MODES_API)
applyGlobalZenModeAsImplicitZenRule_update_unsnoozesRule()6262     public void applyGlobalZenModeAsImplicitZenRule_update_unsnoozesRule() {
6263         mZenModeHelper.mConfig.automaticRules.clear();
6264 
6265         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6266                 CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6267         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1);
6268         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).getConditionOverride())
6269                 .isEqualTo(OVERRIDE_NONE);
6270 
6271         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, null, ORIGIN_APP, "test",
6272                 "test", 0);
6273         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).getConditionOverride())
6274                 .isEqualTo(OVERRIDE_DEACTIVATE);
6275 
6276         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6277                 CUSTOM_PKG_UID, ZEN_MODE_ALARMS);
6278 
6279         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).getConditionOverride())
6280                 .isEqualTo(OVERRIDE_NONE);
6281         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).condition.state)
6282                 .isEqualTo(STATE_TRUE);
6283     }
6284 
6285     @Test
6286     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
applyGlobalZenModeAsImplicitZenRule_again_refreshesRuleName()6287     public void applyGlobalZenModeAsImplicitZenRule_again_refreshesRuleName() {
6288         mZenModeHelper.mConfig.automaticRules.clear();
6289         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT,
6290                 mContext.getPackageName(), CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6291         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1);
6292         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).name)
6293                 .isEqualTo("Do Not Disturb (" + CUSTOM_APP_LABEL + ")");
6294         // "Break" the rule name to check that applying again restores it.
6295         mZenModeHelper.mConfig.automaticRules.valueAt(0).name = "BOOM!";
6296 
6297         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT,
6298                 mContext.getPackageName(), CUSTOM_PKG_UID, ZEN_MODE_ALARMS);
6299 
6300         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).name)
6301                 .isEqualTo("Do Not Disturb (" + CUSTOM_APP_LABEL + ")");
6302     }
6303 
6304     @Test
6305     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
applyGlobalZenModeAsImplicitZenRule_again_doesNotChangeCustomizedRuleName()6306     public void applyGlobalZenModeAsImplicitZenRule_again_doesNotChangeCustomizedRuleName() {
6307         mZenModeHelper.mConfig.automaticRules.clear();
6308         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT,
6309                 mContext.getPackageName(), CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6310         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1);
6311         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).name)
6312                 .isEqualTo("Do Not Disturb (" + CUSTOM_APP_LABEL + ")");
6313         String ruleId = ZenModeConfig.implicitRuleId(mContext.getPackageName());
6314 
6315         // User chooses a new name.
6316         AutomaticZenRule azr = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
6317         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
6318                 new AutomaticZenRule.Builder(azr).setName("User chose this").build(),
6319                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
6320 
6321         // App triggers the rule again.
6322         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT,
6323                 mContext.getPackageName(), CUSTOM_PKG_UID, ZEN_MODE_ALARMS);
6324 
6325         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).name)
6326                 .isEqualTo("User chose this");
6327     }
6328 
6329     @Test
6330     @DisableFlags(FLAG_MODES_API)
applyGlobalZenModeAsImplicitZenRule_flagOff_ignored()6331     public void applyGlobalZenModeAsImplicitZenRule_flagOff_ignored() {
6332         mZenModeHelper.mConfig.automaticRules.clear();
6333 
6334         withoutWtfCrash(
6335                 () -> mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT,
6336                         CUSTOM_PKG_NAME, CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS));
6337 
6338         assertThat(mZenModeHelper.mConfig.automaticRules).isEmpty();
6339     }
6340 
6341     @Test
6342     @EnableFlags(FLAG_MODES_API)
applyGlobalPolicyAsImplicitZenRule_createsImplicitRule()6343     public void applyGlobalPolicyAsImplicitZenRule_createsImplicitRule() {
6344         mZenModeHelper.mConfig.automaticRules.clear();
6345 
6346         Policy policy = new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS,
6347                 PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED,
6348                 Policy.getAllSuppressedVisualEffects(), CONVERSATION_SENDERS_IMPORTANT);
6349         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6350                 CUSTOM_PKG_UID, policy);
6351 
6352         ZenPolicy expectedZenPolicy = new ZenPolicy.Builder()
6353                 .disallowAllSounds()
6354                 .allowCalls(PEOPLE_TYPE_CONTACTS)
6355                 .allowConversations(CONVERSATION_SENDERS_IMPORTANT)
6356                 .hideAllVisualEffects()
6357                 .allowPriorityChannels(true)
6358                 .build();
6359         assertThat(mZenModeHelper.mConfig.automaticRules.values())
6360                 .comparingElementsUsing(IGNORE_METADATA)
6361                 .containsExactly(
6362                         expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
6363                                 expectedZenPolicy, /* conditionActive= */ null));
6364     }
6365 
6366     @Test
6367     @EnableFlags(FLAG_MODES_API)
applyGlobalPolicyAsImplicitZenRule_updatesImplicitRule()6368     public void applyGlobalPolicyAsImplicitZenRule_updatesImplicitRule() {
6369         mZenModeHelper.mConfig.automaticRules.clear();
6370 
6371         Policy original = new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS,
6372                 PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED,
6373                 Policy.getAllSuppressedVisualEffects(), CONVERSATION_SENDERS_IMPORTANT);
6374         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6375                 CUSTOM_PKG_UID, original);
6376 
6377         // Change priorityCallSenders: contacts -> starred.
6378         Policy updated = new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS,
6379                 PRIORITY_SENDERS_STARRED, PRIORITY_SENDERS_STARRED,
6380                 Policy.getAllSuppressedVisualEffects(), CONVERSATION_SENDERS_IMPORTANT);
6381         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6382                 CUSTOM_PKG_UID, updated);
6383 
6384         ZenPolicy expectedZenPolicy = new ZenPolicy.Builder()
6385                 .disallowAllSounds()
6386                 .allowCalls(PEOPLE_TYPE_STARRED)
6387                 .allowConversations(CONVERSATION_SENDERS_IMPORTANT)
6388                 .hideAllVisualEffects()
6389                 .allowPriorityChannels(true)
6390                 .build();
6391         assertThat(mZenModeHelper.mConfig.automaticRules.values())
6392                 .comparingElementsUsing(IGNORE_METADATA)
6393                 .containsExactly(
6394                         expectedImplicitRule(CUSTOM_PKG_NAME, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
6395                                 expectedZenPolicy, /* conditionActive= */ null));
6396     }
6397 
6398     @Test
6399     @EnableFlags(FLAG_MODES_API)
applyGlobalPolicyAsImplicitZenRule_ruleCustomized_doesNotUpdateRule()6400     public void applyGlobalPolicyAsImplicitZenRule_ruleCustomized_doesNotUpdateRule() {
6401         mZenModeHelper.mConfig.automaticRules.clear();
6402         String pkg = mContext.getPackageName();
6403 
6404         // From app, call "setNotificationPolicy" and create and implicit rule.
6405         Policy originalPolicy = new Policy(PRIORITY_CATEGORY_MEDIA, 0, 0);
6406         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT, pkg, CUSTOM_PKG_UID,
6407                 originalPolicy);
6408         String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet());
6409 
6410         // Store this for checking later.
6411         ZenPolicy originalEffectiveZenPolicy = new ZenPolicy.Builder(
6412                 mZenModeHelper.mConfig.getZenPolicy()).allowMedia(true).build();
6413 
6414         // From user, update that rule's policy.
6415         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
6416         ZenPolicy userUpdateZenPolicy = new ZenPolicy.Builder().disallowAllSounds()
6417                 .allowAlarms(true).build();
6418         AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule)
6419                 .setZenPolicy(userUpdateZenPolicy)
6420                 .build();
6421         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdateRule,
6422                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
6423 
6424         // From app, call "setNotificationPolicy" again.
6425         Policy appUpdatePolicy = new Policy(PRIORITY_CATEGORY_SYSTEM, 0, 0);
6426         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT, pkg, CUSTOM_PKG_UID,
6427                 appUpdatePolicy);
6428 
6429         // The app's update was ignored, and the user's update is still current.
6430         assertThat(mZenModeHelper.mConfig.automaticRules.values())
6431                 .comparingElementsUsing(IGNORE_METADATA)
6432                 .containsExactly(
6433                         expectedImplicitRule(pkg, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
6434                                 // the final policy for the rule should contain the user's update
6435                                 // overlaid on top of the original existing policy.
6436                                 originalEffectiveZenPolicy.overwrittenWith(userUpdateZenPolicy),
6437                                 /* conditionActive= */ null));
6438     }
6439 
6440     @Test
6441     @EnableFlags(FLAG_MODES_API)
applyGlobalPolicyAsImplicitZenRule_ruleCustomizedButNotZenPolicy_updatesRule()6442     public void applyGlobalPolicyAsImplicitZenRule_ruleCustomizedButNotZenPolicy_updatesRule() {
6443         mZenModeHelper.mConfig.automaticRules.clear();
6444         String pkg = mContext.getPackageName();
6445 
6446         // From app, call "setNotificationPolicy" and create and implicit rule.
6447         Policy originalPolicy = new Policy(PRIORITY_CATEGORY_MEDIA, 0, 0);
6448         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT, pkg, CUSTOM_PKG_UID,
6449                 originalPolicy);
6450         String ruleId = getOnlyElement(mZenModeHelper.mConfig.automaticRules.keySet());
6451 
6452         // Store this for checking later.
6453         ZenPolicy originalEffectiveZenPolicy = new ZenPolicy.Builder(
6454                 mZenModeHelper.mConfig.getZenPolicy()).allowMedia(true).build();
6455 
6456         // From user, update something in that rule, but not the ZenPolicy.
6457         AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
6458         AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule)
6459                 .setName("Rule renamed, not touching policy")
6460                 .build();
6461         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, userUpdateRule,
6462                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
6463 
6464         // From app, call "setNotificationPolicy" again.
6465         Policy appUpdatePolicy = new Policy(PRIORITY_CATEGORY_SYSTEM, 0, 0);
6466         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT, pkg, CUSTOM_PKG_UID,
6467                 appUpdatePolicy);
6468 
6469         // The app's update was applied.
6470         ZenPolicy appsSecondZenPolicy = new ZenPolicy.Builder()
6471                 .disallowAllSounds()
6472                 .allowSystem(true)
6473                 .allowPriorityChannels(true)
6474                 .build();
6475         assertThat(getOnlyElement(mZenModeHelper.mConfig.automaticRules.values()).zenPolicy)
6476                 .isEqualTo(originalEffectiveZenPolicy.overwrittenWith(appsSecondZenPolicy));
6477     }
6478 
6479     @Test
6480     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
applyGlobalPolicyAsImplicitZenRule_again_refreshesRuleName()6481     public void applyGlobalPolicyAsImplicitZenRule_again_refreshesRuleName() {
6482         mZenModeHelper.mConfig.automaticRules.clear();
6483         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT,
6484                 mContext.getPackageName(), CUSTOM_PKG_UID, new Policy(0, 0, 0));
6485         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1);
6486         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).name)
6487                 .isEqualTo("Do Not Disturb (" + CUSTOM_APP_LABEL + ")");
6488         // "Break" the rule name to check that updating it again restores it.
6489         mZenModeHelper.mConfig.automaticRules.valueAt(0).name = "BOOM!";
6490 
6491         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT,
6492                 mContext.getPackageName(), CUSTOM_PKG_UID, new Policy(0, 0, 0));
6493 
6494         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).name)
6495                 .isEqualTo("Do Not Disturb (" + CUSTOM_APP_LABEL + ")");
6496     }
6497 
6498     @Test
6499     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
applyGlobalPolicyAsImplicitZenRule_again_doesNotChangeCustomizedRuleName()6500     public void applyGlobalPolicyAsImplicitZenRule_again_doesNotChangeCustomizedRuleName() {
6501         mZenModeHelper.mConfig.automaticRules.clear();
6502         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT,
6503                 mContext.getPackageName(), CUSTOM_PKG_UID, new Policy(0, 0, 0));
6504         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1);
6505         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).name)
6506                 .isEqualTo("Do Not Disturb (" + CUSTOM_APP_LABEL + ")");
6507         String ruleId = ZenModeConfig.implicitRuleId(mContext.getPackageName());
6508 
6509         // User chooses a new name.
6510         AutomaticZenRule azr = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT, ruleId);
6511         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId,
6512                 new AutomaticZenRule.Builder(azr).setName("User chose this").build(),
6513                 ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID);
6514 
6515         // App updates the implicit rule again.
6516         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT,
6517                 mContext.getPackageName(), CUSTOM_PKG_UID, new Policy(0, 0, 0));
6518 
6519         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).name)
6520                 .isEqualTo("User chose this");
6521     }
6522 
6523     @Test
6524     @DisableFlags(FLAG_MODES_API)
applyGlobalPolicyAsImplicitZenRule_flagOff_ignored()6525     public void applyGlobalPolicyAsImplicitZenRule_flagOff_ignored() {
6526         mZenModeHelper.mConfig.automaticRules.clear();
6527 
6528         withoutWtfCrash(
6529                 () -> mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT,
6530                         CUSTOM_PKG_NAME, CUSTOM_PKG_UID, new Policy(0, 0, 0)));
6531 
6532         assertThat(mZenModeHelper.mConfig.automaticRules).isEmpty();
6533     }
6534 
6535     @Test
6536     @EnableFlags(FLAG_MODES_API)
getNotificationPolicyFromImplicitZenRule_returnsSetPolicy()6537     public void getNotificationPolicyFromImplicitZenRule_returnsSetPolicy() {
6538         Policy writtenPolicy = new Policy(PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_CONVERSATIONS,
6539                 PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED,
6540                 Policy.getAllSuppressedVisualEffects(), STATE_FALSE,
6541                 CONVERSATION_SENDERS_IMPORTANT);
6542         mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6543                 CUSTOM_PKG_UID, writtenPolicy);
6544 
6545         Policy readPolicy = mZenModeHelper.getNotificationPolicyFromImplicitZenRule(
6546                 UserHandle.CURRENT, CUSTOM_PKG_NAME);
6547 
6548         assertThat(readPolicy).isEqualTo(writtenPolicy);
6549     }
6550 
6551     @Test
6552     @EnableFlags(FLAG_MODES_API)
6553     @DisableFlags(FLAG_MODES_UI)
getNotificationPolicyFromImplicitZenRule_ruleWithoutPolicy_copiesGlobalPolicy()6554     public void getNotificationPolicyFromImplicitZenRule_ruleWithoutPolicy_copiesGlobalPolicy() {
6555         // Implicit rule will get the global policy at the time of rule creation.
6556         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
6557                 CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
6558 
6559         // If the policy then changes afterwards, it should inherit updates because user cannot
6560         // edit the policy in the UI.
6561         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT,
6562                 new Policy(PRIORITY_CATEGORY_ALARMS, 0, 0), ORIGIN_APP, 1);
6563         Policy readPolicy = mZenModeHelper.getNotificationPolicyFromImplicitZenRule(
6564                 UserHandle.CURRENT, CUSTOM_PKG_NAME);
6565 
6566         assertThat(readPolicy).isNotNull();
6567         assertThat(readPolicy.allowCalls()).isFalse();
6568         assertThat(readPolicy.allowAlarms()).isTrue();
6569     }
6570 
6571     @Test
6572     @EnableFlags(FLAG_MODES_API)
getNotificationPolicyFromImplicitZenRule_noImplicitRule_returnsGlobalPolicy()6573     public void getNotificationPolicyFromImplicitZenRule_noImplicitRule_returnsGlobalPolicy() {
6574         Policy policy = new Policy(PRIORITY_CATEGORY_CALLS, PRIORITY_SENDERS_STARRED, 0);
6575         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, policy, ORIGIN_APP,
6576                 CUSTOM_PKG_UID);
6577 
6578         Policy readPolicy = mZenModeHelper.getNotificationPolicyFromImplicitZenRule(
6579                 UserHandle.CURRENT, CUSTOM_PKG_NAME);
6580 
6581         assertThat(readPolicy).isNotNull();
6582         assertThat(readPolicy.allowCalls()).isTrue();
6583         assertThat(readPolicy.allowConversations()).isFalse();
6584     }
6585 
6586     @Test
6587     @EnableFlags(FLAG_MODES_API)
6588     @DisableFlags(FLAG_MODES_UI)
setNotificationPolicy_updatesRulePolicies_ifRulePolicyIsDefaultOrGlobalPolicy()6589     public void setNotificationPolicy_updatesRulePolicies_ifRulePolicyIsDefaultOrGlobalPolicy() {
6590         ZenPolicy defaultZenPolicy = mZenModeHelper.getDefaultZenPolicy();
6591         Policy previousManualPolicy = mZenModeHelper.mConfig.toNotificationPolicy();
6592         ZenPolicy previousManualZenPolicy = ZenAdapters.notificationPolicyToZenPolicy(
6593                 previousManualPolicy);
6594         ZenPolicy customZenPolicy = new ZenPolicy.Builder(defaultZenPolicy).allowConversations(
6595                 CONVERSATION_SENDERS_ANYONE).build();
6596 
6597         mZenModeHelper.mConfig.automaticRules.clear();
6598         addZenRule(mZenModeHelper.mConfig, "appWithDefault", "app.pkg",
6599                 ZEN_MODE_IMPORTANT_INTERRUPTIONS, defaultZenPolicy);
6600         addZenRule(mZenModeHelper.mConfig, "appWithSameAsManual", "app.pkg",
6601                 ZEN_MODE_IMPORTANT_INTERRUPTIONS, previousManualZenPolicy);
6602         addZenRule(mZenModeHelper.mConfig, "appWithCustom", "app.pkg",
6603                 ZEN_MODE_IMPORTANT_INTERRUPTIONS, customZenPolicy);
6604         addZenRule(mZenModeHelper.mConfig, "appWithOtherFilter", "app.pkg",
6605                 ZEN_MODE_ALARMS, null);
6606         addZenRule(mZenModeHelper.mConfig, "systemWithDefault", "android",
6607                 ZEN_MODE_IMPORTANT_INTERRUPTIONS, defaultZenPolicy);
6608         addZenRule(mZenModeHelper.mConfig, "systemWithSameAsManual", "android",
6609                 ZEN_MODE_IMPORTANT_INTERRUPTIONS, previousManualZenPolicy);
6610 
6611         Policy newManualPolicy = new Policy(PRIORITY_CATEGORY_EVENTS, 0, 0);
6612         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, newManualPolicy, ORIGIN_APP,
6613                 CUSTOM_PKG_UID);
6614         ZenPolicy newManualZenPolicy = ZenAdapters.notificationPolicyToZenPolicy(newManualPolicy);
6615 
6616         // Only app rules with default or same-as-manual policies were updated.
6617         assertThat(mZenModeHelper.mConfig.automaticRules.get("appWithDefault").zenPolicy)
6618                 .isEqualTo(newManualZenPolicy);
6619         assertThat(mZenModeHelper.mConfig.automaticRules.get("appWithSameAsManual").zenPolicy)
6620                 .isEqualTo(newManualZenPolicy);
6621 
6622         assertThat(mZenModeHelper.mConfig.automaticRules.get("appWithCustom").zenPolicy)
6623                 .isEqualTo(customZenPolicy);
6624         assertThat(mZenModeHelper.mConfig.automaticRules.get("appWithOtherFilter").zenPolicy)
6625                 .isNull();
6626         assertThat(mZenModeHelper.mConfig.automaticRules.get("systemWithDefault").zenPolicy)
6627                 .isEqualTo(defaultZenPolicy);
6628         assertThat(mZenModeHelper.mConfig.automaticRules.get("systemWithSameAsManual").zenPolicy)
6629                 .isEqualTo(previousManualZenPolicy);
6630     }
6631 
6632     @Test
6633     @EnableFlags(Flags.FLAG_MODES_API)
addRule_iconIdWithResourceNameTooLong_ignoresIcon()6634     public void addRule_iconIdWithResourceNameTooLong_ignoresIcon() {
6635         int resourceId = 999;
6636         String veryLongResourceName = "com.android.server.notification:drawable/"
6637                 + "omg_this_is_one_long_resource_name".repeat(100);
6638         when(mResources.getResourceName(resourceId)).thenReturn(veryLongResourceName);
6639         when(mResources.getIdentifier(veryLongResourceName, null, null)).thenReturn(resourceId);
6640 
6641         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT,
6642                 mContext.getPackageName(),
6643                 new AutomaticZenRule.Builder("Rule", CONDITION_ID).setIconResId(resourceId).build(),
6644                 ORIGIN_APP, "reason", CUSTOM_PKG_UID);
6645         AutomaticZenRule storedRule = mZenModeHelper.getAutomaticZenRule(UserHandle.CURRENT,
6646                 ruleId);
6647 
6648         assertThat(storedRule.getIconResId()).isEqualTo(0);
6649     }
6650 
6651     @Test
6652     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setManualZenRuleDeviceEffects_noPreexistingMode()6653     public void setManualZenRuleDeviceEffects_noPreexistingMode() {
6654         ZenDeviceEffects effects = new ZenDeviceEffects.Builder()
6655                 .setShouldDimWallpaper(true)
6656                 .build();
6657         mZenModeHelper.setManualZenRuleDeviceEffects(UserHandle.CURRENT, effects,
6658                 ORIGIN_USER_IN_SYSTEMUI, "settings", SYSTEM_UID);
6659 
6660         assertThat(mZenModeHelper.getConfig().manualRule).isNotNull();
6661         assertThat(mZenModeHelper.getConfig().isManualActive()).isFalse();
6662         assertThat(mZenModeHelper.getConfig().manualRule.zenDeviceEffects).isEqualTo(effects);
6663     }
6664 
6665     @Test
6666     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setManualZenRuleDeviceEffects_preexistingMode()6667     public void setManualZenRuleDeviceEffects_preexistingMode() {
6668         mZenModeHelper.setManualZenMode(UserHandle.CURRENT, ZEN_MODE_OFF, Uri.EMPTY,
6669                 ORIGIN_USER_IN_SYSTEMUI, "create manual rule", "settings", SYSTEM_UID);
6670 
6671         ZenDeviceEffects effects = new ZenDeviceEffects.Builder()
6672                 .setShouldDimWallpaper(true)
6673                 .build();
6674         mZenModeHelper.setManualZenRuleDeviceEffects(UserHandle.CURRENT, effects,
6675                 ORIGIN_USER_IN_SYSTEMUI, "settings", SYSTEM_UID);
6676 
6677         assertThat(mZenModeHelper.getConfig().manualRule).isNotNull();
6678         assertThat(mZenModeHelper.getConfig().isManualActive()).isFalse();
6679         assertThat(mZenModeHelper.getConfig().manualRule.zenDeviceEffects).isEqualTo(effects);
6680     }
6681 
6682     @Test
6683     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
addAutomaticZenRule_startsDisabled_recordsDisabledOrigin()6684     public void addAutomaticZenRule_startsDisabled_recordsDisabledOrigin() {
6685         AutomaticZenRule startsDisabled = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
6686                 .setOwner(new ComponentName(mPkg, "SomeProvider"))
6687                 .setEnabled(false)
6688                 .build();
6689 
6690         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, startsDisabled,
6691                 ORIGIN_APP,
6692                 "new", CUSTOM_PKG_UID);
6693 
6694         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
6695                 ORIGIN_APP);
6696     }
6697 
6698     @Test
6699     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
updateAutomaticZenRule_disabling_recordsDisabledOrigin()6700     public void updateAutomaticZenRule_disabling_recordsDisabledOrigin() {
6701         AutomaticZenRule startsEnabled = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
6702                 .setOwner(new ComponentName(mPkg, "SomeProvider"))
6703                 .setEnabled(true)
6704                 .build();
6705         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, startsEnabled,
6706                 ORIGIN_APP,
6707                 "new", CUSTOM_PKG_UID);
6708         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
6709                 ORIGIN_UNKNOWN);
6710 
6711         AutomaticZenRule nowDisabled = new AutomaticZenRule.Builder(startsEnabled)
6712                 .setEnabled(false)
6713                 .build();
6714         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, nowDisabled,
6715                 ORIGIN_USER_IN_SYSTEMUI, "off", SYSTEM_UID);
6716 
6717         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
6718                 ORIGIN_USER_IN_SYSTEMUI);
6719     }
6720 
6721     @Test
6722     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
updateAutomaticZenRule_keepingDisabled_preservesPreviousDisabledOrigin()6723     public void updateAutomaticZenRule_keepingDisabled_preservesPreviousDisabledOrigin() {
6724         AutomaticZenRule startsEnabled = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
6725                 .setOwner(new ComponentName(mPkg, "SomeProvider"))
6726                 .setEnabled(true)
6727                 .build();
6728         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, startsEnabled,
6729                 ORIGIN_APP,
6730                 "new", CUSTOM_PKG_UID);
6731         AutomaticZenRule nowDisabled = new AutomaticZenRule.Builder(startsEnabled)
6732                 .setEnabled(false)
6733                 .build();
6734         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, nowDisabled,
6735                 ORIGIN_USER_IN_SYSTEMUI, "off", SYSTEM_UID);
6736         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
6737                 ORIGIN_USER_IN_SYSTEMUI);
6738 
6739         // Now update it again, for an unrelated reason with a different origin.
6740         AutomaticZenRule nowRenamed = new AutomaticZenRule.Builder(nowDisabled)
6741                 .setName("Fancy pants rule")
6742                 .build();
6743         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, nowRenamed, ORIGIN_APP,
6744                 "update", CUSTOM_PKG_UID);
6745 
6746         // Identity of the disabler is preserved.
6747         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
6748                 ORIGIN_USER_IN_SYSTEMUI);
6749     }
6750 
6751     @Test
6752     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
updateAutomaticZenRule_enabling_clearsDisabledOrigin()6753     public void updateAutomaticZenRule_enabling_clearsDisabledOrigin() {
6754         AutomaticZenRule startsEnabled = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
6755                 .setOwner(new ComponentName(mPkg, "SomeProvider"))
6756                 .setEnabled(true)
6757                 .build();
6758         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, startsEnabled,
6759                 ORIGIN_APP,
6760                 "new", CUSTOM_PKG_UID);
6761         AutomaticZenRule nowDisabled = new AutomaticZenRule.Builder(startsEnabled)
6762                 .setEnabled(false)
6763                 .build();
6764         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, nowDisabled,
6765                 ORIGIN_USER_IN_SYSTEMUI, "off", SYSTEM_UID);
6766         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
6767                 ORIGIN_USER_IN_SYSTEMUI);
6768 
6769         // Now enable it again
6770         AutomaticZenRule nowEnabled = new AutomaticZenRule.Builder(nowDisabled)
6771                 .setEnabled(true)
6772                 .build();
6773         mZenModeHelper.updateAutomaticZenRule(UserHandle.CURRENT, ruleId, nowEnabled, ORIGIN_APP,
6774                 "on", CUSTOM_PKG_UID);
6775 
6776         // Identity of the disabler was cleared.
6777         assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
6778                 ORIGIN_UNKNOWN);
6779     }
6780 
6781     @Test
6782     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_manualActivation_appliesOverride()6783     public void setAutomaticZenRuleState_manualActivation_appliesOverride() {
6784         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
6785                 .setPackage(mPkg)
6786                 .build();
6787         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
6788                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
6789 
6790         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6791                 new Condition(rule.getConditionId(), "manual-on", STATE_TRUE, SOURCE_USER_ACTION),
6792                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
6793 
6794         ZenRule zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6795         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_ACTIVATE);
6796         assertThat(zenRule.condition).isNull();
6797     }
6798 
6799     @Test
6800     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_manualActivationAndThenDeactivation_removesOverride()6801     public void setAutomaticZenRuleState_manualActivationAndThenDeactivation_removesOverride() {
6802         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
6803                 .setPackage(mPkg)
6804                 .build();
6805         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
6806                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
6807         Condition autoOn = new Condition(rule.getConditionId(), "auto-on", STATE_TRUE,
6808                 SOURCE_CONTEXT);
6809         ZenRule zenRule;
6810 
6811         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6812                 new Condition(rule.getConditionId(), "manual-on", STATE_TRUE, SOURCE_USER_ACTION),
6813                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
6814         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6815         assertThat(zenRule.isActive()).isTrue();
6816         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_ACTIVATE);
6817         assertThat(zenRule.condition).isNull();
6818 
6819         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6820                 new Condition(rule.getConditionId(), "manual-off", STATE_FALSE, SOURCE_USER_ACTION),
6821                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
6822         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6823         assertThat(zenRule.isActive()).isFalse();
6824         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6825         assertThat(zenRule.condition).isNull();
6826 
6827         // Bonus check: app has resumed control over the rule and can now turn it on.
6828         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, autoOn, ORIGIN_APP,
6829                 CUSTOM_PKG_UID);
6830         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6831         assertThat(zenRule.isActive()).isTrue();
6832         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6833         assertThat(zenRule.condition).isEqualTo(autoOn);
6834     }
6835 
6836     @Test
6837     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_manualDeactivationAndThenReactivation_removesOverride()6838     public void setAutomaticZenRuleState_manualDeactivationAndThenReactivation_removesOverride() {
6839         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
6840                 .setPackage(mPkg)
6841                 .build();
6842         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
6843                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
6844         Condition autoOn = new Condition(rule.getConditionId(), "auto-on", STATE_TRUE,
6845                 SOURCE_CONTEXT);
6846         Condition autoOff = new Condition(rule.getConditionId(), "auto-off", STATE_FALSE,
6847                 SOURCE_CONTEXT);
6848         ZenRule zenRule;
6849 
6850         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, autoOn, ORIGIN_APP,
6851                 CUSTOM_PKG_UID);
6852         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6853         assertThat(zenRule.isActive()).isTrue();
6854         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6855         assertThat(zenRule.condition).isEqualTo(autoOn);
6856 
6857         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6858                 new Condition(rule.getConditionId(), "manual-off", STATE_FALSE, SOURCE_USER_ACTION),
6859                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
6860         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6861         assertThat(zenRule.isActive()).isFalse();
6862         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_DEACTIVATE);
6863         assertThat(zenRule.condition).isEqualTo(autoOn);
6864 
6865         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6866                 new Condition(rule.getConditionId(), "manual-on", STATE_TRUE, SOURCE_USER_ACTION),
6867                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
6868         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6869         assertThat(zenRule.isActive()).isTrue();
6870         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6871         assertThat(zenRule.condition).isEqualTo(autoOn);
6872 
6873         // Bonus check: app has resumed control over the rule and can now turn it off.
6874         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, autoOff, ORIGIN_APP,
6875                 CUSTOM_PKG_UID);
6876         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6877         assertThat(zenRule.isActive()).isFalse();
6878         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6879         assertThat(zenRule.condition).isEqualTo(autoOff);
6880     }
6881 
6882     @Test
6883     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_manualDeactivation_appliesOverride()6884     public void setAutomaticZenRuleState_manualDeactivation_appliesOverride() {
6885         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
6886                 .setPackage(mPkg)
6887                 .build();
6888         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
6889                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
6890 
6891         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6892                 new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, SOURCE_CONTEXT),
6893                 ORIGIN_APP, CUSTOM_PKG_UID);
6894         ZenRule zenRuleOn = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6895         assertThat(zenRuleOn.isActive()).isTrue();
6896         assertThat(zenRuleOn.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6897         assertThat(zenRuleOn.condition).isNotNull();
6898 
6899         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6900                 new Condition(rule.getConditionId(), "manual-off", STATE_FALSE, SOURCE_USER_ACTION),
6901                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
6902         ZenRule zenRuleOff = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6903         assertThat(zenRuleOff.isActive()).isFalse();
6904         assertThat(zenRuleOff.getConditionOverride()).isEqualTo(OVERRIDE_DEACTIVATE);
6905         assertThat(zenRuleOff.condition).isNotNull();
6906     }
6907 
6908     @Test
6909     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_ifManualActive_appCannotDeactivateBeforeActivating()6910     public void setAutomaticZenRuleState_ifManualActive_appCannotDeactivateBeforeActivating() {
6911         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
6912                 .setPackage(mPkg)
6913                 .build();
6914         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
6915                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
6916         ZenRule zenRule;
6917 
6918         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6919                 new Condition(rule.getConditionId(), "manual-on", STATE_TRUE, SOURCE_USER_ACTION),
6920                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
6921         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6922         assertThat(zenRule.isActive()).isTrue();
6923         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_ACTIVATE);
6924 
6925         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6926                 new Condition(rule.getConditionId(), "auto-off", STATE_FALSE, SOURCE_CONTEXT),
6927                 ORIGIN_APP, CUSTOM_PKG_UID);
6928         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6929         assertThat(zenRule.isActive()).isTrue();
6930         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_ACTIVATE);
6931 
6932         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6933                 new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, SOURCE_CONTEXT),
6934                 ORIGIN_APP, CUSTOM_PKG_UID);
6935         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6936         assertThat(zenRule.isActive()).isTrue();
6937         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6938         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6939                 new Condition(rule.getConditionId(), "auto-off", STATE_FALSE, SOURCE_CONTEXT),
6940                 ORIGIN_APP, CUSTOM_PKG_UID);
6941         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6942         assertThat(zenRule.isActive()).isFalse();
6943     }
6944 
6945     @Test
6946     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_ifManualInactive_appCannotReactivateBeforeDeactivating()6947     public void setAutomaticZenRuleState_ifManualInactive_appCannotReactivateBeforeDeactivating() {
6948         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
6949                 .setPackage(mPkg)
6950                 .build();
6951         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
6952                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
6953         ZenRule zenRule;
6954 
6955         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6956                 new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, SOURCE_CONTEXT),
6957                 ORIGIN_APP, CUSTOM_PKG_UID);
6958         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6959         assertThat(zenRule.isActive()).isTrue();
6960         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6961 
6962         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6963                 new Condition(rule.getConditionId(), "manual-off", STATE_FALSE, SOURCE_USER_ACTION),
6964                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
6965         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6966         assertThat(zenRule.isActive()).isFalse();
6967         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_DEACTIVATE);
6968 
6969         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6970                 new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, SOURCE_CONTEXT),
6971                 ORIGIN_APP, CUSTOM_PKG_UID);
6972         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6973         assertThat(zenRule.isActive()).isFalse();
6974         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_DEACTIVATE);
6975 
6976         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6977                 new Condition(rule.getConditionId(), "auto-off", STATE_FALSE, SOURCE_CONTEXT),
6978                 ORIGIN_APP, CUSTOM_PKG_UID);
6979         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6980         assertThat(zenRule.isActive()).isFalse();
6981         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6982 
6983         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
6984                 new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, SOURCE_CONTEXT),
6985                 ORIGIN_APP, CUSTOM_PKG_UID);
6986         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
6987         assertThat(zenRule.isActive()).isTrue();
6988         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
6989     }
6990 
6991     @Test
6992     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_withActivationOverride_userActionFromAppCanDeactivate()6993     public void setAutomaticZenRuleState_withActivationOverride_userActionFromAppCanDeactivate() {
6994         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
6995                 .setPackage(mPkg)
6996                 .build();
6997         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
6998                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
6999 
7000         // User manually turns on rule from SysUI / Settings...
7001         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7002                 new Condition(rule.getConditionId(), "manual-on-from-sysui", STATE_TRUE,
7003                         SOURCE_USER_ACTION), ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
7004         assertThat(getZenRule(ruleId).isActive()).isTrue();
7005         assertThat(getZenRule(ruleId).getConditionOverride()).isEqualTo(OVERRIDE_ACTIVATE);
7006 
7007         // ... and they can turn it off manually from inside the app.
7008         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7009                 new Condition(rule.getConditionId(), "manual-off-from-app", STATE_FALSE,
7010                         SOURCE_USER_ACTION), ORIGIN_USER_IN_APP, CUSTOM_PKG_UID);
7011         assertThat(getZenRule(ruleId).isActive()).isFalse();
7012         assertThat(getZenRule(ruleId).getConditionOverride()).isEqualTo(OVERRIDE_NONE);
7013     }
7014 
7015     @Test
7016     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_withDeactivationOverride_userActionFromAppCanActivate()7017     public void setAutomaticZenRuleState_withDeactivationOverride_userActionFromAppCanActivate() {
7018         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
7019                 .setPackage(mPkg)
7020                 .build();
7021         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
7022                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
7023 
7024         // Rule is activated due to its schedule.
7025         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7026                 new Condition(rule.getConditionId(), "auto-on-from-app", STATE_TRUE,
7027                         SOURCE_SCHEDULE), ORIGIN_APP, CUSTOM_PKG_UID);
7028         assertThat(getZenRule(ruleId).isActive()).isTrue();
7029         assertThat(getZenRule(ruleId).getConditionOverride()).isEqualTo(OVERRIDE_NONE);
7030 
7031         // User manually turns off rule from SysUI / Settings...
7032         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7033                 new Condition(rule.getConditionId(), "manual-off-from-sysui", STATE_FALSE,
7034                         SOURCE_USER_ACTION), ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
7035         assertThat(getZenRule(ruleId).isActive()).isFalse();
7036         assertThat(getZenRule(ruleId).getConditionOverride()).isEqualTo(OVERRIDE_DEACTIVATE);
7037 
7038         // ... and they can turn it on manually from inside the app.
7039         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7040                 new Condition(rule.getConditionId(), "manual-on-from-app", STATE_TRUE,
7041                         SOURCE_USER_ACTION), ORIGIN_USER_IN_APP, CUSTOM_PKG_UID);
7042         assertThat(getZenRule(ruleId).isActive()).isTrue();
7043         assertThat(getZenRule(ruleId).getConditionOverride()).isEqualTo(OVERRIDE_NONE);
7044     }
7045 
7046     @Test
7047     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_manualActionFromApp_isNotOverride()7048     public void setAutomaticZenRuleState_manualActionFromApp_isNotOverride() {
7049         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
7050                 .setPackage(mPkg)
7051                 .build();
7052         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
7053                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
7054 
7055         // Rule is manually activated by the user in the app.
7056         // This turns the rule on, but is NOT an override...
7057         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7058                 new Condition(rule.getConditionId(), "manual-on-from-app", STATE_TRUE,
7059                         SOURCE_USER_ACTION), ORIGIN_USER_IN_APP, CUSTOM_PKG_UID);
7060         assertThat(getZenRule(ruleId).isActive()).isTrue();
7061         assertThat(getZenRule(ruleId).getConditionOverride()).isEqualTo(OVERRIDE_NONE);
7062 
7063         // ... so the app can turn it off when its schedule is over.
7064         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7065                 new Condition(rule.getConditionId(), "auto-off-from-app", STATE_FALSE,
7066                         SOURCE_SCHEDULE), ORIGIN_APP, CUSTOM_PKG_UID);
7067         assertThat(getZenRule(ruleId).isActive()).isFalse();
7068         assertThat(getZenRule(ruleId).getConditionOverride()).isEqualTo(OVERRIDE_NONE);
7069     }
7070 
7071     @Test
7072     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_implicitRuleManualActivation_doesNotUseOverride()7073     public void setAutomaticZenRuleState_implicitRuleManualActivation_doesNotUseOverride() {
7074         mContext.getTestablePermissions().setPermission(Manifest.permission.MANAGE_NOTIFICATIONS,
7075                 PERMISSION_GRANTED); // So that canManageAZR succeeds.
7076         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
7077                 CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
7078         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
7079                 CUSTOM_PKG_UID, ZEN_MODE_OFF);
7080         ZenRule implicitRule = getZenRule(implicitRuleId(CUSTOM_PKG_NAME));
7081         assertThat(implicitRule.isActive()).isFalse();
7082 
7083         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, implicitRule.id,
7084                 new Condition(implicitRule.conditionId, "on!", STATE_TRUE, SOURCE_USER_ACTION),
7085                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
7086 
7087         implicitRule = getZenRule(implicitRuleId(CUSTOM_PKG_NAME));
7088         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, implicitRule.id))
7089                 .isEqualTo(STATE_TRUE);
7090         assertThat(implicitRule.isActive()).isTrue();
7091         assertThat(implicitRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
7092     }
7093 
7094     @Test
7095     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_implicitRuleManualDeactivation_doesNotUseOverride()7096     public void setAutomaticZenRuleState_implicitRuleManualDeactivation_doesNotUseOverride() {
7097         mContext.getTestablePermissions().setPermission(Manifest.permission.MANAGE_NOTIFICATIONS,
7098                 PERMISSION_GRANTED); // So that canManageAZR succeeds.
7099         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(UserHandle.CURRENT, CUSTOM_PKG_NAME,
7100                 CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
7101         ZenRule implicitRule = getZenRule(implicitRuleId(CUSTOM_PKG_NAME));
7102         assertThat(implicitRule.isActive()).isTrue();
7103 
7104         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, implicitRule.id,
7105                 new Condition(implicitRule.conditionId, "off!", STATE_FALSE, SOURCE_USER_ACTION),
7106                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
7107 
7108         implicitRule = getZenRule(implicitRuleId(CUSTOM_PKG_NAME));
7109         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, implicitRule.id))
7110                 .isEqualTo(STATE_FALSE);
7111         assertThat(implicitRule.isActive()).isFalse();
7112         assertThat(implicitRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
7113     }
7114 
getZenRule(String ruleId)7115     private ZenRule getZenRule(String ruleId) {
7116         return checkNotNull(mZenModeHelper.mConfig.automaticRules.get(ruleId),
7117                 "Didn't find rule with id %s", ruleId);
7118     }
7119 
7120     @Test
7121     @DisableFlags({FLAG_MODES_API, FLAG_MODES_UI})
testDefaultConfig_preModesApi_rulesAreBare()7122     public void testDefaultConfig_preModesApi_rulesAreBare() {
7123         // Create a new user, which should get a copy of the default policy.
7124         mZenModeHelper.onUserSwitched(101);
7125 
7126         ZenRule eventsRule = mZenModeHelper.mConfig.automaticRules.get(
7127                 ZenModeConfig.EVENTS_OBSOLETE_RULE_ID);
7128 
7129         assertThat(eventsRule).isNotNull();
7130         assertThat(eventsRule.zenPolicy).isNull();
7131         assertThat(eventsRule.type).isEqualTo(TYPE_UNKNOWN);
7132         assertThat(eventsRule.triggerDescription).isNull();
7133     }
7134 
7135     @Test
7136     @EnableFlags(FLAG_MODES_API)
7137     @DisableFlags(FLAG_MODES_UI)
testDefaultConfig_modesApi_rulesHaveFullPolicy()7138     public void testDefaultConfig_modesApi_rulesHaveFullPolicy() {
7139         // Create a new user, which should get a copy of the default policy.
7140         mZenModeHelper.onUserSwitched(201);
7141 
7142         ZenRule eventsRule = mZenModeHelper.mConfig.automaticRules.get(
7143                 ZenModeConfig.EVENTS_OBSOLETE_RULE_ID);
7144 
7145         assertThat(eventsRule).isNotNull();
7146         assertThat(eventsRule.zenPolicy).isEqualTo(mZenModeHelper.getDefaultZenPolicy());
7147         assertThat(eventsRule.type).isEqualTo(TYPE_UNKNOWN);
7148         assertThat(eventsRule.triggerDescription).isNull();
7149     }
7150 
7151     @Test
7152     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
testDefaultConfig_modesUi_rulesHaveFullPolicy()7153     public void testDefaultConfig_modesUi_rulesHaveFullPolicy() {
7154         // Create a new user, which should get a copy of the default policy.
7155         mZenModeHelper.onUserSwitched(301);
7156 
7157         ZenRule eventsRule = mZenModeHelper.mConfig.automaticRules.get(
7158                 ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID);
7159 
7160         assertThat(eventsRule).isNotNull();
7161         assertThat(eventsRule.zenPolicy).isEqualTo(mZenModeHelper.getDefaultZenPolicy());
7162         assertThat(eventsRule.type).isEqualTo(TYPE_SCHEDULE_TIME);
7163         assertThat(eventsRule.triggerDescription).isNotEmpty();
7164     }
7165 
7166     @Test
7167     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_withManualActivation_activeOnReboot()7168     public void setAutomaticZenRuleState_withManualActivation_activeOnReboot()
7169             throws Exception {
7170         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
7171                 .setPackage(mPkg)
7172                 .build();
7173         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
7174                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
7175         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7176                 new Condition(rule.getConditionId(), "manual-on", STATE_TRUE, SOURCE_USER_ACTION),
7177                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
7178         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, ruleId))
7179                 .isEqualTo(STATE_TRUE);
7180         ZenRule zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
7181         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_ACTIVATE);
7182         assertThat(zenRule.condition).isNull();
7183 
7184         ByteArrayOutputStream xmlBytes = writeXmlAndPurge(ZenModeConfig.XML_VERSION_MODES_UI);
7185         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
7186         assertThat(zenRule).isNull();
7187 
7188         // Now simulate a reboot -> reload the configuration after purging.
7189         TypedXmlPullParser parser = getParserForByteStream(xmlBytes);
7190         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
7191 
7192         if (Flags.modesUi()) {
7193             assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, ruleId))
7194                     .isEqualTo(STATE_TRUE);
7195             zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
7196             assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_ACTIVATE);
7197             assertThat(zenRule.condition).isNull();
7198         } else {
7199             assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, ruleId))
7200                     .isEqualTo(STATE_FALSE);
7201         }
7202     }
7203 
7204     @Test
7205     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
setAutomaticZenRuleState_withManualDeactivation_clearedOnReboot()7206     public void setAutomaticZenRuleState_withManualDeactivation_clearedOnReboot()
7207             throws Exception {
7208         AutomaticZenRule rule = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
7209                 .setPackage(mPkg)
7210                 .build();
7211         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, rule,
7212                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
7213         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7214                 new Condition(rule.getConditionId(), "auto-on", STATE_TRUE, SOURCE_CONTEXT),
7215                 ORIGIN_APP, CUSTOM_PKG_UID);
7216         mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId,
7217                 new Condition(rule.getConditionId(), "snooze", STATE_FALSE, SOURCE_USER_ACTION),
7218                 ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID);
7219         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, ruleId))
7220                 .isEqualTo(STATE_FALSE);
7221         ZenRule zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
7222         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_DEACTIVATE);
7223         assertThat(zenRule.condition).isNotNull();
7224 
7225         ByteArrayOutputStream xmlBytes = writeXmlAndPurge(ZenModeConfig.XML_VERSION_MODES_UI);
7226         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
7227         assertThat(zenRule).isNull();
7228 
7229         // Now simulate a reboot -> reload the configuration after purging.
7230         TypedXmlPullParser parser = getParserForByteStream(xmlBytes);
7231         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
7232 
7233         assertThat(mZenModeHelper.getAutomaticZenRuleState(UserHandle.CURRENT, ruleId))
7234                 .isEqualTo(STATE_TRUE);
7235         zenRule = mZenModeHelper.mConfig.automaticRules.get(ruleId);
7236         assertThat(zenRule.getConditionOverride()).isEqualTo(OVERRIDE_NONE);
7237         assertThat(zenRule.condition).isNotNull();
7238     }
7239 
7240     @Test
7241     @EnableFlags(FLAG_MODES_API)
addAutomaticZenRule_withoutPolicy_getsItsOwnInstanceOfDefaultPolicy()7242     public void addAutomaticZenRule_withoutPolicy_getsItsOwnInstanceOfDefaultPolicy() {
7243         // Add a rule without policy -> uses default config
7244         AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.parse("cond"))
7245                 .setPackage(mPkg)
7246                 .build();
7247         String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, azr,
7248                 ORIGIN_APP, "adding", CUSTOM_PKG_UID);
7249 
7250         ZenRule zenRule = checkNotNull(mZenModeHelper.mConfig.automaticRules.get(ruleId));
7251 
7252         assertThat(zenRule.zenPolicy).isEqualTo(mZenModeHelper.getDefaultZenPolicy());
7253         assertThat(zenRule.zenPolicy).isNotSameInstanceAs(mZenModeHelper.getDefaultZenPolicy());
7254     }
7255 
7256     @Test
7257     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
readXml_withDisabledEventsRule_deletesIt()7258     public void readXml_withDisabledEventsRule_deletesIt() throws Exception {
7259         ZenRule rule = new ZenRule();
7260         rule.id = ZenModeConfig.EVENTS_OBSOLETE_RULE_ID;
7261         rule.name = "Events";
7262         rule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
7263         rule.conditionId = Uri.parse("events");
7264 
7265         rule.enabled = false;
7266         mZenModeHelper.mConfig.automaticRules.put(ZenModeConfig.EVENTS_OBSOLETE_RULE_ID, rule);
7267         ByteArrayOutputStream xmlBytes = writeXmlAndPurge(ZenModeConfig.XML_VERSION_MODES_UI);
7268         TypedXmlPullParser parser = getParserForByteStream(xmlBytes);
7269 
7270         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
7271 
7272         assertThat(mZenModeHelper.mConfig.automaticRules).doesNotContainKey(
7273                 ZenModeConfig.EVENTS_OBSOLETE_RULE_ID);
7274     }
7275 
7276     @Test
7277     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
readXml_withEnabledEventsRule_keepsIt()7278     public void readXml_withEnabledEventsRule_keepsIt() throws Exception {
7279         ZenRule rule = new ZenRule();
7280         rule.id = ZenModeConfig.EVENTS_OBSOLETE_RULE_ID;
7281         rule.name = "Events";
7282         rule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
7283         rule.conditionId = Uri.parse("events");
7284 
7285         rule.enabled = true;
7286         mZenModeHelper.mConfig.automaticRules.put(ZenModeConfig.EVENTS_OBSOLETE_RULE_ID, rule);
7287         ByteArrayOutputStream xmlBytes = writeXmlAndPurge(ZenModeConfig.XML_VERSION_MODES_UI);
7288         TypedXmlPullParser parser = getParserForByteStream(xmlBytes);
7289 
7290         mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL, null);
7291 
7292         assertThat(mZenModeHelper.mConfig.automaticRules).containsKey(
7293                 ZenModeConfig.EVENTS_OBSOLETE_RULE_ID);
7294     }
7295 
7296     @Test
7297     @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
updateHasPriorityChannels_keepsChannelSettings()7298     public void updateHasPriorityChannels_keepsChannelSettings() {
7299         setupZenConfig();
7300 
7301         // Set priority channels setting on manual mode to confirm that it is unaffected by changes
7302         // to the state describing the existence of such channels.
7303         mZenModeHelper.mConfig.manualRule.zenPolicy =
7304                 new ZenPolicy.Builder(mZenModeHelper.mConfig.manualRule.zenPolicy)
7305                         .allowPriorityChannels(false)
7306                         .build();
7307 
7308         mZenModeHelper.updateHasPriorityChannels(UserHandle.CURRENT, true);
7309         assertThat(mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT).hasPriorityChannels())
7310                 .isTrue();
7311 
7312         // getNotificationPolicy() gets its policy from the manual rule; channels not permitted
7313         assertThat(mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT).allowPriorityChannels())
7314                 .isFalse();
7315 
7316         mZenModeHelper.updateHasPriorityChannels(UserHandle.CURRENT, false);
7317         assertThat(mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT).hasPriorityChannels())
7318                 .isFalse();
7319         assertThat(mZenModeHelper.getNotificationPolicy(UserHandle.CURRENT).allowPriorityChannels())
7320                 .isFalse();
7321     }
7322 
7323     @Test
7324     @EnableFlags(FLAG_MODES_MULTIUSER)
setManualZenMode_fromCurrentUser_updatesCurrentConfig()7325     public void setManualZenMode_fromCurrentUser_updatesCurrentConfig() {
7326         // Initialize default configurations (default rules) for both users.
7327         mZenModeHelper.onUserSwitched(1);
7328         mZenModeHelper.onUserSwitched(2);
7329         UserHandle currentUser = UserHandle.of(2);
7330         ZenModeHelper.Callback callback = mock(ZenModeHelper.Callback.class);
7331         mZenModeHelper.addCallback(callback);
7332 
7333         mZenModeHelper.setManualZenMode(currentUser, ZEN_MODE_ALARMS, null, ORIGIN_APP, "reason",
7334                 mPkg, CUSTOM_PKG_UID);
7335 
7336         assertThat(mZenModeHelper.mConfig.isManualActive()).isTrue();
7337         assertThat(mZenModeHelper.mConfigs.get(1).isManualActive()).isFalse();
7338 
7339         // And we sent the broadcast announcing the change.
7340         mTestableLooper.processAllMessages();
7341         verify(callback).onZenModeChanged();
7342     }
7343 
7344     @Test
7345     @EnableFlags(FLAG_MODES_MULTIUSER)
setInterruptionFilter_fromNonCurrentUser_updatesNonCurrentConfig()7346     public void setInterruptionFilter_fromNonCurrentUser_updatesNonCurrentConfig() {
7347         // Initialize default configurations (default rules) for both users.
7348         // Afterwards, 2 is current, and 1 is background.
7349         mZenModeHelper.onUserSwitched(1);
7350         mZenModeHelper.onUserSwitched(2);
7351         UserHandle backgroundUser = UserHandle.of(1);
7352         ZenModeHelper.Callback callback = mock(ZenModeHelper.Callback.class);
7353         mZenModeHelper.addCallback(callback);
7354 
7355         mZenModeHelper.setManualZenMode(backgroundUser, ZEN_MODE_ALARMS, null, ORIGIN_APP, "reason",
7356                 mPkg, CUSTOM_PKG_UID);
7357 
7358         assertThat(mZenModeHelper.mConfig.isManualActive()).isFalse();
7359         assertThat(mZenModeHelper.mConfigs.get(1).isManualActive()).isTrue();
7360 
7361         // And no broadcasts is sent for "background" changes (they were not evaluated).
7362         mTestableLooper.processAllMessages();
7363         verify(callback, never()).onZenModeChanged();
7364     }
7365 
7366     @Test
7367     @EnableFlags(FLAG_MODES_MULTIUSER)
getNotificationPolicy_fromUserWithoutZenConfig_returnsDefaultPolicy()7368     public void getNotificationPolicy_fromUserWithoutZenConfig_returnsDefaultPolicy() {
7369         // Set a custom policy for the current user to double check we return a default one below.
7370         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, new Policy(0, 0, 0), ORIGIN_SYSTEM,
7371                 SYSTEM_UID);
7372 
7373         Policy ghostPolicy = mZenModeHelper.getNotificationPolicy(UserHandle.of(5552368));
7374 
7375         assertThat(ghostPolicy).isNotNull();
7376         assertThat(ZenAdapters.notificationPolicyToZenPolicy(ghostPolicy))
7377                 .isEqualTo(mZenModeHelper.getDefaultZenPolicy());
7378     }
7379 
addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode, @Nullable ZenPolicy zenPolicy)7380     private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode,
7381             @Nullable ZenPolicy zenPolicy) {
7382         ZenRule rule = new ZenRule();
7383         rule.id = id;
7384         rule.pkg = ownerPkg;
7385         rule.enabled = true;
7386         rule.zenMode = zenMode;
7387         rule.zenPolicy = zenPolicy;
7388         // Plus stuff so that isValidAutomaticRule() passes
7389         rule.name = String.format("Rule %s from %s with mode=%s and policy=%s", id, ownerPkg,
7390                 zenMode, zenPolicy);
7391         rule.conditionId = Uri.parse(rule.name);
7392 
7393         config.automaticRules.put(id, rule);
7394     }
7395 
7396     private static final Correspondence<ZenRule, ZenRule> IGNORE_METADATA =
7397             Correspondence.transforming(zr -> {
7398                         Parcel p = Parcel.obtain();
7399                         try {
7400                             zr.writeToParcel(p, 0);
7401                             p.setDataPosition(0);
7402                             ZenRule copy = new ZenRule(p);
7403                             copy.creationTime = 0;
7404                             copy.userModifiedFields = 0;
7405                             copy.zenPolicyUserModifiedFields = 0;
7406                             copy.zenDeviceEffectsUserModifiedFields = 0;
7407                             return copy;
7408                         } finally {
7409                             p.recycle();
7410                         }
7411                     },
7412                     "Ignoring timestamp and userModifiedFields");
7413 
expectedImplicitRule(String ownerPkg, int zenMode, ZenPolicy policy, @Nullable Boolean conditionActive)7414     private ZenRule expectedImplicitRule(String ownerPkg, int zenMode, ZenPolicy policy,
7415             @Nullable Boolean conditionActive) {
7416         ZenRule rule = new ZenModeConfig.ZenRule();
7417         rule.id = "implicit_" + ownerPkg;
7418         rule.conditionId = Uri.parse("condition://android/implicit/" + ownerPkg);
7419         if (conditionActive != null) {
7420             rule.condition = conditionActive
7421                     ? new Condition(rule.conditionId,
7422                     mContext.getString(R.string.zen_mode_implicit_activated), STATE_TRUE)
7423                     : new Condition(rule.conditionId,
7424                             mContext.getString(R.string.zen_mode_implicit_deactivated),
7425                             STATE_FALSE);
7426         }
7427         rule.zenMode = zenMode;
7428         rule.zenPolicy = policy;
7429         rule.pkg = ownerPkg;
7430         if (Flags.modesUi()) {
7431             rule.name = mContext.getString(R.string.zen_mode_implicit_name, CUSTOM_APP_LABEL);
7432         } else {
7433             rule.name = CUSTOM_APP_LABEL;
7434         }
7435         rule.triggerDescription = mContext.getString(R.string.zen_mode_implicit_trigger_description,
7436                 CUSTOM_APP_LABEL);
7437         rule.type = AutomaticZenRule.TYPE_OTHER;
7438         rule.enabled = true;
7439         return rule;
7440     }
7441 
7442     // TODO: b/310620812 - Update setup methods to include allowChannels() when MODES_API is inlined
setupZenConfig()7443     private void setupZenConfig() {
7444         Policy customPolicy = new Policy(PRIORITY_CATEGORY_REMINDERS
7445                 | PRIORITY_CATEGORY_CALLS | PRIORITY_CATEGORY_MESSAGES
7446                 | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REPEAT_CALLERS
7447                 | PRIORITY_CATEGORY_CONVERSATIONS,
7448                 PRIORITY_SENDERS_STARRED,
7449                 PRIORITY_SENDERS_STARRED,
7450                 SUPPRESSED_EFFECT_BADGE,
7451                 0,
7452                 CONVERSATION_SENDERS_IMPORTANT);
7453         mZenModeHelper.setNotificationPolicy(UserHandle.CURRENT, customPolicy, ORIGIN_UNKNOWN, 1);
7454         if (!Flags.modesUi()) {
7455             mZenModeHelper.mConfig.manualRule = null;
7456         }
7457     }
7458 
checkDndProtoMatchesSetupZenConfig(DNDPolicyProto dndProto)7459     private void checkDndProtoMatchesSetupZenConfig(DNDPolicyProto dndProto) {
7460         assertEquals(STATE_DISALLOW, dndProto.getAlarms().getNumber());
7461         assertEquals(STATE_DISALLOW, dndProto.getMedia().getNumber());
7462         assertEquals(STATE_DISALLOW, dndProto.getSystem().getNumber());
7463         assertEquals(STATE_ALLOW, dndProto.getReminders().getNumber());
7464         assertEquals(STATE_ALLOW, dndProto.getCalls().getNumber());
7465         assertEquals(PEOPLE_STARRED, dndProto.getAllowCallsFrom().getNumber());
7466         assertEquals(STATE_ALLOW, dndProto.getMessages().getNumber());
7467         assertEquals(STATE_ALLOW, dndProto.getEvents().getNumber());
7468         assertEquals(STATE_ALLOW, dndProto.getRepeatCallers().getNumber());
7469         assertEquals(STATE_ALLOW, dndProto.getFullscreen().getNumber());
7470         assertEquals(STATE_ALLOW, dndProto.getLights().getNumber());
7471         assertEquals(STATE_ALLOW, dndProto.getPeek().getNumber());
7472         assertEquals(STATE_ALLOW, dndProto.getStatusBar().getNumber());
7473         assertEquals(STATE_DISALLOW, dndProto.getBadge().getNumber());
7474         assertEquals(STATE_ALLOW, dndProto.getAmbient().getNumber());
7475         assertEquals(STATE_ALLOW, dndProto.getNotificationList().getNumber());
7476     }
7477 
checkDndProtoMatchesDefaultZenConfig(DNDPolicyProto dndProto)7478     private void checkDndProtoMatchesDefaultZenConfig(DNDPolicyProto dndProto) {
7479         if (!Flags.modesUi()) {
7480             checkDndProtoMatchesSetupZenConfig(dndProto);
7481             return;
7482         }
7483 
7484         // When modes_api flag is on, the default zen config is the device defaults.
7485         assertThat(dndProto.getAlarms().getNumber()).isEqualTo(STATE_ALLOW);
7486         assertThat(dndProto.getMedia().getNumber()).isEqualTo(STATE_ALLOW);
7487         assertThat(dndProto.getSystem().getNumber()).isEqualTo(STATE_DISALLOW);
7488         assertThat(dndProto.getReminders().getNumber()).isEqualTo(STATE_DISALLOW);
7489         assertThat(dndProto.getCalls().getNumber()).isEqualTo(STATE_ALLOW);
7490         assertThat(dndProto.getAllowCallsFrom().getNumber()).isEqualTo(PEOPLE_STARRED);
7491         assertThat(dndProto.getMessages().getNumber()).isEqualTo(STATE_ALLOW);
7492         assertThat(dndProto.getAllowMessagesFrom().getNumber()).isEqualTo(PEOPLE_STARRED);
7493         assertThat(dndProto.getEvents().getNumber()).isEqualTo(STATE_DISALLOW);
7494         assertThat(dndProto.getRepeatCallers().getNumber()).isEqualTo(STATE_ALLOW);
7495         assertThat(dndProto.getFullscreen().getNumber()).isEqualTo(STATE_DISALLOW);
7496         assertThat(dndProto.getLights().getNumber()).isEqualTo(STATE_DISALLOW);
7497         assertThat(dndProto.getPeek().getNumber()).isEqualTo(STATE_DISALLOW);
7498         assertThat(dndProto.getStatusBar().getNumber()).isEqualTo(STATE_ALLOW);
7499         assertThat(dndProto.getBadge().getNumber()).isEqualTo(STATE_ALLOW);
7500         assertThat(dndProto.getAmbient().getNumber()).isEqualTo(STATE_DISALLOW);
7501         assertThat(dndProto.getNotificationList().getNumber()).isEqualTo(STATE_ALLOW);
7502     }
7503 
withoutWtfCrash(Runnable test)7504     private static void withoutWtfCrash(Runnable test) {
7505         Log.TerribleFailureHandler oldHandler = Log.setWtfHandler((tag, what, system) -> {
7506         });
7507         try {
7508             test.run();
7509         } finally {
7510             Log.setWtfHandler(oldHandler);
7511         }
7512     }
7513 
7514     /**
7515      * Wrapper to use TypedXmlPullParser as XmlResourceParser for Resources.getXml()
7516      */
7517     final class XmlResourceParserImpl implements XmlResourceParser {
7518         private TypedXmlPullParser parser;
7519 
XmlResourceParserImpl(TypedXmlPullParser parser)7520         public XmlResourceParserImpl(TypedXmlPullParser parser) {
7521             this.parser = parser;
7522         }
7523 
getEventType()7524         public int getEventType() throws XmlPullParserException {
7525             return parser.getEventType();
7526         }
7527 
7528         @Override
setFeature(String name, boolean state)7529         public void setFeature(String name, boolean state) throws XmlPullParserException {
7530             parser.setFeature(name, state);
7531         }
7532 
7533         @Override
getFeature(String name)7534         public boolean getFeature(String name) {
7535             return false;
7536         }
7537 
7538         @Override
setProperty(String name, Object value)7539         public void setProperty(String name, Object value) throws XmlPullParserException {
7540             parser.setProperty(name, value);
7541         }
7542 
7543         @Override
getProperty(String name)7544         public Object getProperty(String name) {
7545             return parser.getProperty(name);
7546         }
7547 
7548         @Override
setInput(Reader in)7549         public void setInput(Reader in) throws XmlPullParserException {
7550             parser.setInput(in);
7551         }
7552 
7553         @Override
setInput(InputStream inputStream, String inputEncoding)7554         public void setInput(InputStream inputStream, String inputEncoding)
7555                 throws XmlPullParserException {
7556             parser.setInput(inputStream, inputEncoding);
7557         }
7558 
7559         @Override
getInputEncoding()7560         public String getInputEncoding() {
7561             return parser.getInputEncoding();
7562         }
7563 
7564         @Override
defineEntityReplacementText(String entityName, String replacementText)7565         public void defineEntityReplacementText(String entityName, String replacementText)
7566                 throws XmlPullParserException {
7567             parser.defineEntityReplacementText(entityName, replacementText);
7568         }
7569 
7570         @Override
getNamespaceCount(int depth)7571         public int getNamespaceCount(int depth) throws XmlPullParserException {
7572             return parser.getNamespaceCount(depth);
7573         }
7574 
7575         @Override
getNamespacePrefix(int pos)7576         public String getNamespacePrefix(int pos) throws XmlPullParserException {
7577             return parser.getNamespacePrefix(pos);
7578         }
7579 
7580         @Override
getNamespaceUri(int pos)7581         public String getNamespaceUri(int pos) throws XmlPullParserException {
7582             return parser.getNamespaceUri(pos);
7583         }
7584 
7585         @Override
getNamespace(String prefix)7586         public String getNamespace(String prefix) {
7587             return parser.getNamespace(prefix);
7588         }
7589 
7590         @Override
getDepth()7591         public int getDepth() {
7592             return parser.getDepth();
7593         }
7594 
7595         @Override
getPositionDescription()7596         public String getPositionDescription() {
7597             return parser.getPositionDescription();
7598         }
7599 
7600         @Override
getLineNumber()7601         public int getLineNumber() {
7602             return parser.getLineNumber();
7603         }
7604 
7605         @Override
getColumnNumber()7606         public int getColumnNumber() {
7607             return parser.getColumnNumber();
7608         }
7609 
7610         @Override
isWhitespace()7611         public boolean isWhitespace() throws XmlPullParserException {
7612             return parser.isWhitespace();
7613         }
7614 
7615         @Override
getText()7616         public String getText() {
7617             return parser.getText();
7618         }
7619 
7620         @Override
getTextCharacters(int[] holderForStartAndLength)7621         public char[] getTextCharacters(int[] holderForStartAndLength) {
7622             return parser.getTextCharacters(holderForStartAndLength);
7623         }
7624 
7625         @Override
getNamespace()7626         public String getNamespace() {
7627             return parser.getNamespace();
7628         }
7629 
7630         @Override
getName()7631         public String getName() {
7632             return parser.getName();
7633         }
7634 
7635         @Override
getPrefix()7636         public String getPrefix() {
7637             return parser.getPrefix();
7638         }
7639 
7640         @Override
isEmptyElementTag()7641         public boolean isEmptyElementTag() throws XmlPullParserException {
7642             return false;
7643         }
7644 
7645         @Override
getAttributeCount()7646         public int getAttributeCount() {
7647             return parser.getAttributeCount();
7648         }
7649 
next()7650         public int next() throws IOException, XmlPullParserException {
7651             return parser.next();
7652         }
7653 
7654         @Override
nextToken()7655         public int nextToken() throws XmlPullParserException, IOException {
7656             return parser.next();
7657         }
7658 
7659         @Override
require(int type, String namespace, String name)7660         public void require(int type, String namespace, String name)
7661                 throws XmlPullParserException, IOException {
7662             parser.require(type, namespace, name);
7663         }
7664 
7665         @Override
nextText()7666         public String nextText() throws XmlPullParserException, IOException {
7667             return parser.nextText();
7668         }
7669 
7670         @Override
getAttributeNamespace(int index)7671         public String getAttributeNamespace(int index) {
7672             return "";
7673         }
7674 
7675         @Override
getAttributeName(int index)7676         public String getAttributeName(int index) {
7677             return parser.getAttributeName(index);
7678         }
7679 
7680         @Override
getAttributePrefix(int index)7681         public String getAttributePrefix(int index) {
7682             return parser.getAttributePrefix(index);
7683         }
7684 
7685         @Override
getAttributeType(int index)7686         public String getAttributeType(int index) {
7687             return parser.getAttributeType(index);
7688         }
7689 
7690         @Override
isAttributeDefault(int index)7691         public boolean isAttributeDefault(int index) {
7692             return parser.isAttributeDefault(index);
7693         }
7694 
7695         @Override
getAttributeValue(int index)7696         public String getAttributeValue(int index) {
7697             return parser.getAttributeValue(index);
7698         }
7699 
7700         @Override
getAttributeValue(String namespace, String name)7701         public String getAttributeValue(String namespace, String name) {
7702             return parser.getAttributeValue(namespace, name);
7703         }
7704 
7705         @Override
getAttributeNameResource(int index)7706         public int getAttributeNameResource(int index) {
7707             return 0;
7708         }
7709 
7710         @Override
getAttributeListValue(String namespace, String attribute, String[] options, int defaultValue)7711         public int getAttributeListValue(String namespace, String attribute, String[] options,
7712                 int defaultValue) {
7713             return 0;
7714         }
7715 
7716         @Override
getAttributeBooleanValue(String namespace, String attribute, boolean defaultValue)7717         public boolean getAttributeBooleanValue(String namespace, String attribute,
7718                 boolean defaultValue) {
7719             return false;
7720         }
7721 
7722         @Override
getAttributeResourceValue(String namespace, String attribute, int defaultValue)7723         public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
7724             return 0;
7725         }
7726 
7727         @Override
getAttributeIntValue(String namespace, String attribute, int defaultValue)7728         public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
7729             return 0;
7730         }
7731 
7732         @Override
getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue)7733         public int getAttributeUnsignedIntValue(String namespace, String attribute,
7734                 int defaultValue) {
7735             return 0;
7736         }
7737 
7738         @Override
getAttributeFloatValue(String namespace, String attribute, float defaultValue)7739         public float getAttributeFloatValue(String namespace, String attribute,
7740                 float defaultValue) {
7741             return 0;
7742         }
7743 
7744         @Override
getAttributeListValue(int index, String[] options, int defaultValue)7745         public int getAttributeListValue(int index, String[] options, int defaultValue) {
7746             return 0;
7747         }
7748 
7749         @Override
getAttributeBooleanValue(int index, boolean defaultValue)7750         public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
7751             return false;
7752         }
7753 
7754         @Override
getAttributeResourceValue(int index, int defaultValue)7755         public int getAttributeResourceValue(int index, int defaultValue) {
7756             return 0;
7757         }
7758 
7759         @Override
getAttributeIntValue(int index, int defaultValue)7760         public int getAttributeIntValue(int index, int defaultValue) {
7761             return 0;
7762         }
7763 
7764         @Override
getAttributeUnsignedIntValue(int index, int defaultValue)7765         public int getAttributeUnsignedIntValue(int index, int defaultValue) {
7766             return 0;
7767         }
7768 
7769         @Override
getAttributeFloatValue(int index, float defaultValue)7770         public float getAttributeFloatValue(int index, float defaultValue) {
7771             return 0;
7772         }
7773 
7774         @Override
getIdAttribute()7775         public String getIdAttribute() {
7776             return null;
7777         }
7778 
7779         @Override
getClassAttribute()7780         public String getClassAttribute() {
7781             return null;
7782         }
7783 
7784         @Override
getIdAttributeResourceValue(int defaultValue)7785         public int getIdAttributeResourceValue(int defaultValue) {
7786             return 0;
7787         }
7788 
7789         @Override
getStyleAttribute()7790         public int getStyleAttribute() {
7791             return 0;
7792         }
7793 
7794         @Override
close()7795         public void close() {
7796         }
7797 
7798         @Override
nextTag()7799         public int nextTag() throws IOException, XmlPullParserException {
7800             return parser.nextTag();
7801         }
7802     }
7803 
7804     private static class TestClock extends SimpleClock {
7805         private long mNowMillis = 441644400000L;
7806 
TestClock()7807         private TestClock() {
7808             super(ZoneOffset.UTC);
7809         }
7810 
7811         @Override
millis()7812         public long millis() {
7813             return mNowMillis;
7814         }
7815 
setNowMillis(long millis)7816         private void setNowMillis(long millis) {
7817             mNowMillis = millis;
7818         }
7819 
advanceByMillis(long millis)7820         private void advanceByMillis(long millis) {
7821             mNowMillis += millis;
7822         }
7823     }
7824 }
7825