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

Commit 42cef834 authored by Jeff DeCew's avatar Jeff DeCew Committed by Android (Google) Code Review
Browse files

Merge "Clean up MessagingLayout notifications" into sc-dev

parents ea924944 f82dcec6
Loading
Loading
Loading
Loading
+53 −30
Original line number Diff line number Diff line
@@ -5116,6 +5116,7 @@ public class Notification implements Parcelable
                TemplateBindResult result) {
            p.headerless(resId == getBaseLayoutResource()
                    || resId == getHeadsUpBaseLayoutResource()
                    || resId == getMessagingLayoutResource()
                    || resId == R.layout.notification_template_material_media);
            RemoteViews contentView = new BuilderRemoteViews(mContext.getApplicationInfo(), resId);

@@ -6641,6 +6642,10 @@ public class Notification implements Parcelable
            return R.layout.notification_template_material_messaging;
        }

        private int getBigMessagingLayoutResource() {
            return R.layout.notification_template_material_big_messaging;
        }

        private int getConversationLayoutResource() {
            return R.layout.notification_template_material_conversation;
        }
@@ -8151,12 +8156,14 @@ public class Notification implements Parcelable
         */
        @Override
        public RemoteViews makeContentView(boolean increasedHeight) {
            // All messaging templates contain the actions
            ArrayList<Action> originalActions = mBuilder.mActions;
            try {
                mBuilder.mActions = new ArrayList<>();
            RemoteViews remoteViews = makeMessagingView(true /* isCollapsed */,
                    false /* hideLargeIcon */);
                return makeMessagingView(StandardTemplateParams.VIEW_TYPE_NORMAL);
            } finally {
                mBuilder.mActions = originalActions;
            return remoteViews;
            }
        }

        /**
@@ -8242,18 +8249,24 @@ public class Notification implements Parcelable
         */
        @Override
        public RemoteViews makeBigContentView() {
            return makeMessagingView(false /* isCollapsed */, true /* hideLargeIcon */);
            return makeMessagingView(StandardTemplateParams.VIEW_TYPE_BIG);
        }

        /**
         * Create a messaging layout.
         *
         * @param isCollapsed Should this use the collapsed layout
         * @param hideRightIcons Should the reply affordance be shown at the end of the notification
         * @param viewType one of StandardTemplateParams.VIEW_TYPE_NORMAL, VIEW_TYPE_BIG,
         *                VIEW_TYPE_HEADS_UP
         * @return the created remoteView.
         */
        @NonNull
        private RemoteViews makeMessagingView(boolean isCollapsed, boolean hideRightIcons) {
        private RemoteViews makeMessagingView(int viewType) {
            boolean isCollapsed = viewType != StandardTemplateParams.VIEW_TYPE_BIG;
            boolean hideRightIcons = viewType != StandardTemplateParams.VIEW_TYPE_NORMAL;
            boolean isConversationLayout = mConversationType != CONVERSATION_TYPE_LEGACY;
            boolean isImportantConversation = mConversationType == CONVERSATION_TYPE_IMPORTANT;
            boolean isHeaderless = !isConversationLayout && isCollapsed;

            CharSequence conversationTitle = !TextUtils.isEmpty(super.mBigContentTitle)
                    ? super.mBigContentTitle
                    : mConversationTitle;
@@ -8271,23 +8284,26 @@ public class Notification implements Parcelable
            } else {
                isOneToOne = !isGroupConversation();
            }
            boolean isConversationLayout = mConversationType != CONVERSATION_TYPE_LEGACY;
            boolean isImportantConversation = mConversationType == CONVERSATION_TYPE_IMPORTANT;
            if (isHeaderless && isOneToOne && TextUtils.isEmpty(conversationTitle)) {
                conversationTitle = getOtherPersonName();
            }

            Icon largeIcon = mBuilder.mN.mLargeIcon;
            TemplateBindResult bindResult = new TemplateBindResult();
            StandardTemplateParams p = mBuilder.mParams.reset()
                    .viewType(isCollapsed ? StandardTemplateParams.VIEW_TYPE_NORMAL
                            : StandardTemplateParams.VIEW_TYPE_BIG)
                    .viewType(viewType)
                    .highlightExpander(isConversationLayout)
                    .hideProgress(true)
                    .title(conversationTitle)
                    .title(isHeaderless ? conversationTitle : null)
                    .text(null)
                    .hideLargeIcon(hideRightIcons || isOneToOne)
                    .headerTextSecondary(conversationTitle);
                    .headerTextSecondary(isHeaderless ? null : conversationTitle);
            RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
                    isConversationLayout
                            ? mBuilder.getConversationLayoutResource()
                            : mBuilder.getMessagingLayoutResource(),
                            : isCollapsed
                                    ? mBuilder.getMessagingLayoutResource()
                                    : mBuilder.getBigMessagingLayoutResource(),
                    p,
                    bindResult);
            if (isConversationLayout) {
@@ -8296,14 +8312,6 @@ public class Notification implements Parcelable
            }

            addExtras(mBuilder.mN.extras);
            if (!isConversationLayout) {
                // also update the end margin if there is an image
                // NOTE: This template doesn't support moving this icon to the left, so we don't
                // need to fully apply the MarginSet
                contentView.setViewLayoutMargin(R.id.notification_messaging, RemoteViews.MARGIN_END,
                        bindResult.mHeadingExtraMarginSet.getDpValue(),
                        TypedValue.COMPLEX_UNIT_DIP);
            }
            contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor",
                    mBuilder.getSmallIconColor(p));
            contentView.setInt(R.id.status_bar_latest_event_content, "setSenderTextColor",
@@ -8329,6 +8337,10 @@ public class Notification implements Parcelable
                contentView.setBoolean(R.id.status_bar_latest_event_content,
                        "setIsImportantConversation", isImportantConversation);
            }
            if (isHeaderless) {
                // Collapsed legacy messaging style has a 1-line limit.
                contentView.setInt(R.id.notification_messaging, "setMaxDisplayedLines", 1);
            }
            contentView.setIcon(R.id.status_bar_latest_event_content, "setLargeIcon",
                    largeIcon);
            contentView.setBundle(R.id.status_bar_latest_event_content, "setData",
@@ -8336,6 +8348,22 @@ public class Notification implements Parcelable
            return contentView;
        }

        private CharSequence getKey(Person person) {
            return person == null ? null
                    : person.getKey() == null ? person.getName() : person.getKey();
        }

        private CharSequence getOtherPersonName() {
            CharSequence userKey = getKey(mUser);
            for (int i = mMessages.size() - 1; i >= 0; i--) {
                Person sender = mMessages.get(i).getSenderPerson();
                if (sender != null && !TextUtils.equals(userKey, getKey(sender))) {
                    return sender.getName();
                }
            }
            return null;
        }

        private boolean hasOnlyWhiteSpaceSenders() {
            for (int i = 0; i < mMessages.size(); i++) {
                Message m = mMessages.get(i);
@@ -8370,12 +8398,7 @@ public class Notification implements Parcelable
         */
        @Override
        public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
            RemoteViews remoteViews = makeMessagingView(true /* isCollapsed */,
                    true /* hideLargeIcon */);
            if (mConversationType == CONVERSATION_TYPE_LEGACY) {
                remoteViews.setInt(R.id.notification_messaging, "setMaxDisplayedLines", 1);
            }
            return remoteViews;
            return makeMessagingView(StandardTemplateParams.VIEW_TYPE_HEADS_UP);
        }

        public static final class Message {
+3 −36
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ import com.android.internal.R;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

@@ -530,13 +531,7 @@ public class ConversationLayout extends FrameLayout
        mConversationText.setText(conversationText);
        // Update if the groups can hide the sender if they are first (applies to 1:1 conversations)
        // This needs to happen after all of the above o update all of the groups
        for (int i = mGroups.size() - 1; i >= 0; i--) {
            MessagingGroup messagingGroup = mGroups.get(i);
            CharSequence messageSender = messagingGroup.getSenderName();
            boolean canHide = mIsOneToOne
                    && TextUtils.equals(conversationText, messageSender);
            messagingGroup.setCanHideSenderIfFirst(canHide);
        }
        mPeopleHelper.maybeHideFirstSenderName(mGroups, mIsOneToOne, conversationText);
        updateAppName();
        updateIconPositionAndSize();
        updateImageMessages();
@@ -779,35 +774,7 @@ public class ConversationLayout extends FrameLayout

    private void updateTitleAndNamesDisplay() {
        // Map of unique names to their prefix
        ArrayMap<CharSequence, 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 < mGroups.size(); i++) {
            MessagingGroup group = mGroups.get(i);
            CharSequence senderName = group.getSenderName();
            if (!group.needsGeneratedAvatar() || TextUtils.isEmpty(senderName)) {
                continue;
            }
            if (!uniqueNames.containsKey(senderName)) {
                String charPrefix = mPeopleHelper.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, mPeopleHelper.findNameSplit(existingName));
                        uniqueCharacters.put(charPrefix, null);
                    }
                    uniqueNames.put(senderName, mPeopleHelper.findNameSplit(senderName));
                } else {
                    uniqueNames.put(senderName, charPrefix);
                    uniqueCharacters.put(charPrefix, senderName);
                }
            }
        }
        Map<CharSequence, String> uniqueNames = mPeopleHelper.mapUniqueNamesToPrefix(mGroups);

        // Now that we have the correct symbols, let's look what we have cached
        ArrayMap<CharSequence, Icon> cachedAvatars = new ArrayMap<>();
+28 −11
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.annotation.StyleRes;
import android.app.Person;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
@@ -109,7 +110,10 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
    private boolean mIsInConversation = true;
    private ViewGroup mMessagingIconContainer;
    private int mConversationContentStart;
    private int mNonConversationMarginEnd;
    private int mNonConversationContentStart;
    private int mNonConversationPaddingStart;
    private int mConversationAvatarSize;
    private int mNonConversationAvatarSize;
    private int mNotificationTextMarginTop;

    public MessagingGroup(@NonNull Context context) {
@@ -141,16 +145,21 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
        mMessagingIconContainer = findViewById(R.id.message_icon_container);
        mContentContainer = findViewById(R.id.messaging_group_content_container);
        mSendingSpinnerContainer = findViewById(R.id.messaging_group_sending_progress_container);
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        Resources res = getResources();
        DisplayMetrics displayMetrics = res.getDisplayMetrics();
        mDisplaySize.x = displayMetrics.widthPixels;
        mDisplaySize.y = displayMetrics.heightPixels;
        mSenderTextPaddingSingleLine = getResources().getDimensionPixelSize(
        mSenderTextPaddingSingleLine = res.getDimensionPixelSize(
                R.dimen.messaging_group_singleline_sender_padding_end);
        mConversationContentStart = getResources().getDimensionPixelSize(
                R.dimen.conversation_content_start);
        mNonConversationMarginEnd = getResources().getDimensionPixelSize(
                R.dimen.messaging_layout_margin_end);
        mNotificationTextMarginTop = getResources().getDimensionPixelSize(
        mConversationContentStart = res.getDimensionPixelSize(R.dimen.conversation_content_start);
        mNonConversationContentStart = res.getDimensionPixelSize(
                R.dimen.notification_content_margin_start);
        mNonConversationPaddingStart = res.getDimensionPixelSize(
                R.dimen.messaging_layout_icon_padding_start);
        mConversationAvatarSize = res.getDimensionPixelSize(R.dimen.messaging_avatar_size);
        mNonConversationAvatarSize = res.getDimensionPixelSize(
                R.dimen.notification_icon_circle_size);
        mNotificationTextMarginTop = res.getDimensionPixelSize(
                R.dimen.notification_text_margin_top);
    }

@@ -696,10 +705,18 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
            mIsInConversation = isInConversation;
            MarginLayoutParams layoutParams =
                    (MarginLayoutParams) mMessagingIconContainer.getLayoutParams();
            layoutParams.width = mIsInConversation ? mConversationContentStart
                    : ViewPager.LayoutParams.WRAP_CONTENT;
            layoutParams.setMarginEnd(mIsInConversation ? 0 : mNonConversationMarginEnd);
            layoutParams.width = mIsInConversation
                    ? mConversationContentStart
                    : mNonConversationContentStart;
            mMessagingIconContainer.setLayoutParams(layoutParams);
            int imagePaddingStart = isInConversation ? 0 : mNonConversationPaddingStart;
            mMessagingIconContainer.setPaddingRelative(imagePaddingStart, 0, 0, 0);

            ViewGroup.LayoutParams avatarLayoutParams = mAvatarView.getLayoutParams();
            int size = mIsInConversation ? mConversationAvatarSize : mNonConversationAvatarSize;
            avatarLayoutParams.height = size;
            avatarLayoutParams.width = size;
            mAvatarView.setLayoutParams(avatarLayoutParams);
        }
    }

+65 −87

File changed.

Preview size limit exceeded, changes collapsed.

+58 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.android.internal.widget.MessagingPropertyAnimator.ALPHA_OUT;

import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -28,12 +29,15 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Icon;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.view.View;

import com.android.internal.R;
import com.android.internal.graphics.ColorUtils;
import com.android.internal.util.ContrastColorUtil;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
@@ -176,4 +180,58 @@ public class PeopleHelper {
        }
        return findNamePrefix(name, "");
    }

    /**
     * Creates a mapping of the unique sender names in the groups to the string 1- or 2-character
     * prefix strings for the names, which are extracted as the initials, and should be used for
     * generating the avatar.  Senders not requiring a generated avatar, or with an empty name are
     * omitted.
     */
    public Map<CharSequence, String> mapUniqueNamesToPrefix(List<MessagingGroup> groups) {
        // Map of unique names to their prefix
        ArrayMap<CharSequence, 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++) {
            MessagingGroup group = groups.get(i);
            CharSequence senderName = group.getSenderName();
            if (!group.needsGeneratedAvatar() || TextUtils.isEmpty(senderName)) {
                continue;
            }
            if (!uniqueNames.containsKey(senderName)) {
                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, findNameSplit(existingName));
                        uniqueCharacters.put(charPrefix, null);
                    }
                    uniqueNames.put(senderName, findNameSplit(senderName));
                } else {
                    uniqueNames.put(senderName, charPrefix);
                    uniqueCharacters.put(charPrefix, senderName);
                }
            }
        }
        return 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)
     */
    public void maybeHideFirstSenderName(@NonNull List<MessagingGroup> groups,
            boolean isOneToOne, @Nullable CharSequence conversationTitle) {
        for (int i = groups.size() - 1; i >= 0; i--) {
            MessagingGroup messagingGroup = groups.get(i);
            CharSequence messageSender = messagingGroup.getSenderName();
            boolean canHide = isOneToOne && TextUtils.equals(conversationTitle, messageSender);
            messagingGroup.setCanHideSenderIfFirst(canHide);
        }
    }
}
Loading