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&calendar=&" 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&start=22.0" 388 + "&end=7.0&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