diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 6e1d1cd2e4c9b..6bb35db6e712b 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -7917,6 +7917,8 @@ public class Notification implements Parcelable * @hide */ public MessagingStyle setShortcutIcon(@Nullable Icon conversationIcon) { + // TODO(b/228941516): This icon should be downscaled to avoid using too much memory, + // see reduceImageSizes. mShortcutIcon = conversationIcon; return this; } @@ -8423,6 +8425,51 @@ public class Notification implements Parcelable return makeMessagingView(StandardTemplateParams.VIEW_TYPE_HEADS_UP); } + /** + * @hide + */ + @Override + public void reduceImageSizes(Context context) { + super.reduceImageSizes(context); + Resources resources = context.getResources(); + boolean isLowRam = ActivityManager.isLowRamDeviceStatic(); + if (mShortcutIcon != null) { + int maxSize = resources.getDimensionPixelSize( + isLowRam ? R.dimen.notification_small_icon_size_low_ram + : R.dimen.notification_small_icon_size); + mShortcutIcon.scaleDownIfNecessary(maxSize, maxSize); + } + + int maxAvatarSize = resources.getDimensionPixelSize( + isLowRam ? R.dimen.notification_person_icon_max_size + : R.dimen.notification_person_icon_max_size_low_ram); + if (mUser != null && mUser.getIcon() != null) { + mUser.getIcon().scaleDownIfNecessary(maxAvatarSize, maxAvatarSize); + } + + reduceMessagesIconSizes(mMessages, maxAvatarSize); + reduceMessagesIconSizes(mHistoricMessages, maxAvatarSize); + } + + /** + * @hide + */ + private static void reduceMessagesIconSizes(@Nullable List messages, int maxSize) { + if (messages == null) { + return; + } + + for (Message message : messages) { + Person sender = message.mSender; + if (sender != null) { + Icon icon = sender.getIcon(); + if (icon != null) { + icon.scaleDownIfNecessary(maxSize, maxSize); + } + } + } + } + public static final class Message { /** @hide */ public static final String KEY_TEXT = "text"; diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 323c72667c33b..5a6ee22756e98 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -779,6 +779,10 @@ @dimen/notification_icon_circle_start 0.5 + + 144dp @dimen/notification_small_icon_size @@ -792,6 +796,10 @@ 294dp @dimen/notification_right_icon_size + + 96dp 256dp diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f177226c4ec33..0b13dde483110 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3603,6 +3603,7 @@ + @@ -3611,6 +3612,7 @@ + diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java index e6d23643e8c03..a5da4424f7225 100644 --- a/core/tests/coretests/src/android/app/NotificationTest.java +++ b/core/tests/coretests/src/android/app/NotificationTest.java @@ -520,6 +520,70 @@ public class NotificationTest { R.dimen.notification_small_icon_size)); } + @Test + public void testBuild_ensureMessagingUserIsNotTooBig_resizesIcon() { + Icon hugeIcon = Icon.createWithBitmap( + Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888)); + Icon hugeMessageAvatar = Icon.createWithBitmap( + Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888)); + Icon hugeHistoricMessageAvatar = Icon.createWithBitmap( + Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888)); + + Notification.MessagingStyle style = new Notification.MessagingStyle( + new Person.Builder().setIcon(hugeIcon).setName("A User").build()); + style.addMessage(new Notification.MessagingStyle.Message("A message", 123456, + new Person.Builder().setIcon(hugeMessageAvatar).setName("A Sender").build())); + style.addHistoricMessage(new Notification.MessagingStyle.Message("A message", 123456, + new Person.Builder().setIcon(hugeHistoricMessageAvatar).setName( + "A Historic Sender").build())); + Notification notification = new Notification.Builder(mContext, "Channel").setStyle( + style).build(); + + Bitmap personIcon = style.getUser().getIcon().getBitmap(); + assertThat(personIcon.getWidth()).isEqualTo( + mContext.getResources().getDimensionPixelSize( + R.dimen.notification_person_icon_max_size)); + assertThat(personIcon.getHeight()).isEqualTo( + mContext.getResources().getDimensionPixelSize( + R.dimen.notification_person_icon_max_size)); + + Bitmap avatarIcon = style.getMessages().get(0).getSenderPerson().getIcon().getBitmap(); + assertThat(avatarIcon.getWidth()).isEqualTo( + mContext.getResources().getDimensionPixelSize( + R.dimen.notification_person_icon_max_size)); + assertThat(avatarIcon.getHeight()).isEqualTo( + mContext.getResources().getDimensionPixelSize( + R.dimen.notification_person_icon_max_size)); + + Bitmap historicAvatarIcon = style.getHistoricMessages().get( + 0).getSenderPerson().getIcon().getBitmap(); + assertThat(historicAvatarIcon.getWidth()).isEqualTo( + mContext.getResources().getDimensionPixelSize( + R.dimen.notification_person_icon_max_size)); + assertThat(historicAvatarIcon.getHeight()).isEqualTo( + mContext.getResources().getDimensionPixelSize( + R.dimen.notification_person_icon_max_size)); + } + + @Test + public void testBuild_ensureMessagingShortcutIconIsNotTooBig_resizesIcon() { + Icon hugeIcon = Icon.createWithBitmap( + Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888)); + Notification.MessagingStyle style = new Notification.MessagingStyle( + new Person.Builder().setName("A User").build()).setShortcutIcon(hugeIcon); + + Notification notification = new Notification.Builder(mContext, "Channel").setStyle( + style).build(); + Bitmap shortcutIcon = style.getShortcutIcon().getBitmap(); + + assertThat(shortcutIcon.getWidth()).isEqualTo( + mContext.getResources().getDimensionPixelSize( + R.dimen.notification_small_icon_size)); + assertThat(shortcutIcon.getHeight()).isEqualTo( + mContext.getResources().getDimensionPixelSize( + R.dimen.notification_small_icon_size)); + } + @Test public void testColors_ensureColors_dayMode_producesValidPalette() { Notification.Colors c = new Notification.Colors();