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

Commit e6050a4a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "messaging_people"

* changes:
  Clipping to the top roundness when scrolling
  Made the notification side paddings consistent
  Changing messaging style and overall visual adoption
  Improved the MessagingStyle API with Person
  Added People to the Notification API
parents 6bdaf49c b0ee18f3
Loading
Loading
Loading
Loading
+32 −8
Original line number Diff line number Diff line
@@ -5206,15 +5206,17 @@ package android.app {
    field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
    field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
    field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
    field public static final java.lang.String EXTRA_MESSAGING_PERSON = "android.messagingUser";
    field public static final java.lang.String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
    field public static final java.lang.String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
    field public static final java.lang.String EXTRA_PEOPLE = "android.people";
    field public static final deprecated java.lang.String EXTRA_PEOPLE = "android.people";
    field public static final java.lang.String EXTRA_PEOPLE_LIST = "android.people.list";
    field public static final java.lang.String EXTRA_PICTURE = "android.picture";
    field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
    field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
    field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
    field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
    field public static final java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
    field public static final deprecated java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
    field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
    field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
    field public static final deprecated java.lang.String EXTRA_SMALL_ICON = "android.icon";
@@ -5354,7 +5356,8 @@ package android.app {
    method public deprecated android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent);
    method public android.app.Notification.Builder addAction(android.app.Notification.Action);
    method public android.app.Notification.Builder addExtras(android.os.Bundle);
    method public android.app.Notification.Builder addPerson(java.lang.String);
    method public deprecated android.app.Notification.Builder addPerson(java.lang.String);
    method public android.app.Notification.Builder addPerson(android.app.Notification.Person);
    method public android.app.Notification build();
    method public android.widget.RemoteViews createBigContentView();
    method public android.widget.RemoteViews createContentView();
@@ -5477,14 +5480,17 @@ package android.app {
  }
  public static class Notification.MessagingStyle extends android.app.Notification.Style {
    ctor public Notification.MessagingStyle(java.lang.CharSequence);
    ctor public deprecated Notification.MessagingStyle(java.lang.CharSequence);
    ctor public Notification.MessagingStyle(android.app.Notification.Person);
    method public android.app.Notification.MessagingStyle addHistoricMessage(android.app.Notification.MessagingStyle.Message);
    method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
    method public deprecated android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
    method public android.app.Notification.MessagingStyle addMessage(java.lang.CharSequence, long, android.app.Notification.Person);
    method public android.app.Notification.MessagingStyle addMessage(android.app.Notification.MessagingStyle.Message);
    method public java.lang.CharSequence getConversationTitle();
    method public java.util.List<android.app.Notification.MessagingStyle.Message> getHistoricMessages();
    method public java.util.List<android.app.Notification.MessagingStyle.Message> getMessages();
    method public java.lang.CharSequence getUserDisplayName();
    method public android.app.Notification.Person getUser();
    method public deprecated java.lang.CharSequence getUserDisplayName();
    method public boolean isGroupConversation();
    method public android.app.Notification.MessagingStyle setConversationTitle(java.lang.CharSequence);
    method public android.app.Notification.MessagingStyle setGroupConversation(boolean);
@@ -5492,16 +5498,34 @@ package android.app {
  }
  public static final class Notification.MessagingStyle.Message {
    ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
    ctor public deprecated Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
    ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, android.app.Notification.Person);
    method public java.lang.String getDataMimeType();
    method public android.net.Uri getDataUri();
    method public android.os.Bundle getExtras();
    method public java.lang.CharSequence getSender();
    method public deprecated java.lang.CharSequence getSender();
    method public android.app.Notification.Person getSenderPerson();
    method public java.lang.CharSequence getText();
    method public long getTimestamp();
    method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
  }
  public static final class Notification.Person implements android.os.Parcelable {
    ctor protected Notification.Person(android.os.Parcel);
    ctor public Notification.Person();
    method public int describeContents();
    method public android.graphics.drawable.Icon getIcon();
    method public java.lang.String getKey();
    method public java.lang.CharSequence getName();
    method public java.lang.String getUri();
    method public android.app.Notification.Person setIcon(android.graphics.drawable.Icon);
    method public android.app.Notification.Person setKey(java.lang.String);
    method public android.app.Notification.Person setName(java.lang.CharSequence);
    method public android.app.Notification.Person setUri(java.lang.String);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.app.Notification.Person> CREATOR;
  }
  public static abstract class Notification.Style {
    ctor public Notification.Style();
    method public android.app.Notification build();
+378 −34

File changed.

Preview size limit exceeded, changes collapsed.

+21 −0
Original line number Diff line number Diff line
@@ -890,6 +890,8 @@ public abstract class NotificationListenerService extends Service {
                createLegacyIconExtras(notification);
                // populate remote views for older clients.
                maybePopulateRemoteViews(notification);
                // populate people for older clients.
                maybePopulatePeople(notification);
            } catch (IllegalArgumentException e) {
                if (corruptNotifications == null) {
                    corruptNotifications = new ArrayList<>(N);
@@ -1178,6 +1180,25 @@ public abstract class NotificationListenerService extends Service {
        }
    }

    /**
     * Populates remote views for pre-P targeting apps.
     */
    private void maybePopulatePeople(Notification notification) {
        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P) {
            ArrayList<Notification.Person> people = notification.extras.getParcelableArrayList(
                    Notification.EXTRA_PEOPLE_LIST);
            if (people != null && people.isEmpty()) {
                int size = people.size();
                String[] peopleArray = new String[size];
                for (int i = 0; i < size; i++) {
                    Notification.Person person = people.get(i);
                    peopleArray[i] = person.resolveToLegacyUri();
                }
                notification.extras.putStringArray(Notification.EXTRA_PEOPLE, peopleArray);
            }
        }
    }

    /** @hide */
    protected class NotificationListenerWrapper extends INotificationListener.Stub {
        @Override
+26 −20
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ public class NotificationHeaderView extends ViewGroup {
    private final int mGravity;
    private View mAppName;
    private View mHeaderText;
    private View mSecondaryHeaderText;
    private OnClickListener mExpandClickListener;
    private HeaderTouchListener mTouchListener = new HeaderTouchListener();
    private ImageView mExpandButton;
@@ -58,7 +59,6 @@ public class NotificationHeaderView extends ViewGroup {
    private boolean mShowExpandButtonAtEnd;
    private boolean mShowWorkBadgeAtEnd;
    private Drawable mBackground;
    private int mHeaderBackgroundHeight;
    private boolean mEntireHeaderClickable;
    private boolean mExpandOnlyOnButton;
    private boolean mAcceptAllTouches;
@@ -68,7 +68,7 @@ public class NotificationHeaderView extends ViewGroup {
        @Override
        public void getOutline(View view, Outline outline) {
            if (mBackground != null) {
                outline.setRect(0, 0, getWidth(), mHeaderBackgroundHeight);
                outline.setRect(0, 0, getWidth(), getHeight());
                outline.setAlpha(1f);
            }
        }
@@ -91,8 +91,6 @@ public class NotificationHeaderView extends ViewGroup {
        Resources res = getResources();
        mChildMinWidth = res.getDimensionPixelSize(R.dimen.notification_header_shrink_min_width);
        mContentEndMargin = res.getDimensionPixelSize(R.dimen.notification_content_margin_end);
        mHeaderBackgroundHeight = res.getDimensionPixelSize(
                R.dimen.notification_header_background_height);
        mEntireHeaderClickable = res.getBoolean(R.bool.config_notificationHeaderClickableForExpand);

        int[] attrIds = { android.R.attr.gravity };
@@ -106,6 +104,7 @@ public class NotificationHeaderView extends ViewGroup {
        super.onFinishInflate();
        mAppName = findViewById(com.android.internal.R.id.app_name_text);
        mHeaderText = findViewById(com.android.internal.R.id.header_text);
        mSecondaryHeaderText = findViewById(com.android.internal.R.id.header_text_secondary);
        mExpandButton = findViewById(com.android.internal.R.id.expand_button);
        mIcon = findViewById(com.android.internal.R.id.icon);
        mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
@@ -137,24 +136,31 @@ public class NotificationHeaderView extends ViewGroup {
        if (totalWidth > givenWidth) {
            int overFlow = totalWidth - givenWidth;
            // We are overflowing, lets shrink the app name first
            final int appWidth = mAppName.getMeasuredWidth();
            if (overFlow > 0 && mAppName.getVisibility() != GONE && appWidth > mChildMinWidth) {
                int newSize = appWidth - Math.min(appWidth - mChildMinWidth, overFlow);
                int childWidthSpec = MeasureSpec.makeMeasureSpec(newSize, MeasureSpec.AT_MOST);
                mAppName.measure(childWidthSpec, wrapContentHeightSpec);
                overFlow -= appWidth - newSize;
            overFlow = shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mAppName,
                    mChildMinWidth);

            // still overflowing, we shrink the header text
            overFlow = shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mHeaderText, 0);

            // still overflowing, finally we shrink the secondary header text
            shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mSecondaryHeaderText,
                    0);
        }
        mTotalWidth = Math.min(totalWidth, givenWidth);
        setMeasuredDimension(givenWidth, givenHeight);
    }
            // still overflowing, finaly we shrink the header text
            if (overFlow > 0 && mHeaderText.getVisibility() != GONE) {

    private int shrinkViewForOverflow(int heightSpec, int overFlow, View targetView,
            int minimumWidth) {
        final int oldWidth = targetView.getMeasuredWidth();
        if (overFlow > 0 && targetView.getVisibility() != GONE && oldWidth > minimumWidth) {
            // we're still too big
                final int textWidth = mHeaderText.getMeasuredWidth();
                int newSize = Math.max(0, textWidth - overFlow);
            int newSize = Math.max(minimumWidth, oldWidth - overFlow);
            int childWidthSpec = MeasureSpec.makeMeasureSpec(newSize, MeasureSpec.AT_MOST);
                mHeaderText.measure(childWidthSpec, wrapContentHeightSpec);
            }
            targetView.measure(childWidthSpec, heightSpec);
            overFlow -= oldWidth - newSize;
        }
        mTotalWidth = Math.min(totalWidth, givenWidth);
        setMeasuredDimension(givenWidth, givenHeight);
        return overFlow;
    }

    @Override
@@ -228,7 +234,7 @@ public class NotificationHeaderView extends ViewGroup {
    @Override
    protected void onDraw(Canvas canvas) {
        if (mBackground != null) {
            mBackground.setBounds(0, 0, getWidth(), mHeaderBackgroundHeight);
            mBackground.setBounds(0, 0, getWidth(), getHeight());
            mBackground.draw(canvas);
        }
    }
+15 −35
Original line number Diff line number Diff line
@@ -20,17 +20,12 @@ import android.annotation.AttrRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StyleRes;
import android.app.Notification;
import android.content.Context;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Pools;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -41,7 +36,6 @@ import android.widget.LinearLayout;
import android.widget.RemoteViews;

import com.android.internal.R;
import com.android.internal.util.NotificationColorUtil;

import java.util.ArrayList;
import java.util.List;
@@ -60,12 +54,12 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
    private int mLayoutColor;
    private CharSequence mAvatarName = "";
    private Icon mAvatarIcon;
    private ColorFilter mMessageBackgroundFilter;
    private int mTextColor;
    private List<MessagingMessage> mMessages;
    private ArrayList<MessagingMessage> mAddedMessages = new ArrayList<>();
    private boolean mFirstLayout;
    private boolean mIsHidingAnimated;
    private boolean mNeedsGeneratedAvatar;

    public MessagingGroup(@NonNull Context context) {
        super(context);
@@ -94,27 +88,19 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
        mAvatarView = findViewById(R.id.message_icon);
    }

    public void setSender(CharSequence sender) {
        if (sender == null) {
            mAvatarView.setVisibility(GONE);
            mSenderName.setVisibility(GONE);
            setGravity(Gravity.END);
            mMessageBackgroundFilter = new PorterDuffColorFilter(mLayoutColor,
                    PorterDuff.Mode.SRC_ATOP);
            mTextColor = NotificationColorUtil.isColorLight(mLayoutColor) ? getNormalTextColor()
                    : Color.WHITE;
        } else {
            mSenderName.setText(sender);
    public void setSender(Notification.Person sender) {
        mSenderName.setText(sender.getName());
        mNeedsGeneratedAvatar = sender.getIcon() == null;
        if (!mNeedsGeneratedAvatar) {
            setAvatar(sender.getIcon());
        }
        mAvatarView.setVisibility(VISIBLE);
        mSenderName.setVisibility(VISIBLE);
            setGravity(Gravity.START);
            mMessageBackgroundFilter = null;
        mTextColor = getNormalTextColor();
    }
    }

    private int getNormalTextColor() {
        return mContext.getColor(R.color.notification_primary_text_color_light);
        return mContext.getColor(R.color.notification_secondary_text_color_light);
    }

    public void setAvatar(Icon icon) {
@@ -207,10 +193,6 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
        return mSenderName.getText();
    }

    public void setSenderVisible(boolean visible) {
        mSenderName.setVisibility(visible ? VISIBLE : GONE);
    }

    public static void dropCache() {
        sInstancePool = new Pools.SynchronizedPool<>(10);
    }
@@ -317,12 +299,6 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
                mMessageContainer.removeView(message);
                mMessageContainer.addView(message, messageIndex);
            }
            // Let's make sure the message color is correct
            Drawable targetDrawable = message.getBackground();

            if (targetDrawable != null) {
                targetDrawable.mutate().setColorFilter(mMessageBackgroundFilter);
            }
            message.setTextColor(mTextColor);
        }
        mMessages = group;
@@ -390,4 +366,8 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
    public MessagingLinearLayout getMessageContainer() {
        return mMessageContainer;
    }

    public boolean needsGeneratedAvatar() {
        return mNeedsGeneratedAvatar;
    }
}
Loading