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 17package com.android.systemui.statusbar; 18 19import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE; 20import static android.app.NotificationManager.IMPORTANCE_LOW; 21import static android.app.NotificationManager.IMPORTANCE_MIN; 22import static android.app.NotificationManager.IMPORTANCE_NONE; 23import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; 24import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME; 25import static android.view.View.GONE; 26import static android.view.View.VISIBLE; 27 28import static junit.framework.Assert.assertEquals; 29import static junit.framework.Assert.assertFalse; 30import static junit.framework.Assert.assertTrue; 31 32import static org.mockito.Mockito.any; 33import static org.mockito.Mockito.anyBoolean; 34import static org.mockito.Mockito.anyInt; 35import static org.mockito.Mockito.anyString; 36import static org.mockito.Mockito.doCallRealMethod; 37import static org.mockito.Mockito.doNothing; 38import static org.mockito.Mockito.eq; 39import static org.mockito.Mockito.mock; 40import static org.mockito.Mockito.never; 41import static org.mockito.Mockito.spy; 42import static org.mockito.Mockito.times; 43import static org.mockito.Mockito.verify; 44import static org.mockito.Mockito.when; 45 46import android.app.INotificationManager; 47import android.app.Notification; 48import android.app.NotificationChannel; 49import android.app.NotificationChannelGroup; 50import android.content.Intent; 51import android.content.pm.ActivityInfo; 52import android.content.pm.ApplicationInfo; 53import android.content.pm.PackageInfo; 54import android.content.pm.PackageManager; 55import android.content.pm.ResolveInfo; 56import android.graphics.drawable.Drawable; 57import android.os.IBinder; 58import android.os.UserHandle; 59import android.service.notification.StatusBarNotification; 60import android.test.suitebuilder.annotation.SmallTest; 61import android.testing.AndroidTestingRunner; 62import android.testing.PollingCheck; 63import android.testing.TestableLooper; 64import android.testing.UiThreadTest; 65import android.view.LayoutInflater; 66import android.view.View; 67import android.widget.ImageView; 68import android.widget.TextView; 69 70import com.android.internal.logging.MetricsLogger; 71import com.android.systemui.Dependency; 72import com.android.systemui.R; 73import com.android.systemui.SysuiTestCase; 74 75import org.junit.Before; 76import org.junit.Rule; 77import org.junit.Test; 78import org.junit.runner.RunWith; 79import org.mockito.ArgumentCaptor; 80import org.mockito.Mock; 81import org.mockito.junit.MockitoJUnit; 82import org.mockito.junit.MockitoRule; 83 84import java.util.ArrayList; 85import java.util.List; 86import java.util.concurrent.CountDownLatch; 87 88@SmallTest 89@RunWith(AndroidTestingRunner.class) 90@TestableLooper.RunWithLooper 91public class NotificationInfoTest extends SysuiTestCase { 92 private static final String TEST_PACKAGE_NAME = "test_package"; 93 private static final String TEST_SYSTEM_PACKAGE_NAME = PRINT_SPOOLER_PACKAGE_NAME; 94 private static final int TEST_UID = 1; 95 private static final int MULTIPLE_CHANNEL_COUNT = 2; 96 private static final String TEST_CHANNEL = "test_channel"; 97 private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME"; 98 99 private TestableLooper mTestableLooper; 100 private NotificationInfo mNotificationInfo; 101 private NotificationChannel mNotificationChannel; 102 private NotificationChannel mDefaultNotificationChannel; 103 private StatusBarNotification mSbn; 104 105 @Rule public MockitoRule mockito = MockitoJUnit.rule(); 106 @Mock private MetricsLogger mMetricsLogger; 107 @Mock private INotificationManager mMockINotificationManager; 108 @Mock private PackageManager mMockPackageManager; 109 @Mock private NotificationBlockingHelperManager mBlockingHelperManager; 110 111 @Before 112 public void setUp() throws Exception { 113 mDependency.injectTestDependency( 114 NotificationBlockingHelperManager.class, 115 mBlockingHelperManager); 116 mTestableLooper = TestableLooper.get(this); 117 mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper()); 118 mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger); 119 // Inflate the layout 120 final LayoutInflater layoutInflater = LayoutInflater.from(mContext); 121 mNotificationInfo = (NotificationInfo) layoutInflater.inflate(R.layout.notification_info, 122 null); 123 mNotificationInfo.setGutsParent(mock(NotificationGuts.class)); 124 125 // PackageManager must return a packageInfo and applicationInfo. 126 final PackageInfo packageInfo = new PackageInfo(); 127 packageInfo.packageName = TEST_PACKAGE_NAME; 128 when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt())) 129 .thenReturn(packageInfo); 130 final ApplicationInfo applicationInfo = new ApplicationInfo(); 131 applicationInfo.uid = TEST_UID; // non-zero 132 when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).thenReturn( 133 applicationInfo); 134 final PackageInfo systemPackageInfo = new PackageInfo(); 135 systemPackageInfo.packageName = TEST_SYSTEM_PACKAGE_NAME; 136 when(mMockPackageManager.getPackageInfo(eq(TEST_SYSTEM_PACKAGE_NAME), anyInt())) 137 .thenReturn(systemPackageInfo); 138 when(mMockPackageManager.getPackageInfo(eq("android"), anyInt())) 139 .thenReturn(packageInfo); 140 141 // Package has one channel by default. 142 when(mMockINotificationManager.getNumNotificationChannelsForPackage( 143 eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(1); 144 145 // Some test channels. 146 mNotificationChannel = new NotificationChannel( 147 TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_LOW); 148 mDefaultNotificationChannel = new NotificationChannel( 149 NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME, 150 IMPORTANCE_LOW); 151 mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0, 152 new Notification(), UserHandle.CURRENT, null, 0); 153 } 154 155 // TODO: if tests are taking too long replace this with something that makes the animation 156 // finish instantly. 157 private void waitForUndoButton() { 158 PollingCheck.waitFor(1000, 159 () -> VISIBLE == mNotificationInfo.findViewById(R.id.confirmation).getVisibility()); 160 } 161 private void waitForStopButton() { 162 PollingCheck.waitFor(1000, 163 () -> VISIBLE == mNotificationInfo.findViewById(R.id.prompt).getVisibility()); 164 } 165 166 @Test 167 public void testBindNotification_SetsTextApplicationName() throws Exception { 168 when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name"); 169 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 170 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 171 final TextView textView = mNotificationInfo.findViewById(R.id.pkgname); 172 assertTrue(textView.getText().toString().contains("App Name")); 173 assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility()); 174 } 175 176 @Test 177 public void testBindNotification_SetsPackageIcon() throws Exception { 178 final Drawable iconDrawable = mock(Drawable.class); 179 when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class))) 180 .thenReturn(iconDrawable); 181 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 182 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 183 final ImageView iconView = mNotificationInfo.findViewById(R.id.pkgicon); 184 assertEquals(iconDrawable, iconView.getDrawable()); 185 } 186 187 @Test 188 public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception { 189 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 190 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 191 final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name); 192 assertEquals(GONE, groupNameView.getVisibility()); 193 final TextView groupDividerView = mNotificationInfo.findViewById(R.id.pkg_group_divider); 194 assertEquals(GONE, groupDividerView.getVisibility()); 195 } 196 197 @Test 198 public void testBindNotification_SetsGroupNameIfNonNull() throws Exception { 199 mNotificationChannel.setGroup("test_group_id"); 200 final NotificationChannelGroup notificationChannelGroup = 201 new NotificationChannelGroup("test_group_id", "Test Group Name"); 202 when(mMockINotificationManager.getNotificationChannelGroupForPackage( 203 eq("test_group_id"), eq(TEST_PACKAGE_NAME), eq(TEST_UID))) 204 .thenReturn(notificationChannelGroup); 205 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 206 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 207 final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name); 208 assertEquals(View.VISIBLE, groupNameView.getVisibility()); 209 assertEquals("Test Group Name", groupNameView.getText()); 210 final TextView groupDividerView = mNotificationInfo.findViewById(R.id.pkg_group_divider); 211 assertEquals(View.VISIBLE, groupDividerView.getVisibility()); 212 } 213 214 @Test 215 public void testBindNotification_SetsTextChannelName() throws Exception { 216 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 217 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 218 final TextView textView = mNotificationInfo.findViewById(R.id.channel_name); 219 assertEquals(TEST_CHANNEL_NAME, textView.getText()); 220 } 221 222 @Test 223 public void testBindNotification_DefaultChannelDoesNotUseChannelName() throws Exception { 224 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 225 TEST_PACKAGE_NAME, mDefaultNotificationChannel, 1, mSbn, null, null, null, false); 226 final TextView textView = mNotificationInfo.findViewById(R.id.channel_name); 227 assertEquals(GONE, textView.getVisibility()); 228 } 229 230 @Test 231 public void testBindNotification_DefaultChannelUsesChannelNameIfMoreChannelsExist() 232 throws Exception { 233 // Package has one channel by default. 234 when(mMockINotificationManager.getNumNotificationChannelsForPackage( 235 eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(10); 236 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 237 TEST_PACKAGE_NAME, mDefaultNotificationChannel, 1, mSbn, null, null, null, false); 238 final TextView textView = mNotificationInfo.findViewById(R.id.channel_name); 239 assertEquals(VISIBLE, textView.getVisibility()); 240 } 241 242 @Test 243 public void testBindNotification_UnblockablePackageUsesChannelName() throws Exception { 244 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 245 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 246 final TextView textView = mNotificationInfo.findViewById(R.id.channel_name); 247 assertEquals(VISIBLE, textView.getVisibility()); 248 } 249 250 @Test 251 public void testBindNotification_BlockButton() throws Exception { 252 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 253 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 254 final View block = mNotificationInfo.findViewById(R.id.block); 255 final View minimize = mNotificationInfo.findViewById(R.id.minimize); 256 assertEquals(VISIBLE, block.getVisibility()); 257 assertEquals(GONE, minimize.getVisibility()); 258 } 259 260 @Test 261 public void testBindNotification_MinButton() throws Exception { 262 mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE; 263 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 264 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 265 final View block = mNotificationInfo.findViewById(R.id.block); 266 final View minimize = mNotificationInfo.findViewById(R.id.minimize); 267 assertEquals(GONE, block.getVisibility()); 268 assertEquals(VISIBLE, minimize.getVisibility()); 269 } 270 271 @Test 272 public void testBindNotification_SetsOnClickListenerForSettings() throws Exception { 273 final CountDownLatch latch = new CountDownLatch(1); 274 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 275 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, 276 (View v, NotificationChannel c, int appUid) -> { 277 assertEquals(mNotificationChannel, c); 278 latch.countDown(); 279 }, null, false); 280 281 final View settingsButton = mNotificationInfo.findViewById(R.id.info); 282 settingsButton.performClick(); 283 // Verify that listener was triggered. 284 assertEquals(0, latch.getCount()); 285 } 286 287 @Test 288 public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() throws Exception { 289 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 290 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 291 final View settingsButton = mNotificationInfo.findViewById(R.id.info); 292 assertTrue(settingsButton.getVisibility() != View.VISIBLE); 293 } 294 295 @Test 296 public void testBindNotification_SettingsButtonReappearsAfterSecondBind() throws Exception { 297 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 298 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 299 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 300 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, 301 (View v, NotificationChannel c, int appUid) -> { 302 }, null, false); 303 final View settingsButton = mNotificationInfo.findViewById(R.id.info); 304 assertEquals(View.VISIBLE, settingsButton.getVisibility()); 305 } 306 307 @Test 308 public void testLogBlockingHelperCounter_doesntLogForNormalGutsView() throws Exception { 309 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 310 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 311 mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent"); 312 verify(mMetricsLogger, times(0)).count(anyString(), anyInt()); 313 } 314 315 @Test 316 public void testLogBlockingHelperCounter_logsForBlockingHelper() throws Exception { 317 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 318 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, true, 319 true); 320 mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent"); 321 verify(mMetricsLogger, times(1)).count(anyString(), anyInt()); 322 } 323 324 @Test 325 public void testOnClickListenerPassesNullChannelForBundle() throws Exception { 326 final CountDownLatch latch = new CountDownLatch(1); 327 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 328 TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, mSbn, null, 329 (View v, NotificationChannel c, int appUid) -> { 330 assertEquals(null, c); 331 latch.countDown(); 332 }, null, true); 333 334 mNotificationInfo.findViewById(R.id.info).performClick(); 335 // Verify that listener was triggered. 336 assertEquals(0, latch.getCount()); 337 } 338 339 @Test 340 @UiThreadTest 341 public void testBindNotification_ChannelNameInvisibleWhenBundleFromDifferentChannels() 342 throws Exception { 343 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 344 TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, mSbn, null, null, 345 null, true); 346 final TextView channelNameView = 347 mNotificationInfo.findViewById(R.id.channel_name); 348 assertEquals(GONE, channelNameView.getVisibility()); 349 } 350 351 @Test 352 @UiThreadTest 353 public void testStopInvisibleIfBundleFromDifferentChannels() throws Exception { 354 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 355 TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, mSbn, null, null, 356 null, true); 357 final TextView blockView = mNotificationInfo.findViewById(R.id.block); 358 assertEquals(GONE, blockView.getVisibility()); 359 } 360 361 @Test 362 public void testbindNotification_BlockingHelper() throws Exception { 363 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 364 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, false, 365 true); 366 final TextView view = mNotificationInfo.findViewById(R.id.block_prompt); 367 assertEquals(View.VISIBLE, view.getVisibility()); 368 assertEquals(mContext.getString(R.string.inline_blocking_helper), view.getText()); 369 } 370 371 @Test 372 public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception { 373 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 374 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 375 final TextView view = mNotificationInfo.findViewById(R.id.block_prompt); 376 assertEquals(View.VISIBLE, view.getVisibility()); 377 assertEquals(mContext.getString(R.string.notification_unblockable_desc), 378 view.getText()); 379 } 380 381 @Test 382 public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception { 383 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 384 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 385 mTestableLooper.processAllMessages(); 386 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( 387 anyString(), eq(TEST_UID), any()); 388 } 389 390 @Test 391 public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception { 392 mNotificationChannel.setImportance(IMPORTANCE_LOW); 393 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 394 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 395 396 mNotificationInfo.findViewById(R.id.block).performClick(); 397 mTestableLooper.processAllMessages(); 398 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( 399 anyString(), eq(TEST_UID), any()); 400 } 401 402 @Test 403 public void testDoesNotUpdateNotificationChannelAfterImportanceChangedMin() 404 throws Exception { 405 mNotificationChannel.setImportance(IMPORTANCE_LOW); 406 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 407 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 408 409 mNotificationInfo.findViewById(R.id.minimize).performClick(); 410 mTestableLooper.processAllMessages(); 411 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( 412 anyString(), eq(TEST_UID), any()); 413 } 414 415 @Test 416 public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged() 417 throws Exception { 418 int originalImportance = mNotificationChannel.getImportance(); 419 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 420 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 421 422 mNotificationInfo.handleCloseControls(true, false); 423 mTestableLooper.processAllMessages(); 424 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( 425 anyString(), eq(TEST_UID), any()); 426 assertEquals(originalImportance, mNotificationChannel.getImportance()); 427 } 428 429 @Test 430 public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnspecified() 431 throws Exception { 432 mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED); 433 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 434 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 435 436 mNotificationInfo.handleCloseControls(true, false); 437 438 mTestableLooper.processAllMessages(); 439 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( 440 anyString(), eq(TEST_UID), any()); 441 assertEquals(IMPORTANCE_UNSPECIFIED, mNotificationChannel.getImportance()); 442 } 443 444 @Test 445 public void testHandleCloseControls_setsNotificationsDisabledForMultipleChannelNotifications() 446 throws Exception { 447 mNotificationChannel.setImportance(IMPORTANCE_LOW); 448 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 449 TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */, 450 10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */, 451 null /* onSettingsClick */, null /* onAppSettingsClick */ , 452 false /* isNonblockable */); 453 454 mNotificationInfo.findViewById(R.id.block).performClick(); 455 waitForUndoButton(); 456 mNotificationInfo.handleCloseControls(true, false); 457 458 mTestableLooper.processAllMessages(); 459 verify(mMockINotificationManager, times(1)) 460 .setNotificationsEnabledWithImportanceLockForPackage( 461 anyString(), eq(TEST_UID), eq(false)); 462 } 463 464 465 @Test 466 public void testHandleCloseControls_keepsNotificationsEnabledForMultipleChannelNotifications() 467 throws Exception { 468 mNotificationChannel.setImportance(IMPORTANCE_LOW); 469 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 470 TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */, 471 10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */, 472 null /* onSettingsClick */, null /* onAppSettingsClick */ , 473 false /* isNonblockable */); 474 475 mNotificationInfo.findViewById(R.id.block).performClick(); 476 waitForUndoButton(); 477 mNotificationInfo.handleCloseControls(true, false); 478 479 mTestableLooper.processAllMessages(); 480 verify(mMockINotificationManager, times(1)) 481 .setNotificationsEnabledWithImportanceLockForPackage( 482 anyString(), eq(TEST_UID), eq(false)); 483 } 484 485 @Test 486 public void testCloseControls_blockingHelperSavesImportanceForMultipleChannelNotifications() 487 throws Exception { 488 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 489 TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */, 490 10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */, 491 null /* onSettingsClick */, null /* onAppSettingsClick */ , 492 false /* isNonblockable */, true /* isForBlockingHelper */, 493 true /* isUserSentimentNegative */); 494 495 NotificationGuts guts = spy(new NotificationGuts(mContext, null)); 496 when(guts.getWindowToken()).thenReturn(mock(IBinder.class)); 497 doNothing().when(guts).animateClose(anyInt(), anyInt(), anyBoolean()); 498 doNothing().when(guts).setExposed(anyBoolean(), anyBoolean()); 499 guts.setGutsContent(mNotificationInfo); 500 mNotificationInfo.setGutsParent(guts); 501 502 mNotificationInfo.findViewById(R.id.keep).performClick(); 503 504 verify(mBlockingHelperManager).dismissCurrentBlockingHelper(); 505 mTestableLooper.processAllMessages(); 506 verify(mMockINotificationManager, times(1)) 507 .setNotificationsEnabledWithImportanceLockForPackage( 508 anyString(), eq(TEST_UID), eq(true)); 509 } 510 511 @Test 512 public void testCloseControls_nonNullCheckSaveListenerDoesntDelayKeepShowing() 513 throws Exception { 514 NotificationInfo.CheckSaveListener listener = 515 mock(NotificationInfo.CheckSaveListener.class); 516 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 517 TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */, 518 10 /* numUniqueChannelsInRow */, mSbn, listener /* checkSaveListener */, 519 null /* onSettingsClick */, null /* onAppSettingsClick */ , 520 false /* isNonblockable */, true /* isForBlockingHelper */, 521 true /* isUserSentimentNegative */); 522 523 NotificationGuts guts = spy(new NotificationGuts(mContext, null)); 524 when(guts.getWindowToken()).thenReturn(mock(IBinder.class)); 525 doNothing().when(guts).animateClose(anyInt(), anyInt(), anyBoolean()); 526 doNothing().when(guts).setExposed(anyBoolean(), anyBoolean()); 527 guts.setGutsContent(mNotificationInfo); 528 mNotificationInfo.setGutsParent(guts); 529 530 mNotificationInfo.findViewById(R.id.keep).performClick(); 531 532 verify(mBlockingHelperManager).dismissCurrentBlockingHelper(); 533 mTestableLooper.processAllMessages(); 534 verify(mMockINotificationManager, times(1)) 535 .setNotificationsEnabledWithImportanceLockForPackage( 536 anyString(), eq(TEST_UID), eq(true)); 537 } 538 539 @Test 540 public void testCloseControls_nonNullCheckSaveListenerDoesntDelayDismiss() 541 throws Exception { 542 NotificationInfo.CheckSaveListener listener = 543 mock(NotificationInfo.CheckSaveListener.class); 544 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 545 TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */, 546 10 /* numUniqueChannelsInRow */, mSbn, listener /* checkSaveListener */, 547 null /* onSettingsClick */, null /* onAppSettingsClick */ , 548 false /* isNonblockable */, true /* isForBlockingHelper */, 549 true /* isUserSentimentNegative */); 550 551 mNotificationInfo.handleCloseControls(true /* save */, false /* force */); 552 553 mTestableLooper.processAllMessages(); 554 verify(listener, times(0)).checkSave(any(Runnable.class), eq(mSbn)); 555 } 556 557 @Test 558 public void testCloseControls_checkSaveListenerDelaysStopNotifications() 559 throws Exception { 560 NotificationInfo.CheckSaveListener listener = 561 mock(NotificationInfo.CheckSaveListener.class); 562 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 563 TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */, 564 10 /* numUniqueChannelsInRow */, mSbn, listener /* checkSaveListener */, 565 null /* onSettingsClick */, null /* onAppSettingsClick */ , 566 false /* isNonblockable */, true /* isForBlockingHelper */, 567 true /* isUserSentimentNegative */); 568 569 mNotificationInfo.findViewById(R.id.block).performClick(); 570 waitForUndoButton(); 571 mNotificationInfo.handleCloseControls(true /* save */, false /* force */); 572 573 mTestableLooper.processAllMessages(); 574 verify(listener).checkSave(any(Runnable.class), eq(mSbn)); 575 } 576 577 @Test 578 public void testCloseControls_blockingHelperDismissedIfShown() throws Exception { 579 mNotificationInfo.bindNotification( 580 mMockPackageManager, 581 mMockINotificationManager, 582 TEST_PACKAGE_NAME, 583 mNotificationChannel, 584 1 /* numChannels */, 585 mSbn, 586 null /* checkSaveListener */, 587 null /* onSettingsClick */, 588 null /* onAppSettingsClick */, 589 false /* isNonblockable */, 590 true /* isForBlockingHelper */, 591 false /* isUserSentimentNegative */); 592 NotificationGuts guts = mock(NotificationGuts.class); 593 doCallRealMethod().when(guts).closeControls(anyInt(), anyInt(), anyBoolean(), anyBoolean()); 594 mNotificationInfo.setGutsParent(guts); 595 596 mNotificationInfo.closeControls(mNotificationInfo); 597 598 verify(mBlockingHelperManager).dismissCurrentBlockingHelper(); 599 } 600 601 @Test 602 public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception { 603 mNotificationChannel.setImportance(IMPORTANCE_LOW); 604 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 605 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 606 mNotificationInfo.findViewById(R.id.block).performClick(); 607 waitForUndoButton(); 608 609 mTestableLooper.processAllMessages(); 610 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( 611 anyString(), eq(TEST_UID), any()); 612 } 613 614 @Test 615 public void testBlockChangedCallsUpdateNotificationChannel() throws Exception { 616 mNotificationChannel.setImportance(IMPORTANCE_LOW); 617 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 618 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 619 620 mNotificationInfo.findViewById(R.id.block).performClick(); 621 waitForUndoButton(); 622 mNotificationInfo.handleCloseControls(true, false); 623 624 mTestableLooper.processAllMessages(); 625 ArgumentCaptor<NotificationChannel> updated = 626 ArgumentCaptor.forClass(NotificationChannel.class); 627 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( 628 anyString(), eq(TEST_UID), updated.capture()); 629 assertTrue((updated.getValue().getUserLockedFields() 630 & USER_LOCKED_IMPORTANCE) != 0); 631 assertEquals(IMPORTANCE_NONE, updated.getValue().getImportance()); 632 } 633 634 @Test 635 public void testBlockChangedCallsUpdateNotificationChannel_blockingHelper() throws Exception { 636 mNotificationChannel.setImportance(IMPORTANCE_LOW); 637 mNotificationInfo.bindNotification( 638 mMockPackageManager, 639 mMockINotificationManager, 640 TEST_PACKAGE_NAME, 641 mNotificationChannel, 642 1 /* numChannels */, 643 mSbn, 644 null /* checkSaveListener */, 645 null /* onSettingsClick */, 646 null /* onAppSettingsClick */, 647 false /* isNonblockable */, 648 true /* isForBlockingHelper */, 649 true /* isUserSentimentNegative */); 650 651 mNotificationInfo.findViewById(R.id.block).performClick(); 652 waitForUndoButton(); 653 mNotificationInfo.handleCloseControls(true, false); 654 655 mTestableLooper.processAllMessages(); 656 ArgumentCaptor<NotificationChannel> updated = 657 ArgumentCaptor.forClass(NotificationChannel.class); 658 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( 659 anyString(), eq(TEST_UID), updated.capture()); 660 assertTrue((updated.getValue().getUserLockedFields() 661 & USER_LOCKED_IMPORTANCE) != 0); 662 assertEquals(IMPORTANCE_NONE, updated.getValue().getImportance()); 663 } 664 665 666 @Test 667 public void testNonBlockableAppDoesNotBecomeMin() throws Exception { 668 mNotificationChannel.setImportance(IMPORTANCE_LOW); 669 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 670 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 671 mNotificationInfo.findViewById(R.id.minimize).performClick(); 672 waitForUndoButton(); 673 674 mTestableLooper.processAllMessages(); 675 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( 676 anyString(), eq(TEST_UID), any()); 677 } 678 679 @Test 680 public void testMinChangedCallsUpdateNotificationChannel() throws Exception { 681 mNotificationChannel.setImportance(IMPORTANCE_LOW); 682 mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE; 683 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 684 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 685 686 mNotificationInfo.findViewById(R.id.minimize).performClick(); 687 waitForUndoButton(); 688 mNotificationInfo.handleCloseControls(true, false); 689 690 mTestableLooper.processAllMessages(); 691 ArgumentCaptor<NotificationChannel> updated = 692 ArgumentCaptor.forClass(NotificationChannel.class); 693 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( 694 anyString(), eq(TEST_UID), updated.capture()); 695 assertTrue((updated.getValue().getUserLockedFields() 696 & USER_LOCKED_IMPORTANCE) != 0); 697 assertEquals(IMPORTANCE_MIN, updated.getValue().getImportance()); 698 } 699 700 @Test 701 public void testKeepUpdatesNotificationChannel() throws Exception { 702 mNotificationChannel.setImportance(IMPORTANCE_LOW); 703 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 704 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 705 706 mNotificationInfo.handleCloseControls(true, false); 707 708 mTestableLooper.processAllMessages(); 709 ArgumentCaptor<NotificationChannel> updated = 710 ArgumentCaptor.forClass(NotificationChannel.class); 711 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( 712 anyString(), eq(TEST_UID), updated.capture()); 713 assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE)); 714 assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance()); 715 } 716 717 @Test 718 public void testBlockUndoDoesNotBlockNotificationChannel() throws Exception { 719 mNotificationChannel.setImportance(IMPORTANCE_LOW); 720 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 721 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 722 723 mNotificationInfo.findViewById(R.id.block).performClick(); 724 waitForUndoButton(); 725 mNotificationInfo.findViewById(R.id.undo).performClick(); 726 waitForStopButton(); 727 mNotificationInfo.handleCloseControls(true, false); 728 729 mTestableLooper.processAllMessages(); 730 ArgumentCaptor<NotificationChannel> updated = 731 ArgumentCaptor.forClass(NotificationChannel.class); 732 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( 733 anyString(), eq(TEST_UID), updated.capture()); 734 assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE)); 735 assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance()); 736 } 737 738 @Test 739 public void testMinUndoDoesNotMinNotificationChannel() throws Exception { 740 mNotificationChannel.setImportance(IMPORTANCE_LOW); 741 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 742 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false); 743 744 mNotificationInfo.findViewById(R.id.minimize).performClick(); 745 waitForUndoButton(); 746 mNotificationInfo.findViewById(R.id.undo).performClick(); 747 waitForStopButton(); 748 mNotificationInfo.handleCloseControls(true, false); 749 750 mTestableLooper.processAllMessages(); 751 ArgumentCaptor<NotificationChannel> updated = 752 ArgumentCaptor.forClass(NotificationChannel.class); 753 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( 754 anyString(), eq(TEST_UID), updated.capture()); 755 assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE)); 756 assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance()); 757 } 758 759 @Test 760 public void testCloseControlsDoesNotUpdateiMinIfSaveIsFalse() throws Exception { 761 mNotificationChannel.setImportance(IMPORTANCE_LOW); 762 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 763 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 764 765 mNotificationInfo.findViewById(R.id.minimize).performClick(); 766 waitForUndoButton(); 767 mNotificationInfo.handleCloseControls(false, false); 768 769 mTestableLooper.processAllMessages(); 770 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( 771 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel)); 772 } 773 774 @Test 775 public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception { 776 mNotificationChannel.setImportance(IMPORTANCE_LOW); 777 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 778 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 779 780 mNotificationInfo.findViewById(R.id.block).performClick(); 781 waitForUndoButton(); 782 mNotificationInfo.handleCloseControls(false, false); 783 784 mTestableLooper.processAllMessages(); 785 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( 786 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel)); 787 } 788 789 @Test 790 public void testCloseControlsDoesNotUpdateIfCheckSaveListenerIsNoOp() throws Exception { 791 mNotificationChannel.setImportance(IMPORTANCE_LOW); 792 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 793 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, 794 (Runnable saveImportance, StatusBarNotification sbn) -> { 795 }, null, null, true); 796 797 mNotificationInfo.findViewById(R.id.block).performClick(); 798 waitForUndoButton(); 799 mNotificationInfo.handleCloseControls(true, false); 800 801 mTestableLooper.processAllMessages(); 802 verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( 803 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel)); 804 } 805 806 @Test 807 public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception { 808 mNotificationChannel.setImportance(IMPORTANCE_LOW); 809 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 810 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, 811 (Runnable saveImportance, StatusBarNotification sbn) -> { 812 saveImportance.run(); 813 }, null, null, false); 814 815 mNotificationInfo.findViewById(R.id.block).performClick(); 816 waitForUndoButton(); 817 mNotificationInfo.handleCloseControls(true, false); 818 819 mTestableLooper.processAllMessages(); 820 verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( 821 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel)); 822 } 823 824 @Test 825 public void testDisplaySettingsLink() throws Exception { 826 final CountDownLatch latch = new CountDownLatch(1); 827 final String settingsText = "work chats"; 828 final ResolveInfo ri = new ResolveInfo(); 829 ri.activityInfo = new ActivityInfo(); 830 ri.activityInfo.packageName = TEST_PACKAGE_NAME; 831 ri.activityInfo.name = "something"; 832 List<ResolveInfo> ris = new ArrayList<>(); 833 ris.add(ri); 834 when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris); 835 mNotificationChannel.setImportance(IMPORTANCE_LOW); 836 Notification n = new Notification.Builder(mContext, mNotificationChannel.getId()) 837 .setSettingsText(settingsText).build(); 838 StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 839 0, null, 0, 0, n, UserHandle.CURRENT, null, 0); 840 841 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 842 TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null, 843 (View v, Intent intent) -> { 844 latch.countDown(); 845 }, false); 846 final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings); 847 assertEquals(View.VISIBLE, settingsLink.getVisibility()); 848 settingsLink.performClick(); 849 assertEquals(0, latch.getCount()); 850 } 851 852 @Test 853 public void testDisplaySettingsLink_multipleChannels() throws Exception { 854 final CountDownLatch latch = new CountDownLatch(1); 855 final String settingsText = "work chats"; 856 final ResolveInfo ri = new ResolveInfo(); 857 ri.activityInfo = new ActivityInfo(); 858 ri.activityInfo.packageName = TEST_PACKAGE_NAME; 859 ri.activityInfo.name = "something"; 860 List<ResolveInfo> ris = new ArrayList<>(); 861 ris.add(ri); 862 when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris); 863 mNotificationChannel.setImportance(IMPORTANCE_LOW); 864 Notification n = new Notification.Builder(mContext, mNotificationChannel.getId()) 865 .setSettingsText(settingsText).build(); 866 StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 867 0, null, 0, 0, n, UserHandle.CURRENT, null, 0); 868 869 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 870 TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, sbn, null, null, 871 (View v, Intent intent) -> { 872 latch.countDown(); 873 }, false); 874 final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings); 875 assertEquals(View.VISIBLE, settingsLink.getVisibility()); 876 settingsLink.performClick(); 877 assertEquals(0, latch.getCount()); 878 } 879 880 @Test 881 public void testNoSettingsLink_noHandlingActivity() throws Exception { 882 final String settingsText = "work chats"; 883 when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(null); 884 mNotificationChannel.setImportance(IMPORTANCE_LOW); 885 Notification n = new Notification.Builder(mContext, mNotificationChannel.getId()) 886 .setSettingsText(settingsText).build(); 887 StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 888 0, null, 0, 0, n, UserHandle.CURRENT, null, 0); 889 890 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 891 TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, sbn, null, null, 892 null, false); 893 final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings); 894 assertEquals(GONE, settingsLink.getVisibility()); 895 } 896 897 @Test 898 public void testNoSettingsLink_noLinkText() throws Exception { 899 final ResolveInfo ri = new ResolveInfo(); 900 ri.activityInfo = new ActivityInfo(); 901 ri.activityInfo.packageName = TEST_PACKAGE_NAME; 902 ri.activityInfo.name = "something"; 903 List<ResolveInfo> ris = new ArrayList<>(); 904 ris.add(ri); 905 when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris); 906 mNotificationChannel.setImportance(IMPORTANCE_LOW); 907 Notification n = new Notification.Builder(mContext, mNotificationChannel.getId()).build(); 908 StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 909 0, null, 0, 0, n, UserHandle.CURRENT, null, 0); 910 911 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 912 TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null, null, false); 913 final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings); 914 assertEquals(GONE, settingsLink.getVisibility()); 915 } 916 917 @Test 918 public void testBindHeader_noSettingsLinkWhenIsForBlockingHelper() throws Exception { 919 final String settingsText = "work chats"; 920 final ResolveInfo ri = new ResolveInfo(); 921 ri.activityInfo = new ActivityInfo(); 922 ri.activityInfo.packageName = TEST_PACKAGE_NAME; 923 ri.activityInfo.name = "something"; 924 List<ResolveInfo> ris = new ArrayList<>(); 925 ris.add(ri); 926 when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris); 927 mNotificationChannel.setImportance(IMPORTANCE_LOW); 928 Notification n = new Notification.Builder(mContext, mNotificationChannel.getId()) 929 .setSettingsText(settingsText).build(); 930 StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 931 0, null, 0, 0, n, UserHandle.CURRENT, null, 0); 932 933 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 934 TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null, null, false, true, 935 true); 936 final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings); 937 assertEquals(GONE, settingsLink.getVisibility()); 938 } 939 940 941 @Test 942 public void testWillBeRemovedReturnsFalseBeforeBind() throws Exception { 943 assertFalse(mNotificationInfo.willBeRemoved()); 944 } 945 946 @Test 947 public void testUndoText_min() throws Exception { 948 mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE; 949 mNotificationChannel.setImportance(IMPORTANCE_LOW); 950 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 951 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 952 953 mNotificationInfo.findViewById(R.id.minimize).performClick(); 954 waitForUndoButton(); 955 TextView confirmationText = mNotificationInfo.findViewById(R.id.confirmation_text); 956 assertTrue(confirmationText.getText().toString().contains("minimized")); 957 } 958 959 @Test 960 public void testUndoText_block() throws Exception { 961 mNotificationChannel.setImportance(IMPORTANCE_LOW); 962 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 963 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 964 965 mNotificationInfo.findViewById(R.id.block).performClick(); 966 waitForUndoButton(); 967 TextView confirmationText = mNotificationInfo.findViewById(R.id.confirmation_text); 968 assertTrue(confirmationText.getText().toString().contains("won't see")); 969 } 970 971 @Test 972 public void testNoHeaderOnConfirmation() throws Exception { 973 mNotificationChannel.setImportance(IMPORTANCE_LOW); 974 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 975 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 976 977 mNotificationInfo.findViewById(R.id.block).performClick(); 978 waitForUndoButton(); 979 assertEquals(GONE, mNotificationInfo.findViewById(R.id.header).getVisibility()); 980 } 981 982 @Test 983 public void testHeaderOnUndo() throws Exception { 984 mNotificationChannel.setImportance(IMPORTANCE_LOW); 985 mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager, 986 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true); 987 988 mNotificationInfo.findViewById(R.id.block).performClick(); 989 waitForUndoButton(); 990 mNotificationInfo.findViewById(R.id.undo).performClick(); 991 waitForStopButton(); 992 assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility()); 993 } 994} 995