Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 618ffc01 authored by Yining Liu's avatar Yining Liu Committed by Android (Google) Code Review
Browse files

Merge "Move hybrid notification view inflation to the background thread" into main

parents 8d486c7a c2405db6
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -5487,6 +5487,15 @@ public class Notification implements Parcelable
            return mColors;
        }
        /**
         * @param isHeader If the notification is a notification header
         * @return An instance of mColors after resolving the palette
         */
        private Colors getColors(boolean isHeader) {
            mColors.resolvePalette(mContext, mN.color, !isHeader && mN.isColorized(), mInNightMode);
            return mColors;
        }
        private void updateBackgroundColor(RemoteViews contentView,
                StandardTemplateParams p) {
            if (isBackgroundColorized(p)) {
@@ -6618,6 +6627,23 @@ public class Notification implements Parcelable
            return getColors(p).getContrastColor();
        }
        /**
         * Gets the foreground color of the small icon.  If the notification is colorized, this
         * is the primary text color, otherwise it's the contrast-adjusted app-provided color.
         * @hide
         */
        public @ColorInt int getSmallIconColor(boolean isHeader) {
            return getColors(/* isHeader = */ isHeader).getContrastColor();
        }
        /**
         * Gets the background color of the notification.
         * @hide
         */
        public @ColorInt int getBackgroundColor(boolean isHeader) {
            return getColors(/* isHeader = */ isHeader).getBackgroundColor();
        }
        /** @return the theme's accent color for colored UI elements. */
        private @ColorInt int getPrimaryAccentColor(StandardTemplateParams p) {
            return getColors(p).getPrimaryAccentColor();
@@ -8532,6 +8558,8 @@ public class Notification implements Parcelable
            boolean isImportantConversation = mConversationType == CONVERSATION_TYPE_IMPORTANT;
            boolean isHeaderless = !isConversationLayout && isCollapsed;
            //TODO (b/217799515): ensure mConversationTitle always returns the correct
            // conversationTitle, probably set mConversationTitle = conversationTitle after this
            CharSequence conversationTitle = !TextUtils.isEmpty(super.mBigContentTitle)
                    ? super.mBigContentTitle
                    : mConversationTitle;
+29 −8
Original line number Diff line number Diff line
@@ -105,6 +105,9 @@ public class ConversationLayout extends FrameLayout
    private int mConversationIconTopPaddingExpandedGroup;
    private int mConversationIconTopPadding;
    private int mExpandedGroupMessagePadding;
    // TODO (b/217799515) Currently, mConversationText shows the conversation title, the actual
    //  conversation text is inside of mMessagingLinearLayout, which is misleading, we should rename
    //  this to mConversationTitleView
    private TextView mConversationText;
    private View mConversationIconBadge;
    private CachingIconView mConversationIconBadgeBg;
@@ -125,6 +128,11 @@ public class ConversationLayout extends FrameLayout
    private int mNotificationBackgroundColor;
    private CharSequence mFallbackChatName;
    private CharSequence mFallbackGroupChatName;
    //TODO (b/217799515) Currently, Notification.MessagingStyle, ConversationLayout, and
    // HybridConversationNotificationView, each has their own definition of "ConversationTitle".
    // What make things worse is that the term of "ConversationTitle" often confuses with
    // "ConversationText".
    // We need to unify them or differentiate the namings.
    private CharSequence mConversationTitle;
    private int mMessageSpacingStandard;
    private int mMessageSpacingGroup;
@@ -297,13 +305,17 @@ public class ConversationLayout extends FrameLayout
        mNameReplacement = nameReplacement;
    }

    /** Sets this conversation as "important", adding some additional UI treatment. */
    /**
     * Sets this conversation as "important", adding some additional UI treatment.
     */
    @RemotableViewMethod
    public void setIsImportantConversation(boolean isImportantConversation) {
        setIsImportantConversation(isImportantConversation, false);
    }

    /** @hide **/
    /**
     * @hide
     **/
    public void setIsImportantConversation(boolean isImportantConversation, boolean animate) {
        mImportantConversation = isImportantConversation;
        mImportanceRingView.setVisibility(isImportantConversation && mIcon.getVisibility() != GONE
@@ -386,6 +398,7 @@ public class ConversationLayout extends FrameLayout

    /**
     * Set conversation data
     *
     * @param extras Bundle contains conversation data
     */
    @RemotableViewMethod(asyncImpl = "setDataAsync")
@@ -427,6 +440,7 @@ public class ConversationLayout extends FrameLayout
     * RemotableViewMethod's asyncImpl of {@link #setData(Bundle)}.
     * This should be called on a background thread, and returns a Runnable which is then must be
     * called on the main thread to complete the operation and set text.
     *
     * @param extras Bundle contains conversation data
     * @hide
     */
@@ -449,6 +463,7 @@ public class ConversationLayout extends FrameLayout

    /**
     * enable/disable precomputed text usage
     *
     * @hide
     */
    public void setPrecomputedTextEnabled(boolean precomputedTextEnabled) {
@@ -466,7 +481,9 @@ public class ConversationLayout extends FrameLayout
        mImageResolver = resolver;
    }

    /** @hide */
    /**
     * @hide
     */
    public void setUnreadCount(int unreadCount) {
        mExpandButton.setNumber(unreadCount);
    }
@@ -795,6 +812,10 @@ public class ConversationLayout extends FrameLayout
        mConversationTitle = conversationTitle != null ? conversationTitle.toString() : null;
    }

    // TODO (b/217799515) getConversationTitle is not consistent with setConversationTitle
    //  if you call getConversationTitle() immediately after setConversationTitle(), the result
    //  will not correctly reflect the new change without calling updateConversationLayout, for
    //  example.
    public CharSequence getConversationTitle() {
        return mConversationText.getText();
    }
+68 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import static com.android.internal.widget.MessagingPropertyAnimator.ALPHA_OUT;
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
import android.app.Person;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -221,6 +223,72 @@ public class PeopleHelper {
        return uniqueNames;
    }

    /**
     * A class that represents a map from unique sender names in the groups to the string 1- or
     * 2-character prefix strings for the names. This class uses the String value of the
     * CharSequence Names as the key.
     */
    public class NameToPrefixMap {
        Map<String, String> mMap;
        NameToPrefixMap(Map<String, String> map) {
            this.mMap = map;
        }

        /**
         * @param name the name
         * @return the prefix of the given name
         */
        public String getPrefix(CharSequence name) {
            return mMap.get(name.toString());
        }
    }

    /**
     * Same functionality as mapUniqueNamesToPrefix, but takes list-represented message groups as
     * the input. This method is better when inflating MessagingGroup from the UI thread is not
     * an option.
     * @param groups message groups represented by lists. A message group is some consecutive
     *               messages (>=3) from the same sender in a conversation.
     */
    public NameToPrefixMap mapUniqueNamesToPrefixWithGroupList(
            List<List<Notification.MessagingStyle.Message>> groups) {
        // Map of unique names to their prefix
        ArrayMap<String, String> uniqueNames = new ArrayMap<>();
        // Map of single-character string prefix to the only name which uses it, or null if multiple
        ArrayMap<String, CharSequence> uniqueCharacters = new ArrayMap<>();
        for (int i = 0; i < groups.size(); i++) {
            List<Notification.MessagingStyle.Message> group = groups.get(i);
            if (group.isEmpty()) continue;
            Person sender = group.get(0).getSenderPerson();
            if (sender == null) continue;
            CharSequence senderName = sender.getName();
            if (sender.getIcon() != null || TextUtils.isEmpty(senderName)) {
                continue;
            }
            String senderNameString = senderName.toString();
            if (!uniqueNames.containsKey(senderNameString)) {
                String charPrefix = findNamePrefix(senderName, null);
                if (charPrefix == null) {
                    continue;
                }
                if (uniqueCharacters.containsKey(charPrefix)) {
                    // this character was already used, lets make it more unique. We first need to
                    // resolve the existing character if it exists
                    CharSequence existingName = uniqueCharacters.get(charPrefix);
                    if (existingName != null) {
                        uniqueNames.put(existingName.toString(), findNameSplit(existingName));
                        uniqueCharacters.put(charPrefix, null);
                    }
                    uniqueNames.put(senderNameString, findNameSplit(senderName));
                } else {
                    uniqueNames.put(senderNameString, charPrefix);
                    uniqueCharacters.put(charPrefix, senderName);
                }
            }
        }
        return new NameToPrefixMap(uniqueNames);
    }

    /**
     * Update whether the groups can hide the sender if they are first
     * (happens only for 1:1 conversations where the given title matches the sender's name)
+3 −2
Original line number Diff line number Diff line
@@ -52,8 +52,8 @@ class ConversationNotificationProcessor @Inject constructor(
            entry: NotificationEntry,
            recoveredBuilder: Notification.Builder,
            logger: NotificationContentInflaterLogger
    ) {
        val messagingStyle = recoveredBuilder.style as? Notification.MessagingStyle ?: return
    ): Notification.MessagingStyle? {
        val messagingStyle = recoveredBuilder.style as? Notification.MessagingStyle ?: return null
        messagingStyle.conversationType =
                if (entry.ranking.channel.isImportantConversation)
                    Notification.MessagingStyle.CONVERSATION_TYPE_IMPORTANT
@@ -68,6 +68,7 @@ class ConversationNotificationProcessor @Inject constructor(
        }
        messagingStyle.unreadMessageCount =
                conversationNotificationManager.getUnreadCount(entry, recoveredBuilder)
        return messagingStyle
    }
}

+6 −2
Original line number Diff line number Diff line
@@ -362,8 +362,12 @@ public class PreparationCoordinator implements Coordinator {
    }

    NotifInflater.Params getInflaterParams(NotifUiAdjustment adjustment, String reason) {
        return new NotifInflater.Params(adjustment.isMinimized(), reason,
                adjustment.isSnoozeEnabled());
        return new NotifInflater.Params(
                adjustment.isMinimized(),
                reason,
                adjustment.isSnoozeEnabled(),
                adjustment.isChildInGroup()
        );
    }

    private void abortInflation(NotificationEntry entry, String reason) {
Loading