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