1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is 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 android.app; 18 19 import static android.app.Notification.CarExtender.UnreadConversation.KEY_ON_READ; 20 import static android.app.Notification.CarExtender.UnreadConversation.KEY_ON_REPLY; 21 import static android.app.Notification.CarExtender.UnreadConversation.KEY_REMOTE_INPUT; 22 import static android.app.Notification.DEFAULT_SOUND; 23 import static android.app.Notification.DEFAULT_VIBRATE; 24 import static android.app.Notification.EXTRA_ANSWER_INTENT; 25 import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO; 26 import static android.app.Notification.EXTRA_CALL_PERSON; 27 import static android.app.Notification.EXTRA_CONVERSATION_ICON; 28 import static android.app.Notification.EXTRA_DECLINE_INTENT; 29 import static android.app.Notification.EXTRA_HANG_UP_INTENT; 30 import static android.app.Notification.EXTRA_LARGE_ICON; 31 import static android.app.Notification.EXTRA_LARGE_ICON_BIG; 32 import static android.app.Notification.EXTRA_MEDIA_REMOTE_INTENT; 33 import static android.app.Notification.EXTRA_MEDIA_SESSION; 34 import static android.app.Notification.EXTRA_MESSAGING_PERSON; 35 import static android.app.Notification.EXTRA_PEOPLE_LIST; 36 import static android.app.Notification.EXTRA_PICTURE; 37 import static android.app.Notification.EXTRA_PICTURE_ICON; 38 import static android.app.Notification.EXTRA_SUMMARY_TEXT; 39 import static android.app.Notification.EXTRA_TITLE; 40 import static android.app.Notification.FLAG_CAN_COLORIZE; 41 import static android.app.Notification.GROUP_ALERT_CHILDREN; 42 import static android.app.Notification.GROUP_ALERT_SUMMARY; 43 import static android.app.Notification.GROUP_KEY_SILENT; 44 import static android.app.Notification.MessagingStyle.Message.KEY_DATA_URI; 45 import static android.app.Notification.MessagingStyle.Message.KEY_SENDER_PERSON; 46 import static android.app.Notification.MessagingStyle.Message.KEY_TEXT; 47 import static android.app.Notification.MessagingStyle.Message.KEY_TIMESTAMP; 48 import static android.app.Notification.TvExtender.EXTRA_CONTENT_INTENT; 49 import static android.app.Notification.TvExtender.EXTRA_DELETE_INTENT; 50 import static android.app.Notification.WearableExtender.KEY_BACKGROUND; 51 import static android.app.Notification.WearableExtender.KEY_DISPLAY_INTENT; 52 53 import static com.android.compatibility.common.util.SystemUtil.runShellCommand; 54 import static com.android.internal.util.ContrastColorUtilTest.assertContrastIsAtLeast; 55 import static com.android.internal.util.ContrastColorUtilTest.assertContrastIsWithinRange; 56 57 import static com.google.common.truth.Truth.assertThat; 58 59 import static junit.framework.Assert.assertNotNull; 60 import static junit.framework.Assert.fail; 61 62 import static org.junit.Assert.assertEquals; 63 import static org.junit.Assert.assertFalse; 64 import static org.junit.Assert.assertNotSame; 65 import static org.junit.Assert.assertNull; 66 import static org.junit.Assert.assertSame; 67 import static org.junit.Assert.assertTrue; 68 import static org.mockito.Mockito.mock; 69 import static org.mockito.Mockito.spy; 70 import static org.mockito.Mockito.when; 71 72 import android.annotation.Nullable; 73 import android.compat.testing.PlatformCompatChangeRule; 74 import android.content.Context; 75 import android.content.Intent; 76 import android.content.LocusId; 77 import android.content.res.Configuration; 78 import android.graphics.Bitmap; 79 import android.graphics.BitmapFactory; 80 import android.graphics.Color; 81 import android.graphics.Typeface; 82 import android.graphics.drawable.Icon; 83 import android.net.Uri; 84 import android.os.Build; 85 import android.os.Bundle; 86 import android.os.Parcel; 87 import android.os.Parcelable; 88 import android.platform.test.annotations.DisableFlags; 89 import android.platform.test.annotations.EnableFlags; 90 import android.platform.test.annotations.Presubmit; 91 import android.platform.test.flag.junit.SetFlagsRule; 92 import android.text.Spannable; 93 import android.text.SpannableString; 94 import android.text.SpannableStringBuilder; 95 import android.text.Spanned; 96 import android.text.style.ForegroundColorSpan; 97 import android.text.style.StyleSpan; 98 import android.text.style.TextAppearanceSpan; 99 import android.util.Pair; 100 import android.widget.RemoteViews; 101 102 import androidx.test.InstrumentationRegistry; 103 import androidx.test.ext.junit.runners.AndroidJUnit4; 104 import androidx.test.filters.SmallTest; 105 106 import com.android.internal.R; 107 import com.android.internal.util.ContrastColorUtil; 108 109 import junit.framework.Assert; 110 111 import libcore.junit.util.compat.CoreCompatChangeRule; 112 113 import org.junit.Before; 114 import org.junit.Ignore; 115 import org.junit.Rule; 116 import org.junit.Test; 117 import org.junit.rules.TestRule; 118 import org.junit.runner.RunWith; 119 120 import java.util.Collections; 121 import java.util.List; 122 import java.util.function.Consumer; 123 124 @RunWith(AndroidJUnit4.class) 125 @SmallTest 126 @Presubmit 127 public class NotificationTest { 128 129 private Context mContext; 130 131 private RemoteViews mRemoteViews; 132 133 @Rule 134 public TestRule compatChangeRule = new PlatformCompatChangeRule(); 135 @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 136 137 @Before setUp()138 public void setUp() { 139 mContext = InstrumentationRegistry.getContext(); 140 mRemoteViews = new RemoteViews( 141 mContext.getPackageName(), R.layout.notification_template_header); 142 } 143 144 @Test testColorizedByPermission()145 public void testColorizedByPermission() { 146 Notification n = new Notification.Builder(mContext, "test") 147 .setFlag(FLAG_CAN_COLORIZE, true) 148 .setColorized(true).setColor(Color.WHITE) 149 .build(); 150 assertTrue(n.isColorized()); 151 152 n = new Notification.Builder(mContext, "test") 153 .setFlag(FLAG_CAN_COLORIZE, true) 154 .build(); 155 assertFalse(n.isColorized()); 156 157 n = new Notification.Builder(mContext, "test") 158 .setFlag(FLAG_CAN_COLORIZE, false) 159 .setColorized(true).setColor(Color.WHITE) 160 .build(); 161 assertFalse(n.isColorized()); 162 } 163 164 @Test testColorizedByForeground()165 public void testColorizedByForeground() { 166 Notification n = new Notification.Builder(mContext, "test") 167 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true) 168 .setColorized(true).setColor(Color.WHITE) 169 .build(); 170 assertTrue(n.isColorized()); 171 172 n = new Notification.Builder(mContext, "test") 173 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true) 174 .build(); 175 assertFalse(n.isColorized()); 176 177 n = new Notification.Builder(mContext, "test") 178 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, false) 179 .setColorized(true).setColor(Color.WHITE) 180 .build(); 181 assertFalse(n.isColorized()); 182 } 183 184 @Test testHasCompletedProgress_noProgress()185 public void testHasCompletedProgress_noProgress() { 186 Notification n = new Notification.Builder(mContext).build(); 187 188 assertFalse(n.hasCompletedProgress()); 189 } 190 191 @Test testHasCompletedProgress_complete()192 public void testHasCompletedProgress_complete() { 193 Notification n = new Notification.Builder(mContext) 194 .setProgress(100, 100, true) 195 .build(); 196 Notification n2 = new Notification.Builder(mContext) 197 .setProgress(10, 10, false) 198 .build(); 199 assertTrue(n.hasCompletedProgress()); 200 assertTrue(n2.hasCompletedProgress()); 201 } 202 203 @Test testHasCompletedProgress_notComplete()204 public void testHasCompletedProgress_notComplete() { 205 Notification n = new Notification.Builder(mContext) 206 .setProgress(100, 99, true) 207 .build(); 208 Notification n2 = new Notification.Builder(mContext) 209 .setProgress(10, 4, false) 210 .build(); 211 assertFalse(n.hasCompletedProgress()); 212 assertFalse(n2.hasCompletedProgress()); 213 } 214 215 @Test testHasCompletedProgress_zeroMax()216 public void testHasCompletedProgress_zeroMax() { 217 Notification n = new Notification.Builder(mContext) 218 .setProgress(0, 0, true) 219 .build(); 220 assertFalse(n.hasCompletedProgress()); 221 } 222 223 @Test 224 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasTitle_noStyle()225 public void testHasTitle_noStyle() { 226 Notification n = new Notification.Builder(mContext, "test") 227 .setContentTitle("TITLE") 228 .build(); 229 assertThat(n.hasTitle()).isTrue(); 230 } 231 232 @Test 233 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasTitle_bigText()234 public void testHasTitle_bigText() { 235 Notification n = new Notification.Builder(mContext, "test") 236 .setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG")) 237 .build(); 238 assertThat(n.hasTitle()).isTrue(); 239 } 240 241 @Test 242 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasTitle_noTitle()243 public void testHasTitle_noTitle() { 244 Notification n = new Notification.Builder(mContext, "test") 245 .setContentText("text not title") 246 .build(); 247 assertThat(n.hasTitle()).isFalse(); 248 } 249 250 @Test 251 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testContainsCustomViews_none()252 public void testContainsCustomViews_none() { 253 Notification np = new Notification.Builder(mContext, "test") 254 .setSmallIcon(android.R.drawable.sym_def_app_icon) 255 .setContentText("test") 256 .build(); 257 Notification n = new Notification.Builder(mContext, "test") 258 .setSmallIcon(android.R.drawable.sym_def_app_icon) 259 .setContentText("test") 260 .setPublicVersion(np) 261 .build(); 262 assertThat(n.containsCustomViews()).isFalse(); 263 } 264 265 @Test 266 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testContainsCustomViews_content()267 public void testContainsCustomViews_content() { 268 Notification np = new Notification.Builder(mContext, "test") 269 .setSmallIcon(android.R.drawable.sym_def_app_icon) 270 .setContentText("test") 271 .build(); 272 Notification n = new Notification.Builder(mContext, "test") 273 .setSmallIcon(android.R.drawable.sym_def_app_icon) 274 .setContentText("test") 275 .setCustomContentView(mRemoteViews) 276 .setPublicVersion(np) 277 .build(); 278 assertThat(n.containsCustomViews()).isTrue(); 279 } 280 281 @Test 282 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testContainsCustomViews_big()283 public void testContainsCustomViews_big() { 284 Notification np = new Notification.Builder(mContext, "test") 285 .setSmallIcon(android.R.drawable.sym_def_app_icon) 286 .setContentText("test") 287 .build(); 288 Notification n = new Notification.Builder(mContext, "test") 289 .setSmallIcon(android.R.drawable.sym_def_app_icon) 290 .setContentText("test") 291 .setCustomBigContentView(mRemoteViews) 292 .setPublicVersion(np) 293 .build(); 294 assertThat(n.containsCustomViews()).isTrue(); 295 } 296 297 @Test 298 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testContainsCustomViews_headsUp()299 public void testContainsCustomViews_headsUp() { 300 Notification np = new Notification.Builder(mContext, "test") 301 .setSmallIcon(android.R.drawable.sym_def_app_icon) 302 .setContentText("test") 303 .build(); 304 Notification n = new Notification.Builder(mContext, "test") 305 .setSmallIcon(android.R.drawable.sym_def_app_icon) 306 .setContentText("test") 307 .setCustomHeadsUpContentView(mRemoteViews) 308 .setPublicVersion(np) 309 .build(); 310 assertThat(n.containsCustomViews()).isTrue(); 311 } 312 313 @Test 314 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testContainsCustomViews_content_public()315 public void testContainsCustomViews_content_public() { 316 Notification np = new Notification.Builder(mContext, "test") 317 .setSmallIcon(android.R.drawable.sym_def_app_icon) 318 .setContentText("public") 319 .setCustomContentView(mRemoteViews) 320 .build(); 321 Notification n = new Notification.Builder(mContext, "test") 322 .setSmallIcon(android.R.drawable.sym_def_app_icon) 323 .setContentText("test") 324 .setPublicVersion(np) 325 .build(); 326 assertThat(n.containsCustomViews()).isTrue(); 327 } 328 329 @Test 330 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testContainsCustomViews_big_public()331 public void testContainsCustomViews_big_public() { 332 Notification np = new Notification.Builder(mContext, "test") 333 .setSmallIcon(android.R.drawable.sym_def_app_icon) 334 .setContentText("test") 335 .setCustomBigContentView(mRemoteViews) 336 .build(); 337 Notification n = new Notification.Builder(mContext, "test") 338 .setSmallIcon(android.R.drawable.sym_def_app_icon) 339 .setContentText("test") 340 .setPublicVersion(np) 341 .build(); 342 assertThat(n.containsCustomViews()).isTrue(); 343 } 344 345 @Test 346 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testContainsCustomViews_headsUp_public()347 public void testContainsCustomViews_headsUp_public() { 348 Notification np = new Notification.Builder(mContext, "test") 349 .setSmallIcon(android.R.drawable.sym_def_app_icon) 350 .setContentText("test") 351 .setCustomHeadsUpContentView(mRemoteViews) 352 .build(); 353 Notification n = new Notification.Builder(mContext, "test") 354 .setSmallIcon(android.R.drawable.sym_def_app_icon) 355 .setContentText("test") 356 .setPublicVersion(np) 357 .build(); 358 assertThat(n.containsCustomViews()).isTrue(); 359 } 360 361 @Test 362 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableStyle_noStyle()363 public void testHasPromotableStyle_noStyle() { 364 Notification n = new Notification.Builder(mContext, "test") 365 .setSmallIcon(android.R.drawable.sym_def_app_icon) 366 .setContentText("test") 367 .build(); 368 assertThat(n.hasPromotableStyle()).isTrue(); 369 } 370 371 @Test 372 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableStyle_bigPicture()373 public void testHasPromotableStyle_bigPicture() { 374 Notification n = new Notification.Builder(mContext, "test") 375 .setSmallIcon(android.R.drawable.sym_def_app_icon) 376 .setStyle(new Notification.BigPictureStyle()) 377 .build(); 378 assertThat(n.hasPromotableStyle()).isTrue(); 379 } 380 381 @Test 382 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableStyle_bigText()383 public void testHasPromotableStyle_bigText() { 384 Notification n = new Notification.Builder(mContext, "test") 385 .setSmallIcon(android.R.drawable.sym_def_app_icon) 386 .setStyle(new Notification.BigTextStyle()) 387 .build(); 388 assertThat(n.hasPromotableStyle()).isTrue(); 389 } 390 391 @Test 392 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableStyle_no_messagingStyle()393 public void testHasPromotableStyle_no_messagingStyle() { 394 Notification.MessagingStyle style = new Notification.MessagingStyle("self name") 395 .setGroupConversation(true) 396 .setConversationTitle("test conversation title"); 397 Notification n = new Notification.Builder(mContext, "test") 398 .setSmallIcon(android.R.drawable.sym_def_app_icon) 399 .setStyle(style) 400 .build(); 401 assertThat(n.hasPromotableStyle()).isFalse(); 402 } 403 404 @Test 405 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableStyle_no_mediaStyle()406 public void testHasPromotableStyle_no_mediaStyle() { 407 Notification n = new Notification.Builder(mContext, "test") 408 .setSmallIcon(android.R.drawable.sym_def_app_icon) 409 .setStyle(new Notification.MediaStyle()) 410 .build(); 411 assertThat(n.hasPromotableStyle()).isFalse(); 412 } 413 414 @Test 415 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableStyle_no_inboxStyle()416 public void testHasPromotableStyle_no_inboxStyle() { 417 Notification n = new Notification.Builder(mContext, "test") 418 .setSmallIcon(android.R.drawable.sym_def_app_icon) 419 .setStyle(new Notification.InboxStyle()) 420 .build(); 421 assertThat(n.hasPromotableStyle()).isFalse(); 422 } 423 424 @Test 425 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableStyle_callText()426 public void testHasPromotableStyle_callText() { 427 PendingIntent answerIntent = createPendingIntent("answer"); 428 PendingIntent declineIntent = createPendingIntent("decline"); 429 Notification.CallStyle style = Notification.CallStyle.forIncomingCall( 430 new Person.Builder().setName("A Caller").build(), 431 declineIntent, 432 answerIntent 433 ); 434 Notification n = new Notification.Builder(mContext, "test") 435 .setSmallIcon(android.R.drawable.sym_def_app_icon) 436 .setStyle(style) 437 .build(); 438 assertThat(n.hasPromotableStyle()).isTrue(); 439 } 440 441 @Test 442 @EnableFlags({Flags.FLAG_UI_RICH_ONGOING, Flags.FLAG_API_RICH_ONGOING}) testHasPromotableStyle_progress()443 public void testHasPromotableStyle_progress() { 444 Notification n = new Notification.Builder(mContext, "test") 445 .setSmallIcon(android.R.drawable.sym_def_app_icon) 446 .setStyle(new Notification.ProgressStyle()) 447 .build(); 448 assertThat(n.hasPromotableStyle()).isTrue(); 449 } 450 451 @Test 452 @EnableFlags({Flags.FLAG_UI_RICH_ONGOING}) testHasPromotableStyle_unknownStyle()453 public void testHasPromotableStyle_unknownStyle() { 454 Notification n = new Notification.Builder(mContext, "test") 455 .setSmallIcon(android.R.drawable.sym_def_app_icon) 456 .setStyle(new NotAPlatformStyle()) 457 .build(); 458 459 assertThat(n.hasPromotableStyle()).isTrue(); 460 } 461 462 @Test 463 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableCharacteristics()464 public void testHasPromotableCharacteristics() { 465 Notification n = new Notification.Builder(mContext, "test") 466 .setSmallIcon(android.R.drawable.sym_def_app_icon) 467 .setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG")) 468 .setColor(Color.WHITE) 469 .setColorized(true) 470 .setOngoing(true) 471 .build(); 472 assertThat(n.hasPromotableCharacteristics()).isTrue(); 473 } 474 475 @Test 476 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableCharacteristics_notOngoing()477 public void testHasPromotableCharacteristics_notOngoing() { 478 Notification n = new Notification.Builder(mContext, "test") 479 .setSmallIcon(android.R.drawable.sym_def_app_icon) 480 .setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG")) 481 .setColor(Color.WHITE) 482 .setColorized(true) 483 .build(); 484 assertThat(n.hasPromotableCharacteristics()).isFalse(); 485 } 486 487 @Test 488 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableCharacteristics_wrongStyle()489 public void testHasPromotableCharacteristics_wrongStyle() { 490 Notification n = new Notification.Builder(mContext, "test") 491 .setSmallIcon(android.R.drawable.sym_def_app_icon) 492 .setStyle(new Notification.InboxStyle()) 493 .setContentTitle("TITLE") 494 .setColor(Color.WHITE) 495 .setColorized(true) 496 .setOngoing(true) 497 .build(); 498 assertThat(n.hasPromotableCharacteristics()).isFalse(); 499 } 500 501 @Test 502 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableCharacteristics_notColorized()503 public void testHasPromotableCharacteristics_notColorized() { 504 Notification n = new Notification.Builder(mContext, "test") 505 .setSmallIcon(android.R.drawable.sym_def_app_icon) 506 .setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG")) 507 .setColor(Color.WHITE) 508 .setOngoing(true) 509 .build(); 510 assertThat(n.hasPromotableCharacteristics()).isFalse(); 511 } 512 513 @Test 514 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableCharacteristics_noTitle()515 public void testHasPromotableCharacteristics_noTitle() { 516 Notification n = new Notification.Builder(mContext, "test") 517 .setSmallIcon(android.R.drawable.sym_def_app_icon) 518 .setStyle(new Notification.BigTextStyle()) 519 .setColor(Color.WHITE) 520 .setColorized(true) 521 .setOngoing(true) 522 .build(); 523 assertThat(n.hasPromotableCharacteristics()).isFalse(); 524 } 525 526 @Test 527 @EnableFlags(Flags.FLAG_UI_RICH_ONGOING) testHasPromotableCharacteristics_groupSummary()528 public void testHasPromotableCharacteristics_groupSummary() { 529 Notification n = new Notification.Builder(mContext, "test") 530 .setSmallIcon(android.R.drawable.sym_def_app_icon) 531 .setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG")) 532 .setColor(Color.WHITE) 533 .setColorized(true) 534 .setOngoing(true) 535 .setGroup("someGroup") 536 .setGroupSummary(true) 537 .build(); 538 assertThat(n.hasPromotableCharacteristics()).isFalse(); 539 } 540 541 @Test 542 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) testGetShortCriticalText_noneSet()543 public void testGetShortCriticalText_noneSet() { 544 Notification n = new Notification.Builder(mContext, "test") 545 .build(); 546 547 assertSame(n.getShortCriticalText(), null); 548 } 549 550 @Test 551 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) testGetShortCriticalText_isSet()552 public void testGetShortCriticalText_isSet() { 553 Notification n = new Notification.Builder(mContext, "test") 554 .setShortCriticalText("short critical text here") 555 .build(); 556 557 assertSame(n.getShortCriticalText(), "short critical text here"); 558 } 559 560 @Test largeIconMultipleReferences_keptAfterParcelling()561 public void largeIconMultipleReferences_keptAfterParcelling() { 562 Icon originalIcon = Icon.createWithBitmap(BitmapFactory.decodeResource( 563 mContext.getResources(), com.android.frameworks.coretests.R.drawable.test128x96)); 564 565 Notification n = new Notification.Builder(mContext).setLargeIcon(originalIcon).build(); 566 assertSame(n.getLargeIcon(), originalIcon); 567 568 Notification q = writeAndReadParcelable(n); 569 assertNotSame(q.getLargeIcon(), n.getLargeIcon()); 570 571 assertTrue(q.getLargeIcon().getBitmap().sameAs(n.getLargeIcon().getBitmap())); 572 assertSame(q.getLargeIcon(), q.extras.getParcelable(EXTRA_LARGE_ICON)); 573 } 574 575 @Test largeIconReferenceInExtrasOnly_keptAfterParcelling()576 public void largeIconReferenceInExtrasOnly_keptAfterParcelling() { 577 Icon originalIcon = Icon.createWithBitmap(BitmapFactory.decodeResource( 578 mContext.getResources(), com.android.frameworks.coretests.R.drawable.test128x96)); 579 580 Notification n = new Notification.Builder(mContext).build(); 581 n.extras.putParcelable(EXTRA_LARGE_ICON, originalIcon); 582 assertSame(n.getLargeIcon(), null); 583 584 Notification q = writeAndReadParcelable(n); 585 assertSame(q.getLargeIcon(), null); 586 assertTrue(((Icon) q.extras.getParcelable(EXTRA_LARGE_ICON)).getBitmap() 587 .sameAs(originalIcon.getBitmap())); 588 } 589 590 @Test allPendingIntents_recollectedAfterReusingBuilder()591 public void allPendingIntents_recollectedAfterReusingBuilder() { 592 PendingIntent intent1 = PendingIntent.getActivity( 593 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE); 594 PendingIntent intent2 = PendingIntent.getActivity( 595 mContext, 0, new Intent("test2"), PendingIntent.FLAG_IMMUTABLE); 596 597 Notification.Builder builder = new Notification.Builder(mContext, "channel"); 598 builder.setContentIntent(intent1); 599 600 Parcel p = Parcel.obtain(); 601 602 Notification n1 = builder.build(); 603 n1.writeToParcel(p, 0); 604 605 builder.setContentIntent(intent2); 606 Notification n2 = builder.build(); 607 n2.writeToParcel(p, 0); 608 609 assertTrue(n2.allPendingIntents.contains(intent2)); 610 } 611 612 @Test allPendingIntents_containsCustomRemoteViews()613 public void allPendingIntents_containsCustomRemoteViews() { 614 PendingIntent intent = PendingIntent.getActivity(mContext, 0, 615 new Intent("test").setPackage(mContext.getPackageName()), 616 PendingIntent.FLAG_MUTABLE); 617 618 RemoteViews contentView = new RemoteViews(mContext.getPackageName(), 0 /* layoutId */); 619 contentView.setOnClickPendingIntent(1 /* id */, intent); 620 621 Notification.Builder builder = new Notification.Builder(mContext, "channel"); 622 builder.setCustomContentView(contentView); 623 624 Parcel p = Parcel.obtain(); 625 626 Notification n = builder.build(); 627 n.writeToParcel(p, 0); 628 629 assertTrue(n.allPendingIntents.contains(intent)); 630 } 631 632 @Test allPendingIntents_resilientToAnotherNotificationInExtras()633 public void allPendingIntents_resilientToAnotherNotificationInExtras() { 634 PendingIntent contentIntent = createPendingIntent("content"); 635 PendingIntent actionIntent = createPendingIntent("action"); 636 Notification another = new Notification.Builder(mContext, "channel").build(); 637 Bundle bundleContainingAnotherNotification = new Bundle(); 638 bundleContainingAnotherNotification.putParcelable(null, another); 639 Notification source = new Notification.Builder(mContext, "channel") 640 .setContentIntent(contentIntent) 641 .addAction(new Notification.Action.Builder(null, "action", actionIntent).build()) 642 .setExtras(bundleContainingAnotherNotification) 643 .build(); 644 645 Parcel p = Parcel.obtain(); 646 source.writeToParcel(p, 0); 647 p.setDataPosition(0); 648 Notification unparceled = new Notification(p); 649 650 assertThat(unparceled.allPendingIntents).containsExactly(contentIntent, actionIntent); 651 } 652 653 @Test allPendingIntents_alsoInPublicVersion()654 public void allPendingIntents_alsoInPublicVersion() { 655 PendingIntent contentIntent = createPendingIntent("content"); 656 PendingIntent actionIntent = createPendingIntent("action"); 657 PendingIntent publicContentIntent = createPendingIntent("publicContent"); 658 PendingIntent publicActionIntent = createPendingIntent("publicAction"); 659 Notification source = new Notification.Builder(mContext, "channel") 660 .setContentIntent(contentIntent) 661 .addAction(new Notification.Action.Builder(null, "action", actionIntent).build()) 662 .setPublicVersion(new Notification.Builder(mContext, "channel") 663 .setContentIntent(publicContentIntent) 664 .addAction(new Notification.Action.Builder( 665 null, "publicAction", publicActionIntent).build()) 666 .build()) 667 .build(); 668 669 Parcel p = Parcel.obtain(); 670 source.writeToParcel(p, 0); 671 p.setDataPosition(0); 672 Notification unparceled = new Notification(p); 673 674 assertThat(unparceled.allPendingIntents).containsExactly(contentIntent, actionIntent, 675 publicContentIntent, publicActionIntent); 676 assertThat(unparceled.publicVersion.allPendingIntents).containsExactly(publicContentIntent, 677 publicActionIntent); 678 } 679 680 @Test messagingStyle_isGroupConversation()681 public void messagingStyle_isGroupConversation() { 682 mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.P; 683 Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("self name") 684 .setGroupConversation(true) 685 .setConversationTitle("test conversation title"); 686 Notification notification = new Notification.Builder(mContext, "test id") 687 .setSmallIcon(1) 688 .setContentTitle("test title") 689 .setStyle(messagingStyle) 690 .build(); 691 692 assertTrue(messagingStyle.isGroupConversation()); 693 assertTrue(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION)); 694 } 695 696 @Test messagingStyle_isGroupConversation_noConversationTitle()697 public void messagingStyle_isGroupConversation_noConversationTitle() { 698 mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.P; 699 Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("self name") 700 .setGroupConversation(true) 701 .setConversationTitle(null); 702 Notification notification = new Notification.Builder(mContext, "test id") 703 .setSmallIcon(1) 704 .setContentTitle("test title") 705 .setStyle(messagingStyle) 706 .build(); 707 708 assertTrue(messagingStyle.isGroupConversation()); 709 assertTrue(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION)); 710 } 711 712 @Test messagingStyle_isGroupConversation_withConversationTitle_legacy()713 public void messagingStyle_isGroupConversation_withConversationTitle_legacy() { 714 // In legacy (version < P), isGroupConversation is controlled by conversationTitle. 715 mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.O; 716 Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("self name") 717 .setGroupConversation(false) 718 .setConversationTitle("test conversation title"); 719 Notification notification = new Notification.Builder(mContext, "test id") 720 .setSmallIcon(1) 721 .setContentTitle("test title") 722 .setStyle(messagingStyle) 723 .build(); 724 725 assertTrue(messagingStyle.isGroupConversation()); 726 assertFalse(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION)); 727 } 728 729 @Test messagingStyle_isGroupConversation_withoutConversationTitle_legacy()730 public void messagingStyle_isGroupConversation_withoutConversationTitle_legacy() { 731 // In legacy (version < P), isGroupConversation is controlled by conversationTitle. 732 mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.O; 733 Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle("self name") 734 .setGroupConversation(true) 735 .setConversationTitle(null); 736 Notification notification = new Notification.Builder(mContext, "test id") 737 .setSmallIcon(1) 738 .setContentTitle("test title") 739 .setStyle(messagingStyle) 740 .build(); 741 742 assertFalse(messagingStyle.isGroupConversation()); 743 assertTrue(notification.extras.getBoolean(Notification.EXTRA_IS_GROUP_CONVERSATION)); 744 } 745 746 @Test action_builder_hasDefault()747 public void action_builder_hasDefault() { 748 Notification.Action action = makeNotificationAction(null); 749 assertEquals(Notification.Action.SEMANTIC_ACTION_NONE, action.getSemanticAction()); 750 } 751 752 @Test action_builder_setSemanticAction()753 public void action_builder_setSemanticAction() { 754 Notification.Action action = makeNotificationAction( 755 builder -> builder.setSemanticAction(Notification.Action.SEMANTIC_ACTION_REPLY)); 756 assertEquals(Notification.Action.SEMANTIC_ACTION_REPLY, action.getSemanticAction()); 757 } 758 759 @Test action_parcel()760 public void action_parcel() { 761 Notification.Action action = writeAndReadParcelable( 762 makeNotificationAction(builder -> { 763 builder.setSemanticAction(Notification.Action.SEMANTIC_ACTION_ARCHIVE); 764 builder.setAllowGeneratedReplies(true); 765 })); 766 767 assertEquals(Notification.Action.SEMANTIC_ACTION_ARCHIVE, action.getSemanticAction()); 768 assertTrue(action.getAllowGeneratedReplies()); 769 } 770 771 @Test action_clone()772 public void action_clone() { 773 Notification.Action action = makeNotificationAction( 774 builder -> builder.setSemanticAction(Notification.Action.SEMANTIC_ACTION_DELETE)); 775 assertEquals( 776 Notification.Action.SEMANTIC_ACTION_DELETE, 777 action.clone().getSemanticAction()); 778 } 779 780 @Test testBuilder_setLocusId()781 public void testBuilder_setLocusId() { 782 LocusId locusId = new LocusId("4815162342"); 783 Notification notification = new Notification.Builder(mContext, "whatever") 784 .setLocusId(locusId).build(); 785 assertEquals(locusId, notification.getLocusId()); 786 787 Notification clone = writeAndReadParcelable(notification); 788 assertEquals(locusId, clone.getLocusId()); 789 } 790 791 @Test testBuilder_setLocusId_null()792 public void testBuilder_setLocusId_null() { 793 Notification notification = new Notification.Builder(mContext, "whatever") 794 .setLocusId(null).build(); 795 assertNull(notification.getLocusId()); 796 797 Notification clone = writeAndReadParcelable(notification); 798 assertNull(clone.getLocusId()); 799 } 800 801 @Test testBuilder_getFullLengthSpanColor_returnsNullForString()802 public void testBuilder_getFullLengthSpanColor_returnsNullForString() { 803 assertThat(Notification.Builder.getFullLengthSpanColor("String")).isNull(); 804 } 805 806 @Test testBuilder_getFullLengthSpanColor_returnsNullWithPartialSpan()807 public void testBuilder_getFullLengthSpanColor_returnsNullWithPartialSpan() { 808 CharSequence text = new SpannableStringBuilder() 809 .append("text with ") 810 .append("some red", new ForegroundColorSpan(Color.RED), 811 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 812 assertThat(Notification.Builder.getFullLengthSpanColor(text)).isNull(); 813 } 814 815 @Test testBuilder_getFullLengthSpanColor_worksWithSingleSpan()816 public void testBuilder_getFullLengthSpanColor_worksWithSingleSpan() { 817 CharSequence text = new SpannableStringBuilder() 818 .append("text that is all red", new ForegroundColorSpan(Color.RED), 819 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 820 assertThat(Notification.Builder.getFullLengthSpanColor(text)).isEqualTo(Color.RED); 821 } 822 823 @Test testBuilder_getFullLengthSpanColor_worksWithFullAndPartialSpans()824 public void testBuilder_getFullLengthSpanColor_worksWithFullAndPartialSpans() { 825 Spannable text = new SpannableString("blue text with yellow and green"); 826 text.setSpan(new ForegroundColorSpan(Color.YELLOW), 15, 21, 827 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 828 text.setSpan(new ForegroundColorSpan(Color.BLUE), 0, text.length(), 829 Spanned.SPAN_INCLUSIVE_INCLUSIVE); 830 text.setSpan(new ForegroundColorSpan(Color.GREEN), 26, 31, 831 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 832 assertThat(Notification.Builder.getFullLengthSpanColor(text)).isEqualTo(Color.BLUE); 833 } 834 835 @Test testBuilder_getFullLengthSpanColor_worksWithTextAppearance()836 public void testBuilder_getFullLengthSpanColor_worksWithTextAppearance() { 837 Spannable text = new SpannableString("title text with yellow and green"); 838 text.setSpan(new ForegroundColorSpan(Color.YELLOW), 15, 21, 839 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 840 TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(mContext, 841 R.style.TextAppearance_DeviceDefault_Notification_Title); 842 int expectedTextColor = textAppearanceSpan.getTextColor().getDefaultColor(); 843 text.setSpan(textAppearanceSpan, 0, text.length(), 844 Spanned.SPAN_INCLUSIVE_INCLUSIVE); 845 text.setSpan(new ForegroundColorSpan(Color.GREEN), 26, 31, 846 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 847 assertThat(Notification.Builder.getFullLengthSpanColor(text)).isEqualTo(expectedTextColor); 848 } 849 850 851 852 @Test testBuilder_ensureButtonFillContrast_adjustsDarker()853 public void testBuilder_ensureButtonFillContrast_adjustsDarker() { 854 int background = Color.LTGRAY; 855 int foreground = Color.LTGRAY; 856 int result = Notification.Builder.ensureButtonFillContrast(foreground, background); 857 assertContrastIsWithinRange(result, background, 1.3, 1.5); 858 assertThat(ContrastColorUtil.calculateLuminance(result)) 859 .isLessThan(ContrastColorUtil.calculateLuminance(background)); 860 } 861 862 @Test testBuilder_ensureButtonFillContrast_adjustsLighter()863 public void testBuilder_ensureButtonFillContrast_adjustsLighter() { 864 int background = Color.DKGRAY; 865 int foreground = Color.DKGRAY; 866 int result = Notification.Builder.ensureButtonFillContrast(foreground, background); 867 assertContrastIsWithinRange(result, background, 1.3, 1.5); 868 assertThat(ContrastColorUtil.calculateLuminance(result)) 869 .isGreaterThan(ContrastColorUtil.calculateLuminance(background)); 870 } 871 872 @Test testBuilder_setSilent_summaryBehavior_groupAlertChildren()873 public void testBuilder_setSilent_summaryBehavior_groupAlertChildren() { 874 Notification summaryNotif = new Notification.Builder(mContext, "channelId") 875 .setGroupSummary(true) 876 .setGroup("groupKey") 877 .setSilent(true) 878 .build(); 879 assertEquals(GROUP_ALERT_CHILDREN, summaryNotif.getGroupAlertBehavior()); 880 } 881 882 @Test testBuilder_setSilent_childBehavior_groupAlertSummary()883 public void testBuilder_setSilent_childBehavior_groupAlertSummary() { 884 Notification childNotif = new Notification.Builder(mContext, "channelId") 885 .setGroupSummary(false) 886 .setGroup("groupKey") 887 .setSilent(true) 888 .build(); 889 assertEquals(GROUP_ALERT_SUMMARY, childNotif.getGroupAlertBehavior()); 890 } 891 892 @Test 893 @DisableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG) testBuilder_setSilent_emptyGroupKey_groupKeySilent()894 public void testBuilder_setSilent_emptyGroupKey_groupKeySilent() { 895 Notification emptyGroupKeyNotif = new Notification.Builder(mContext, "channelId") 896 .setGroup("") 897 .setSilent(true) 898 .build(); 899 assertThat(emptyGroupKeyNotif.getGroup()).isEqualTo(GROUP_KEY_SILENT); 900 assertThat(emptyGroupKeyNotif.isSilent()).isTrue(); 901 } 902 903 @Test 904 @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG) testBuilder_setSilent_flagSilent()905 public void testBuilder_setSilent_flagSilent() { 906 final String groupKey = "groupKey"; 907 Notification emptyGroupKeyNotif = new Notification.Builder(mContext, "channelId") 908 .setGroup(groupKey) 909 .setSilent(true) 910 .build(); 911 assertThat(emptyGroupKeyNotif.getGroup()).isEqualTo(groupKey); 912 assertThat(emptyGroupKeyNotif.isSilent()).isTrue(); 913 } 914 915 @Test testBuilder_setSilent_vibrateNull()916 public void testBuilder_setSilent_vibrateNull() { 917 Notification silentNotif = new Notification.Builder(mContext, "channelId") 918 .setGroup("") 919 .setSilent(true) 920 .build(); 921 922 assertNull(silentNotif.vibrate); 923 } 924 925 @Test testBuilder_setSilent_soundNull()926 public void testBuilder_setSilent_soundNull() { 927 Notification silentNotif = new Notification.Builder(mContext, "channelId") 928 .setGroup("") 929 .setSilent(true) 930 .build(); 931 932 assertNull(silentNotif.sound); 933 } 934 935 @Test testBuilder_setSilent_noDefaultSound()936 public void testBuilder_setSilent_noDefaultSound() { 937 Notification silentNotif = new Notification.Builder(mContext, "channelId") 938 .setGroup("") 939 .setSilent(true) 940 .build(); 941 942 assertEquals(0, (silentNotif.defaults & DEFAULT_SOUND)); 943 } 944 945 @Test testBuilder_setSilent_noDefaultVibrate()946 public void testBuilder_setSilent_noDefaultVibrate() { 947 Notification silentNotif = new Notification.Builder(mContext, "channelId") 948 .setGroup("") 949 .setSilent(true) 950 .build(); 951 952 assertEquals(0, (silentNotif.defaults & DEFAULT_VIBRATE)); 953 } 954 955 @Test testCallStyle_getSystemActions_forIncomingCall()956 public void testCallStyle_getSystemActions_forIncomingCall() { 957 PendingIntent answerIntent = createPendingIntent("answer"); 958 PendingIntent declineIntent = createPendingIntent("decline"); 959 Notification.CallStyle style = Notification.CallStyle.forIncomingCall( 960 new Person.Builder().setName("A Caller").build(), 961 declineIntent, 962 answerIntent 963 ); 964 style.setBuilder(new Notification.Builder(mContext, "Channel")); 965 966 List<Notification.Action> actions = style.getActionsListWithSystemActions(); 967 968 assertEquals(2, actions.size()); 969 assertEquals(declineIntent, actions.get(0).actionIntent); 970 assertEquals(answerIntent, actions.get(1).actionIntent); 971 } 972 973 @Test testCallStyle_getSystemActions_forOngoingCall()974 public void testCallStyle_getSystemActions_forOngoingCall() { 975 PendingIntent hangUpIntent = createPendingIntent("hangUp"); 976 Notification.CallStyle style = Notification.CallStyle.forOngoingCall( 977 new Person.Builder().setName("A Caller").build(), 978 hangUpIntent 979 ); 980 style.setBuilder(new Notification.Builder(mContext, "Channel")); 981 982 List<Notification.Action> actions = style.getActionsListWithSystemActions(); 983 984 assertEquals(1, actions.size()); 985 assertEquals(hangUpIntent, actions.get(0).actionIntent); 986 } 987 988 @Test testCallStyle_getSystemActions_forIncomingCallWithOtherActions()989 public void testCallStyle_getSystemActions_forIncomingCallWithOtherActions() { 990 PendingIntent answerIntent = createPendingIntent("answer"); 991 PendingIntent declineIntent = createPendingIntent("decline"); 992 Notification.CallStyle style = Notification.CallStyle.forIncomingCall( 993 new Person.Builder().setName("A Caller").build(), 994 declineIntent, 995 answerIntent 996 ); 997 Notification.Action actionToKeep = makeNotificationAction(null); 998 Notification.Action actionToDrop = makeNotificationAction(null); 999 Notification.Builder notifBuilder = new Notification.Builder(mContext, "Channel") 1000 .addAction(actionToKeep) 1001 .addAction(actionToDrop); //expect to move this action to the end 1002 style.setBuilder(notifBuilder); //add a builder with actions 1003 1004 List<Notification.Action> actions = style.getActionsListWithSystemActions(); 1005 1006 assertEquals(4, actions.size()); 1007 assertEquals(declineIntent, actions.get(0).actionIntent); 1008 assertEquals(actionToKeep, actions.get(1)); 1009 assertEquals(answerIntent, actions.get(2).actionIntent); 1010 assertEquals(actionToDrop, actions.get(3)); 1011 } 1012 1013 @Test testCallStyle_getSystemActions_forOngoingCallWithOtherActions()1014 public void testCallStyle_getSystemActions_forOngoingCallWithOtherActions() { 1015 PendingIntent hangUpIntent = createPendingIntent("hangUp"); 1016 Notification.CallStyle style = Notification.CallStyle.forOngoingCall( 1017 new Person.Builder().setName("A Caller").build(), 1018 hangUpIntent 1019 ); 1020 Notification.Action firstAction = makeNotificationAction(null); 1021 Notification.Action secondAction = makeNotificationAction(null); 1022 Notification.Builder notifBuilder = new Notification.Builder(mContext, "Channel") 1023 .addAction(firstAction) 1024 .addAction(secondAction); 1025 style.setBuilder(notifBuilder); //add a builder with actions 1026 1027 List<Notification.Action> actions = style.getActionsListWithSystemActions(); 1028 1029 assertEquals(3, actions.size()); 1030 assertEquals(hangUpIntent, actions.get(0).actionIntent); 1031 assertEquals(firstAction, actions.get(1)); 1032 assertEquals(secondAction, actions.get(2)); 1033 } 1034 1035 @Test testCallStyle_getSystemActions_dropsOldSystemActions()1036 public void testCallStyle_getSystemActions_dropsOldSystemActions() { 1037 PendingIntent hangUpIntent = createPendingIntent("decline"); 1038 Notification.CallStyle style = Notification.CallStyle.forOngoingCall( 1039 new Person.Builder().setName("A Caller").build(), 1040 hangUpIntent 1041 ); 1042 Bundle actionExtras = new Bundle(); 1043 actionExtras.putBoolean("key_action_priority", true); 1044 Notification.Action oldSystemAction = makeNotificationAction( 1045 builder -> builder.addExtras(actionExtras) 1046 ); 1047 Notification.Builder notifBuilder = new Notification.Builder(mContext, "Channel") 1048 .addAction(oldSystemAction); 1049 style.setBuilder(notifBuilder); //add a builder with actions 1050 1051 List<Notification.Action> actions = style.getActionsListWithSystemActions(); 1052 1053 assertFalse("Old versions of system actions should be dropped.", 1054 actions.contains(oldSystemAction)); 1055 } 1056 1057 @Test testBuild_ensureSmallIconIsNotTooBig_resizesIcon()1058 public void testBuild_ensureSmallIconIsNotTooBig_resizesIcon() { 1059 Icon hugeIcon = Icon.createWithBitmap( 1060 Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888)); 1061 Notification notification = new Notification.Builder(mContext, "Channel").setSmallIcon( 1062 hugeIcon).build(); 1063 1064 Bitmap smallNotificationIcon = notification.getSmallIcon().getBitmap(); 1065 assertThat((float) smallNotificationIcon.getWidth()).isWithin(3f).of( 1066 mContext.getResources().getDimensionPixelSize( 1067 R.dimen.notification_small_icon_size)); 1068 assertThat((float) smallNotificationIcon.getHeight()).isWithin(3f).of( 1069 mContext.getResources().getDimensionPixelSize( 1070 R.dimen.notification_small_icon_size)); 1071 } 1072 1073 @Test testBuild_ensureMessagingUserIsNotTooBig_resizesIcon()1074 public void testBuild_ensureMessagingUserIsNotTooBig_resizesIcon() { 1075 Icon hugeIcon = Icon.createWithBitmap( 1076 Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888)); 1077 Icon hugeMessageAvatar = Icon.createWithBitmap( 1078 Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888)); 1079 Icon hugeHistoricMessageAvatar = Icon.createWithBitmap( 1080 Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888)); 1081 1082 Notification.MessagingStyle style = new Notification.MessagingStyle( 1083 new Person.Builder().setIcon(hugeIcon).setName("A User").build()); 1084 style.addMessage(new Notification.MessagingStyle.Message("A message", 123456, 1085 new Person.Builder().setIcon(hugeMessageAvatar).setName("A Sender").build())); 1086 style.addHistoricMessage(new Notification.MessagingStyle.Message("A message", 123456, 1087 new Person.Builder().setIcon(hugeHistoricMessageAvatar).setName( 1088 "A Historic Sender").build())); 1089 Notification notification = new Notification.Builder(mContext, "Channel").setStyle( 1090 style).build(); 1091 1092 float targetSize = mContext.getResources().getDimensionPixelSize( 1093 ActivityManager.isLowRamDeviceStatic() 1094 ? R.dimen.notification_person_icon_max_size_low_ram 1095 : R.dimen.notification_person_icon_max_size); 1096 1097 Bitmap personIcon = style.getUser().getIcon().getBitmap(); 1098 assertThat((float) personIcon.getWidth()).isWithin(3f).of(targetSize); 1099 assertThat((float) personIcon.getHeight()).isWithin(3f).of(targetSize); 1100 1101 Bitmap avatarIcon = style.getMessages().get(0).getSenderPerson().getIcon().getBitmap(); 1102 assertThat((float) avatarIcon.getWidth()).isWithin(3f).of(targetSize); 1103 assertThat((float) avatarIcon.getHeight()).isWithin(3f).of(targetSize); 1104 1105 Bitmap historicAvatarIcon = style.getHistoricMessages().get( 1106 0).getSenderPerson().getIcon().getBitmap(); 1107 assertThat((float) historicAvatarIcon.getWidth()).isWithin(3f).of(targetSize); 1108 assertThat((float) historicAvatarIcon.getHeight()).isWithin(3f).of(targetSize); 1109 } 1110 1111 @Test testBuild_ensureMessagingShortcutIconIsNotTooBig_resizesIcon()1112 public void testBuild_ensureMessagingShortcutIconIsNotTooBig_resizesIcon() { 1113 Icon hugeIcon = Icon.createWithBitmap( 1114 Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888)); 1115 Notification.MessagingStyle style = new Notification.MessagingStyle( 1116 new Person.Builder().setName("A User").build()).setShortcutIcon(hugeIcon); 1117 1118 Notification notification = new Notification.Builder(mContext, "Channel").setStyle( 1119 style).build(); 1120 Bitmap shortcutIcon = style.getShortcutIcon().getBitmap(); 1121 1122 assertThat((float) shortcutIcon.getWidth()).isWithin(3f).of( 1123 mContext.getResources().getDimensionPixelSize( 1124 R.dimen.notification_small_icon_size)); 1125 assertThat((float) shortcutIcon.getHeight()).isWithin(3f).of( 1126 mContext.getResources().getDimensionPixelSize( 1127 R.dimen.notification_small_icon_size)); 1128 } 1129 1130 @Test 1131 @Ignore // TODO: b/329389261 - Restore or delete testColors_ensureColors_dayMode_producesValidPalette()1132 public void testColors_ensureColors_dayMode_producesValidPalette() { 1133 Notification.Colors c = new Notification.Colors(); 1134 boolean colorized = false; 1135 boolean nightMode = false; 1136 resolveColorsInNightMode(nightMode, c, Color.BLUE, colorized); 1137 assertValid(c); 1138 } 1139 1140 @Test testColors_ensureColors_nightMode_producesValidPalette()1141 public void testColors_ensureColors_nightMode_producesValidPalette() { 1142 Notification.Colors c = new Notification.Colors(); 1143 boolean colorized = false; 1144 boolean nightMode = true; 1145 resolveColorsInNightMode(nightMode, c, Color.BLUE, colorized); 1146 assertValid(c); 1147 } 1148 1149 @Test testColors_ensureColors_colorized_producesValidPalette_default()1150 public void testColors_ensureColors_colorized_producesValidPalette_default() { 1151 validateColorizedPaletteForColor(Notification.COLOR_DEFAULT); 1152 } 1153 1154 @Test testColors_ensureColors_colorized_producesValidPalette_blue()1155 public void testColors_ensureColors_colorized_producesValidPalette_blue() { 1156 validateColorizedPaletteForColor(Color.BLUE); 1157 } 1158 1159 @Test 1160 @Ignore // TODO: b/329389261 - Restore or delete testColors_ensureColors_colorized_producesValidPalette_red()1161 public void testColors_ensureColors_colorized_producesValidPalette_red() { 1162 validateColorizedPaletteForColor(Color.RED); 1163 } 1164 1165 @Test 1166 @Ignore // b/347089000 - Restore or delete testColors_ensureColors_colorized_producesValidPalette_white()1167 public void testColors_ensureColors_colorized_producesValidPalette_white() { 1168 validateColorizedPaletteForColor(Color.WHITE); 1169 } 1170 1171 @Test testColors_ensureColors_colorized_producesValidPalette_black()1172 public void testColors_ensureColors_colorized_producesValidPalette_black() { 1173 validateColorizedPaletteForColor(Color.BLACK); 1174 } 1175 1176 @Test testIsMediaNotification_nullSession_returnsFalse()1177 public void testIsMediaNotification_nullSession_returnsFalse() { 1178 // Null media session 1179 Notification.MediaStyle mediaStyle = new Notification.MediaStyle(); 1180 Notification notification = new Notification.Builder(mContext, "test id") 1181 .setStyle(mediaStyle) 1182 .build(); 1183 assertFalse(notification.isMediaNotification()); 1184 } 1185 1186 @Test testIsMediaNotification_invalidSession_returnsFalse()1187 public void testIsMediaNotification_invalidSession_returnsFalse() { 1188 // Extra was set manually to an invalid type 1189 Bundle extras = new Bundle(); 1190 extras.putParcelable(EXTRA_MEDIA_SESSION, new Intent()); 1191 Notification.MediaStyle mediaStyle = new Notification.MediaStyle(); 1192 Notification notification = new Notification.Builder(mContext, "test id") 1193 .setStyle(mediaStyle) 1194 .addExtras(extras) 1195 .build(); 1196 assertFalse(notification.isMediaNotification()); 1197 } 1198 validateColorizedPaletteForColor(int rawColor)1199 public void validateColorizedPaletteForColor(int rawColor) { 1200 Notification.Colors cDay = new Notification.Colors(); 1201 Notification.Colors cNight = new Notification.Colors(); 1202 boolean colorized = true; 1203 1204 resolveColorsInNightMode(false, cDay, rawColor, colorized); 1205 resolveColorsInNightMode(true, cNight, rawColor, colorized); 1206 1207 if (rawColor != Notification.COLOR_DEFAULT) { 1208 assertEquals(rawColor, cDay.getBackgroundColor()); 1209 assertEquals(rawColor, cNight.getBackgroundColor()); 1210 } 1211 1212 assertValid(cDay); 1213 assertValid(cNight); 1214 1215 if (rawColor != Notification.COLOR_DEFAULT) { 1216 // When a color is provided, night mode should have no effect on the notification 1217 assertEquals(cDay.getBackgroundColor(), cNight.getBackgroundColor()); 1218 assertEquals(cDay.getPrimaryTextColor(), cNight.getPrimaryTextColor()); 1219 assertEquals(cDay.getSecondaryTextColor(), cNight.getSecondaryTextColor()); 1220 assertEquals(cDay.getPrimaryAccentColor(), cNight.getPrimaryAccentColor()); 1221 assertEquals(cDay.getSecondaryAccentColor(), cNight.getSecondaryAccentColor()); 1222 assertEquals(cDay.getTertiaryAccentColor(), cNight.getTertiaryAccentColor()); 1223 assertEquals(cDay.getOnTertiaryAccentTextColor(), 1224 cNight.getOnTertiaryAccentTextColor()); 1225 assertEquals(cDay.getTertiaryFixedDimAccentColor(), 1226 cNight.getTertiaryFixedDimAccentColor()); 1227 assertEquals(cDay.getOnTertiaryFixedAccentTextColor(), 1228 cNight.getOnTertiaryFixedAccentTextColor()); 1229 assertEquals(cDay.getProtectionColor(), cNight.getProtectionColor()); 1230 assertEquals(cDay.getContrastColor(), cNight.getContrastColor()); 1231 assertEquals(cDay.getRippleAlpha(), cNight.getRippleAlpha()); 1232 } 1233 } 1234 1235 @Test testRecoverBuilder_nullExtraPeopleList_noCrash()1236 public void testRecoverBuilder_nullExtraPeopleList_noCrash() { 1237 Bundle extras = new Bundle(); 1238 extras.putParcelable(EXTRA_PEOPLE_LIST, null); 1239 1240 Notification n = new Notification.Builder(mContext, "test") 1241 .setSmallIcon(0) 1242 .addExtras(extras) 1243 .build(); 1244 Bundle fakeTypes = new Bundle(); 1245 fakeTypes.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, new Bundle()); 1246 1247 Notification.Builder.recoverBuilder(mContext, n); 1248 1249 // no crash, good 1250 } 1251 1252 @Test testVisitUris_invalidExtra_noCrash()1253 public void testVisitUris_invalidExtra_noCrash() { 1254 Notification n = new Notification.Builder(mContext, "test") 1255 .setSmallIcon(0) 1256 .build(); 1257 Bundle fakeTypes = new Bundle(); 1258 fakeTypes.putParcelable(EXTRA_LARGE_ICON_BIG, new Bundle()); 1259 fakeTypes.putParcelable(EXTRA_PICTURE_ICON, new Bundle()); 1260 fakeTypes.putParcelable(EXTRA_MESSAGING_PERSON, new Bundle()); 1261 1262 Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class); 1263 n.visitUris(visitor); 1264 1265 // no crash, good 1266 } 1267 1268 @Test testRecoverBuilder_invalidExtra_noCrash()1269 public void testRecoverBuilder_invalidExtra_noCrash() { 1270 Notification n = new Notification.Builder(mContext, "test") 1271 .setSmallIcon(0) 1272 .build(); 1273 Bundle fakeTypes = new Bundle(); 1274 fakeTypes.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, new Bundle()); 1275 1276 Notification.Builder.recoverBuilder(mContext, n); 1277 1278 // no crash, good 1279 } 1280 1281 @Test testIsMediaNotification_invalidExtra_noCrash()1282 public void testIsMediaNotification_invalidExtra_noCrash() { 1283 Notification n = new Notification.Builder(mContext, "test") 1284 .setSmallIcon(0) 1285 .setStyle(new Notification.MediaStyle()) 1286 .build(); 1287 Bundle fakeTypes = new Bundle(); 1288 fakeTypes.putParcelable(EXTRA_MEDIA_SESSION, new Bundle()); 1289 1290 n.isMediaNotification(); 1291 1292 // no crash, good 1293 } 1294 1295 @Test testRestoreFromExtras_BigText_invalidExtra_noCrash()1296 public void testRestoreFromExtras_BigText_invalidExtra_noCrash() { 1297 Notification.Style style = new Notification.BigTextStyle(); 1298 Bundle fakeTypes = new Bundle(); 1299 fakeTypes.putParcelable(EXTRA_LARGE_ICON_BIG, new Bundle()); 1300 1301 1302 // no crash, good 1303 } 1304 1305 @Test testRestoreFromExtras_Messaging_invalidExtra_noCrash()1306 public void testRestoreFromExtras_Messaging_invalidExtra_noCrash() { 1307 Notification.Style style = new Notification.MessagingStyle("test"); 1308 Bundle fakeTypes = new Bundle(); 1309 fakeTypes.putParcelable(EXTRA_MESSAGING_PERSON, new Bundle()); 1310 fakeTypes.putParcelable(EXTRA_CONVERSATION_ICON, new Bundle()); 1311 1312 Notification n = new Notification.Builder(mContext, "test") 1313 .setStyle(style) 1314 .setExtras(fakeTypes) 1315 .build(); 1316 Notification.Builder.recoverBuilder(mContext, n); 1317 1318 // no crash, good 1319 } 1320 1321 @Test testRestoreFromExtras_Media_invalidExtra_noCrash()1322 public void testRestoreFromExtras_Media_invalidExtra_noCrash() { 1323 Notification.Style style = new Notification.MediaStyle(); 1324 Bundle fakeTypes = new Bundle(); 1325 fakeTypes.putParcelable(EXTRA_MEDIA_SESSION, new Bundle()); 1326 fakeTypes.putParcelable(EXTRA_MEDIA_REMOTE_INTENT, new Bundle()); 1327 1328 Notification n = new Notification.Builder(mContext, "test") 1329 .setStyle(style) 1330 .setExtras(fakeTypes) 1331 .build(); 1332 Notification.Builder.recoverBuilder(mContext, n); 1333 1334 // no crash, good 1335 } 1336 1337 @Test testRestoreFromExtras_Call_invalidExtra_noCrash()1338 public void testRestoreFromExtras_Call_invalidExtra_noCrash() { 1339 PendingIntent intent1 = PendingIntent.getActivity( 1340 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE); 1341 Notification.Style style = Notification.CallStyle.forIncomingCall( 1342 new Person.Builder().setName("hi").build(), intent1, intent1); 1343 1344 Bundle fakeTypes = new Bundle(); 1345 fakeTypes.putParcelable(EXTRA_CALL_PERSON, new Bundle()); 1346 fakeTypes.putParcelable(EXTRA_ANSWER_INTENT, new Bundle()); 1347 fakeTypes.putParcelable(EXTRA_DECLINE_INTENT, new Bundle()); 1348 fakeTypes.putParcelable(EXTRA_HANG_UP_INTENT, new Bundle()); 1349 1350 Notification n = new Notification.Builder(mContext, "test") 1351 .setStyle(style) 1352 .setExtras(fakeTypes) 1353 .build(); 1354 Notification.Builder.recoverBuilder(mContext, n); 1355 // no crash, good 1356 } 1357 1358 @Test testGetPictureIcon_invalidExtra_noCrash()1359 public void testGetPictureIcon_invalidExtra_noCrash() { 1360 Bundle fakeTypes = new Bundle(); 1361 fakeTypes.putParcelable(EXTRA_PICTURE, new Bundle()); 1362 fakeTypes.putParcelable(EXTRA_PICTURE_ICON, new Bundle()); 1363 1364 Notification.BigPictureStyle.getPictureIcon(fakeTypes); 1365 1366 // no crash, good 1367 } 1368 1369 @Test testWearableExtender_invalidExtra_noCrash()1370 public void testWearableExtender_invalidExtra_noCrash() { 1371 Notification n = new Notification.Builder(mContext, "test") 1372 .setSmallIcon(0) 1373 .setStyle(new Notification.MediaStyle()) 1374 .build(); 1375 Bundle fakeTypes = new Bundle(); 1376 fakeTypes.putParcelable(KEY_DISPLAY_INTENT, new Bundle()); 1377 fakeTypes.putParcelable(KEY_BACKGROUND, new Bundle()); 1378 Notification.WearableExtender extender = new Notification.WearableExtender(n); 1379 1380 // no crash, good 1381 } 1382 1383 @Test testCarExtender_invalidExtra_noCrash()1384 public void testCarExtender_invalidExtra_noCrash() { 1385 Notification n = new Notification.Builder(mContext, "test") 1386 .setSmallIcon(0) 1387 .setStyle(new Notification.MediaStyle()) 1388 .build(); 1389 Bundle fakeTypes = new Bundle(); 1390 fakeTypes.putParcelable(EXTRA_LARGE_ICON, new Bundle()); 1391 Notification.CarExtender extender = new Notification.CarExtender(n); 1392 1393 // no crash, good 1394 } 1395 1396 @Test testTvExtender_invalidExtra_noCrash()1397 public void testTvExtender_invalidExtra_noCrash() { 1398 Notification n = new Notification.Builder(mContext, "test") 1399 .setSmallIcon(0) 1400 .setStyle(new Notification.MediaStyle()) 1401 .build(); 1402 Bundle fakeTypes = new Bundle(); 1403 fakeTypes.putParcelable(EXTRA_CONTENT_INTENT, new Bundle()); 1404 fakeTypes.putParcelable(EXTRA_DELETE_INTENT, new Bundle()); 1405 Notification.TvExtender extender = new Notification.TvExtender(n); 1406 1407 // no crash, good 1408 } 1409 1410 @Test testGetUnreadConversationFromBundle_invalidExtra_noCrash()1411 public void testGetUnreadConversationFromBundle_invalidExtra_noCrash() { 1412 Bundle fakeTypes = new Bundle(); 1413 fakeTypes.putParcelable(KEY_ON_READ, new Bundle()); 1414 fakeTypes.putParcelable(KEY_ON_REPLY, new Bundle()); 1415 fakeTypes.putParcelable(KEY_REMOTE_INPUT, new Bundle()); 1416 1417 Notification n = new Notification.Builder(mContext, "test") 1418 .setExtras(fakeTypes) 1419 .build(); 1420 Notification.CarExtender extender = new Notification.CarExtender(n); 1421 1422 // no crash, good 1423 } 1424 1425 @Test testGetMessageFromBundle_invalidExtra_noCrash()1426 public void testGetMessageFromBundle_invalidExtra_noCrash() { 1427 Bundle fakeTypes = new Bundle(); 1428 fakeTypes.putParcelable(KEY_SENDER_PERSON, new Bundle()); 1429 fakeTypes.putString(KEY_TEXT, "text"); 1430 fakeTypes.putLong(KEY_TIMESTAMP, 0); 1431 fakeTypes.putParcelable(KEY_REMOTE_INPUT, new Bundle()); 1432 fakeTypes.putParcelable(KEY_DATA_URI, new Bundle()); 1433 Notification.MessagingStyle.Message.getMessageFromBundle(fakeTypes); 1434 1435 // no crash, good 1436 } 1437 1438 @Test testToBundle_getMessageFromBundle_returnsSameData()1439 public void testToBundle_getMessageFromBundle_returnsSameData() { 1440 Notification.MessagingStyle.Message message = 1441 new Notification.MessagingStyle.Message( 1442 "a", 100, new Person.Builder().setName("hi").build()); 1443 message.setData("text", Uri.parse("http://test/uri")); 1444 1445 Notification.MessagingStyle.Message convertedMessage = 1446 Notification.MessagingStyle.Message.getMessageFromBundle(message.toBundle()); 1447 1448 assertThat(convertedMessage).isNotNull(); 1449 assertThat(message.getText()).isEqualTo(convertedMessage.getText()); 1450 assertThat(message.getTimestamp()).isEqualTo(convertedMessage.getTimestamp()); 1451 assertThat(message.getExtras().size()).isEqualTo(convertedMessage.getExtras().size()); 1452 assertThat(message.getSender()).isEqualTo(convertedMessage.getSender()); 1453 assertThat(message.getSenderPerson()).isEqualTo(convertedMessage.getSenderPerson()); 1454 assertThat(message.getDataMimeType()).isEqualTo(convertedMessage.getDataMimeType()); 1455 assertThat(message.getDataUri()).isEqualTo(convertedMessage.getDataUri()); 1456 assertThat(message.isRemoteInputHistory()) 1457 .isEqualTo(convertedMessage.isRemoteInputHistory()); 1458 } 1459 1460 @Test testDoesNotStripsExtenders()1461 public void testDoesNotStripsExtenders() { 1462 Notification.Builder nb = new Notification.Builder(mContext, "channel"); 1463 nb.extend(new Notification.CarExtender().setColor(Color.RED)); 1464 nb.extend(new Notification.TvExtender().setChannelId("different channel")); 1465 nb.extend(new Notification.WearableExtender().setDismissalId("dismiss")); 1466 Notification before = nb.build(); 1467 Notification after = Notification.Builder.maybeCloneStrippedForDelivery(before); 1468 1469 assertTrue(before == after); 1470 1471 Assert.assertEquals("different channel", 1472 new Notification.TvExtender(before).getChannelId()); 1473 Assert.assertEquals(Color.RED, new Notification.CarExtender(before).getColor()); 1474 Assert.assertEquals("dismiss", new Notification.WearableExtender(before).getDismissalId()); 1475 } 1476 1477 @Test areIconsDifferent_sameSmallIcon_false()1478 public void areIconsDifferent_sameSmallIcon_false() { 1479 Notification n1 = new Notification.Builder(mContext, "test").setSmallIcon(1).build(); 1480 Notification n2 = new Notification.Builder(mContext, "test").setSmallIcon(1).build(); 1481 1482 assertThat(Notification.areIconsDifferent(n1, n2)).isFalse(); 1483 } 1484 1485 @Test areIconsDifferent_differentSmallIcon_true()1486 public void areIconsDifferent_differentSmallIcon_true() { 1487 Notification n1 = new Notification.Builder(mContext, "test").setSmallIcon(1).build(); 1488 Notification n2 = new Notification.Builder(mContext, "test").setSmallIcon(2).build(); 1489 1490 assertThat(Notification.areIconsDifferent(n1, n2)).isTrue(); 1491 } 1492 1493 @Test areIconsDifferent_sameLargeIcon_false()1494 public void areIconsDifferent_sameLargeIcon_false() { 1495 Icon icon1 = Icon.createWithContentUri("uri"); 1496 Icon icon2 = Icon.createWithContentUri("uri"); 1497 Notification n1 = new Notification.Builder(mContext, "test") 1498 .setSmallIcon(1).setLargeIcon(icon1).build(); 1499 Notification n2 = new Notification.Builder(mContext, "test") 1500 .setSmallIcon(1).setLargeIcon(icon2).build(); 1501 1502 // Note that this will almost certainly not happen for Icons created from Bitmaps, since 1503 // their serialization/deserialization of Bitmaps (app -> system_process) results in a 1504 // different getGenerationId() value. :( 1505 assertThat(Notification.areIconsDifferent(n1, n2)).isFalse(); 1506 } 1507 1508 @Test areIconsDifferent_differentLargeIcon_true()1509 public void areIconsDifferent_differentLargeIcon_true() { 1510 Icon icon1 = Icon.createWithContentUri("uri1"); 1511 Icon icon2 = Icon.createWithContentUri("uri2"); 1512 Notification n1 = new Notification.Builder(mContext, "test") 1513 .setSmallIcon(1).setLargeIcon(icon1).build(); 1514 Notification n2 = new Notification.Builder(mContext, "test") 1515 .setSmallIcon(2).setLargeIcon(icon2).build(); 1516 1517 assertThat(Notification.areIconsDifferent(n1, n2)).isTrue(); 1518 } 1519 1520 @Test areIconsDifferent_addedLargeIcon_true()1521 public void areIconsDifferent_addedLargeIcon_true() { 1522 Icon icon = Icon.createWithContentUri("uri"); 1523 Notification n1 = new Notification.Builder(mContext, "test").setSmallIcon(1).build(); 1524 Notification n2 = new Notification.Builder(mContext, "test") 1525 .setSmallIcon(2).setLargeIcon(icon).build(); 1526 1527 assertThat(Notification.areIconsDifferent(n1, n2)).isTrue(); 1528 } 1529 1530 @Test areIconsDifferent_removedLargeIcon_true()1531 public void areIconsDifferent_removedLargeIcon_true() { 1532 Icon icon = Icon.createWithContentUri("uri"); 1533 Notification n1 = new Notification.Builder(mContext, "test") 1534 .setSmallIcon(1).setLargeIcon(icon).build(); 1535 Notification n2 = new Notification.Builder(mContext, "test").setSmallIcon(2).build(); 1536 1537 assertThat(Notification.areIconsDifferent(n1, n2)).isTrue(); 1538 } 1539 1540 @Test testStyleChangeVisiblyDifferent_noStyles()1541 public void testStyleChangeVisiblyDifferent_noStyles() { 1542 Notification.Builder n1 = new Notification.Builder(mContext, "test"); 1543 Notification.Builder n2 = new Notification.Builder(mContext, "test"); 1544 1545 assertFalse(Notification.areStyledNotificationsVisiblyDifferent(n1, n2)); 1546 } 1547 1548 @Test testStyleChangeVisiblyDifferent_noStyleToStyle()1549 public void testStyleChangeVisiblyDifferent_noStyleToStyle() { 1550 Notification.Builder n1 = new Notification.Builder(mContext, "test"); 1551 Notification.Builder n2 = new Notification.Builder(mContext, "test") 1552 .setStyle(new Notification.BigTextStyle()); 1553 1554 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(n1, n2)); 1555 } 1556 1557 @Test testStyleChangeVisiblyDifferent_styleToNoStyle()1558 public void testStyleChangeVisiblyDifferent_styleToNoStyle() { 1559 Notification.Builder n2 = new Notification.Builder(mContext, "test"); 1560 Notification.Builder n1 = new Notification.Builder(mContext, "test") 1561 .setStyle(new Notification.BigTextStyle()); 1562 1563 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(n1, n2)); 1564 } 1565 1566 @Test testStyleChangeVisiblyDifferent_changeStyle()1567 public void testStyleChangeVisiblyDifferent_changeStyle() { 1568 Notification.Builder n1 = new Notification.Builder(mContext, "test") 1569 .setStyle(new Notification.InboxStyle()); 1570 Notification.Builder n2 = new Notification.Builder(mContext, "test") 1571 .setStyle(new Notification.BigTextStyle()); 1572 1573 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(n1, n2)); 1574 } 1575 1576 @Test testInboxTextChange()1577 public void testInboxTextChange() { 1578 Notification.Builder nInbox1 = new Notification.Builder(mContext, "test") 1579 .setStyle(new Notification.InboxStyle().addLine("a").addLine("b")); 1580 Notification.Builder nInbox2 = new Notification.Builder(mContext, "test") 1581 .setStyle(new Notification.InboxStyle().addLine("b").addLine("c")); 1582 1583 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(nInbox1, nInbox2)); 1584 } 1585 1586 @Test testBigTextTextChange()1587 public void testBigTextTextChange() { 1588 Notification.Builder nBigText1 = new Notification.Builder(mContext, "test") 1589 .setStyle(new Notification.BigTextStyle().bigText("something")); 1590 Notification.Builder nBigText2 = new Notification.Builder(mContext, "test") 1591 .setStyle(new Notification.BigTextStyle().bigText("else")); 1592 1593 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(nBigText1, nBigText2)); 1594 } 1595 1596 @Test testBigPictureChange()1597 public void testBigPictureChange() { 1598 Bitmap bitA = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888); 1599 Bitmap bitB = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888); 1600 1601 Notification.Builder nBigPic1 = new Notification.Builder(mContext, "test") 1602 .setStyle(new Notification.BigPictureStyle().bigPicture(bitA)); 1603 Notification.Builder nBigPic2 = new Notification.Builder(mContext, "test") 1604 .setStyle(new Notification.BigPictureStyle().bigPicture(bitB)); 1605 1606 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(nBigPic1, nBigPic2)); 1607 } 1608 1609 @Test testBigPictureStyle_setExtras_pictureIconNull_noPictureIconKey()1610 public void testBigPictureStyle_setExtras_pictureIconNull_noPictureIconKey() { 1611 Notification.BigPictureStyle bpStyle = new Notification.BigPictureStyle(); 1612 bpStyle.bigPicture((Bitmap) null); 1613 1614 Bundle extras = new Bundle(); 1615 bpStyle.addExtras(extras); 1616 1617 assertThat(extras.containsKey(EXTRA_PICTURE_ICON)).isFalse(); 1618 } 1619 1620 @Test testBigPictureStyle_setExtras_pictureIconNull_noPictureKey()1621 public void testBigPictureStyle_setExtras_pictureIconNull_noPictureKey() { 1622 Notification.BigPictureStyle bpStyle = new Notification.BigPictureStyle(); 1623 bpStyle.bigPicture((Bitmap) null); 1624 1625 Bundle extras = new Bundle(); 1626 bpStyle.addExtras(extras); 1627 1628 assertThat(extras.containsKey(EXTRA_PICTURE)).isFalse(); 1629 } 1630 1631 @Test testBigPictureStyle_setExtras_pictureIconTypeBitmap_pictureIconKeyNull()1632 public void testBigPictureStyle_setExtras_pictureIconTypeBitmap_pictureIconKeyNull() { 1633 Bitmap bitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888); 1634 Notification.BigPictureStyle bpStyle = new Notification.BigPictureStyle(); 1635 bpStyle.bigPicture(bitmap); 1636 1637 Bundle extras = new Bundle(); 1638 bpStyle.addExtras(extras); 1639 1640 assertThat(extras.containsKey(EXTRA_PICTURE_ICON)).isTrue(); 1641 final Parcelable pictureIcon = extras.getParcelable(EXTRA_PICTURE_ICON); 1642 assertThat(pictureIcon).isNull(); 1643 } 1644 1645 @Test testBigPictureStyle_setExtras_pictureIconTypeIcon_pictureKeyNull()1646 public void testBigPictureStyle_setExtras_pictureIconTypeIcon_pictureKeyNull() { 1647 Icon icon = Icon.createWithResource(mContext, R.drawable.btn_plus); 1648 Notification.BigPictureStyle bpStyle = new Notification.BigPictureStyle(); 1649 bpStyle.bigPicture(icon); 1650 1651 Bundle extras = new Bundle(); 1652 bpStyle.addExtras(extras); 1653 1654 assertThat(extras.containsKey(EXTRA_PICTURE)).isTrue(); 1655 final Parcelable picture = extras.getParcelable(EXTRA_PICTURE); 1656 assertThat(picture).isNull(); 1657 } 1658 1659 @Test testMessagingChange_text()1660 public void testMessagingChange_text() { 1661 Notification.Builder nM1 = new Notification.Builder(mContext, "test") 1662 .setStyle(new Notification.MessagingStyle("") 1663 .addMessage(new Notification.MessagingStyle.Message( 1664 "a", 100, new Person.Builder().setName("hi").build()))); 1665 Notification.Builder nM2 = new Notification.Builder(mContext, "test") 1666 .setStyle(new Notification.MessagingStyle("") 1667 .addMessage(new Notification.MessagingStyle.Message( 1668 "a", 100, new Person.Builder().setName("hi").build())) 1669 .addMessage(new Notification.MessagingStyle.Message( 1670 "b", 100, new Person.Builder().setName("hi").build())) 1671 ); 1672 1673 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(nM1, nM2)); 1674 } 1675 1676 @Test testMessagingChange_data()1677 public void testMessagingChange_data() { 1678 Notification.Builder nM1 = new Notification.Builder(mContext, "test") 1679 .setStyle(new Notification.MessagingStyle("") 1680 .addMessage(new Notification.MessagingStyle.Message( 1681 "a", 100, new Person.Builder().setName("hi").build()) 1682 .setData("text", mock(Uri.class)))); 1683 Notification.Builder nM2 = new Notification.Builder(mContext, "test") 1684 .setStyle(new Notification.MessagingStyle("") 1685 .addMessage(new Notification.MessagingStyle.Message( 1686 "a", 100, new Person.Builder().setName("hi").build()))); 1687 1688 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(nM1, nM2)); 1689 } 1690 1691 @Test testMessagingChange_sender()1692 public void testMessagingChange_sender() { 1693 Person a = new Person.Builder().setName("A").build(); 1694 Person b = new Person.Builder().setName("b").build(); 1695 Notification.Builder nM1 = new Notification.Builder(mContext, "test") 1696 .setStyle(new Notification.MessagingStyle("") 1697 .addMessage(new Notification.MessagingStyle.Message("a", 100, b))); 1698 Notification.Builder nM2 = new Notification.Builder(mContext, "test") 1699 .setStyle(new Notification.MessagingStyle("") 1700 .addMessage(new Notification.MessagingStyle.Message("a", 100, a))); 1701 1702 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(nM1, nM2)); 1703 } 1704 1705 @Test testMessagingChange_key()1706 public void testMessagingChange_key() { 1707 Person a = new Person.Builder().setName("hi").setKey("A").build(); 1708 Person b = new Person.Builder().setName("hi").setKey("b").build(); 1709 Notification.Builder nM1 = new Notification.Builder(mContext, "test") 1710 .setStyle(new Notification.MessagingStyle("") 1711 .addMessage(new Notification.MessagingStyle.Message("a", 100, a))); 1712 Notification.Builder nM2 = new Notification.Builder(mContext, "test") 1713 .setStyle(new Notification.MessagingStyle("") 1714 .addMessage(new Notification.MessagingStyle.Message("a", 100, b))); 1715 1716 assertTrue(Notification.areStyledNotificationsVisiblyDifferent(nM1, nM2)); 1717 } 1718 1719 @Test testMessagingChange_ignoreTimeChange()1720 public void testMessagingChange_ignoreTimeChange() { 1721 Notification.Builder nM1 = new Notification.Builder(mContext, "test") 1722 .setStyle(new Notification.MessagingStyle("") 1723 .addMessage(new Notification.MessagingStyle.Message( 1724 "a", 100, new Person.Builder().setName("hi").build()))); 1725 Notification.Builder nM2 = new Notification.Builder(mContext, "test") 1726 .setStyle(new Notification.MessagingStyle("") 1727 .addMessage(new Notification.MessagingStyle.Message( 1728 "a", 1000, new Person.Builder().setName("hi").build())) 1729 ); 1730 1731 assertFalse(Notification.areStyledNotificationsVisiblyDifferent(nM1, nM2)); 1732 } 1733 1734 @Test testRemoteViews_nullChange()1735 public void testRemoteViews_nullChange() { 1736 Notification.Builder n1 = new Notification.Builder(mContext, "test") 1737 .setContent(mock(RemoteViews.class)); 1738 Notification.Builder n2 = new Notification.Builder(mContext, "test"); 1739 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1740 1741 n1 = new Notification.Builder(mContext, "test"); 1742 n2 = new Notification.Builder(mContext, "test") 1743 .setContent(mock(RemoteViews.class)); 1744 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1745 1746 n1 = new Notification.Builder(mContext, "test") 1747 .setCustomBigContentView(mock(RemoteViews.class)); 1748 n2 = new Notification.Builder(mContext, "test"); 1749 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1750 1751 n1 = new Notification.Builder(mContext, "test"); 1752 n2 = new Notification.Builder(mContext, "test") 1753 .setCustomBigContentView(mock(RemoteViews.class)); 1754 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1755 1756 n1 = new Notification.Builder(mContext, "test"); 1757 n2 = new Notification.Builder(mContext, "test"); 1758 assertFalse(Notification.areRemoteViewsChanged(n1, n2)); 1759 } 1760 1761 @Test testRemoteViews_layoutChange()1762 public void testRemoteViews_layoutChange() { 1763 RemoteViews a = mock(RemoteViews.class); 1764 when(a.getLayoutId()).thenReturn(234); 1765 RemoteViews b = mock(RemoteViews.class); 1766 when(b.getLayoutId()).thenReturn(189); 1767 1768 Notification.Builder n1 = new Notification.Builder(mContext, "test").setContent(a); 1769 Notification.Builder n2 = new Notification.Builder(mContext, "test").setContent(b); 1770 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1771 1772 n1 = new Notification.Builder(mContext, "test").setCustomBigContentView(a); 1773 n2 = new Notification.Builder(mContext, "test").setCustomBigContentView(b); 1774 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1775 1776 n1 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(a); 1777 n2 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(b); 1778 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1779 } 1780 1781 @Test testRemoteViews_layoutSame()1782 public void testRemoteViews_layoutSame() { 1783 RemoteViews a = mock(RemoteViews.class); 1784 when(a.getLayoutId()).thenReturn(234); 1785 RemoteViews b = mock(RemoteViews.class); 1786 when(b.getLayoutId()).thenReturn(234); 1787 1788 Notification.Builder n1 = new Notification.Builder(mContext, "test").setContent(a); 1789 Notification.Builder n2 = new Notification.Builder(mContext, "test").setContent(b); 1790 assertFalse(Notification.areRemoteViewsChanged(n1, n2)); 1791 1792 n1 = new Notification.Builder(mContext, "test").setCustomBigContentView(a); 1793 n2 = new Notification.Builder(mContext, "test").setCustomBigContentView(b); 1794 assertFalse(Notification.areRemoteViewsChanged(n1, n2)); 1795 1796 n1 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(a); 1797 n2 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(b); 1798 assertFalse(Notification.areRemoteViewsChanged(n1, n2)); 1799 } 1800 1801 @Test testRemoteViews_sequenceChange()1802 public void testRemoteViews_sequenceChange() { 1803 RemoteViews a = mock(RemoteViews.class); 1804 when(a.getLayoutId()).thenReturn(234); 1805 when(a.getSequenceNumber()).thenReturn(1); 1806 RemoteViews b = mock(RemoteViews.class); 1807 when(b.getLayoutId()).thenReturn(234); 1808 when(b.getSequenceNumber()).thenReturn(2); 1809 1810 Notification.Builder n1 = new Notification.Builder(mContext, "test").setContent(a); 1811 Notification.Builder n2 = new Notification.Builder(mContext, "test").setContent(b); 1812 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1813 1814 n1 = new Notification.Builder(mContext, "test").setCustomBigContentView(a); 1815 n2 = new Notification.Builder(mContext, "test").setCustomBigContentView(b); 1816 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1817 1818 n1 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(a); 1819 n2 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(b); 1820 assertTrue(Notification.areRemoteViewsChanged(n1, n2)); 1821 } 1822 1823 @Test testRemoteViews_sequenceSame()1824 public void testRemoteViews_sequenceSame() { 1825 RemoteViews a = mock(RemoteViews.class); 1826 when(a.getLayoutId()).thenReturn(234); 1827 when(a.getSequenceNumber()).thenReturn(1); 1828 RemoteViews b = mock(RemoteViews.class); 1829 when(b.getLayoutId()).thenReturn(234); 1830 when(b.getSequenceNumber()).thenReturn(1); 1831 1832 Notification.Builder n1 = new Notification.Builder(mContext, "test").setContent(a); 1833 Notification.Builder n2 = new Notification.Builder(mContext, "test").setContent(b); 1834 assertFalse(Notification.areRemoteViewsChanged(n1, n2)); 1835 1836 n1 = new Notification.Builder(mContext, "test").setCustomBigContentView(a); 1837 n2 = new Notification.Builder(mContext, "test").setCustomBigContentView(b); 1838 assertFalse(Notification.areRemoteViewsChanged(n1, n2)); 1839 1840 n1 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(a); 1841 n2 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(b); 1842 assertFalse(Notification.areRemoteViewsChanged(n1, n2)); 1843 } 1844 1845 @Test testActionsDifferent_null()1846 public void testActionsDifferent_null() { 1847 Notification n1 = new Notification.Builder(mContext, "test") 1848 .build(); 1849 Notification n2 = new Notification.Builder(mContext, "test") 1850 .build(); 1851 1852 assertFalse(Notification.areActionsVisiblyDifferent(n1, n2)); 1853 } 1854 1855 @Test testActionsDifferentSame()1856 public void testActionsDifferentSame() { 1857 PendingIntent intent = PendingIntent.getActivity( 1858 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE);; 1859 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 1860 1861 Notification n1 = new Notification.Builder(mContext, "test") 1862 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent).build()) 1863 .build(); 1864 Notification n2 = new Notification.Builder(mContext, "test") 1865 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent).build()) 1866 .build(); 1867 1868 assertFalse(Notification.areActionsVisiblyDifferent(n1, n2)); 1869 } 1870 1871 @Test testActionsDifferentText()1872 public void testActionsDifferentText() { 1873 PendingIntent intent = PendingIntent.getActivity( 1874 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE);; 1875 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 1876 1877 Notification n1 = new Notification.Builder(mContext, "test") 1878 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent).build()) 1879 .build(); 1880 Notification n2 = new Notification.Builder(mContext, "test") 1881 .addAction(new Notification.Action.Builder(icon, "TEXT 2", intent).build()) 1882 .build(); 1883 1884 assertTrue(Notification.areActionsVisiblyDifferent(n1, n2)); 1885 } 1886 1887 @Test testActionsDifferentSpannables()1888 public void testActionsDifferentSpannables() { 1889 PendingIntent intent = PendingIntent.getActivity( 1890 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE);; 1891 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 1892 1893 Notification n1 = new Notification.Builder(mContext, "test") 1894 .addAction(new Notification.Action.Builder(icon, 1895 new SpannableStringBuilder().append("test1", 1896 new StyleSpan(Typeface.BOLD), 1897 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE), 1898 intent).build()) 1899 .build(); 1900 Notification n2 = new Notification.Builder(mContext, "test") 1901 .addAction(new Notification.Action.Builder(icon, "test1", intent).build()) 1902 .build(); 1903 1904 assertFalse(Notification.areActionsVisiblyDifferent(n1, n2)); 1905 } 1906 1907 @Test testActionsDifferentNumber()1908 public void testActionsDifferentNumber() { 1909 PendingIntent intent = PendingIntent.getActivity( 1910 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE); 1911 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 1912 1913 Notification n1 = new Notification.Builder(mContext, "test") 1914 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent).build()) 1915 .build(); 1916 Notification n2 = new Notification.Builder(mContext, "test") 1917 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent).build()) 1918 .addAction(new Notification.Action.Builder(icon, "TEXT 2", intent).build()) 1919 .build(); 1920 1921 assertTrue(Notification.areActionsVisiblyDifferent(n1, n2)); 1922 } 1923 1924 @Test testActionsDifferentIntent()1925 public void testActionsDifferentIntent() { 1926 PendingIntent intent1 = PendingIntent.getActivity( 1927 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE); 1928 PendingIntent intent2 = PendingIntent.getActivity( 1929 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE); 1930 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 1931 1932 Notification n1 = new Notification.Builder(mContext, "test") 1933 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent1).build()) 1934 .build(); 1935 Notification n2 = new Notification.Builder(mContext, "test") 1936 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent2).build()) 1937 .build(); 1938 1939 assertFalse(Notification.areActionsVisiblyDifferent(n1, n2)); 1940 } 1941 1942 @Test testActionsIgnoresRemoteInputs()1943 public void testActionsIgnoresRemoteInputs() { 1944 PendingIntent intent = PendingIntent.getActivity( 1945 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE);; 1946 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 1947 1948 Notification n1 = new Notification.Builder(mContext, "test") 1949 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent) 1950 .addRemoteInput(new RemoteInput.Builder("a") 1951 .setChoices(new CharSequence[] {"i", "m"}) 1952 .build()) 1953 .build()) 1954 .build(); 1955 Notification n2 = new Notification.Builder(mContext, "test") 1956 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent) 1957 .addRemoteInput(new RemoteInput.Builder("a") 1958 .setChoices(new CharSequence[] {"t", "m"}) 1959 .build()) 1960 .build()) 1961 .build(); 1962 1963 assertFalse(Notification.areActionsVisiblyDifferent(n1, n2)); 1964 } 1965 1966 @Test testFreeformRemoteInputActionPair_noRemoteInput()1967 public void testFreeformRemoteInputActionPair_noRemoteInput() { 1968 PendingIntent intent = PendingIntent.getActivity( 1969 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE);; 1970 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 1971 Notification notification = new Notification.Builder(mContext, "test") 1972 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent) 1973 .build()) 1974 .build(); 1975 Assert.assertNull(notification.findRemoteInputActionPair(false)); 1976 } 1977 1978 @Test testFreeformRemoteInputActionPair_hasRemoteInput()1979 public void testFreeformRemoteInputActionPair_hasRemoteInput() { 1980 PendingIntent intent = PendingIntent.getActivity( 1981 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE);; 1982 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 1983 1984 RemoteInput remoteInput = new RemoteInput.Builder("a").build(); 1985 1986 Notification.Action actionWithRemoteInput = 1987 new Notification.Action.Builder(icon, "TEXT 1", intent) 1988 .addRemoteInput(remoteInput) 1989 .addRemoteInput(remoteInput) 1990 .build(); 1991 1992 Notification.Action actionWithoutRemoteInput = 1993 new Notification.Action.Builder(icon, "TEXT 2", intent) 1994 .build(); 1995 1996 Notification notification = new Notification.Builder(mContext, "test") 1997 .addAction(actionWithoutRemoteInput) 1998 .addAction(actionWithRemoteInput) 1999 .build(); 2000 2001 Pair<RemoteInput, Notification.Action> remoteInputActionPair = 2002 notification.findRemoteInputActionPair(false); 2003 2004 assertNotNull(remoteInputActionPair); 2005 Assert.assertEquals(remoteInput, remoteInputActionPair.first); 2006 Assert.assertEquals(actionWithRemoteInput, remoteInputActionPair.second); 2007 } 2008 2009 @Test testFreeformRemoteInputActionPair_requestFreeform_noFreeformRemoteInput()2010 public void testFreeformRemoteInputActionPair_requestFreeform_noFreeformRemoteInput() { 2011 PendingIntent intent = PendingIntent.getActivity( 2012 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE);; 2013 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 2014 Notification notification = new Notification.Builder(mContext, "test") 2015 .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent) 2016 .addRemoteInput( 2017 new RemoteInput.Builder("a") 2018 .setAllowFreeFormInput(false).build()) 2019 .build()) 2020 .build(); 2021 Assert.assertNull(notification.findRemoteInputActionPair(true)); 2022 } 2023 2024 @Test testFreeformRemoteInputActionPair_requestFreeform_hasFreeformRemoteInput()2025 public void testFreeformRemoteInputActionPair_requestFreeform_hasFreeformRemoteInput() { 2026 PendingIntent intent = PendingIntent.getActivity( 2027 mContext, 0, new Intent("test1"), PendingIntent.FLAG_IMMUTABLE);; 2028 Icon icon = Icon.createWithBitmap(Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 2029 2030 RemoteInput remoteInput = 2031 new RemoteInput.Builder("a").setAllowFreeFormInput(false).build(); 2032 RemoteInput freeformRemoteInput = 2033 new RemoteInput.Builder("b").setAllowFreeFormInput(true).build(); 2034 2035 Notification.Action actionWithFreeformRemoteInput = 2036 new Notification.Action.Builder(icon, "TEXT 1", intent) 2037 .addRemoteInput(remoteInput) 2038 .addRemoteInput(freeformRemoteInput) 2039 .build(); 2040 2041 Notification.Action actionWithoutFreeformRemoteInput = 2042 new Notification.Action.Builder(icon, "TEXT 2", intent) 2043 .addRemoteInput(remoteInput) 2044 .build(); 2045 2046 Notification notification = new Notification.Builder(mContext, "test") 2047 .addAction(actionWithoutFreeformRemoteInput) 2048 .addAction(actionWithFreeformRemoteInput) 2049 .build(); 2050 2051 Pair<RemoteInput, Notification.Action> remoteInputActionPair = 2052 notification.findRemoteInputActionPair(true); 2053 2054 assertNotNull(remoteInputActionPair); 2055 Assert.assertEquals(freeformRemoteInput, remoteInputActionPair.first); 2056 Assert.assertEquals(actionWithFreeformRemoteInput, remoteInputActionPair.second); 2057 } 2058 2059 // Ensures that extras in a Notification Builder can be updated. 2060 @Test testExtras_cachedExtrasOverwrittenByUserProvided()2061 public void testExtras_cachedExtrasOverwrittenByUserProvided() { 2062 Bundle extras = new Bundle(); 2063 extras.putCharSequence(EXTRA_TITLE, "test title"); 2064 extras.putCharSequence(EXTRA_SUMMARY_TEXT, "summary text"); 2065 2066 Notification.Builder builder = new Notification.Builder(mContext, "test id") 2067 .addExtras(extras); 2068 2069 Notification notification = builder.build(); 2070 assertThat(notification.extras.getCharSequence(EXTRA_TITLE).toString()).isEqualTo( 2071 "test title"); 2072 assertThat(notification.extras.getCharSequence(EXTRA_SUMMARY_TEXT).toString()).isEqualTo( 2073 "summary text"); 2074 2075 extras.putCharSequence(EXTRA_TITLE, "new title"); 2076 builder.addExtras(extras); 2077 notification = builder.build(); 2078 assertThat(notification.extras.getCharSequence(EXTRA_TITLE).toString()).isEqualTo( 2079 "new title"); 2080 assertThat(notification.extras.getCharSequence(EXTRA_SUMMARY_TEXT).toString()).isEqualTo( 2081 "summary text"); 2082 } 2083 2084 // Ensures that extras in a Notification Builder can be updated by an extender. 2085 @Test testExtras_cachedExtrasOverwrittenByExtender()2086 public void testExtras_cachedExtrasOverwrittenByExtender() { 2087 Notification.CarExtender extender = new Notification.CarExtender().setColor(1234); 2088 2089 Notification notification = new Notification.Builder(mContext, "test id") 2090 .extend(extender).build(); 2091 2092 extender.setColor(5678); 2093 2094 Notification.Builder.recoverBuilder(mContext, notification).extend(extender).build(); 2095 2096 Notification.CarExtender recoveredExtender = new Notification.CarExtender(notification); 2097 assertThat(recoveredExtender.getColor()).isEqualTo(5678); 2098 } 2099 2100 @Test 2101 @CoreCompatChangeRule.EnableCompatChanges({Notification.WEARABLE_EXTENDER_BACKGROUND_BLOCKED}) wearableBackgroundBlockEnabled_wearableBackgroundSet_valueRemainsNull()2102 public void wearableBackgroundBlockEnabled_wearableBackgroundSet_valueRemainsNull() { 2103 Notification.WearableExtender extender = new Notification.WearableExtender(); 2104 Bitmap bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888); 2105 extender.setBackground(bitmap); 2106 Notification notif = 2107 new Notification.Builder(mContext, "test id") 2108 .setSmallIcon(1) 2109 .setContentTitle("test_title") 2110 .extend(extender) 2111 .build(); 2112 2113 Notification.WearableExtender result = new Notification.WearableExtender(notif); 2114 Assert.assertNull(result.getBackground()); 2115 } 2116 2117 @Test 2118 @CoreCompatChangeRule.DisableCompatChanges({Notification.WEARABLE_EXTENDER_BACKGROUND_BLOCKED}) wearableBackgroundBlockDisabled_wearableBackgroundSet_valueKeepsBitmap()2119 public void wearableBackgroundBlockDisabled_wearableBackgroundSet_valueKeepsBitmap() { 2120 Notification.WearableExtender extender = new Notification.WearableExtender(); 2121 Bitmap bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888); 2122 extender.setBackground(bitmap); 2123 Notification notif = 2124 new Notification.Builder(mContext, "test id") 2125 .setSmallIcon(1) 2126 .setContentTitle("test_title") 2127 .extend(extender) 2128 .build(); 2129 2130 Notification.WearableExtender result = new Notification.WearableExtender(notif); 2131 Bitmap resultBitmap = result.getBackground(); 2132 assertNotNull(resultBitmap); 2133 Assert.assertEquals(bitmap, resultBitmap); 2134 } 2135 2136 @Test testGetWhen_zero()2137 public void testGetWhen_zero() { 2138 Notification n = new Notification.Builder(mContext, "test") 2139 .setWhen(0) 2140 .build(); 2141 2142 mSetFlagsRule.disableFlags(Flags.FLAG_SORT_SECTION_BY_TIME); 2143 2144 assertThat(n.getWhen()).isEqualTo(0); 2145 2146 mSetFlagsRule.enableFlags(Flags.FLAG_SORT_SECTION_BY_TIME); 2147 2148 assertThat(n.getWhen()).isEqualTo(n.creationTime); 2149 } 2150 2151 @Test testGetWhen_devProvidedNonZero()2152 public void testGetWhen_devProvidedNonZero() { 2153 Notification n = new Notification.Builder(mContext, "test") 2154 .setWhen(9) 2155 .build(); 2156 2157 mSetFlagsRule.disableFlags(Flags.FLAG_SORT_SECTION_BY_TIME); 2158 2159 assertThat(n.getWhen()).isEqualTo(9); 2160 2161 mSetFlagsRule.enableFlags(Flags.FLAG_SORT_SECTION_BY_TIME); 2162 2163 assertThat(n.getWhen()).isEqualTo(9); 2164 } 2165 2166 @Test getNotificationStyleClass_forPlatformClassName_returnsPlatformClass()2167 public void getNotificationStyleClass_forPlatformClassName_returnsPlatformClass() { 2168 final List<Class<? extends Notification.Style>> platformStyleClasses = List.of( 2169 Notification.BigTextStyle.class, Notification.BigPictureStyle.class, 2170 Notification.MessagingStyle.class, Notification.CallStyle.class, 2171 Notification.InboxStyle.class, Notification.MediaStyle.class, 2172 Notification.DecoratedCustomViewStyle.class, 2173 Notification.DecoratedMediaCustomViewStyle.class 2174 ); 2175 2176 for (Class<? extends Notification.Style> platformStyleClass : platformStyleClasses) { 2177 assertThat(Notification.getNotificationStyleClass(platformStyleClass.getName())) 2178 .isEqualTo(platformStyleClass); 2179 } 2180 } 2181 2182 @Test getNotificationStyleClass_forNotPlatformClassName_returnsNull()2183 public void getNotificationStyleClass_forNotPlatformClassName_returnsNull() { 2184 assertThat(Notification.getNotificationStyleClass(NotAPlatformStyle.class.getName())) 2185 .isNull(); 2186 } 2187 2188 @Test 2189 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_richOngoingEnabled_platformClass()2190 public void progressStyle_richOngoingEnabled_platformClass() { 2191 assertThat( 2192 Notification.getNotificationStyleClass(Notification.ProgressStyle.class.getName())) 2193 .isEqualTo(Notification.ProgressStyle.class); 2194 } 2195 2196 @Test 2197 @DisableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_richOngoingDisabled_notPlatformClass()2198 public void progressStyle_richOngoingDisabled_notPlatformClass() { 2199 assertThat( 2200 Notification.getNotificationStyleClass(Notification.ProgressStyle.class.getName())) 2201 .isNull(); 2202 } 2203 2204 @Test 2205 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_onSegmentChange_visiblyDifferent()2206 public void progressStyle_onSegmentChange_visiblyDifferent() { 2207 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2208 .setStyle(new Notification.ProgressStyle() 2209 .addProgressSegment(new Notification.ProgressStyle.Segment(100)) 2210 .addProgressSegment(new Notification.ProgressStyle.Segment(50) 2211 .setColor(Color.RED))); 2212 2213 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2214 .setStyle(new Notification.ProgressStyle() 2215 .addProgressSegment(new Notification.ProgressStyle.Segment(100)) 2216 .addProgressSegment(new Notification.ProgressStyle.Segment(50) 2217 .setColor(Color.BLUE))); 2218 2219 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2220 .isTrue(); 2221 } 2222 2223 @Test 2224 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) indeterminateProgressStyle_onSegmentChange_visiblyNotDifferent()2225 public void indeterminateProgressStyle_onSegmentChange_visiblyNotDifferent() { 2226 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2227 .setStyle(new Notification.ProgressStyle().setProgressIndeterminate(true) 2228 .addProgressSegment(new Notification.ProgressStyle.Segment(100)) 2229 .addProgressSegment(new Notification.ProgressStyle.Segment(50) 2230 .setColor(Color.RED))); 2231 2232 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2233 .setStyle(new Notification.ProgressStyle().setProgressIndeterminate(true) 2234 .addProgressSegment(new Notification.ProgressStyle.Segment(100)) 2235 .addProgressSegment(new Notification.ProgressStyle.Segment(50) 2236 .setColor(Color.BLUE))); 2237 2238 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2239 .isFalse(); 2240 } 2241 2242 @Test 2243 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_onStartIconChange_visiblyDifferent()2244 public void progressStyle_onStartIconChange_visiblyDifferent() { 2245 final Icon icon1 = Icon.createWithBitmap(BitmapFactory.decodeResource( 2246 mContext.getResources(), com.android.frameworks.coretests.R.drawable.test128x96)); 2247 2248 final Icon icon2 = Icon.createWithBitmap( 2249 Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 2250 2251 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2252 .setStyle(new Notification.ProgressStyle().setProgressStartIcon(icon1)); 2253 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2254 .setStyle(new Notification.ProgressStyle().setProgressStartIcon(icon2)); 2255 2256 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2257 .isTrue(); 2258 } 2259 2260 @Test 2261 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_onEndIconChange_visiblyDifferent()2262 public void progressStyle_onEndIconChange_visiblyDifferent() { 2263 final Icon icon1 = Icon.createWithBitmap(BitmapFactory.decodeResource( 2264 mContext.getResources(), com.android.frameworks.coretests.R.drawable.test128x96)); 2265 2266 final Icon icon2 = Icon.createWithBitmap( 2267 Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 2268 2269 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2270 .setStyle(new Notification.ProgressStyle().setProgressEndIcon(icon1)); 2271 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2272 .setStyle(new Notification.ProgressStyle().setProgressEndIcon(icon2)); 2273 2274 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2275 .isTrue(); 2276 } 2277 2278 @Test 2279 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_onProgressChange_visiblyDifferent()2280 public void progressStyle_onProgressChange_visiblyDifferent() { 2281 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2282 .setStyle(new Notification.ProgressStyle().setProgress(20)); 2283 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2284 .setStyle(new Notification.ProgressStyle().setProgress(21)); 2285 2286 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2287 .isTrue(); 2288 } 2289 2290 @Test 2291 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) indeterminateProgressStyle_onProgressChange_visiblyNotDifferent()2292 public void indeterminateProgressStyle_onProgressChange_visiblyNotDifferent() { 2293 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2294 .setStyle(new Notification.ProgressStyle() 2295 .setProgressIndeterminate(true).setProgress(20)); 2296 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2297 .setStyle(new Notification.ProgressStyle() 2298 .setProgressIndeterminate(true).setProgress(21)); 2299 2300 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2301 .isFalse(); 2302 } 2303 2304 @Test 2305 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_onIsStyledByProgressChange_visiblyDifferent()2306 public void progressStyle_onIsStyledByProgressChange_visiblyDifferent() { 2307 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2308 .setStyle(new Notification.ProgressStyle().setStyledByProgress(true)); 2309 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2310 .setStyle(new Notification.ProgressStyle().setStyledByProgress(false)); 2311 2312 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2313 .isTrue(); 2314 } 2315 2316 @Test 2317 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) indeterminateProgressStyle_onIsStyledByProgressChange_visiblyNotDifferent()2318 public void indeterminateProgressStyle_onIsStyledByProgressChange_visiblyNotDifferent() { 2319 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2320 .setStyle(new Notification.ProgressStyle() 2321 .setProgressIndeterminate(true).setStyledByProgress(true)); 2322 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2323 .setStyle(new Notification.ProgressStyle() 2324 .setProgressIndeterminate(true).setStyledByProgress(false)); 2325 2326 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2327 .isFalse(); 2328 } 2329 2330 @Test 2331 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_onProgressPointChange_visiblyDifferent()2332 public void progressStyle_onProgressPointChange_visiblyDifferent() { 2333 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2334 .setStyle(new Notification.ProgressStyle() 2335 .addProgressPoint(new Notification.ProgressStyle.Point(10))); 2336 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2337 .setStyle(new Notification.ProgressStyle() 2338 .addProgressPoint(new Notification.ProgressStyle.Point(12))); 2339 2340 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2341 .isTrue(); 2342 } 2343 2344 @Test 2345 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) indeterminateProgressStyle_onProgressPointChange_visiblyNotDifferent()2346 public void indeterminateProgressStyle_onProgressPointChange_visiblyNotDifferent() { 2347 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2348 .setStyle(new Notification.ProgressStyle().setProgressIndeterminate(true) 2349 .addProgressPoint(new Notification.ProgressStyle.Point(10))); 2350 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2351 .setStyle(new Notification.ProgressStyle().setProgressIndeterminate(true) 2352 .addProgressPoint(new Notification.ProgressStyle.Point(12))); 2353 2354 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2355 .isFalse(); 2356 } 2357 2358 @Test 2359 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_onTrackerIconChange_visiblyDifferent()2360 public void progressStyle_onTrackerIconChange_visiblyDifferent() { 2361 final Icon icon1 = Icon.createWithBitmap(BitmapFactory.decodeResource( 2362 mContext.getResources(), com.android.frameworks.coretests.R.drawable.test128x96)); 2363 2364 final Icon icon2 = Icon.createWithBitmap( 2365 Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 2366 2367 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2368 .setStyle(new Notification.ProgressStyle().setProgressTrackerIcon(icon1)); 2369 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2370 .setStyle(new Notification.ProgressStyle().setProgressTrackerIcon(icon2)); 2371 2372 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2373 .isTrue(); 2374 } 2375 2376 @Test 2377 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) indeterminateProgressStyle_onTrackerIconChange_visiblyNotDifferent()2378 public void indeterminateProgressStyle_onTrackerIconChange_visiblyNotDifferent() { 2379 final Icon icon1 = Icon.createWithBitmap(BitmapFactory.decodeResource( 2380 mContext.getResources(), com.android.frameworks.coretests.R.drawable.test128x96)); 2381 2382 final Icon icon2 = Icon.createWithBitmap( 2383 Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888)); 2384 2385 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2386 .setStyle(new Notification.ProgressStyle().setProgressIndeterminate(true) 2387 .setProgressTrackerIcon(icon1)); 2388 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2389 .setStyle(new Notification.ProgressStyle() 2390 .setProgressIndeterminate(true).setProgressTrackerIcon(icon2)); 2391 2392 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2393 .isFalse(); 2394 } 2395 2396 @Test 2397 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_onIndeterminateChange_visiblyDifferent()2398 public void progressStyle_onIndeterminateChange_visiblyDifferent() { 2399 final Notification.Builder nProgress1 = new Notification.Builder(mContext, "test") 2400 .setStyle(new Notification.ProgressStyle().setProgressIndeterminate(true)); 2401 final Notification.Builder nProgress2 = new Notification.Builder(mContext, "test") 2402 .setStyle(new Notification.ProgressStyle().setProgressIndeterminate(false)); 2403 2404 assertThat(Notification.areStyledNotificationsVisiblyDifferent(nProgress1, nProgress2)) 2405 .isTrue(); 2406 } 2407 2408 @Test 2409 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_getProgressMax_default100()2410 public void progressStyle_getProgressMax_default100() { 2411 final Notification.ProgressStyle progressStyle = new Notification.ProgressStyle(); 2412 assertThat(progressStyle.getProgressMax()).isEqualTo(100); 2413 } 2414 2415 @Test 2416 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_getProgressMax_nooSegments_returnsDefault()2417 public void progressStyle_getProgressMax_nooSegments_returnsDefault() { 2418 final Notification.ProgressStyle progressStyle = new Notification.ProgressStyle(); 2419 progressStyle.setProgressSegments(Collections.emptyList()); 2420 assertThat(progressStyle.getProgressMax()).isEqualTo(100); 2421 } 2422 2423 @Test 2424 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_getProgressMax_returnsSumOfSegmentLength()2425 public void progressStyle_getProgressMax_returnsSumOfSegmentLength() { 2426 final Notification.ProgressStyle progressStyle = new Notification.ProgressStyle(); 2427 progressStyle 2428 .setProgressSegments(List.of(new Notification.ProgressStyle.Segment(15), 2429 new Notification.ProgressStyle.Segment(25))) 2430 .addProgressSegment(new Notification.ProgressStyle.Segment(10)) 2431 .addProgressSegment(new Notification.ProgressStyle.Segment(20)); 2432 2433 assertThat(progressStyle.getProgressMax()).isEqualTo(70); 2434 } 2435 2436 @Test 2437 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_getProgressMax_onSetProgressSegments_resets()2438 public void progressStyle_getProgressMax_onSetProgressSegments_resets() { 2439 final Notification.ProgressStyle progressStyle = new Notification.ProgressStyle(); 2440 progressStyle 2441 .addProgressSegment(new Notification.ProgressStyle.Segment(10)) 2442 .addProgressSegment(new Notification.ProgressStyle.Segment(20)) 2443 .setProgressSegments(List.of(new Notification.ProgressStyle.Segment(15), 2444 new Notification.ProgressStyle.Segment(25))); 2445 2446 assertThat(progressStyle.getProgressMax()).isEqualTo(40); 2447 } 2448 2449 @Test 2450 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_getProgressMax_onSegmentOverflow_returnsDefault()2451 public void progressStyle_getProgressMax_onSegmentOverflow_returnsDefault() { 2452 final Notification.ProgressStyle progressStyle = new Notification.ProgressStyle(); 2453 progressStyle 2454 .addProgressSegment(new Notification.ProgressStyle.Segment(Integer.MAX_VALUE)) 2455 .addProgressSegment(new Notification.ProgressStyle.Segment(10)); 2456 2457 assertThat(progressStyle.getProgressMax()).isEqualTo(100); 2458 } 2459 2460 @Test 2461 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_indeterminate_defaultValueFalse()2462 public void progressStyle_indeterminate_defaultValueFalse() { 2463 final Notification.ProgressStyle progressStyle1 = new Notification.ProgressStyle(); 2464 2465 assertThat(progressStyle1.isProgressIndeterminate()).isFalse(); 2466 } 2467 2468 @Test 2469 @EnableFlags(Flags.FLAG_API_RICH_ONGOING) progressStyle_styledByProgress_defaultValueTrue()2470 public void progressStyle_styledByProgress_defaultValueTrue() { 2471 final Notification.ProgressStyle progressStyle1 = new Notification.ProgressStyle(); 2472 2473 assertThat(progressStyle1.isStyledByProgress()).isTrue(); 2474 } assertValid(Notification.Colors c)2475 private void assertValid(Notification.Colors c) { 2476 // Assert that all colors are populated 2477 assertThat(c.getBackgroundColor()).isNotEqualTo(Notification.COLOR_INVALID); 2478 assertThat(c.getProtectionColor()).isNotEqualTo(Notification.COLOR_INVALID); 2479 assertThat(c.getPrimaryTextColor()).isNotEqualTo(Notification.COLOR_INVALID); 2480 assertThat(c.getSecondaryTextColor()).isNotEqualTo(Notification.COLOR_INVALID); 2481 assertThat(c.getPrimaryAccentColor()).isNotEqualTo(Notification.COLOR_INVALID); 2482 assertThat(c.getSecondaryAccentColor()).isNotEqualTo(Notification.COLOR_INVALID); 2483 assertThat(c.getTertiaryAccentColor()).isNotEqualTo(Notification.COLOR_INVALID); 2484 assertThat(c.getOnTertiaryAccentTextColor()).isNotEqualTo(Notification.COLOR_INVALID); 2485 assertThat(c.getTertiaryFixedDimAccentColor()).isNotEqualTo(Notification.COLOR_INVALID); 2486 assertThat(c.getOnTertiaryFixedAccentTextColor()).isNotEqualTo(Notification.COLOR_INVALID); 2487 assertThat(c.getErrorColor()).isNotEqualTo(Notification.COLOR_INVALID); 2488 assertThat(c.getContrastColor()).isNotEqualTo(Notification.COLOR_INVALID); 2489 assertThat(c.getRippleAlpha()).isAtLeast(0x00); 2490 assertThat(c.getRippleAlpha()).isAtMost(0xff); 2491 2492 // Assert that various colors have sufficient contrast with the background 2493 assertContrastIsAtLeast(c.getPrimaryTextColor(), c.getBackgroundColor(), 4.5); 2494 assertContrastIsAtLeast(c.getSecondaryTextColor(), c.getBackgroundColor(), 4.5); 2495 assertContrastIsAtLeast(c.getPrimaryAccentColor(), c.getBackgroundColor(), 4.5); 2496 assertContrastIsAtLeast(c.getErrorColor(), c.getBackgroundColor(), 4.5); 2497 assertContrastIsAtLeast(c.getContrastColor(), c.getBackgroundColor(), 4.5); 2498 2499 // These colors are only used for emphasized buttons; they do not need contrast 2500 assertContrastIsAtLeast(c.getSecondaryAccentColor(), c.getBackgroundColor(), 1); 2501 assertContrastIsAtLeast(c.getTertiaryAccentColor(), c.getBackgroundColor(), 1); 2502 assertContrastIsAtLeast(c.getTertiaryFixedDimAccentColor(), c.getBackgroundColor(), 1); 2503 2504 // The text that is used within the accent color DOES need to have contrast 2505 assertContrastIsAtLeast(c.getOnTertiaryAccentTextColor(), c.getTertiaryAccentColor(), 4.5); 2506 assertContrastIsAtLeast(c.getOnTertiaryFixedAccentTextColor(), 2507 c.getTertiaryFixedDimAccentColor(), 4.5); 2508 } 2509 resolveColorsInNightMode(boolean nightMode, Notification.Colors c, int rawColor, boolean colorized)2510 private void resolveColorsInNightMode(boolean nightMode, Notification.Colors c, int rawColor, 2511 boolean colorized) { 2512 runInNightMode(nightMode, 2513 () -> c.resolvePalette(mContext, rawColor, colorized, nightMode)); 2514 } 2515 runInNightMode(boolean nightMode, Runnable task)2516 private void runInNightMode(boolean nightMode, Runnable task) { 2517 final String initialNightMode = changeNightMode(nightMode); 2518 try { 2519 Configuration currentConfig = mContext.getResources().getConfiguration(); 2520 boolean isNightMode = (currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) 2521 == Configuration.UI_MODE_NIGHT_YES; 2522 assertEquals(nightMode, isNightMode); 2523 task.run(); 2524 } finally { 2525 runShellCommand("cmd uimode night " + initialNightMode); 2526 } 2527 } 2528 2529 2530 // Change the night mode and return the previous mode changeNightMode(boolean nightMode)2531 private String changeNightMode(boolean nightMode) { 2532 final String nightModeText = runShellCommand("cmd uimode night"); 2533 final String[] nightModeSplit = nightModeText.split(":"); 2534 if (nightModeSplit.length != 2) { 2535 fail("Failed to get initial night mode value from " + nightModeText); 2536 } 2537 String previousMode = nightModeSplit[1].trim(); 2538 runShellCommand("cmd uimode night " + (nightMode ? "yes" : "no")); 2539 return previousMode; 2540 } 2541 2542 /** 2543 * Writes an arbitrary {@link Parcelable} into a {@link Parcel} using its writeToParcel 2544 * method before reading it out again to check that it was sent properly. 2545 */ writeAndReadParcelable(T original)2546 private static <T extends Parcelable> T writeAndReadParcelable(T original) { 2547 Parcel p = Parcel.obtain(); 2548 p.writeParcelable(original, /* flags */ 0); 2549 p.setDataPosition(0); 2550 return p.readParcelable(/* classLoader */ null); 2551 } 2552 2553 /** 2554 * Creates a Notification.Action by mocking initial dependencies and then applying 2555 * transformations if they're defined. 2556 */ makeNotificationAction( @ullable Consumer<Notification.Action.Builder> transformation)2557 private Notification.Action makeNotificationAction( 2558 @Nullable Consumer<Notification.Action.Builder> transformation) { 2559 Notification.Action.Builder actionBuilder = 2560 new Notification.Action.Builder(null, "Test Title", null); 2561 if (transformation != null) { 2562 transformation.accept(actionBuilder); 2563 } 2564 return actionBuilder.build(); 2565 } 2566 2567 /** 2568 * Creates a PendingIntent with the given action. 2569 */ createPendingIntent(String action)2570 private PendingIntent createPendingIntent(String action) { 2571 return PendingIntent.getActivity(mContext, 0, 2572 new Intent(action).setPackage(mContext.getPackageName()), 2573 PendingIntent.FLAG_MUTABLE); 2574 } 2575 2576 private static class NotAPlatformStyle extends Notification.Style { 2577 @Override areNotificationsVisiblyDifferent(Notification.Style other)2578 public boolean areNotificationsVisiblyDifferent(Notification.Style other) { 2579 return false; 2580 } 2581 } 2582 } 2583