From 26fa46ade807a22a5329b9cbd9e455c9b7d7ae88 Mon Sep 17 00:00:00 2001 From: Ibrahim Yilmaz Date: Mon, 19 Aug 2024 13:46:37 +0000 Subject: [RONs] Implement Notification.EnRouteStyle Test: presubmit Bug: 359918677 Flag: android.app.api_rich_ongoing Change-Id: Iba8cf6539e888f0a2cb96b9e5e1b3a09284d286d --- core/java/android/app/Notification.java | 158 +++++++++++++++++++++ .../notification/NotificationVisitUrisTest.java | 2 +- 2 files changed, 159 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index db979a5dd30b..e99ba84276cd 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1577,6 +1577,22 @@ public class Notification implements Parcelable */ public static final String EXTRA_DECLINE_COLOR = "android.declineColor"; + /** + * {@link #extras} key: {@link Icon} of an image used as an overlay Icon on + * {@link Notification#mLargeIcon} for {@link EnRouteStyle} notifications. + * This extra is an {@code Icon}. + * @hide + */ + @FlaggedApi(Flags.FLAG_API_RICH_ONGOING) + public static final String EXTRA_ENROUTE_OVERLAY_ICON = "android.enrouteOverlayIcon"; + + /** + * {@link #extras} key: text used as a sub-text for the largeIcon of + * {@link EnRouteStyle} notification. This extra is a {@code CharSequence}. + * @hide + */ + @FlaggedApi(Flags.FLAG_API_RICH_ONGOING) + public static final String EXTRA_ENROUTE_LARGE_ICON_SUBTEXT = "android.enrouteLargeIconSubText"; /** * {@link #extras} key: whether the notification should be colorized as * supplied to {@link Builder#setColorized(boolean)}. @@ -3039,6 +3055,10 @@ public class Notification implements Parcelable visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON, Icon.class)); } + if (Flags.apiRichOngoing()) { + visitIconUri(visitor, extras.getParcelable(EXTRA_ENROUTE_OVERLAY_ICON, Icon.class)); + } + if (mBubbleMetadata != null) { visitIconUri(visitor, mBubbleMetadata.getIcon()); } @@ -10978,6 +10998,144 @@ public class Notification implements Parcelable } } + /** + * TODO(b/360827871): Make EnRouteStyle public. + * A style used to represent the progress of a real-world journey with a known destination. + * For example: + * + * + * The exact fields from {@link Notification} that are shown with this style may vary by + * the surface where this update appears, but the following fields are recommended: + * + * @hide + */ + @FlaggedApi(Flags.FLAG_API_RICH_ONGOING) + public static class EnRouteStyle extends Notification.Style { + + @Nullable + private Icon mOverlayIcon = null; + + @Nullable + private CharSequence mLargeIconSubText = null; + + public EnRouteStyle() { + } + + /** + * Returns the overlay icon to be displayed on {@link Notification#mLargeIcon}. + * @see EnRouteStyle#setOverlayIcon + */ + @Nullable + public Icon getOverlayIcon() { + return mOverlayIcon; + } + + /** + * Optional icon to be displayed on {@link Notification#mLargeIcon}. + * + * This image will be cropped to a circle and will obscure + * a semicircle of the right side of the large icon. + */ + @NonNull + public EnRouteStyle setOverlayIcon(@Nullable Icon overlayIcon) { + mOverlayIcon = overlayIcon; + return this; + } + + /** + * Returns the sub-text for {@link Notification#mLargeIcon}. + * @see EnRouteStyle#setLargeIconSubText + */ + @Nullable + public CharSequence getLargeIconSubText() { + return mLargeIconSubText; + } + + /** + * Optional text which generally related to + * the {@link Notification.Builder#setLargeIcon} or {@link #setOverlayIcon} or both. + */ + @NonNull + public EnRouteStyle setLargeIconSubText(@Nullable CharSequence largeIconSubText) { + mLargeIconSubText = stripStyling(largeIconSubText); + return this; + } + + /** + * @hide + */ + @Override + public boolean areNotificationsVisiblyDifferent(Style other) { + if (other == null || getClass() != other.getClass()) { + return true; + } + + final EnRouteStyle enRouteStyle = (EnRouteStyle) other; + return !Objects.equals(mOverlayIcon, enRouteStyle.mOverlayIcon) + || !Objects.equals(mLargeIconSubText, enRouteStyle.mLargeIconSubText); + } + + /** + * @hide + */ + @Override + public void addExtras(Bundle extras) { + super.addExtras(extras); + extras.putParcelable(EXTRA_ENROUTE_OVERLAY_ICON, mOverlayIcon); + extras.putCharSequence(EXTRA_ENROUTE_LARGE_ICON_SUBTEXT, mLargeIconSubText); + } + + /** + * @hide + */ + @Override + protected void restoreFromExtras(Bundle extras) { + super.restoreFromExtras(extras); + mOverlayIcon = extras.getParcelable(EXTRA_ENROUTE_OVERLAY_ICON, Icon.class); + mLargeIconSubText = extras.getCharSequence(EXTRA_ENROUTE_LARGE_ICON_SUBTEXT); + } + + /** + * @hide + */ + @Override + public void purgeResources() { + super.purgeResources(); + if (mOverlayIcon != null) { + mOverlayIcon.convertToAshmem(); + } + } + + /** + * @hide + */ + @Override + public void reduceImageSizes(Context context) { + super.reduceImageSizes(context); + if (mOverlayIcon != null) { + final Resources resources = context.getResources(); + final boolean isLowRam = ActivityManager.isLowRamDeviceStatic(); + + int rightIconSize = resources.getDimensionPixelSize(isLowRam + ? R.dimen.notification_right_icon_size_low_ram + : R.dimen.notification_right_icon_size); + mOverlayIcon.scaleDownIfNecessary(rightIconSize, rightIconSize); + } + } + } + /** * Notification style for custom views that are decorated by the system * diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java index 6a99731b77b3..411a6102f45a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java @@ -89,7 +89,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; @RunWith(AndroidJUnit4.class) -@EnableFlags(Flags.FLAG_VISIT_PERSON_URI) +@EnableFlags({Flags.FLAG_VISIT_PERSON_URI, Flags.FLAG_API_RICH_ONGOING}) public class NotificationVisitUrisTest extends UiServiceTestCase { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); -- cgit v1.2.3-59-g8ed1b