1 /* 2 * Copyright (C) 2016 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 */ 16 17 package com.android.server.notification; 18 19 import static android.app.NotificationManager.IMPORTANCE_HIGH; 20 import static android.app.NotificationManager.IMPORTANCE_LOW; 21 import static android.app.NotificationManager.IMPORTANCE_NONE; 22 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; 23 import static android.content.pm.PackageManager.PERMISSION_DENIED; 24 25 import static junit.framework.Assert.assertEquals; 26 import static junit.framework.Assert.assertFalse; 27 import static junit.framework.Assert.assertNotNull; 28 import static junit.framework.Assert.assertNull; 29 import static junit.framework.Assert.assertTrue; 30 import static junit.framework.Assert.fail; 31 32 import static org.mockito.Matchers.anyBoolean; 33 import static org.mockito.Matchers.anyLong; 34 import static org.mockito.Matchers.anyString; 35 import static org.mockito.Matchers.eq; 36 import static org.mockito.Mockito.any; 37 import static org.mockito.Mockito.anyInt; 38 import static org.mockito.Mockito.doAnswer; 39 import static org.mockito.Mockito.mock; 40 import static org.mockito.Mockito.never; 41 import static org.mockito.Mockito.reset; 42 import static org.mockito.Mockito.spy; 43 import static org.mockito.Mockito.times; 44 import static org.mockito.Mockito.verify; 45 import static org.mockito.Mockito.when; 46 47 import android.app.ActivityManager; 48 import android.app.INotificationManager; 49 import android.app.Notification; 50 import android.app.NotificationChannel; 51 import android.app.NotificationChannelGroup; 52 import android.app.NotificationManager; 53 import android.companion.ICompanionDeviceManager; 54 import android.content.ComponentName; 55 import android.content.Context; 56 import android.content.Intent; 57 import android.content.pm.ApplicationInfo; 58 import android.content.pm.IPackageManager; 59 import android.content.pm.PackageManager; 60 import android.content.pm.ParceledListSlice; 61 import android.graphics.Color; 62 import android.media.AudioManager; 63 import android.os.Binder; 64 import android.os.Build; 65 import android.os.Process; 66 import android.os.UserHandle; 67 import android.provider.Settings.Secure; 68 import android.service.notification.NotificationListenerService; 69 import android.service.notification.StatusBarNotification; 70 import android.test.suitebuilder.annotation.SmallTest; 71 import android.testing.AndroidTestingRunner; 72 import android.testing.TestableContext; 73 import android.testing.TestableLooper; 74 import android.testing.TestableLooper.RunWithLooper; 75 import android.util.ArrayMap; 76 import android.util.AtomicFile; 77 78 import com.android.server.lights.Light; 79 import com.android.server.lights.LightsManager; 80 import com.android.server.notification.NotificationManagerService.NotificationAssistants; 81 import com.android.server.notification.NotificationManagerService.NotificationListeners; 82 83 import org.junit.After; 84 import org.junit.Before; 85 import org.junit.Test; 86 import org.junit.runner.RunWith; 87 import org.mockito.Mock; 88 import org.mockito.MockitoAnnotations; 89 import org.mockito.stubbing.Answer; 90 91 import java.io.BufferedInputStream; 92 import java.io.ByteArrayInputStream; 93 import java.io.File; 94 import java.io.FileInputStream; 95 import java.io.FileOutputStream; 96 import java.util.ArrayList; 97 import java.util.Arrays; 98 import java.util.List; 99 import java.util.Map; 100 101 @SmallTest 102 @RunWith(AndroidTestingRunner.class) 103 @RunWithLooper 104 public class NotificationManagerServiceTest extends NotificationTestCase { 105 private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId"; 106 private final int mUid = Binder.getCallingUid(); 107 private NotificationManagerService mNotificationManagerService; 108 private INotificationManager mBinderService; 109 private NotificationManagerInternal mInternalService; 110 @Mock 111 private IPackageManager mPackageManager; 112 @Mock 113 private PackageManager mPackageManagerClient; 114 private TestableContext mContext = spy(getContext()); 115 private final String PKG = mContext.getPackageName(); 116 private TestableLooper mTestableLooper; 117 @Mock 118 private RankingHelper mRankingHelper; 119 AtomicFile mPolicyFile; 120 File mFile; 121 @Mock 122 private NotificationUsageStats mUsageStats; 123 @Mock 124 private AudioManager mAudioManager; 125 @Mock 126 ActivityManager mActivityManager; 127 NotificationManagerService.WorkerHandler mHandler; 128 129 private NotificationChannel mTestNotificationChannel = new NotificationChannel( 130 TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT); 131 @Mock 132 private NotificationListeners mListeners; 133 @Mock private NotificationAssistants mAssistants; 134 @Mock private ConditionProviders mConditionProviders; 135 private ManagedServices.ManagedServiceInfo mListener; 136 @Mock private ICompanionDeviceManager mCompanionMgr; 137 @Mock SnoozeHelper mSnoozeHelper; 138 @Mock GroupHelper mGroupHelper; 139 140 // Use a Testable subclass so we can simulate calls from the system without failing. 141 private static class TestableNotificationManagerService extends NotificationManagerService { 142 public TestableNotificationManagerService(Context context) { super(context); } 143 144 @Override 145 protected boolean isCallingUidSystem() { 146 return true; 147 } 148 149 @Override 150 protected boolean isCallerSystemOrPhone() { 151 return true; 152 } 153 154 @Override 155 protected ICompanionDeviceManager getCompanionManager() { 156 return null; 157 } 158 } 159 160 @Before 161 public void setUp() throws Exception { 162 MockitoAnnotations.initMocks(this); 163 164 // most tests assume badging is enabled 165 Secure.putIntForUser(getContext().getContentResolver(), 166 Secure.NOTIFICATION_BADGING, 1, 167 UserHandle.getUserHandleForUid(mUid).getIdentifier()); 168 169 mNotificationManagerService = new TestableNotificationManagerService(mContext); 170 171 // Use this testable looper. 172 mTestableLooper = TestableLooper.get(this); 173 mHandler = mNotificationManagerService.new WorkerHandler(mTestableLooper.getLooper()); 174 // MockPackageManager - default returns ApplicationInfo with matching calling UID 175 mContext.setMockPackageManager(mPackageManagerClient); 176 final ApplicationInfo applicationInfo = new ApplicationInfo(); 177 applicationInfo.uid = mUid; 178 when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt())) 179 .thenReturn(applicationInfo); 180 when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) 181 .thenReturn(applicationInfo); 182 when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid); 183 final LightsManager mockLightsManager = mock(LightsManager.class); 184 when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class)); 185 when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); 186 187 // write to a test file; the system file isn't readable from tests 188 mFile = new File(mContext.getCacheDir(), "test.xml"); 189 mFile.createNewFile(); 190 final String preupgradeXml = "<notification-policy></notification-policy>"; 191 mPolicyFile = new AtomicFile(mFile); 192 FileOutputStream fos = mPolicyFile.startWrite(); 193 fos.write(preupgradeXml.getBytes()); 194 mPolicyFile.finishWrite(fos); 195 FileInputStream fStream = new FileInputStream(mFile); 196 197 // Setup managed services 198 mListener = mListeners.new ManagedServiceInfo( 199 null, new ComponentName(PKG, "test_class"), mUid, true, null, 0); 200 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener); 201 ManagedServices.Config listenerConfig = new ManagedServices.Config(); 202 listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS; 203 when(mListeners.getConfig()).thenReturn(listenerConfig); 204 ManagedServices.Config assistantConfig = new ManagedServices.Config(); 205 assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS; 206 when(mAssistants.getConfig()).thenReturn(assistantConfig); 207 ManagedServices.Config dndConfig = new ManagedServices.Config(); 208 dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS; 209 when(mConditionProviders.getConfig()).thenReturn(dndConfig); 210 211 try { 212 mNotificationManagerService.init(mTestableLooper.getLooper(), 213 mPackageManager, mPackageManagerClient, mockLightsManager, 214 mListeners, mAssistants, mConditionProviders, 215 mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, 216 mGroupHelper); 217 } catch (SecurityException e) { 218 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { 219 throw e; 220 } 221 } 222 mNotificationManagerService.setAudioManager(mAudioManager); 223 224 // Tests call directly into the Binder. 225 mBinderService = mNotificationManagerService.getBinderService(); 226 mInternalService = mNotificationManagerService.getInternalService(); 227 228 mBinderService.createNotificationChannels( 229 PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel))); 230 assertNotNull(mBinderService.getNotificationChannel(PKG, TEST_CHANNEL_ID)); 231 } 232 233 @After 234 public void tearDown() throws Exception { 235 mFile.delete(); 236 } 237 238 public void waitForIdle() throws Exception { 239 mTestableLooper.processAllMessages(); 240 } 241 242 private NotificationRecord generateNotificationRecord(NotificationChannel channel, int id, 243 String groupKey, boolean isSummary) { 244 Notification.Builder nb = new Notification.Builder(mContext, channel.getId()) 245 .setContentTitle("foo") 246 .setSmallIcon(android.R.drawable.sym_def_app_icon) 247 .setGroup(groupKey) 248 .setGroupSummary(isSummary); 249 250 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0, 251 nb.build(), new UserHandle(mUid), null, 0); 252 return new NotificationRecord(mContext, sbn, channel); 253 } 254 255 private NotificationRecord generateNotificationRecord(NotificationChannel channel) { 256 return generateNotificationRecord(channel, null); 257 } 258 259 private NotificationRecord generateNotificationRecord(NotificationChannel channel, 260 Notification.TvExtender extender) { 261 if (channel == null) { 262 channel = mTestNotificationChannel; 263 } 264 Notification.Builder nb = new Notification.Builder(mContext, channel.getId()) 265 .setContentTitle("foo") 266 .setSmallIcon(android.R.drawable.sym_def_app_icon); 267 if (extender != null) { 268 nb.extend(extender); 269 } 270 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0, 271 nb.build(), new UserHandle(mUid), null, 0); 272 return new NotificationRecord(mContext, sbn, channel); 273 } 274 275 private Map<String, Answer> getSignalExtractorSideEffects() { 276 Map<String, Answer> answers = new ArrayMap<>(); 277 278 answers.put("override group key", invocationOnMock -> { 279 ((NotificationRecord) invocationOnMock.getArguments()[0]) 280 .setOverrideGroupKey("bananas"); 281 return null; 282 }); 283 answers.put("override people", invocationOnMock -> { 284 ((NotificationRecord) invocationOnMock.getArguments()[0]) 285 .setPeopleOverride(new ArrayList<>()); 286 return null; 287 }); 288 answers.put("snooze criteria", invocationOnMock -> { 289 ((NotificationRecord) invocationOnMock.getArguments()[0]) 290 .setSnoozeCriteria(new ArrayList<>()); 291 return null; 292 }); 293 answers.put("notification channel", invocationOnMock -> { 294 ((NotificationRecord) invocationOnMock.getArguments()[0]) 295 .updateNotificationChannel(new NotificationChannel("a", "", IMPORTANCE_LOW)); 296 return null; 297 }); 298 answers.put("badging", invocationOnMock -> { 299 NotificationRecord r = (NotificationRecord) invocationOnMock.getArguments()[0]; 300 r.setShowBadge(!r.canShowBadge()); 301 return null; 302 }); 303 answers.put("package visibility", invocationOnMock -> { 304 ((NotificationRecord) invocationOnMock.getArguments()[0]).setPackageVisibilityOverride( 305 Notification.VISIBILITY_SECRET); 306 return null; 307 }); 308 309 return answers; 310 } 311 312 @Test 313 public void testCreateNotificationChannels_SingleChannel() throws Exception { 314 final NotificationChannel channel = 315 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); 316 mBinderService.createNotificationChannels(PKG, 317 new ParceledListSlice(Arrays.asList(channel))); 318 final NotificationChannel createdChannel = 319 mBinderService.getNotificationChannel(PKG, "id"); 320 assertTrue(createdChannel != null); 321 } 322 323 @Test 324 public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception { 325 try { 326 mBinderService.createNotificationChannels(PKG, 327 new ParceledListSlice(Arrays.asList(null))); 328 fail("Exception should be thrown immediately."); 329 } catch (NullPointerException e) { 330 // pass 331 } 332 } 333 334 @Test 335 public void testCreateNotificationChannels_TwoChannels() throws Exception { 336 final NotificationChannel channel1 = 337 new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT); 338 final NotificationChannel channel2 = 339 new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_DEFAULT); 340 mBinderService.createNotificationChannels(PKG, 341 new ParceledListSlice(Arrays.asList(channel1, channel2))); 342 assertTrue(mBinderService.getNotificationChannel(PKG, "id1") != null); 343 assertTrue(mBinderService.getNotificationChannel(PKG, "id2") != null); 344 } 345 346 @Test 347 public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance() 348 throws Exception { 349 final NotificationChannel channel = 350 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); 351 mBinderService.createNotificationChannels(PKG, 352 new ParceledListSlice(Arrays.asList(channel))); 353 354 // Recreating the channel doesn't throw, but ignores importance. 355 final NotificationChannel dupeChannel = 356 new NotificationChannel("id", "name", IMPORTANCE_HIGH); 357 mBinderService.createNotificationChannels(PKG, 358 new ParceledListSlice(Arrays.asList(dupeChannel))); 359 final NotificationChannel createdChannel = 360 mBinderService.getNotificationChannel(PKG, "id"); 361 assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance()); 362 } 363 364 @Test 365 public void testCreateNotificationChannels_SecondCreateAllowedToDowngradeImportance() 366 throws Exception { 367 final NotificationChannel channel = 368 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); 369 mBinderService.createNotificationChannels(PKG, 370 new ParceledListSlice(Arrays.asList(channel))); 371 372 // Recreating with a lower importance is allowed to modify the channel. 373 final NotificationChannel dupeChannel = 374 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW); 375 mBinderService.createNotificationChannels(PKG, 376 new ParceledListSlice(Arrays.asList(dupeChannel))); 377 final NotificationChannel createdChannel = 378 mBinderService.getNotificationChannel(PKG, "id"); 379 assertEquals(NotificationManager.IMPORTANCE_LOW, createdChannel.getImportance()); 380 } 381 382 @Test 383 public void testCreateNotificationChannels_CannotDowngradeImportanceIfAlreadyUpdated() 384 throws Exception { 385 final NotificationChannel channel = 386 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); 387 mBinderService.createNotificationChannels(PKG, 388 new ParceledListSlice(Arrays.asList(channel))); 389 390 // The user modifies importance directly, can no longer be changed by the app. 391 final NotificationChannel updatedChannel = 392 new NotificationChannel("id", "name", IMPORTANCE_HIGH); 393 mBinderService.updateNotificationChannelForPackage(PKG, mUid, updatedChannel); 394 395 // Recreating with a lower importance leaves channel unchanged. 396 final NotificationChannel dupeChannel = 397 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW); 398 mBinderService.createNotificationChannels(PKG, 399 new ParceledListSlice(Arrays.asList(dupeChannel))); 400 final NotificationChannel createdChannel = 401 mBinderService.getNotificationChannel(PKG, "id"); 402 assertEquals(IMPORTANCE_HIGH, createdChannel.getImportance()); 403 } 404 405 @Test 406 public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond() 407 throws Exception { 408 final NotificationChannel channel1 = 409 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT); 410 final NotificationChannel channel2 = 411 new NotificationChannel("id", "name", IMPORTANCE_HIGH); 412 mBinderService.createNotificationChannels(PKG, 413 new ParceledListSlice(Arrays.asList(channel1, channel2))); 414 final NotificationChannel createdChannel = 415 mBinderService.getNotificationChannel(PKG, "id"); 416 assertEquals(NotificationManager.IMPORTANCE_DEFAULT, createdChannel.getImportance()); 417 } 418 419 @Test 420 public void testBlockedNotifications_suspended() throws Exception { 421 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true); 422 423 NotificationChannel channel = new NotificationChannel("id", "name", 424 IMPORTANCE_HIGH); 425 NotificationRecord r = generateNotificationRecord(channel); 426 assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats)); 427 verify(mUsageStats, times(1)).registerSuspendedByAdmin(eq(r)); 428 } 429 430 @Test 431 public void testBlockedNotifications_blockedChannel() throws Exception { 432 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); 433 434 NotificationChannel channel = new NotificationChannel("id", "name", 435 NotificationManager.IMPORTANCE_NONE); 436 NotificationRecord r = generateNotificationRecord(channel); 437 assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats)); 438 verify(mUsageStats, times(1)).registerBlocked(eq(r)); 439 440 mBinderService.createNotificationChannels( 441 PKG, new ParceledListSlice(Arrays.asList(channel))); 442 final StatusBarNotification sbn = generateNotificationRecord(channel).sbn; 443 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 444 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 445 waitForIdle(); 446 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length); 447 } 448 449 @Test 450 public void testEnqueuedBlockedNotifications_appBlockedChannelForegroundService() 451 throws Exception { 452 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); 453 454 NotificationChannel channel = new NotificationChannel("blocked", "name", 455 NotificationManager.IMPORTANCE_NONE); 456 mBinderService.createNotificationChannels( 457 PKG, new ParceledListSlice(Arrays.asList(channel))); 458 459 final StatusBarNotification sbn = generateNotificationRecord(channel).sbn; 460 sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; 461 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 462 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 463 waitForIdle(); 464 assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length); 465 assertEquals(IMPORTANCE_LOW, 466 mNotificationManagerService.getNotificationRecord(sbn.getKey()).getImportance()); 467 assertEquals(IMPORTANCE_LOW, 468 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance()); 469 } 470 471 @Test 472 public void testEnqueuedBlockedNotifications_userBlockedChannelForegroundService() 473 throws Exception { 474 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); 475 476 NotificationChannel channel = 477 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_HIGH); 478 mBinderService.createNotificationChannels( 479 PKG, new ParceledListSlice(Arrays.asList(channel))); 480 481 NotificationChannel update = 482 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE); 483 mBinderService.updateNotificationChannelForPackage(PKG, mUid, update); 484 waitForIdle(); 485 assertEquals(IMPORTANCE_NONE, 486 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance()); 487 488 final StatusBarNotification sbn = generateNotificationRecord(channel).sbn; 489 sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; 490 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 491 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 492 waitForIdle(); 493 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length); 494 assertNull(mNotificationManagerService.getNotificationRecord(sbn.getKey())); 495 assertEquals(IMPORTANCE_NONE, 496 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance()); 497 } 498 499 @Test 500 public void testEnqueuedBlockedNotifications_blockedApp() throws Exception { 501 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); 502 503 mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false); 504 505 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 506 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 507 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 508 waitForIdle(); 509 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length); 510 } 511 512 @Test 513 public void testEnqueuedBlockedNotifications_blockedAppForegroundService() throws Exception { 514 when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false); 515 516 mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false); 517 518 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 519 sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; 520 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 521 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 522 waitForIdle(); 523 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length); 524 assertNull(mNotificationManagerService.getNotificationRecord(sbn.getKey())); 525 } 526 527 @Test 528 public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception { 529 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0, 530 generateNotificationRecord(null).getNotification(), 0); 531 waitForIdle(); 532 StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG); 533 assertEquals(1, notifs.length); 534 assertEquals(1, mNotificationManagerService.getNotificationRecordCount()); 535 } 536 537 @Test 538 public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception { 539 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0, 540 generateNotificationRecord(null).getNotification(), 0); 541 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0); 542 waitForIdle(); 543 StatusBarNotification[] notifs = 544 mBinderService.getActiveNotifications(PKG); 545 assertEquals(0, notifs.length); 546 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 547 } 548 549 @Test 550 public void testCancelNotificationWhilePostedAndEnqueued() throws Exception { 551 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0, 552 generateNotificationRecord(null).getNotification(), 0); 553 waitForIdle(); 554 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0, 555 generateNotificationRecord(null).getNotification(), 0); 556 mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0); 557 waitForIdle(); 558 StatusBarNotification[] notifs = 559 mBinderService.getActiveNotifications(PKG); 560 assertEquals(0, notifs.length); 561 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 562 } 563 564 @Test 565 public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception { 566 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 567 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 568 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 569 mBinderService.cancelNotificationsFromListener(null, null); 570 waitForIdle(); 571 StatusBarNotification[] notifs = 572 mBinderService.getActiveNotifications(sbn.getPackageName()); 573 assertEquals(0, notifs.length); 574 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 575 } 576 577 @Test 578 public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception { 579 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 580 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 581 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 582 mBinderService.cancelAllNotifications(PKG, sbn.getUserId()); 583 waitForIdle(); 584 StatusBarNotification[] notifs = 585 mBinderService.getActiveNotifications(sbn.getPackageName()); 586 assertEquals(0, notifs.length); 587 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 588 } 589 590 @Test 591 public void testUserInitiatedClearAll_noLeak() throws Exception { 592 final NotificationRecord n = generateNotificationRecord( 593 mTestNotificationChannel, 1, "group", true); 594 595 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 596 n.sbn.getId(), n.sbn.getNotification(), n.sbn.getUserId()); 597 waitForIdle(); 598 599 mNotificationManagerService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(), 600 n.getUserId()); 601 waitForIdle(); 602 StatusBarNotification[] notifs = 603 mBinderService.getActiveNotifications(n.sbn.getPackageName()); 604 assertEquals(0, notifs.length); 605 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 606 } 607 608 @Test 609 public void testCancelAllNotificationsCancelsChildren() throws Exception { 610 final NotificationRecord parent = generateNotificationRecord( 611 mTestNotificationChannel, 1, "group1", true); 612 final NotificationRecord child = generateNotificationRecord( 613 mTestNotificationChannel, 2, "group1", false); 614 615 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 616 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId()); 617 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 618 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId()); 619 waitForIdle(); 620 621 mBinderService.cancelAllNotifications(PKG, parent.sbn.getUserId()); 622 waitForIdle(); 623 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 624 } 625 626 @Test 627 public void testCancelAllNotificationsMultipleEnqueuedDoesNotCrash() throws Exception { 628 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 629 for (int i = 0; i < 10; i++) { 630 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 631 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 632 } 633 mBinderService.cancelAllNotifications(PKG, sbn.getUserId()); 634 waitForIdle(); 635 636 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 637 } 638 639 @Test 640 public void testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash() throws Exception { 641 final NotificationRecord parent = generateNotificationRecord( 642 mTestNotificationChannel, 1, "group1", true); 643 final NotificationRecord parentAsChild = generateNotificationRecord( 644 mTestNotificationChannel, 1, "group1", false); 645 final NotificationRecord child = generateNotificationRecord( 646 mTestNotificationChannel, 2, "group1", false); 647 648 // fully post parent notification 649 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 650 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId()); 651 waitForIdle(); 652 653 // enqueue the child several times 654 for (int i = 0; i < 10; i++) { 655 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 656 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId()); 657 } 658 // make the parent a child, which will cancel the child notification 659 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 660 parentAsChild.sbn.getId(), parentAsChild.sbn.getNotification(), 661 parentAsChild.sbn.getUserId()); 662 waitForIdle(); 663 664 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 665 } 666 667 @Test 668 public void testCancelAllNotifications_IgnoreForegroundService() throws Exception { 669 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 670 sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; 671 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 672 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 673 mBinderService.cancelAllNotifications(PKG, sbn.getUserId()); 674 waitForIdle(); 675 StatusBarNotification[] notifs = 676 mBinderService.getActiveNotifications(sbn.getPackageName()); 677 assertEquals(1, notifs.length); 678 assertEquals(1, mNotificationManagerService.getNotificationRecordCount()); 679 } 680 681 @Test 682 public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception { 683 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 684 sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; 685 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 686 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 687 mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId()); 688 waitForIdle(); 689 StatusBarNotification[] notifs = 690 mBinderService.getActiveNotifications(sbn.getPackageName()); 691 assertEquals(1, notifs.length); 692 assertEquals(1, mNotificationManagerService.getNotificationRecordCount()); 693 } 694 695 @Test 696 public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception { 697 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 698 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 699 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 700 mBinderService.cancelAllNotifications(null, sbn.getUserId()); 701 waitForIdle(); 702 StatusBarNotification[] notifs = 703 mBinderService.getActiveNotifications(sbn.getPackageName()); 704 assertEquals(0, notifs.length); 705 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 706 } 707 708 @Test 709 public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception { 710 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 711 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 712 sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL); 713 // Null pkg is how we signal a user switch. 714 mBinderService.cancelAllNotifications(null, sbn.getUserId()); 715 waitForIdle(); 716 StatusBarNotification[] notifs = 717 mBinderService.getActiveNotifications(sbn.getPackageName()); 718 assertEquals(1, notifs.length); 719 assertEquals(1, mNotificationManagerService.getNotificationRecordCount()); 720 } 721 722 @Test 723 public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception { 724 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 725 sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR; 726 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 727 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 728 mBinderService.cancelAllNotifications(PKG, sbn.getUserId()); 729 waitForIdle(); 730 StatusBarNotification[] notifs = 731 mBinderService.getActiveNotifications(sbn.getPackageName()); 732 assertEquals(0, notifs.length); 733 } 734 735 @Test 736 public void testCancelAllNotifications_CancelsNoClearFlag() throws Exception { 737 final NotificationRecord notif = generateNotificationRecord( 738 mTestNotificationChannel, 1, "group", true); 739 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR; 740 mNotificationManagerService.addNotification(notif); 741 mNotificationManagerService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0, true, 742 notif.getUserId(), 0, null); 743 waitForIdle(); 744 StatusBarNotification[] notifs = 745 mBinderService.getActiveNotifications(notif.sbn.getPackageName()); 746 assertEquals(0, notifs.length); 747 } 748 749 @Test 750 public void testUserInitiatedCancelAllOnClearAll_NoClearFlag() throws Exception { 751 final NotificationRecord notif = generateNotificationRecord( 752 mTestNotificationChannel, 1, "group", true); 753 notif.getNotification().flags |= Notification.FLAG_NO_CLEAR; 754 mNotificationManagerService.addNotification(notif); 755 756 mNotificationManagerService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(), 757 notif.getUserId()); 758 waitForIdle(); 759 StatusBarNotification[] notifs = 760 mBinderService.getActiveNotifications(notif.sbn.getPackageName()); 761 assertEquals(1, notifs.length); 762 } 763 764 @Test 765 public void testCancelAllCancelNotificationsFromListener_NoClearFlag() throws Exception { 766 final NotificationRecord parent = generateNotificationRecord( 767 mTestNotificationChannel, 1, "group", true); 768 final NotificationRecord child = generateNotificationRecord( 769 mTestNotificationChannel, 2, "group", false); 770 final NotificationRecord child2 = generateNotificationRecord( 771 mTestNotificationChannel, 3, "group", false); 772 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR; 773 final NotificationRecord newGroup = generateNotificationRecord( 774 mTestNotificationChannel, 4, "group2", false); 775 mNotificationManagerService.addNotification(parent); 776 mNotificationManagerService.addNotification(child); 777 mNotificationManagerService.addNotification(child2); 778 mNotificationManagerService.addNotification(newGroup); 779 mNotificationManagerService.getBinderService().cancelNotificationsFromListener(null, null); 780 waitForIdle(); 781 StatusBarNotification[] notifs = 782 mBinderService.getActiveNotifications(parent.sbn.getPackageName()); 783 assertEquals(1, notifs.length); 784 } 785 786 @Test 787 public void testUserInitiatedCancelAllWithGroup_NoClearFlag() throws Exception { 788 final NotificationRecord parent = generateNotificationRecord( 789 mTestNotificationChannel, 1, "group", true); 790 final NotificationRecord child = generateNotificationRecord( 791 mTestNotificationChannel, 2, "group", false); 792 final NotificationRecord child2 = generateNotificationRecord( 793 mTestNotificationChannel, 3, "group", false); 794 child2.getNotification().flags |= Notification.FLAG_NO_CLEAR; 795 final NotificationRecord newGroup = generateNotificationRecord( 796 mTestNotificationChannel, 4, "group2", false); 797 mNotificationManagerService.addNotification(parent); 798 mNotificationManagerService.addNotification(child); 799 mNotificationManagerService.addNotification(child2); 800 mNotificationManagerService.addNotification(newGroup); 801 mNotificationManagerService.mNotificationDelegate.onClearAll(mUid, Binder.getCallingPid(), 802 parent.getUserId()); 803 waitForIdle(); 804 StatusBarNotification[] notifs = 805 mBinderService.getActiveNotifications(parent.sbn.getPackageName()); 806 assertEquals(1, notifs.length); 807 } 808 809 @Test 810 public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception { 811 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 812 sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE; 813 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, 814 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 815 mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(), 816 sbn.getUserId()); 817 waitForIdle(); 818 StatusBarNotification[] notifs = 819 mBinderService.getActiveNotifications(sbn.getPackageName()); 820 assertEquals(0, notifs[0].getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE); 821 } 822 823 @Test 824 public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception { 825 final StatusBarNotification sbn = generateNotificationRecord(null).sbn; 826 sbn.getNotification().flags = 827 Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE; 828 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 829 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 830 sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT; 831 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 832 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 833 mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId()); 834 waitForIdle(); 835 assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length); 836 assertEquals(0, mNotificationManagerService.getNotificationRecordCount()); 837 } 838 839 @Test 840 public void testFindGroupNotificationsLocked() throws Exception { 841 // make sure the same notification can be found in both lists and returned 842 final NotificationRecord group1 = generateNotificationRecord( 843 mTestNotificationChannel, 1, "group1", true); 844 mNotificationManagerService.addEnqueuedNotification(group1); 845 mNotificationManagerService.addNotification(group1); 846 847 // should not be returned 848 final NotificationRecord group2 = generateNotificationRecord( 849 mTestNotificationChannel, 2, "group2", true); 850 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, 851 group2.sbn.getId(), group2.sbn.getNotification(), group2.sbn.getUserId()); 852 waitForIdle(); 853 854 // should not be returned 855 final NotificationRecord nonGroup = generateNotificationRecord( 856 mTestNotificationChannel, 3, null, false); 857 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, 858 nonGroup.sbn.getId(), nonGroup.sbn.getNotification(), nonGroup.sbn.getUserId()); 859 waitForIdle(); 860 861 // same group, child, should be returned 862 final NotificationRecord group1Child = generateNotificationRecord( 863 mTestNotificationChannel, 4, "group1", false); 864 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, group1Child.sbn.getId(), 865 group1Child.sbn.getNotification(), group1Child.sbn.getUserId()); 866 waitForIdle(); 867 868 List<NotificationRecord> inGroup1 = 869 mNotificationManagerService.findGroupNotificationsLocked(PKG, group1.getGroupKey(), 870 group1.sbn.getUserId()); 871 assertEquals(3, inGroup1.size()); 872 for (NotificationRecord record : inGroup1) { 873 assertTrue(record.getGroupKey().equals(group1.getGroupKey())); 874 assertTrue(record.sbn.getId() == 1 || record.sbn.getId() == 4); 875 } 876 } 877 878 @Test 879 public void testTvExtenderChannelOverride_onTv() throws Exception { 880 mNotificationManagerService.setIsTelevision(true); 881 mNotificationManagerService.setRankingHelper(mRankingHelper); 882 when(mRankingHelper.getNotificationChannel( 883 anyString(), anyInt(), eq("foo"), anyBoolean())).thenReturn( 884 new NotificationChannel("foo", "foo", IMPORTANCE_HIGH)); 885 886 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo"); 887 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0, 888 generateNotificationRecord(null, tv).getNotification(), 0); 889 verify(mRankingHelper, times(1)).getNotificationChannel( 890 anyString(), anyInt(), eq("foo"), anyBoolean()); 891 } 892 893 @Test 894 public void testTvExtenderChannelOverride_notOnTv() throws Exception { 895 mNotificationManagerService.setIsTelevision(false); 896 mNotificationManagerService.setRankingHelper(mRankingHelper); 897 when(mRankingHelper.getNotificationChannel( 898 anyString(), anyInt(), anyString(), anyBoolean())).thenReturn( 899 mTestNotificationChannel); 900 901 Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo"); 902 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0, 903 generateNotificationRecord(null, tv).getNotification(), 0); 904 verify(mRankingHelper, times(1)).getNotificationChannel( 905 anyString(), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean()); 906 } 907 908 @Test 909 public void testCreateChannelNotifyListener() throws Exception { 910 List<String> associations = new ArrayList<>(); 911 associations.add("a"); 912 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 913 mNotificationManagerService.setRankingHelper(mRankingHelper); 914 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(), 915 eq(mTestNotificationChannel.getId()), anyBoolean())) 916 .thenReturn(mTestNotificationChannel); 917 NotificationChannel channel2 = new NotificationChannel("a", "b", IMPORTANCE_LOW); 918 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(), 919 eq(channel2.getId()), anyBoolean())) 920 .thenReturn(channel2); 921 922 reset(mListeners); 923 mBinderService.createNotificationChannels(PKG, 924 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2))); 925 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), 926 eq(Process.myUserHandle()), eq(mTestNotificationChannel), 927 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED)); 928 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), 929 eq(Process.myUserHandle()), eq(channel2), 930 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED)); 931 } 932 933 @Test 934 public void testCreateChannelGroupNotifyListener() throws Exception { 935 List<String> associations = new ArrayList<>(); 936 associations.add("a"); 937 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 938 mNotificationManagerService.setRankingHelper(mRankingHelper); 939 NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b"); 940 NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m"); 941 942 reset(mListeners); 943 mBinderService.createNotificationChannelGroups(PKG, 944 new ParceledListSlice(Arrays.asList(group1, group2))); 945 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG), 946 eq(Process.myUserHandle()), eq(group1), 947 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED)); 948 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG), 949 eq(Process.myUserHandle()), eq(group2), 950 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED)); 951 } 952 953 @Test 954 public void testUpdateChannelNotifyListener() throws Exception { 955 List<String> associations = new ArrayList<>(); 956 associations.add("a"); 957 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 958 mNotificationManagerService.setRankingHelper(mRankingHelper); 959 mTestNotificationChannel.setLightColor(Color.CYAN); 960 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(), 961 eq(mTestNotificationChannel.getId()), anyBoolean())) 962 .thenReturn(mTestNotificationChannel); 963 964 reset(mListeners); 965 mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel); 966 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), 967 eq(Process.myUserHandle()), eq(mTestNotificationChannel), 968 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); 969 } 970 971 @Test 972 public void testDeleteChannelNotifyListener() throws Exception { 973 List<String> associations = new ArrayList<>(); 974 associations.add("a"); 975 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 976 mNotificationManagerService.setRankingHelper(mRankingHelper); 977 when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(), 978 eq(mTestNotificationChannel.getId()), anyBoolean())) 979 .thenReturn(mTestNotificationChannel); 980 reset(mListeners); 981 mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId()); 982 verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), 983 eq(Process.myUserHandle()), eq(mTestNotificationChannel), 984 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED)); 985 } 986 987 @Test 988 public void testDeleteChannelGroupNotifyListener() throws Exception { 989 List<String> associations = new ArrayList<>(); 990 associations.add("a"); 991 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 992 NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c"); 993 mNotificationManagerService.setRankingHelper(mRankingHelper); 994 when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt())) 995 .thenReturn(ncg); 996 reset(mListeners); 997 mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId()); 998 verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG), 999 eq(Process.myUserHandle()), eq(ncg), 1000 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED)); 1001 } 1002 1003 @Test 1004 public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception { 1005 mNotificationManagerService.setRankingHelper(mRankingHelper); 1006 List<String> associations = new ArrayList<>(); 1007 associations.add("a"); 1008 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 1009 1010 mBinderService.updateNotificationChannelFromPrivilegedListener( 1011 null, PKG, Process.myUserHandle(), mTestNotificationChannel); 1012 1013 verify(mRankingHelper, times(1)).updateNotificationChannel( 1014 anyString(), anyInt(), any(), anyBoolean()); 1015 1016 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), 1017 eq(Process.myUserHandle()), eq(mTestNotificationChannel), 1018 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); 1019 } 1020 1021 @Test 1022 public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception { 1023 mNotificationManagerService.setRankingHelper(mRankingHelper); 1024 List<String> associations = new ArrayList<>(); 1025 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 1026 1027 try { 1028 mBinderService.updateNotificationChannelFromPrivilegedListener( 1029 null, PKG, Process.myUserHandle(), mTestNotificationChannel); 1030 fail("listeners that don't have a companion device shouldn't be able to call this"); 1031 } catch (SecurityException e) { 1032 // pass 1033 } 1034 1035 verify(mRankingHelper, never()).updateNotificationChannel( 1036 anyString(), anyInt(), any(), anyBoolean()); 1037 1038 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), 1039 eq(Process.myUserHandle()), eq(mTestNotificationChannel), 1040 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); 1041 } 1042 1043 @Test 1044 public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception { 1045 mNotificationManagerService.setRankingHelper(mRankingHelper); 1046 List<String> associations = new ArrayList<>(); 1047 associations.add("a"); 1048 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 1049 mListener = mock(ManagedServices.ManagedServiceInfo.class); 1050 mListener.component = new ComponentName(PKG, PKG); 1051 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false); 1052 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener); 1053 1054 try { 1055 mBinderService.updateNotificationChannelFromPrivilegedListener( 1056 null, PKG, UserHandle.ALL, mTestNotificationChannel); 1057 fail("incorrectly allowed a change to a user listener cannot see"); 1058 } catch (SecurityException e) { 1059 // pass 1060 } 1061 1062 verify(mRankingHelper, never()).updateNotificationChannel( 1063 anyString(), anyInt(), any(), anyBoolean()); 1064 1065 verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), 1066 eq(Process.myUserHandle()), eq(mTestNotificationChannel), 1067 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); 1068 } 1069 1070 @Test 1071 public void testGetNotificationChannelFromPrivilegedListener_success() throws Exception { 1072 mNotificationManagerService.setRankingHelper(mRankingHelper); 1073 List<String> associations = new ArrayList<>(); 1074 associations.add("a"); 1075 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 1076 1077 mBinderService.getNotificationChannelsFromPrivilegedListener( 1078 null, PKG, Process.myUserHandle()); 1079 1080 verify(mRankingHelper, times(1)).getNotificationChannels( 1081 anyString(), anyInt(), anyBoolean()); 1082 } 1083 1084 @Test 1085 public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception { 1086 mNotificationManagerService.setRankingHelper(mRankingHelper); 1087 List<String> associations = new ArrayList<>(); 1088 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 1089 1090 try { 1091 mBinderService.getNotificationChannelsFromPrivilegedListener( 1092 null, PKG, Process.myUserHandle()); 1093 fail("listeners that don't have a companion device shouldn't be able to call this"); 1094 } catch (SecurityException e) { 1095 // pass 1096 } 1097 1098 verify(mRankingHelper, never()).getNotificationChannels( 1099 anyString(), anyInt(), anyBoolean()); 1100 } 1101 1102 @Test 1103 public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception { 1104 mNotificationManagerService.setRankingHelper(mRankingHelper); 1105 List<String> associations = new ArrayList<>(); 1106 associations.add("a"); 1107 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 1108 mListener = mock(ManagedServices.ManagedServiceInfo.class); 1109 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false); 1110 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener); 1111 1112 try { 1113 mBinderService.getNotificationChannelsFromPrivilegedListener( 1114 null, PKG, Process.myUserHandle()); 1115 fail("listener getting channels from a user they cannot see"); 1116 } catch (SecurityException e) { 1117 // pass 1118 } 1119 1120 verify(mRankingHelper, never()).getNotificationChannels( 1121 anyString(), anyInt(), anyBoolean()); 1122 } 1123 1124 @Test 1125 public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception { 1126 mNotificationManagerService.setRankingHelper(mRankingHelper); 1127 List<String> associations = new ArrayList<>(); 1128 associations.add("a"); 1129 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 1130 1131 mBinderService.getNotificationChannelGroupsFromPrivilegedListener( 1132 null, PKG, Process.myUserHandle()); 1133 1134 verify(mRankingHelper, times(1)).getNotificationChannelGroups(anyString(), anyInt()); 1135 } 1136 1137 @Test 1138 public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception { 1139 mNotificationManagerService.setRankingHelper(mRankingHelper); 1140 List<String> associations = new ArrayList<>(); 1141 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 1142 1143 try { 1144 mBinderService.getNotificationChannelGroupsFromPrivilegedListener( 1145 null, PKG, Process.myUserHandle()); 1146 fail("listeners that don't have a companion device shouldn't be able to call this"); 1147 } catch (SecurityException e) { 1148 // pass 1149 } 1150 1151 verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt()); 1152 } 1153 1154 @Test 1155 public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception { 1156 mNotificationManagerService.setRankingHelper(mRankingHelper); 1157 List<String> associations = new ArrayList<>(); 1158 when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations); 1159 mListener = mock(ManagedServices.ManagedServiceInfo.class); 1160 when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false); 1161 when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener); 1162 1163 try { 1164 mBinderService.getNotificationChannelGroupsFromPrivilegedListener( 1165 null, PKG, Process.myUserHandle()); 1166 fail("listeners that don't have a companion device shouldn't be able to call this"); 1167 } catch (SecurityException e) { 1168 // pass 1169 } 1170 1171 verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt()); 1172 } 1173 1174 @Test 1175 public void testHasCompanionDevice_failure() throws Exception { 1176 when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow( 1177 new IllegalArgumentException()); 1178 mNotificationManagerService.hasCompanionDevice(mListener); 1179 } 1180 1181 @Test 1182 public void testHasCompanionDevice_noService() throws Exception { 1183 mNotificationManagerService = new TestableNotificationManagerService(mContext); 1184 1185 assertFalse(mNotificationManagerService.hasCompanionDevice(mListener)); 1186 } 1187 1188 @Test 1189 public void testSnoozeRunnable_snoozeNonGrouped() throws Exception { 1190 final NotificationRecord nonGrouped = generateNotificationRecord( 1191 mTestNotificationChannel, 1, null, false); 1192 final NotificationRecord grouped = generateNotificationRecord( 1193 mTestNotificationChannel, 2, "group", false); 1194 mNotificationManagerService.addNotification(grouped); 1195 mNotificationManagerService.addNotification(nonGrouped); 1196 1197 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = 1198 mNotificationManagerService.new SnoozeNotificationRunnable( 1199 nonGrouped.getKey(), 100, null); 1200 snoozeNotificationRunnable.run(); 1201 1202 // only snooze the one notification 1203 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong()); 1204 } 1205 1206 @Test 1207 public void testSnoozeRunnable_snoozeSummary_withChildren() throws Exception { 1208 final NotificationRecord parent = generateNotificationRecord( 1209 mTestNotificationChannel, 1, "group", true); 1210 final NotificationRecord child = generateNotificationRecord( 1211 mTestNotificationChannel, 2, "group", false); 1212 final NotificationRecord child2 = generateNotificationRecord( 1213 mTestNotificationChannel, 3, "group", false); 1214 mNotificationManagerService.addNotification(parent); 1215 mNotificationManagerService.addNotification(child); 1216 mNotificationManagerService.addNotification(child2); 1217 1218 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = 1219 mNotificationManagerService.new SnoozeNotificationRunnable( 1220 parent.getKey(), 100, null); 1221 snoozeNotificationRunnable.run(); 1222 1223 // snooze parent and children 1224 verify(mSnoozeHelper, times(3)).snooze(any(NotificationRecord.class), anyLong()); 1225 } 1226 1227 @Test 1228 public void testSnoozeRunnable_snoozeGroupChild_fellowChildren() throws Exception { 1229 final NotificationRecord parent = generateNotificationRecord( 1230 mTestNotificationChannel, 1, "group", true); 1231 final NotificationRecord child = generateNotificationRecord( 1232 mTestNotificationChannel, 2, "group", false); 1233 final NotificationRecord child2 = generateNotificationRecord( 1234 mTestNotificationChannel, 3, "group", false); 1235 mNotificationManagerService.addNotification(parent); 1236 mNotificationManagerService.addNotification(child); 1237 mNotificationManagerService.addNotification(child2); 1238 1239 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = 1240 mNotificationManagerService.new SnoozeNotificationRunnable( 1241 child2.getKey(), 100, null); 1242 snoozeNotificationRunnable.run(); 1243 1244 // only snooze the one child 1245 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong()); 1246 } 1247 1248 @Test 1249 public void testSnoozeRunnable_snoozeGroupChild_onlyChildOfSummary() throws Exception { 1250 final NotificationRecord parent = generateNotificationRecord( 1251 mTestNotificationChannel, 1, "group", true); 1252 assertTrue(parent.sbn.getNotification().isGroupSummary()); 1253 final NotificationRecord child = generateNotificationRecord( 1254 mTestNotificationChannel, 2, "group", false); 1255 mNotificationManagerService.addNotification(parent); 1256 mNotificationManagerService.addNotification(child); 1257 1258 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = 1259 mNotificationManagerService.new SnoozeNotificationRunnable( 1260 child.getKey(), 100, null); 1261 snoozeNotificationRunnable.run(); 1262 1263 // snooze child and summary 1264 verify(mSnoozeHelper, times(2)).snooze(any(NotificationRecord.class), anyLong()); 1265 } 1266 1267 @Test 1268 public void testSnoozeRunnable_snoozeGroupChild_noOthersInGroup() throws Exception { 1269 final NotificationRecord child = generateNotificationRecord( 1270 mTestNotificationChannel, 2, "group", false); 1271 mNotificationManagerService.addNotification(child); 1272 1273 NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable = 1274 mNotificationManagerService.new SnoozeNotificationRunnable( 1275 child.getKey(), 100, null); 1276 snoozeNotificationRunnable.run(); 1277 1278 // snooze child only 1279 verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong()); 1280 } 1281 1282 @Test 1283 public void testPostGroupChild_unsnoozeParent() throws Exception { 1284 final NotificationRecord child = generateNotificationRecord( 1285 mTestNotificationChannel, 2, "group", false); 1286 1287 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, 1288 child.sbn.getId(), child.sbn.getNotification(), child.sbn.getUserId()); 1289 waitForIdle(); 1290 1291 verify(mSnoozeHelper, times(1)).repostGroupSummary( 1292 anyString(), anyInt(), eq(child.getGroupKey())); 1293 } 1294 1295 @Test 1296 public void testPostNonGroup_noUnsnoozing() throws Exception { 1297 final NotificationRecord record = generateNotificationRecord( 1298 mTestNotificationChannel, 2, null, false); 1299 1300 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, 1301 record.sbn.getId(), record.sbn.getNotification(), record.sbn.getUserId()); 1302 waitForIdle(); 1303 1304 verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString()); 1305 } 1306 1307 @Test 1308 public void testPostGroupSummary_noUnsnoozing() throws Exception { 1309 final NotificationRecord parent = generateNotificationRecord( 1310 mTestNotificationChannel, 2, "group", true); 1311 1312 mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null, 1313 parent.sbn.getId(), parent.sbn.getNotification(), parent.sbn.getUserId()); 1314 waitForIdle(); 1315 1316 verify(mSnoozeHelper, never()).repostGroupSummary(anyString(), anyInt(), anyString()); 1317 } 1318 1319 @Test 1320 public void testSetListenerAccessForUser() throws Exception { 1321 UserHandle user = UserHandle.of(10); 1322 ComponentName c = ComponentName.unflattenFromString("package/Component"); 1323 try { 1324 mBinderService.setNotificationListenerAccessGrantedForUser( 1325 c, user.getIdentifier(), true); 1326 } catch (SecurityException e) { 1327 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { 1328 throw e; 1329 } 1330 } 1331 1332 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any()); 1333 verify(mListeners, times(1)).setPackageOrComponentEnabled( 1334 c.flattenToString(), user.getIdentifier(), true, true); 1335 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled( 1336 c.flattenToString(), user.getIdentifier(), false, true); 1337 verify(mAssistants, never()).setPackageOrComponentEnabled( 1338 any(), anyInt(), anyBoolean(), anyBoolean()); 1339 } 1340 1341 @Test 1342 public void testSetAssistantAccessForUser() throws Exception { 1343 UserHandle user = UserHandle.of(10); 1344 ComponentName c = ComponentName.unflattenFromString("package/Component"); 1345 try { 1346 mBinderService.setNotificationAssistantAccessGrantedForUser( 1347 c, user.getIdentifier(), true); 1348 } catch (SecurityException e) { 1349 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { 1350 throw e; 1351 } 1352 } 1353 1354 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any()); 1355 verify(mAssistants, times(1)).setPackageOrComponentEnabled( 1356 c.flattenToString(), user.getIdentifier(), true, true); 1357 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled( 1358 c.flattenToString(), user.getIdentifier(), false, true); 1359 verify(mListeners, never()).setPackageOrComponentEnabled( 1360 any(), anyInt(), anyBoolean(), anyBoolean()); 1361 } 1362 1363 @Test 1364 public void testSetDndAccessForUser() throws Exception { 1365 UserHandle user = UserHandle.of(10); 1366 ComponentName c = ComponentName.unflattenFromString("package/Component"); 1367 try { 1368 mBinderService.setNotificationPolicyAccessGrantedForUser( 1369 c.getPackageName(), user.getIdentifier(), true); 1370 } catch (SecurityException e) { 1371 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { 1372 throw e; 1373 } 1374 } 1375 1376 verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any()); 1377 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled( 1378 c.getPackageName(), user.getIdentifier(), true, true); 1379 verify(mAssistants, never()).setPackageOrComponentEnabled( 1380 any(), anyInt(), anyBoolean(), anyBoolean()); 1381 verify(mListeners, never()).setPackageOrComponentEnabled( 1382 any(), anyInt(), anyBoolean(), anyBoolean()); 1383 } 1384 1385 @Test 1386 public void testSetListenerAccess() throws Exception { 1387 ComponentName c = ComponentName.unflattenFromString("package/Component"); 1388 try { 1389 mBinderService.setNotificationListenerAccessGranted(c, true); 1390 } catch (SecurityException e) { 1391 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { 1392 throw e; 1393 } 1394 } 1395 1396 verify(mListeners, times(1)).setPackageOrComponentEnabled( 1397 c.flattenToString(), 0, true, true); 1398 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled( 1399 c.flattenToString(), 0, false, true); 1400 verify(mAssistants, never()).setPackageOrComponentEnabled( 1401 any(), anyInt(), anyBoolean(), anyBoolean()); 1402 } 1403 1404 @Test 1405 public void testSetAssistantAccess() throws Exception { 1406 ComponentName c = ComponentName.unflattenFromString("package/Component"); 1407 try { 1408 mBinderService.setNotificationAssistantAccessGranted(c, true); 1409 } catch (SecurityException e) { 1410 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { 1411 throw e; 1412 } 1413 } 1414 1415 verify(mAssistants, times(1)).setPackageOrComponentEnabled( 1416 c.flattenToString(), 0, true, true); 1417 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled( 1418 c.flattenToString(), 0, false, true); 1419 verify(mListeners, never()).setPackageOrComponentEnabled( 1420 any(), anyInt(), anyBoolean(), anyBoolean()); 1421 } 1422 1423 @Test 1424 public void testSetDndAccess() throws Exception { 1425 ComponentName c = ComponentName.unflattenFromString("package/Component"); 1426 try { 1427 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true); 1428 } catch (SecurityException e) { 1429 if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { 1430 throw e; 1431 } 1432 } 1433 1434 verify(mConditionProviders, times(1)).setPackageOrComponentEnabled( 1435 c.getPackageName(), 0, true, true); 1436 verify(mAssistants, never()).setPackageOrComponentEnabled( 1437 any(), anyInt(), anyBoolean(), anyBoolean()); 1438 verify(mListeners, never()).setPackageOrComponentEnabled( 1439 any(), anyInt(), anyBoolean(), anyBoolean()); 1440 } 1441 1442 @Test 1443 public void testSetListenerAccess_doesNothingOnLowRam() throws Exception { 1444 when(mActivityManager.isLowRamDevice()).thenReturn(true); 1445 ComponentName c = ComponentName.unflattenFromString("package/Component"); 1446 mBinderService.setNotificationListenerAccessGranted(c, true); 1447 1448 verify(mListeners, never()).setPackageOrComponentEnabled( 1449 c.flattenToString(), 0, true, true); 1450 verify(mConditionProviders, never()).setPackageOrComponentEnabled( 1451 c.flattenToString(), 0, false, true); 1452 verify(mAssistants, never()).setPackageOrComponentEnabled( 1453 any(), anyInt(), anyBoolean(), anyBoolean()); 1454 } 1455 1456 @Test 1457 public void testSetAssistantAccess_doesNothingOnLowRam() throws Exception { 1458 when(mActivityManager.isLowRamDevice()).thenReturn(true); 1459 ComponentName c = ComponentName.unflattenFromString("package/Component"); 1460 mBinderService.setNotificationAssistantAccessGranted(c, true); 1461 1462 1463 verify(mListeners, never()).setPackageOrComponentEnabled( 1464 c.flattenToString(), 0, true, true); 1465 verify(mConditionProviders, never()).setPackageOrComponentEnabled( 1466 c.flattenToString(), 0, false, true); 1467 verify(mAssistants, never()).setPackageOrComponentEnabled( 1468 any(), anyInt(), anyBoolean(), anyBoolean()); 1469 } 1470 1471 @Test 1472 public void testSetDndAccess_doesNothingOnLowRam() throws Exception { 1473 when(mActivityManager.isLowRamDevice()).thenReturn(true); 1474 ComponentName c = ComponentName.unflattenFromString("package/Component"); 1475 mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true); 1476 1477 verify(mListeners, never()).setPackageOrComponentEnabled( 1478 c.flattenToString(), 0, true, true); 1479 verify(mConditionProviders, never()).setPackageOrComponentEnabled( 1480 c.flattenToString(), 0, false, true); 1481 verify(mAssistants, never()).setPackageOrComponentEnabled( 1482 any(), anyInt(), anyBoolean(), anyBoolean()); 1483 } 1484 1485 @Test 1486 public void testOnlyAutogroupIfGroupChanged_noPriorNoti_autogroups() throws Exception { 1487 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false); 1488 mNotificationManagerService.addEnqueuedNotification(r); 1489 NotificationManagerService.PostNotificationRunnable runnable = 1490 mNotificationManagerService.new PostNotificationRunnable(r.getKey()); 1491 runnable.run(); 1492 waitForIdle(); 1493 1494 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean()); 1495 } 1496 1497 @Test 1498 public void testOnlyAutogroupIfGroupChanged_groupChanged_autogroups() 1499 throws Exception { 1500 NotificationRecord r = 1501 generateNotificationRecord(mTestNotificationChannel, 0, "group", false); 1502 mNotificationManagerService.addNotification(r); 1503 1504 r = generateNotificationRecord(mTestNotificationChannel, 0, null, false); 1505 mNotificationManagerService.addEnqueuedNotification(r); 1506 NotificationManagerService.PostNotificationRunnable runnable = 1507 mNotificationManagerService.new PostNotificationRunnable(r.getKey()); 1508 runnable.run(); 1509 waitForIdle(); 1510 1511 verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean()); 1512 } 1513 1514 @Test 1515 public void testOnlyAutogroupIfGroupChanged_noGroupChanged_autogroups() 1516 throws Exception { 1517 NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, "group", 1518 false); 1519 mNotificationManagerService.addNotification(r); 1520 mNotificationManagerService.addEnqueuedNotification(r); 1521 1522 NotificationManagerService.PostNotificationRunnable runnable = 1523 mNotificationManagerService.new PostNotificationRunnable(r.getKey()); 1524 runnable.run(); 1525 waitForIdle(); 1526 1527 verify(mGroupHelper, never()).onNotificationPosted(any(), anyBoolean()); 1528 } 1529 1530 @Test 1531 public void testNoFakeColorizedPermission() throws Exception { 1532 when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED); 1533 Notification.Builder nb = new Notification.Builder(mContext, 1534 mTestNotificationChannel.getId()) 1535 .setContentTitle("foo") 1536 .setColorized(true) 1537 .setFlag(Notification.FLAG_CAN_COLORIZE, true) 1538 .setSmallIcon(android.R.drawable.sym_def_app_icon); 1539 StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0, 1540 nb.build(), new UserHandle(mUid), null, 0); 1541 NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel); 1542 1543 mBinderService.enqueueNotificationWithTag(PKG, PKG, null, 1544 nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId()); 1545 waitForIdle(); 1546 1547 NotificationRecord posted = mNotificationManagerService.findNotificationLocked( 1548 PKG, null, nr.sbn.getId(), nr.sbn.getUserId()); 1549 1550 assertFalse(posted.getNotification().isColorized()); 1551 } 1552 1553 @Test 1554 public void testGetNotificationCountLocked() throws Exception { 1555 for (int i = 0; i < 20; i++) { 1556 NotificationRecord r = 1557 generateNotificationRecord(mTestNotificationChannel, i, null, false); 1558 mNotificationManagerService.addEnqueuedNotification(r); 1559 } 1560 for (int i = 0; i < 20; i++) { 1561 NotificationRecord r = 1562 generateNotificationRecord(mTestNotificationChannel, i, null, false); 1563 mNotificationManagerService.addNotification(r); 1564 } 1565 1566 // another package 1567 Notification n = 1568 new Notification.Builder(mContext, mTestNotificationChannel.getId()) 1569 .setSmallIcon(android.R.drawable.sym_def_app_icon) 1570 .build(); 1571 1572 StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "tag", mUid, 0, 1573 n, new UserHandle(mUid), null, 0); 1574 NotificationRecord otherPackage = 1575 new NotificationRecord(mContext, sbn, mTestNotificationChannel); 1576 mNotificationManagerService.addEnqueuedNotification(otherPackage); 1577 mNotificationManagerService.addNotification(otherPackage); 1578 1579 // Same notifications are enqueued as posted, everything counts b/c id and tag don't match 1580 int userId = new UserHandle(mUid).getIdentifier(); 1581 assertEquals(40, 1582 mNotificationManagerService.getNotificationCountLocked(PKG, userId, 0, null)); 1583 assertEquals(40, 1584 mNotificationManagerService.getNotificationCountLocked(PKG, userId, 0, "tag2")); 1585 assertEquals(2, 1586 mNotificationManagerService.getNotificationCountLocked("a", userId, 0, "banana")); 1587 1588 // exclude a known notification - it's excluded from only the posted list, not enqueued 1589 assertEquals(39, 1590 mNotificationManagerService.getNotificationCountLocked(PKG, userId, 0, "tag")); 1591 } 1592 1593 @Test 1594 public void testAddAutogroup_requestsSort() throws Exception { 1595 RankingHandler rh = mock(RankingHandler.class); 1596 mNotificationManagerService.setRankingHandler(rh); 1597 1598 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); 1599 mNotificationManagerService.addNotification(r); 1600 mNotificationManagerService.addAutogroupKeyLocked(r.getKey()); 1601 1602 verify(rh, times(1)).requestSort(); 1603 } 1604 1605 @Test 1606 public void testRemoveAutogroup_requestsSort() throws Exception { 1607 RankingHandler rh = mock(RankingHandler.class); 1608 mNotificationManagerService.setRankingHandler(rh); 1609 1610 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); 1611 r.setOverrideGroupKey("TEST"); 1612 mNotificationManagerService.addNotification(r); 1613 mNotificationManagerService.removeAutogroupKeyLocked(r.getKey()); 1614 1615 verify(rh, times(1)).requestSort(); 1616 } 1617 1618 @Test 1619 public void testReaddAutogroup_noSort() throws Exception { 1620 RankingHandler rh = mock(RankingHandler.class); 1621 mNotificationManagerService.setRankingHandler(rh); 1622 1623 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); 1624 r.setOverrideGroupKey("TEST"); 1625 mNotificationManagerService.addNotification(r); 1626 mNotificationManagerService.addAutogroupKeyLocked(r.getKey()); 1627 1628 verify(rh, never()).requestSort(); 1629 } 1630 1631 @Test 1632 public void testHandleRankingSort_sendsUpdateOnSignalExtractorChange() throws Exception { 1633 mNotificationManagerService.setRankingHelper(mRankingHelper); 1634 NotificationManagerService.WorkerHandler handler = mock( 1635 NotificationManagerService.WorkerHandler.class); 1636 mNotificationManagerService.setHandler(handler); 1637 1638 Map<String, Answer> answers = getSignalExtractorSideEffects(); 1639 for (String message : answers.keySet()) { 1640 mNotificationManagerService.clearNotifications(); 1641 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); 1642 mNotificationManagerService.addNotification(r); 1643 1644 doAnswer(answers.get(message)).when(mRankingHelper).extractSignals(r); 1645 1646 mNotificationManagerService.handleRankingSort(); 1647 } 1648 verify(handler, times(answers.size())).scheduleSendRankingUpdate(); 1649 } 1650 1651 @Test 1652 public void testHandleRankingSort_noUpdateWhenNoSignalChange() throws Exception { 1653 mNotificationManagerService.setRankingHelper(mRankingHelper); 1654 NotificationManagerService.WorkerHandler handler = mock( 1655 NotificationManagerService.WorkerHandler.class); 1656 mNotificationManagerService.setHandler(handler); 1657 1658 final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel); 1659 mNotificationManagerService.addNotification(r); 1660 1661 mNotificationManagerService.handleRankingSort(); 1662 verify(handler, never()).scheduleSendRankingUpdate(); 1663 } 1664 1665 @Test 1666 public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception { 1667 final String preupgradeXml = "<notification-policy version=\"1\">" 1668 + "<zen></zen>" 1669 + "<ranking></ranking>" 1670 + "<enabled_listeners>" 1671 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />" 1672 + "</enabled_listeners>" 1673 + "<enabled_assistants>" 1674 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />" 1675 + "</enabled_assistants>" 1676 + "<dnd_apps>" 1677 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />" 1678 + "</dnd_apps>" 1679 + "</notification-policy>"; 1680 mNotificationManagerService.readPolicyXml( 1681 new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false); 1682 verify(mListeners, times(1)).readXml(any()); 1683 verify(mConditionProviders, times(1)).readXml(any()); 1684 verify(mAssistants, times(1)).readXml(any()); 1685 1686 // numbers are inflated for setup 1687 verify(mListeners, times(1)).migrateToXml(); 1688 verify(mConditionProviders, times(1)).migrateToXml(); 1689 verify(mAssistants, times(1)).migrateToXml(); 1690 } 1691 1692 @Test 1693 public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception { 1694 final String preupgradeXml = "<notification-policy version=\"1\">" 1695 + "<zen></zen>" 1696 + "<ranking></ranking>" 1697 + "</notification-policy>"; 1698 mNotificationManagerService.readPolicyXml( 1699 new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false); 1700 verify(mListeners, never()).readXml(any()); 1701 verify(mConditionProviders, never()).readXml(any()); 1702 verify(mAssistants, never()).readXml(any()); 1703 1704 // numbers are inflated for setup 1705 verify(mListeners, times(2)).migrateToXml(); 1706 verify(mConditionProviders, times(2)).migrateToXml(); 1707 verify(mAssistants, times(2)).migrateToXml(); 1708 } 1709 1710 1711 @Test 1712 public void testLocaleChangedCallsUpdateDefaultZenModeRules() throws Exception { 1713 ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class); 1714 mNotificationManagerService.mZenModeHelper = mZenModeHelper; 1715 mNotificationManagerService.mLocaleChangeReceiver.onReceive(mContext, 1716 new Intent(Intent.ACTION_LOCALE_CHANGED)); 1717 1718 verify(mZenModeHelper, times(1)).updateDefaultZenRules(); 1719 } 1720 1721 @Test 1722 public void testBumpFGImportance_noChannelChangePreOApp() throws Exception { 1723 String preOPkg = "preO"; 1724 int preOUid = 145; 1725 final ApplicationInfo legacy = new ApplicationInfo(); 1726 legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1; 1727 when(mPackageManagerClient.getApplicationInfoAsUser(eq(preOPkg), anyInt(), anyInt())) 1728 .thenReturn(legacy); 1729 when(mPackageManagerClient.getPackageUidAsUser(eq(preOPkg), anyInt())).thenReturn(preOUid); 1730 getContext().setMockPackageManager(mPackageManagerClient); 1731 1732 Notification.Builder nb = new Notification.Builder(mContext, 1733 NotificationChannel.DEFAULT_CHANNEL_ID) 1734 .setContentTitle("foo") 1735 .setSmallIcon(android.R.drawable.sym_def_app_icon) 1736 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true) 1737 .setPriority(Notification.PRIORITY_MIN); 1738 1739 StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid, 1740 0, nb.build(), new UserHandle(preOUid), null, 0); 1741 1742 mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag", 1743 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 1744 waitForIdle(); 1745 assertEquals(IMPORTANCE_LOW, 1746 mNotificationManagerService.getNotificationRecord(sbn.getKey()).getImportance()); 1747 1748 nb = new Notification.Builder(mContext) 1749 .setContentTitle("foo") 1750 .setSmallIcon(android.R.drawable.sym_def_app_icon) 1751 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true) 1752 .setPriority(Notification.PRIORITY_MIN); 1753 1754 sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid, 1755 0, nb.build(), new UserHandle(preOUid), null, 0); 1756 1757 mBinderService.enqueueNotificationWithTag(preOPkg, preOPkg, "tag", 1758 sbn.getId(), sbn.getNotification(), sbn.getUserId()); 1759 waitForIdle(); 1760 assertEquals(IMPORTANCE_LOW, 1761 mNotificationManagerService.getNotificationRecord(sbn.getKey()).getImportance()); 1762 1763 NotificationChannel defaultChannel = mBinderService.getNotificationChannel( 1764 preOPkg, NotificationChannel.DEFAULT_CHANNEL_ID); 1765 assertEquals(IMPORTANCE_UNSPECIFIED, defaultChannel.getImportance()); 1766 } 1767 } 1768