diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index c2ac9237ea587..d2338f8f13a8c 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -6603,22 +6603,33 @@ public class Notification implements Parcelable * Helper class for generating large-format notifications that include multiple back-and-forth * messages of varying types between any number of people. * - *
+ *

* If the platform does not provide large-format notifications, this method has no effect. The * user will always see the normal notification view. - *
- * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like - * so: + * + *

+ * If the app is targeting Android P and above, it is required to use the {@link Person} + * class in order to get an optimal rendering of the notification and its avatars. For + * conversations involving multiple people, the app should also make sure that it marks the + * conversation as a group with {@link #setGroupConversation(boolean)}. + * + *

+ * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior. + * Here's an example of how this may be used: *

      *
+     * Person user = new Person.Builder().setIcon(userIcon).setName(userName).build();
+     * MessagingStyle style = new MessagingStyle(user)
+     *      .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
+     *      .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
+     *      .setGroupConversation(hasMultiplePeople());
+     *
      * Notification noti = new Notification.Builder()
-     *     .setContentTitle("2 new messages wtih " + sender.toString())
+     *     .setContentTitle("2 new messages with " + sender.toString())
      *     .setContentText(subject)
      *     .setSmallIcon(R.drawable.new_message)
      *     .setLargeIcon(aBitmap)
-     *     .setStyle(new Notification.MessagingStyle(resources.getString(R.string.reply_name))
-     *         .addMessage(messages[0].getText(), messages[0].getTime(), messages[0].getSender())
-     *         .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getSender()))
+     *     .setStyle(style)
      *     .build();
      * 
*/ @@ -6828,7 +6839,9 @@ public class Notification implements Parcelable } /** - * Sets whether this conversation notification represents a group. + * Sets whether this conversation notification represents a group. If the app is targeting + * Android P, this is required if the app wants to display the largeIcon set with + * {@link Notification.Builder#setLargeIcon(Bitmap)}, otherwise it will be hidden. * * @param isGroupConversation {@code true} if the conversation represents a group, * {@code false} otherwise. @@ -7050,12 +7063,21 @@ public class Notification implements Parcelable CharSequence conversationTitle = !TextUtils.isEmpty(super.mBigContentTitle) ? super.mBigContentTitle : mConversationTitle; - boolean isOneToOne = TextUtils.isEmpty(conversationTitle); + boolean atLeastP = mBuilder.mContext.getApplicationInfo().targetSdkVersion + >= Build.VERSION_CODES.P; + boolean isOneToOne; CharSequence nameReplacement = null; - if (hasOnlyWhiteSpaceSenders()) { - isOneToOne = true; - nameReplacement = conversationTitle; - conversationTitle = null; + Icon avatarReplacement = null; + if (!atLeastP) { + isOneToOne = TextUtils.isEmpty(conversationTitle); + avatarReplacement = mBuilder.mN.mLargeIcon; + if (hasOnlyWhiteSpaceSenders()) { + isOneToOne = true; + nameReplacement = conversationTitle; + conversationTitle = null; + } + } else { + isOneToOne = !isGroupConversation(); } TemplateBindResult bindResult = new TemplateBindResult(); RemoteViews contentView = mBuilder.applyStandardTemplateWithActions( @@ -7078,8 +7100,8 @@ public class Notification implements Parcelable mBuilder.getSecondaryTextColor()); contentView.setBoolean(R.id.status_bar_latest_event_content, "setDisplayImagesAtEnd", displayImagesAtEnd); - contentView.setIcon(R.id.status_bar_latest_event_content, "setLargeIcon", - mBuilder.mN.mLargeIcon); + contentView.setIcon(R.id.status_bar_latest_event_content, "setAvatarReplacement", + avatarReplacement); contentView.setCharSequence(R.id.status_bar_latest_event_content, "setNameReplacement", nameReplacement); contentView.setBoolean(R.id.status_bar_latest_event_content, "setIsOneToOne", diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java index d468ce38709f7..03a734d8537e0 100644 --- a/core/java/com/android/internal/widget/MessagingLayout.java +++ b/core/java/com/android/internal/widget/MessagingLayout.java @@ -82,7 +82,7 @@ public class MessagingLayout extends FrameLayout { private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private Paint mTextPaint = new Paint(); private CharSequence mConversationTitle; - private Icon mLargeIcon; + private Icon mAvatarReplacement; private boolean mIsOneToOne; private ArrayList mAddedGroups = new ArrayList<>(); private Person mUser; @@ -125,8 +125,8 @@ public class MessagingLayout extends FrameLayout { } @RemotableViewMethod - public void setLargeIcon(Icon icon) { - mLargeIcon = icon; + public void setAvatarReplacement(Icon icon) { + mAvatarReplacement = icon; } @RemotableViewMethod @@ -228,7 +228,7 @@ public class MessagingLayout extends FrameLayout { boolean isOwnMessage = group.getSender() == mUser; CharSequence senderName = group.getSenderName(); if (!group.needsGeneratedAvatar() || TextUtils.isEmpty(senderName) - || (mIsOneToOne && mLargeIcon != null && !isOwnMessage)) { + || (mIsOneToOne && mAvatarReplacement != null && !isOwnMessage)) { continue; } String symbol = uniqueNames.get(senderName); @@ -246,8 +246,8 @@ public class MessagingLayout extends FrameLayout { if (!group.needsGeneratedAvatar() || TextUtils.isEmpty(senderName)) { continue; } - if (mIsOneToOne && mLargeIcon != null && group.getSender() != mUser) { - group.setAvatar(mLargeIcon); + if (mIsOneToOne && mAvatarReplacement != null && group.getSender() != mUser) { + group.setAvatar(mAvatarReplacement); } else { Icon cachedIcon = cachedAvatars.get(senderName); if (cachedIcon == null) {