RankingHelperTest.java revision 9bfba59417fd0789023005064565d744ed7483d2
1/* 2 * Copyright (C) 2014 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 distributed 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 */ 16package com.android.server.notification; 17 18import static android.app.NotificationManager.IMPORTANCE_DEFAULT; 19import static android.app.NotificationManager.IMPORTANCE_HIGH; 20import static android.app.NotificationManager.IMPORTANCE_LOW; 21 22import static junit.framework.Assert.assertNull; 23import static junit.framework.Assert.fail; 24 25import org.json.JSONArray; 26import org.json.JSONObject; 27import org.junit.Before; 28import org.junit.Test; 29import org.junit.runner.RunWith; 30 31import com.android.internal.util.FastXmlSerializer; 32 33import org.mockito.Mock; 34import org.mockito.MockitoAnnotations; 35import org.xmlpull.v1.XmlPullParser; 36import org.xmlpull.v1.XmlSerializer; 37 38import android.app.Notification; 39import android.app.NotificationChannelGroup; 40import android.content.Context; 41import android.app.NotificationChannel; 42import android.app.NotificationManager; 43import android.content.pm.ApplicationInfo; 44import android.content.pm.PackageManager; 45import android.graphics.Color; 46import android.media.AudioAttributes; 47import android.net.Uri; 48import android.os.Build; 49import android.os.UserHandle; 50import android.service.notification.StatusBarNotification; 51import android.support.test.InstrumentationRegistry; 52import android.support.test.runner.AndroidJUnit4; 53import android.test.suitebuilder.annotation.SmallTest; 54import android.util.ArrayMap; 55import android.util.Xml; 56 57import java.io.BufferedInputStream; 58import java.io.BufferedOutputStream; 59import java.io.ByteArrayInputStream; 60import java.io.ByteArrayOutputStream; 61import java.util.ArrayList; 62import java.util.Arrays; 63import java.util.HashMap; 64import java.util.List; 65import java.util.Map; 66import java.util.Objects; 67import java.util.concurrent.ThreadLocalRandom; 68 69import static org.junit.Assert.assertEquals; 70import static org.junit.Assert.assertFalse; 71import static org.junit.Assert.assertNotNull; 72import static org.junit.Assert.assertTrue; 73import static org.mockito.Matchers.anyInt; 74import static org.mockito.Matchers.anyString; 75import static org.mockito.Matchers.eq; 76import static org.mockito.Mockito.when; 77 78@SmallTest 79@RunWith(AndroidJUnit4.class) 80public class RankingHelperTest { 81 @Mock 82 NotificationUsageStats mUsageStats; 83 @Mock 84 RankingHandler handler; 85 @Mock 86 PackageManager mPm; 87 88 private Notification mNotiGroupGSortA; 89 private Notification mNotiGroupGSortB; 90 private Notification mNotiNoGroup; 91 private Notification mNotiNoGroup2; 92 private Notification mNotiNoGroupSortA; 93 private NotificationRecord mRecordGroupGSortA; 94 private NotificationRecord mRecordGroupGSortB; 95 private NotificationRecord mRecordNoGroup; 96 private NotificationRecord mRecordNoGroup2; 97 private NotificationRecord mRecordNoGroupSortA; 98 private RankingHelper mHelper; 99 private final String pkg = "com.android.server.notification"; 100 private final int uid = 0; 101 private final String pkg2 = "pkg2"; 102 private final int uid2 = 1111111; 103 private static final String TEST_CHANNEL_ID = "test_channel_id"; 104 private AudioAttributes mAudioAttributes; 105 106 private Context getContext() { 107 return InstrumentationRegistry.getTargetContext(); 108 } 109 110 @Before 111 public void setUp() { 112 MockitoAnnotations.initMocks(this); 113 UserHandle user = UserHandle.ALL; 114 115 mHelper = new RankingHelper(getContext(), mPm, handler, mUsageStats, 116 new String[]{ImportanceExtractor.class.getName()}); 117 118 mNotiGroupGSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID) 119 .setContentTitle("A") 120 .setGroup("G") 121 .setSortKey("A") 122 .setWhen(1205) 123 .build(); 124 mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification( 125 "package", "package", 1, null, 0, 0, mNotiGroupGSortA, user, 126 null, System.currentTimeMillis()), getDefaultChannel()); 127 128 mNotiGroupGSortB = new Notification.Builder(getContext(), TEST_CHANNEL_ID) 129 .setContentTitle("B") 130 .setGroup("G") 131 .setSortKey("B") 132 .setWhen(1200) 133 .build(); 134 mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification( 135 "package", "package", 1, null, 0, 0, mNotiGroupGSortB, user, 136 null, System.currentTimeMillis()), getDefaultChannel()); 137 138 mNotiNoGroup = new Notification.Builder(getContext(), TEST_CHANNEL_ID) 139 .setContentTitle("C") 140 .setWhen(1201) 141 .build(); 142 mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification( 143 "package", "package", 1, null, 0, 0, mNotiNoGroup, user, 144 null, System.currentTimeMillis()), getDefaultChannel()); 145 146 mNotiNoGroup2 = new Notification.Builder(getContext(), TEST_CHANNEL_ID) 147 .setContentTitle("D") 148 .setWhen(1202) 149 .build(); 150 mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification( 151 "package", "package", 1, null, 0, 0, mNotiNoGroup2, user, 152 null, System.currentTimeMillis()), getDefaultChannel()); 153 154 mNotiNoGroupSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID) 155 .setContentTitle("E") 156 .setWhen(1201) 157 .setSortKey("A") 158 .build(); 159 mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification( 160 "package", "package", 1, null, 0, 0, mNotiNoGroupSortA, user, 161 null, System.currentTimeMillis()), getDefaultChannel()); 162 163 mAudioAttributes = new AudioAttributes.Builder() 164 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN) 165 .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) 166 .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED) 167 .build(); 168 169 final ApplicationInfo legacy = new ApplicationInfo(); 170 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1; 171 final ApplicationInfo upgrade = new ApplicationInfo(); 172 upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1; 173 try { 174 when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(legacy); 175 when(mPm.getApplicationInfoAsUser(eq(pkg2), anyInt(), anyInt())).thenReturn(upgrade); 176 } catch (PackageManager.NameNotFoundException e) { 177 } 178 } 179 180 private NotificationChannel getDefaultChannel() { 181 return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name", 182 IMPORTANCE_LOW); 183 } 184 185 private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, String... channelIds) 186 throws Exception { 187 XmlSerializer serializer = new FastXmlSerializer(); 188 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 189 serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); 190 serializer.startDocument(null, true); 191 serializer.startTag(null, "ranking"); 192 mHelper.writeXml(serializer, false); 193 serializer.endTag(null, "ranking"); 194 serializer.endDocument(); 195 serializer.flush(); 196 197 for (String channelId : channelIds) { 198 mHelper.permanentlyDeleteNotificationChannel(pkg, uid, channelId); 199 } 200 return baos; 201 } 202 203 private void compareChannels(NotificationChannel expected, NotificationChannel actual) { 204 assertEquals(expected.getId(), actual.getId()); 205 assertEquals(expected.getName(), actual.getName()); 206 assertEquals(expected.shouldVibrate(), actual.shouldVibrate()); 207 assertEquals(expected.shouldShowLights(), actual.shouldShowLights()); 208 assertEquals(expected.getImportance(), actual.getImportance()); 209 assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility()); 210 assertEquals(expected.getSound(), actual.getSound()); 211 assertEquals(expected.canBypassDnd(), actual.canBypassDnd()); 212 assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern())); 213 assertEquals(expected.getGroup(), actual.getGroup()); 214 assertEquals(expected.getAudioAttributes(), actual.getAudioAttributes()); 215 assertEquals(expected.getLightColor(), actual.getLightColor()); 216 } 217 218 private void compareGroups(NotificationChannelGroup expected, NotificationChannelGroup actual) { 219 assertEquals(expected.getId(), actual.getId()); 220 assertEquals(expected.getName(), actual.getName()); 221 } 222 223 @Test 224 public void testFindAfterRankingWithASplitGroup() throws Exception { 225 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3); 226 notificationList.add(mRecordGroupGSortA); 227 notificationList.add(mRecordGroupGSortB); 228 notificationList.add(mRecordNoGroup); 229 notificationList.add(mRecordNoGroupSortA); 230 mHelper.sort(notificationList); 231 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortA) >= 0); 232 assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortB) >= 0); 233 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroup) >= 0); 234 assertTrue(mHelper.indexOf(notificationList, mRecordNoGroupSortA) >= 0); 235 } 236 237 @Test 238 public void testSortShouldNotThrowWithPlainNotifications() throws Exception { 239 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2); 240 notificationList.add(mRecordNoGroup); 241 notificationList.add(mRecordNoGroup2); 242 mHelper.sort(notificationList); 243 } 244 245 @Test 246 public void testSortShouldNotThrowOneSorted() throws Exception { 247 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2); 248 notificationList.add(mRecordNoGroup); 249 notificationList.add(mRecordNoGroupSortA); 250 mHelper.sort(notificationList); 251 } 252 253 @Test 254 public void testSortShouldNotThrowOneNotification() throws Exception { 255 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1); 256 notificationList.add(mRecordNoGroup); 257 mHelper.sort(notificationList); 258 } 259 260 @Test 261 public void testSortShouldNotThrowOneSortKey() throws Exception { 262 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1); 263 notificationList.add(mRecordGroupGSortB); 264 mHelper.sort(notificationList); 265 } 266 267 @Test 268 public void testSortShouldNotThrowOnEmptyList() throws Exception { 269 ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(); 270 mHelper.sort(notificationList); 271 } 272 273 @Test 274 public void testChannelXml() throws Exception { 275 NotificationChannelGroup ncg = new NotificationChannelGroup("1", "bye"); 276 NotificationChannelGroup ncg2 = new NotificationChannelGroup("2", "hello"); 277 NotificationChannel channel1 = 278 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH); 279 NotificationChannel channel2 = 280 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 281 channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes); 282 channel2.enableLights(true); 283 channel2.setBypassDnd(true); 284 channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET); 285 channel2.enableVibration(true); 286 channel2.setGroup(ncg.getId()); 287 channel2.setVibrationPattern(new long[]{100, 67, 145, 156}); 288 channel2.setLightColor(Color.BLUE); 289 290 mHelper.createNotificationChannelGroup(pkg, uid, ncg, true); 291 mHelper.createNotificationChannelGroup(pkg, uid, ncg2, true); 292 mHelper.createNotificationChannel(pkg, uid, channel1, true); 293 mHelper.createNotificationChannel(pkg, uid, channel2, false); 294 295 mHelper.setShowBadge(pkg, uid, true); 296 mHelper.setShowBadge(pkg2, uid2, false); 297 298 ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(), channel2.getId(), 299 NotificationChannel.DEFAULT_CHANNEL_ID); 300 mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{pkg}, new int[]{uid}); 301 302 XmlPullParser parser = Xml.newPullParser(); 303 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), 304 null); 305 parser.nextTag(); 306 mHelper.readXml(parser, false); 307 308 assertFalse(mHelper.canShowBadge(pkg2, uid2)); 309 assertTrue(mHelper.canShowBadge(pkg, uid)); 310 assertEquals(channel1, mHelper.getNotificationChannel(pkg, uid, channel1.getId(), false)); 311 compareChannels(channel2, 312 mHelper.getNotificationChannel(pkg, uid, channel2.getId(), false)); 313 assertNotNull(mHelper.getNotificationChannel( 314 pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, false)); 315 316 List<NotificationChannelGroup> actualGroups = 317 mHelper.getNotificationChannelGroups(pkg, uid, false).getList(); 318 boolean foundNcg = false; 319 for (NotificationChannelGroup actual : actualGroups) { 320 if (ncg.getId().equals(actual.getId())) { 321 foundNcg = true; 322 compareGroups(ncg, actual); 323 } else if (ncg2.getId().equals(actual.getId())) { 324 compareGroups(ncg2, actual); 325 } 326 } 327 assertTrue(foundNcg); 328 329 boolean foundChannel2Group = false; 330 for (NotificationChannelGroup actual : actualGroups) { 331 if (channel2.getGroup().equals(actual.getChannels().get(0).getGroup())) { 332 foundChannel2Group = true; 333 break; 334 } 335 } 336 assertTrue(foundChannel2Group); 337 } 338 339 @Test 340 public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception { 341 NotificationChannel channel1 = 342 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_DEFAULT); 343 344 mHelper.createNotificationChannel(pkg, uid, channel1, true); 345 346 ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(), 347 NotificationChannel.DEFAULT_CHANNEL_ID); 348 349 XmlPullParser parser = Xml.newPullParser(); 350 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), 351 null); 352 parser.nextTag(); 353 mHelper.readXml(parser, false); 354 355 final NotificationChannel updated = mHelper.getNotificationChannel( 356 pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, false); 357 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance()); 358 assertFalse(updated.canBypassDnd()); 359 assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE, updated.getLockscreenVisibility()); 360 assertEquals(0, updated.getUserLockedFields()); 361 } 362 363 @Test 364 public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception { 365 NotificationChannel channel1 = 366 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_MIN); 367 mHelper.createNotificationChannel(pkg, uid, channel1, true); 368 369 final NotificationChannel defaultChannel = mHelper.getNotificationChannel( 370 pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, false); 371 defaultChannel.setImportance(IMPORTANCE_LOW); 372 mHelper.updateNotificationChannel(pkg, uid, defaultChannel); 373 374 ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(), 375 NotificationChannel.DEFAULT_CHANNEL_ID); 376 377 XmlPullParser parser = Xml.newPullParser(); 378 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), 379 null); 380 parser.nextTag(); 381 mHelper.readXml(parser, false); 382 383 assertEquals(IMPORTANCE_LOW, mHelper.getNotificationChannel( 384 pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, false).getImportance()); 385 } 386 387 @Test 388 public void testChannelXml_upgradeCreateDefaultChannel() throws Exception { 389 final String preupgradeXml = "<ranking version=\"1\">\n" 390 + "<package name=\"" + pkg + "\" importance=\"" 391 + NotificationManager.IMPORTANCE_HIGH 392 + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\"" 393 + Notification.VISIBILITY_SECRET + "\"" + " uid=\"" + uid + "\" />\n" 394 + "<package name=\"" + pkg2 + "\" uid=\"" + uid2 + "\" visibility=\"" 395 + Notification.VISIBILITY_PRIVATE + "\" />\n" 396 + "</ranking>"; 397 XmlPullParser parser = Xml.newPullParser(); 398 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), 399 null); 400 parser.nextTag(); 401 mHelper.readXml(parser, false); 402 403 final NotificationChannel updated1 = mHelper.getNotificationChannel( 404 pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID, false); 405 assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance()); 406 assertTrue(updated1.canBypassDnd()); 407 assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility()); 408 assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE 409 | NotificationChannel.USER_LOCKED_PRIORITY 410 | NotificationChannel.USER_LOCKED_VISIBILITY, updated1.getUserLockedFields()); 411 412 final NotificationChannel updated2 = mHelper.getNotificationChannel( 413 pkg2, uid2, NotificationChannel.DEFAULT_CHANNEL_ID, false); 414 // clamped 415 assertEquals(IMPORTANCE_LOW, updated2.getImportance()); 416 assertFalse(updated2.canBypassDnd()); 417 assertEquals(Notification.VISIBILITY_PRIVATE, updated2.getLockscreenVisibility()); 418 assertEquals(NotificationChannel.USER_LOCKED_VISIBILITY, updated2.getUserLockedFields()); 419 } 420 421 @Test 422 public void testCreateChannel_blocked() throws Exception { 423 mHelper.setImportance(pkg, uid, NotificationManager.IMPORTANCE_NONE); 424 425 mHelper.createNotificationChannel(pkg, uid, 426 new NotificationChannel(pkg, "bananas", IMPORTANCE_LOW), true); 427 } 428 429 @Test 430 public void testUpdate_userLockedImportance() throws Exception { 431 // all fields locked by user 432 final NotificationChannel channel = 433 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 434 channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE); 435 436 mHelper.createNotificationChannel(pkg, uid, channel, false); 437 438 // same id, try to update 439 final NotificationChannel channel2 = 440 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH); 441 442 mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2); 443 444 // no fields should be changed 445 assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId(), false)); 446 } 447 448 @Test 449 public void testUpdate_userLockedVisibility() throws Exception { 450 // all fields locked by user 451 final NotificationChannel channel = 452 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 453 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET); 454 channel.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY); 455 456 mHelper.createNotificationChannel(pkg, uid, channel, false); 457 458 // same id, try to update 459 final NotificationChannel channel2 = 460 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH); 461 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); 462 463 mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2); 464 465 // no fields should be changed 466 assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId(), false)); 467 } 468 469 @Test 470 public void testUpdate_userLockedVibration() throws Exception { 471 // all fields locked by user 472 final NotificationChannel channel = 473 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 474 channel.enableLights(false); 475 channel.lockFields(NotificationChannel.USER_LOCKED_VIBRATION); 476 477 mHelper.createNotificationChannel(pkg, uid, channel, false); 478 479 // same id, try to update 480 final NotificationChannel channel2 = 481 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH); 482 channel2.enableVibration(true); 483 channel2.setVibrationPattern(new long[]{100}); 484 485 mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2); 486 487 // no fields should be changed 488 assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId(), false)); 489 } 490 491 @Test 492 public void testUpdate_userLockedLights() throws Exception { 493 // all fields locked by user 494 final NotificationChannel channel = 495 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 496 channel.enableLights(false); 497 channel.lockFields(NotificationChannel.USER_LOCKED_LIGHTS); 498 499 mHelper.createNotificationChannel(pkg, uid, channel, false); 500 501 // same id, try to update 502 final NotificationChannel channel2 = 503 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH); 504 channel2.enableLights(true); 505 506 mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2); 507 508 // no fields should be changed 509 assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId(), false)); 510 } 511 512 @Test 513 public void testUpdate_userLockedPriority() throws Exception { 514 // all fields locked by user 515 final NotificationChannel channel = 516 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 517 channel.setBypassDnd(true); 518 channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY); 519 520 mHelper.createNotificationChannel(pkg, uid, channel, false); 521 522 // same id, try to update all fields 523 final NotificationChannel channel2 = 524 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH); 525 channel2.setBypassDnd(false); 526 527 mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2); 528 529 // no fields should be changed 530 assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId(), false)); 531 } 532 533 @Test 534 public void testUpdate_userLockedRingtone() throws Exception { 535 // all fields locked by user 536 final NotificationChannel channel = 537 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 538 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes); 539 channel.lockFields(NotificationChannel.USER_LOCKED_SOUND); 540 541 mHelper.createNotificationChannel(pkg, uid, channel, false); 542 543 // same id, try to update all fields 544 final NotificationChannel channel2 = 545 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH); 546 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes); 547 548 mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2); 549 550 // no fields should be changed 551 assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId(), false)); 552 } 553 554 @Test 555 public void testUpdate_userLockedBadge() throws Exception { 556 final NotificationChannel channel = 557 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 558 channel.setShowBadge(true); 559 channel.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE); 560 561 mHelper.createNotificationChannel(pkg, uid, channel, false); 562 563 final NotificationChannel channel2 = 564 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH); 565 channel2.setShowBadge(false); 566 567 mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel2); 568 569 // no fields should be changed 570 assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId(), false)); 571 } 572 573 @Test 574 public void testUpdate() throws Exception { 575 // no fields locked by user 576 final NotificationChannel channel = 577 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 578 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes); 579 channel.enableLights(true); 580 channel.setBypassDnd(true); 581 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET); 582 583 mHelper.createNotificationChannel(pkg, uid, channel, false); 584 585 // same id, try to update all fields 586 final NotificationChannel channel2 = 587 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH); 588 channel2.setSound(new Uri.Builder().scheme("test2").build(), mAudioAttributes); 589 channel2.enableLights(false); 590 channel2.setBypassDnd(false); 591 channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); 592 593 mHelper.updateNotificationChannel(pkg, uid, channel2); 594 595 // all fields should be changed 596 assertEquals(channel2, mHelper.getNotificationChannel(pkg, uid, channel.getId(), false)); 597 } 598 599 @Test 600 public void testGetChannelWithFallback() throws Exception { 601 NotificationChannel channel = 602 mHelper.getNotificationChannelWithFallback(pkg, uid, "garbage", false); 603 assertEquals(NotificationChannel.DEFAULT_CHANNEL_ID, channel.getId()); 604 } 605 606 @Test 607 public void testCreateChannel_CannotChangeHiddenFields() throws Exception { 608 final NotificationChannel channel = 609 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 610 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes); 611 channel.enableLights(true); 612 channel.setBypassDnd(true); 613 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET); 614 channel.setShowBadge(true); 615 int lockMask = 0; 616 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) { 617 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i]; 618 } 619 channel.lockFields(lockMask); 620 621 mHelper.createNotificationChannel(pkg, uid, channel, true); 622 623 NotificationChannel savedChannel = 624 mHelper.getNotificationChannel(pkg, uid, channel.getId(), false); 625 626 assertEquals(channel.getName(), savedChannel.getName()); 627 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights()); 628 assertFalse(savedChannel.canBypassDnd()); 629 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility()); 630 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge()); 631 } 632 633 @Test 634 public void testCreateChannel_CannotChangeHiddenFieldsAssistant() throws Exception { 635 final NotificationChannel channel = 636 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 637 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes); 638 channel.enableLights(true); 639 channel.setBypassDnd(true); 640 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET); 641 channel.setShowBadge(true); 642 int lockMask = 0; 643 for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) { 644 lockMask |= NotificationChannel.LOCKABLE_FIELDS[i]; 645 } 646 channel.lockFields(lockMask); 647 648 mHelper.createNotificationChannel(pkg, uid, channel, true); 649 650 NotificationChannel savedChannel = 651 mHelper.getNotificationChannel(pkg, uid, channel.getId(), false); 652 653 assertEquals(channel.getName(), savedChannel.getName()); 654 assertEquals(channel.shouldShowLights(), savedChannel.shouldShowLights()); 655 assertFalse(savedChannel.canBypassDnd()); 656 assertFalse(Notification.VISIBILITY_SECRET == savedChannel.getLockscreenVisibility()); 657 assertEquals(channel.canShowBadge(), savedChannel.canShowBadge()); 658 } 659 660 @Test 661 public void testGetDeletedChannel() throws Exception { 662 NotificationChannel channel = 663 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 664 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes); 665 channel.enableLights(true); 666 channel.setBypassDnd(true); 667 channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET); 668 channel.enableVibration(true); 669 channel.setVibrationPattern(new long[]{100, 67, 145, 156}); 670 671 mHelper.createNotificationChannel(pkg, uid, channel, true); 672 mHelper.deleteNotificationChannel(pkg, uid, channel.getId()); 673 674 // Does not return deleted channel 675 NotificationChannel response = 676 mHelper.getNotificationChannel(pkg, uid, channel.getId(), false); 677 assertNull(response); 678 679 // Returns deleted channel 680 response = mHelper.getNotificationChannel(pkg, uid, channel.getId(), true); 681 compareChannels(channel, response); 682 assertTrue(response.isDeleted()); 683 } 684 685 @Test 686 public void testGetDeletedChannels() throws Exception { 687 Map<String, NotificationChannel> channelMap = new HashMap<>(); 688 NotificationChannel channel = 689 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 690 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes); 691 channel.enableLights(true); 692 channel.setBypassDnd(true); 693 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); 694 channel.enableVibration(true); 695 channel.setVibrationPattern(new long[]{100, 67, 145, 156}); 696 channelMap.put(channel.getId(), channel); 697 NotificationChannel channel2 = 698 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH); 699 channelMap.put(channel2.getId(), channel2); 700 mHelper.createNotificationChannel(pkg, uid, channel, true); 701 mHelper.createNotificationChannel(pkg, uid, channel2, true); 702 703 mHelper.deleteNotificationChannel(pkg, uid, channel.getId()); 704 705 // Returns only non-deleted channels 706 List<NotificationChannel> channels = 707 mHelper.getNotificationChannels(pkg, uid, false).getList(); 708 assertEquals(2, channels.size()); // Default channel + non-deleted channel 709 for (NotificationChannel nc : channels) { 710 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) { 711 compareChannels(channel2, nc); 712 } 713 } 714 715 // Returns deleted channels too 716 channels = mHelper.getNotificationChannels(pkg, uid, true).getList(); 717 assertEquals(3, channels.size()); // Includes default channel 718 for (NotificationChannel nc : channels) { 719 if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) { 720 compareChannels(channelMap.get(nc.getId()), nc); 721 } 722 } 723 } 724 725 @Test 726 public void testGetDeletedChannelCount() throws Exception { 727 NotificationChannel channel = 728 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 729 NotificationChannel channel2 = 730 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH); 731 NotificationChannel channel3 = 732 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH); 733 mHelper.createNotificationChannel(pkg, uid, channel, true); 734 mHelper.createNotificationChannel(pkg, uid, channel2, true); 735 mHelper.createNotificationChannel(pkg, uid, channel3, true); 736 737 mHelper.deleteNotificationChannel(pkg, uid, channel.getId()); 738 mHelper.deleteNotificationChannel(pkg, uid, channel3.getId()); 739 740 assertEquals(2, mHelper.getDeletedChannelCount(pkg, uid)); 741 assertEquals(0, mHelper.getDeletedChannelCount(pkg2, uid2)); 742 } 743 744 @Test 745 public void testUpdateDeletedChannels() throws Exception { 746 NotificationChannel channel = 747 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 748 mHelper.createNotificationChannel(pkg, uid, channel, true); 749 750 mHelper.deleteNotificationChannel(pkg, uid, channel.getId()); 751 752 channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes); 753 try { 754 mHelper.updateNotificationChannel(pkg, uid, channel); 755 fail("Updated deleted channel"); 756 } catch (IllegalArgumentException e) { 757 // :) 758 } 759 760 try { 761 mHelper.updateNotificationChannelFromAssistant(pkg, uid, channel); 762 fail("Updated deleted channel"); 763 } catch (IllegalArgumentException e) { 764 // :) 765 } 766 } 767 768 @Test 769 public void testCreateDeletedChannel() throws Exception { 770 long[] vibration = new long[]{100, 67, 145, 156}; 771 NotificationChannel channel = 772 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 773 channel.setVibrationPattern(vibration); 774 775 mHelper.createNotificationChannel(pkg, uid, channel, true); 776 mHelper.deleteNotificationChannel(pkg, uid, channel.getId()); 777 778 NotificationChannel newChannel = new NotificationChannel( 779 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH); 780 newChannel.setVibrationPattern(new long[]{100}); 781 782 mHelper.createNotificationChannel(pkg, uid, newChannel, true); 783 784 // No long deleted, using old settings 785 compareChannels(channel, 786 mHelper.getNotificationChannel(pkg, uid, newChannel.getId(), false)); 787 } 788 789 @Test 790 public void testCreateChannel_defaultChannelId() throws Exception { 791 try { 792 mHelper.createNotificationChannel(pkg2, uid2, new NotificationChannel( 793 NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true); 794 fail("Allowed to create default channel"); 795 } catch (IllegalArgumentException e) { 796 // pass 797 } 798 } 799 800 @Test 801 public void testCreateChannel_alreadyExists() throws Exception { 802 long[] vibration = new long[]{100, 67, 145, 156}; 803 NotificationChannel channel = 804 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 805 channel.setVibrationPattern(vibration); 806 807 mHelper.createNotificationChannel(pkg, uid, channel, true); 808 809 NotificationChannel newChannel = new NotificationChannel( 810 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH); 811 newChannel.setVibrationPattern(new long[]{100}); 812 813 mHelper.createNotificationChannel(pkg, uid, newChannel, true); 814 815 // Old settings not overridden 816 compareChannels(channel, 817 mHelper.getNotificationChannel(pkg, uid, newChannel.getId(), false)); 818 } 819 820 @Test 821 public void testCreateChannel_addMissingSound() throws Exception { 822 final NotificationChannel channel = 823 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 824 mHelper.createNotificationChannel(pkg, uid, channel, true); 825 assertNotNull(mHelper.getNotificationChannel( 826 pkg, uid, channel.getId(), false).getSound()); 827 } 828 829 @Test 830 public void testCreateChannel_noOverrideSound() throws Exception { 831 Uri sound = new Uri.Builder().scheme("test").build(); 832 final NotificationChannel channel = new NotificationChannel("id2", "name2", 833 NotificationManager.IMPORTANCE_DEFAULT); 834 channel.setSound(sound, mAudioAttributes); 835 mHelper.createNotificationChannel(pkg, uid, channel, true); 836 assertEquals(sound, mHelper.getNotificationChannel( 837 pkg, uid, channel.getId(), false).getSound()); 838 } 839 840 @Test 841 public void testPermanentlyDeleteChannels() throws Exception { 842 NotificationChannel channel1 = 843 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH); 844 NotificationChannel channel2 = 845 new NotificationChannel("id2", "name2", IMPORTANCE_LOW); 846 847 mHelper.createNotificationChannel(pkg, uid, channel1, true); 848 mHelper.createNotificationChannel(pkg, uid, channel2, false); 849 850 mHelper.permanentlyDeleteNotificationChannels(pkg, uid); 851 852 // Only default channel remains 853 assertEquals(1, mHelper.getNotificationChannels(pkg, uid, true).getList().size()); 854 } 855 856 @Test 857 public void testDeleteGroup() throws Exception { 858 NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted"); 859 NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted"); 860 NotificationChannel nonGroupedNonDeletedChannel = 861 new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH); 862 NotificationChannel groupedButNotDeleted = 863 new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT); 864 groupedButNotDeleted.setGroup("not"); 865 NotificationChannel groupedAndDeleted = 866 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT); 867 groupedAndDeleted.setGroup("totally"); 868 869 mHelper.createNotificationChannelGroup(pkg, uid, notDeleted, true); 870 mHelper.createNotificationChannelGroup(pkg, uid, deleted, true); 871 mHelper.createNotificationChannel(pkg, uid, nonGroupedNonDeletedChannel, true); 872 mHelper.createNotificationChannel(pkg, uid, groupedAndDeleted, true); 873 mHelper.createNotificationChannel(pkg, uid, groupedButNotDeleted, true); 874 875 mHelper.deleteNotificationChannelGroup(pkg, uid, deleted.getId()); 876 877 assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), pkg, uid)); 878 assertNotNull(mHelper.getNotificationChannelGroup(notDeleted.getId(), pkg, uid)); 879 880 assertNull(mHelper.getNotificationChannel(pkg, uid, groupedAndDeleted.getId(), false)); 881 compareChannels(groupedAndDeleted, 882 mHelper.getNotificationChannel(pkg, uid, groupedAndDeleted.getId(), true)); 883 884 compareChannels(groupedButNotDeleted, 885 mHelper.getNotificationChannel(pkg, uid, groupedButNotDeleted.getId(), false)); 886 compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel( 887 pkg, uid, nonGroupedNonDeletedChannel.getId(), false)); 888 889 // notDeleted 890 assertEquals(1, mHelper.getNotificationChannelGroups(pkg, uid).size()); 891 } 892 893 @Test 894 public void testOnPackageChanged_packageRemoval() throws Exception { 895 // Deleted 896 NotificationChannel channel1 = 897 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH); 898 mHelper.createNotificationChannel(pkg, uid, channel1, true); 899 900 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{pkg}, new int[]{uid}); 901 902 assertEquals(0, mHelper.getNotificationChannels(pkg, uid, true).getList().size()); 903 904 // Not deleted 905 mHelper.createNotificationChannel(pkg, uid, channel1, true); 906 907 mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{pkg}, new int[]{uid}); 908 assertEquals(2, mHelper.getNotificationChannels(pkg, uid, false).getList().size()); 909 } 910 911 @Test 912 public void testOnPackageChanged_packageRemoval_importance() throws Exception { 913 mHelper.setImportance(pkg, uid, NotificationManager.IMPORTANCE_HIGH); 914 915 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{pkg}, new int[]{uid}); 916 917 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(pkg, uid)); 918 } 919 920 @Test 921 public void testOnPackageChanged_packageRemoval_groups() throws Exception { 922 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1"); 923 mHelper.createNotificationChannelGroup(pkg, uid, ncg, true); 924 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2"); 925 mHelper.createNotificationChannelGroup(pkg, uid, ncg2, true); 926 927 mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{pkg}, new int[]{uid}); 928 929 assertEquals(0, mHelper.getNotificationChannelGroups(pkg, uid).size()); 930 } 931 932 @Test 933 public void testRecordDefaults() throws Exception { 934 assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(pkg, uid)); 935 assertEquals(true, mHelper.canShowBadge(pkg, uid)); 936 assertEquals(1, mHelper.getNotificationChannels(pkg, uid, false).getList().size()); 937 } 938 939 @Test 940 public void testCreateGroup() throws Exception { 941 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1"); 942 mHelper.createNotificationChannelGroup(pkg, uid, ncg, true); 943 assertEquals(ncg, mHelper.getNotificationChannelGroups(pkg, uid).iterator().next()); 944 } 945 946 @Test 947 public void testCannotCreateChannel_badGroup() throws Exception { 948 NotificationChannel channel1 = 949 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH); 950 channel1.setGroup("garbage"); 951 try { 952 mHelper.createNotificationChannel(pkg, uid, channel1, true); 953 fail("Created a channel with a bad group"); 954 } catch (IllegalArgumentException e) { 955 } 956 } 957 958 @Test 959 public void testCannotCreateChannel_goodGroup() throws Exception { 960 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1"); 961 mHelper.createNotificationChannelGroup(pkg, uid, ncg, true); 962 NotificationChannel channel1 = 963 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH); 964 channel1.setGroup(ncg.getId()); 965 mHelper.createNotificationChannel(pkg, uid, channel1, true); 966 967 assertEquals(ncg.getId(), 968 mHelper.getNotificationChannel(pkg, uid, channel1.getId(), false).getGroup()); 969 } 970 971 @Test 972 public void testGetChannelGroups() throws Exception { 973 NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s"); 974 mHelper.createNotificationChannelGroup(pkg, uid, unused, true); 975 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1"); 976 mHelper.createNotificationChannelGroup(pkg, uid, ncg, true); 977 NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2"); 978 mHelper.createNotificationChannelGroup(pkg, uid, ncg2, true); 979 980 NotificationChannel channel1 = 981 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH); 982 channel1.setGroup(ncg.getId()); 983 mHelper.createNotificationChannel(pkg, uid, channel1, true); 984 NotificationChannel channel1a = 985 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH); 986 channel1a.setGroup(ncg.getId()); 987 mHelper.createNotificationChannel(pkg, uid, channel1a, true); 988 989 NotificationChannel channel2 = 990 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH); 991 channel2.setGroup(ncg2.getId()); 992 mHelper.createNotificationChannel(pkg, uid, channel2, true); 993 994 NotificationChannel channel3 = 995 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH); 996 mHelper.createNotificationChannel(pkg, uid, channel3, true); 997 998 List<NotificationChannelGroup> actual = 999 mHelper.getNotificationChannelGroups(pkg, uid, true).getList(); 1000 assertEquals(3, actual.size()); 1001 for (NotificationChannelGroup group : actual) { 1002 if (group.getId() == null) { 1003 assertEquals(2, group.getChannels().size()); // misc channel too 1004 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId()) 1005 || channel3.getId().equals(group.getChannels().get(1).getId())); 1006 } else if (group.getId().equals(ncg.getId())) { 1007 assertEquals(2, group.getChannels().size()); 1008 if (group.getChannels().get(0).getId().equals(channel1.getId())) { 1009 assertTrue(group.getChannels().get(1).getId().equals(channel1a.getId())); 1010 } else if (group.getChannels().get(0).getId().equals(channel1a.getId())) { 1011 assertTrue(group.getChannels().get(1).getId().equals(channel1.getId())); 1012 } else { 1013 fail("expected channel not found"); 1014 } 1015 } else if (group.getId().equals(ncg2.getId())) { 1016 assertEquals(1, group.getChannels().size()); 1017 assertEquals(channel2.getId(), group.getChannels().get(0).getId()); 1018 } 1019 } 1020 } 1021 1022 @Test 1023 public void testGetChannelGroups_noSideEffects() throws Exception { 1024 NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1"); 1025 mHelper.createNotificationChannelGroup(pkg, uid, ncg, true); 1026 1027 NotificationChannel channel1 = 1028 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH); 1029 channel1.setGroup(ncg.getId()); 1030 mHelper.createNotificationChannel(pkg, uid, channel1, true); 1031 mHelper.getNotificationChannelGroups(pkg, uid, true).getList(); 1032 1033 channel1.setImportance(IMPORTANCE_LOW); 1034 mHelper.updateNotificationChannel(pkg, uid, channel1); 1035 1036 List<NotificationChannelGroup> actual = 1037 mHelper.getNotificationChannelGroups(pkg, uid, true).getList(); 1038 1039 assertEquals(2, actual.size()); 1040 for (NotificationChannelGroup group : actual) { 1041 if (Objects.equals(group.getId(), ncg.getId())) { 1042 assertEquals(1, group.getChannels().size()); 1043 } 1044 } 1045 } 1046 1047 @Test 1048 public void testCreateChannel_updateName() throws Exception { 1049 NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT); 1050 mHelper.createNotificationChannel(pkg, uid, nc, true); 1051 NotificationChannel actual = mHelper.getNotificationChannel(pkg, uid, "id", false); 1052 assertEquals("hello", actual.getName()); 1053 1054 nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH); 1055 mHelper.createNotificationChannel(pkg, uid, nc, true); 1056 1057 actual = mHelper.getNotificationChannel(pkg, uid, "id", false); 1058 assertEquals("goodbye", actual.getName()); 1059 assertEquals(IMPORTANCE_DEFAULT, actual.getImportance()); 1060 } 1061 1062 @Test 1063 public void testDumpChannelsJson() throws Exception { 1064 final ApplicationInfo upgrade = new ApplicationInfo(); 1065 upgrade.targetSdkVersion = Build.VERSION_CODES.O; 1066 try { 1067 when(mPm.getApplicationInfoAsUser( 1068 anyString(), anyInt(), anyInt())).thenReturn(upgrade); 1069 } catch (PackageManager.NameNotFoundException e) { 1070 } 1071 ArrayMap<String, Integer> expectedChannels = new ArrayMap<>(); 1072 int numPackages = ThreadLocalRandom.current().nextInt(1, 5); 1073 for (int i = 0; i < numPackages; i++) { 1074 String pkgName = "pkg" + i; 1075 int numChannels = ThreadLocalRandom.current().nextInt(1, 10); 1076 for (int j = 0; j < numChannels; j++) { 1077 mHelper.createNotificationChannel(pkgName, uid, 1078 new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true); 1079 } 1080 expectedChannels.put(pkgName, numChannels); 1081 } 1082 1083 // delete the first channel of the first package 1084 String pkg = expectedChannels.keyAt(0); 1085 mHelper.deleteNotificationChannel("pkg" + 0, uid, "0"); 1086 // dump should not include deleted channels 1087 int count = expectedChannels.get(pkg); 1088 expectedChannels.put(pkg, count - 1); 1089 1090 JSONArray actual = mHelper.dumpChannelsJson(new NotificationManagerService.DumpFilter()); 1091 assertEquals(numPackages, actual.length()); 1092 for (int i = 0; i < numPackages; i++) { 1093 JSONObject object = actual.getJSONObject(i); 1094 assertTrue(expectedChannels.containsKey(object.get("packageName"))); 1095 assertEquals(expectedChannels.get(object.get("packageName")).intValue() + 1, 1096 object.getInt("channelCount")); 1097 } 1098 } 1099} 1100