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