Merge changes Ifbf07b27,Ic9cd89e8 into sc-dev

* changes:
  Notification color overhaul.
  Implement the new visual style of the expand button
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 8167622..ec2336f 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -24,6 +24,7 @@
 
 import static java.util.Objects.requireNonNull;
 
+import android.annotation.AttrRes;
 import android.annotation.ColorInt;
 import android.annotation.ColorRes;
 import android.annotation.DimenRes;
@@ -98,6 +99,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.ColorUtils;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.ContrastColorUtil;
 
@@ -3649,11 +3651,6 @@
         private int mCachedContrastColorIsFor = COLOR_INVALID;
 
         /**
-         * A neutral color color that can be used for icons.
-         */
-        private int mNeutralColor = COLOR_INVALID;
-
-        /**
          * Caches an instance of StandardTemplateParams. Note that this may have been used before,
          * so make sure to call {@link StandardTemplateParams#reset()} before using it.
          */
@@ -3666,6 +3663,7 @@
         private boolean mRebuildStyledRemoteViews;
 
         private boolean mTintActionButtons;
+        private boolean mTintWithThemeAccent;
         private boolean mInNightMode;
 
         /**
@@ -3701,6 +3699,7 @@
             mContext = context;
             Resources res = mContext.getResources();
             mTintActionButtons = res.getBoolean(R.bool.config_tintNotificationActionButtons);
+            mTintWithThemeAccent = res.getBoolean(R.bool.config_tintNotificationsWithTheme);
 
             if (res.getBoolean(R.bool.config_enableNightMode)) {
                 Configuration currentConfig = res.getConfiguration();
@@ -4891,12 +4890,10 @@
         }
 
         private void bindPhishingAlertIcon(RemoteViews contentView, StandardTemplateParams p) {
-            // TODO(b/180334837): Get buy-in on this color, or make sure to give this the
-            //  accent color, while still accommodating the colorized state.
             contentView.setDrawableTint(
                     R.id.phishing_alert,
                     false /* targetBackground */,
-                    getPrimaryTextColor(p),
+                    getErrorColor(p),
                     PorterDuff.Mode.SRC_ATOP);
         }
 
@@ -4943,7 +4940,7 @@
             contentView.setDrawableTint(
                     R.id.alerted_icon,
                     false /* targetBackground */,
-                    getNeutralColor(p),
+                    getHeaderIconColor(p),
                     PorterDuff.Mode.SRC_ATOP);
         }
 
@@ -5057,10 +5054,9 @@
             return text;
         }
 
-        private void setTextViewColorPrimary(RemoteViews contentView, int id,
+        private void setTextViewColorPrimary(RemoteViews contentView, @IdRes int id,
                 StandardTemplateParams p) {
-            ensureColors(p);
-            contentView.setTextColor(id, mPrimaryTextColor);
+            contentView.setTextColor(id, getPrimaryTextColor(p));
         }
 
         private boolean hasForegroundColor() {
@@ -5068,53 +5064,34 @@
         }
 
         /**
-         * Return the primary text color using the existing template params
-         * @hide
-         */
-        @VisibleForTesting
-        public int getPrimaryTextColor() {
-            return getPrimaryTextColor(mParams);
-        }
-
-        /**
          * @param p the template params to inflate this with
          * @return the primary text color
          * @hide
          */
         @VisibleForTesting
-        public int getPrimaryTextColor(StandardTemplateParams p) {
+        public @ColorInt int getPrimaryTextColor(StandardTemplateParams p) {
             ensureColors(p);
             return mPrimaryTextColor;
         }
 
         /**
-         * Return the secondary text color using the existing template params
-         * @hide
-         */
-        @VisibleForTesting
-        public int getSecondaryTextColor() {
-            return getSecondaryTextColor(mParams);
-        }
-
-        /**
          * @param p the template params to inflate this with
          * @return the secondary text color
          * @hide
          */
         @VisibleForTesting
-        public int getSecondaryTextColor(StandardTemplateParams p) {
+        public @ColorInt int getSecondaryTextColor(StandardTemplateParams p) {
             ensureColors(p);
             return mSecondaryTextColor;
         }
 
-        private void setTextViewColorSecondary(RemoteViews contentView, int id,
+        private void setTextViewColorSecondary(RemoteViews contentView, @IdRes int id,
                 StandardTemplateParams p) {
-            ensureColors(p);
-            contentView.setTextColor(id, mSecondaryTextColor);
+            contentView.setTextColor(id, getSecondaryTextColor(p));
         }
 
         private void ensureColors(StandardTemplateParams p) {
-            int backgroundColor = getBackgroundColor(p);
+            int backgroundColor = getUnresolvedBackgroundColor(p);
             if (mPrimaryTextColor == COLOR_INVALID
                     || mSecondaryTextColor == COLOR_INVALID
                     || mTextColorsAreForBackground != backgroundColor) {
@@ -5217,7 +5194,7 @@
                         R.id.progress, ColorStateList.valueOf(mContext.getColor(
                                 R.color.notification_progress_background_color)));
                 if (getRawColor(p) != COLOR_DEFAULT) {
-                    int color = isColorized(p) ? getPrimaryTextColor(p) : resolveContrastColor(p);
+                    int color = getAccentColor(p);
                     ColorStateList colorStateList = ColorStateList.valueOf(color);
                     contentView.setProgressTintList(R.id.progress, colorStateList);
                     contentView.setProgressIndeterminateTintList(R.id.progress, colorStateList);
@@ -5326,11 +5303,14 @@
         }
 
         private void bindExpandButton(RemoteViews contentView, StandardTemplateParams p) {
-            int color = isColorized(p) ? getPrimaryTextColor(p) : getSecondaryTextColor(p);
-            contentView.setDrawableTint(R.id.expand_button, false, color,
-                    PorterDuff.Mode.SRC_ATOP);
-            contentView.setInt(R.id.expand_button, "setOriginalNotificationColor",
-                    color);
+            contentView.setInt(
+                    R.id.expand_button, "setDefaultTextColor", getPrimaryTextColor(p));
+            contentView.setInt(
+                    R.id.expand_button, "setDefaultPillColor", getProtectionColor(p));
+            contentView.setInt(
+                    R.id.expand_button, "setHighlightTextColor", getBackgroundColor(p));
+            contentView.setInt(
+                    R.id.expand_button, "setHighlightPillColor", getAccentColor(p));
         }
 
         private void bindHeaderChronometerAndTime(RemoteViews contentView,
@@ -5461,11 +5441,7 @@
             }
             contentView.setViewVisibility(R.id.app_name_text, View.VISIBLE);
             contentView.setTextViewText(R.id.app_name_text, loadHeaderAppName());
-            if (isColorized(p)) {
-                setTextViewColorPrimary(contentView, R.id.app_name_text, p);
-            } else {
-                contentView.setTextColor(R.id.app_name_text, getSecondaryTextColor(p));
-            }
+            contentView.setTextColor(R.id.app_name_text, getSecondaryTextColor(p));
             return true;
         }
 
@@ -5555,6 +5531,10 @@
 
             resetStandardTemplateWithActions(big);
             bindSnoozeAction(big, p);
+            // color the snooze and bubble actions with the theme color
+            ColorStateList actionColor = ColorStateList.valueOf(getStandardActionColor(p));
+            big.setColorStateList(R.id.snooze_button, "setImageTintList", actionColor);
+            big.setColorStateList(R.id.bubble_button, "setImageTintList", actionColor);
 
             boolean validRemoteInput = false;
 
@@ -5604,8 +5584,7 @@
                         showSpinner ? View.VISIBLE : View.GONE);
                 big.setProgressIndeterminateTintList(
                         R.id.notification_material_reply_progress,
-                        ColorStateList.valueOf(
-                                isColorized(p) ? getPrimaryTextColor(p) : resolveContrastColor(p)));
+                        ColorStateList.valueOf(getAccentColor(p)));
 
                 if (replyText.length > 1 && !TextUtils.isEmpty(replyText[1].getText())
                         && p.maxRemoteInputHistory > 1) {
@@ -6021,14 +6000,14 @@
                 // change the background bgColor
                 CharSequence title = action.title;
                 ColorStateList[] outResultColor = new ColorStateList[1];
-                int background = resolveBackgroundColor(p);
+                int background = getBackgroundColor(p);
                 if (isLegacy()) {
                     title = ContrastColorUtil.clearColorSpans(title);
                 } else {
                     title = ensureColorSpanContrast(title, background, outResultColor);
                 }
                 button.setTextViewText(R.id.action0, processTextSpans(title));
-                int textColor = getPrimaryTextColor(p);
+                final int textColor;
                 boolean hasColorOverride = outResultColor[0] != null;
                 if (hasColorOverride) {
                     // There's a span spanning the full text, let's take it and use it as the
@@ -6036,9 +6015,11 @@
                     background = outResultColor[0].getDefaultColor();
                     textColor = ContrastColorUtil.resolvePrimaryColor(mContext,
                             background, mInNightMode);
-                } else if (getRawColor(p) != COLOR_DEFAULT && !isColorized(p)
-                        && mTintActionButtons && !mInNightMode) {
-                    textColor = resolveContrastColor(p);
+                } else if (mTintActionButtons && !mInNightMode
+                        && getRawColor(p) != COLOR_DEFAULT && !isColorized(p)) {
+                    textColor = getAccentColor(p);
+                } else {
+                    textColor = getPrimaryTextColor(p);
                 }
                 button.setTextColor(R.id.action0, textColor);
                 // We only want about 20% alpha for the ripple
@@ -6056,11 +6037,7 @@
             } else {
                 button.setTextViewText(R.id.action0, processTextSpans(
                         processLegacyText(action.title)));
-                if (isColorized(p)) {
-                    setTextViewColorPrimary(button, R.id.action0, p);
-                } else if (getRawColor(p) != COLOR_DEFAULT && mTintActionButtons) {
-                    button.setTextColor(R.id.action0, resolveContrastColor(p));
-                }
+                button.setTextColor(R.id.action0, getStandardActionColor(p));
             }
             // CallStyle notifications add action buttons which don't actually exist in mActions,
             //  so we have to omit the index in that case.
@@ -6170,9 +6147,9 @@
         private void processSmallIconColor(Icon smallIcon, RemoteViews contentView,
                 StandardTemplateParams p) {
             boolean colorable = !isLegacy() || getColorUtil().isGrayscaleIcon(mContext, smallIcon);
-            int color = isColorized(p) ? getPrimaryTextColor(p) : resolveContrastColor(p);
+            int color = getSmallIconColor(p);
             contentView.setInt(R.id.icon, "setBackgroundColor",
-                    resolveBackgroundColor(p));
+                    getBackgroundColor(p));
             contentView.setInt(R.id.icon, "setOriginalIconColor",
                     colorable ? color : COLOR_INVALID);
         }
@@ -6187,7 +6164,7 @@
             if (largeIcon != null && isLegacy()
                     && getColorUtil().isGrayscaleIcon(mContext, largeIcon)) {
                 // resolve color will fall back to the default when legacy
-                int color = resolveContrastColor(p);
+                int color = getContrastColor(p);
                 contentView.setInt(R.id.icon, "setOriginalIconColor", color);
             }
         }
@@ -6198,14 +6175,94 @@
             }
         }
 
-        int resolveContrastColor(StandardTemplateParams p) {
+        /**
+         * Gets the standard action button color
+         */
+        private @ColorInt int getStandardActionColor(Notification.StandardTemplateParams p) {
+            return mTintActionButtons || isColorized(p) ? getAccentColor(p) : getNeutralColor(p);
+        }
+
+        /**
+         * Gets a neutral color that can be used for icons or similar that should not stand out.
+         */
+        private @ColorInt int getHeaderIconColor(StandardTemplateParams p) {
+            return isColorized(p) ? getSecondaryTextColor(p) : getNeutralColor(p);
+        }
+
+        /**
+         * 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.
+         */
+        private @ColorInt int getSmallIconColor(StandardTemplateParams p) {
+            return isColorized(p) ? getPrimaryTextColor(p) : getContrastColor(p);
+        }
+
+        /**
+         * Gets the accent color for colored UI elements.  If we're tinting with the theme
+         * accent, this is the theme accent color, otherwise this would be identical to
+         * {@link #getSmallIconColor(StandardTemplateParams)}.
+         */
+        private @ColorInt int getAccentColor(StandardTemplateParams p) {
+            if (isColorized(p)) {
+                return getPrimaryTextColor(p);
+            }
+            if (mTintWithThemeAccent) {
+                int color = obtainThemeColor(R.attr.colorAccent, COLOR_INVALID);
+                if (color != COLOR_INVALID) {
+                    return color;
+                }
+            }
+            return getContrastColor(p);
+        }
+
+        /**
+         * Gets the "surface protection" color from the theme, or a variant of the normal background
+         * color when colorized, or when not using theme color tints.
+         */
+        private @ColorInt int getProtectionColor(StandardTemplateParams p) {
+            if (mTintWithThemeAccent && !isColorized(p)) {
+                int color = obtainThemeColor(R.attr.colorBackgroundFloating, COLOR_INVALID);
+                if (color != COLOR_INVALID) {
+                    return color;
+                }
+            }
+            // TODO(b/181048615): What color should we use for the expander pill when colorized
+            return ColorUtils.blendARGB(getPrimaryTextColor(p), getBackgroundColor(p), 0.8f);
+        }
+
+        /**
+         * Gets the theme's error color, or the primary text color for colorized notifications.
+         */
+        private @ColorInt int getErrorColor(StandardTemplateParams p) {
+            if (!isColorized(p)) {
+                int color = obtainThemeColor(R.attr.colorError, COLOR_INVALID);
+                if (color != COLOR_INVALID) {
+                    return color;
+                }
+            }
+            return getPrimaryTextColor(p);
+        }
+
+        /**
+         * Gets the theme's background color
+         */
+        private @ColorInt int getDefaultBackgroundColor() {
+            return obtainThemeColor(R.attr.colorBackground,
+                    mInNightMode ? Color.BLACK : Color.WHITE);
+        }
+
+        /**
+         * Gets the contrast-adjusted version of the color provided by the app.
+         */
+        private @ColorInt int getContrastColor(StandardTemplateParams p) {
             int rawColor = getRawColor(p);
             if (mCachedContrastColorIsFor == rawColor && mCachedContrastColor != COLOR_INVALID) {
                 return mCachedContrastColor;
             }
 
             int color;
-            int background = obtainBackgroundColor();
+            // TODO: Maybe use getBackgroundColor(p) instead -- but doing so could break the cache
+            int background = getDefaultBackgroundColor();
             if (rawColor == COLOR_DEFAULT) {
                 ensureColors(p);
                 color = ContrastColorUtil.resolveDefaultColor(mContext, background, mInNightMode);
@@ -6224,28 +6281,29 @@
         /**
          * Return the raw color of this Notification, which doesn't necessarily satisfy contrast.
          *
-         * @see #resolveContrastColor(StandardTemplateParams) for the contrasted color
+         * @see #getContrastColor(StandardTemplateParams) for the contrasted color
          * @param p the template params to inflate this with
          */
-        private int getRawColor(StandardTemplateParams p) {
+        private @ColorInt int getRawColor(StandardTemplateParams p) {
             if (p.forceDefaultColor) {
                 return COLOR_DEFAULT;
             }
             return mN.color;
         }
 
-        int resolveNeutralColor() {
-            if (mNeutralColor != COLOR_INVALID) {
-                return mNeutralColor;
-            }
-            int background = obtainBackgroundColor();
-            mNeutralColor = ContrastColorUtil.resolveDefaultColor(mContext, background,
+        /**
+         * Gets a neutral palette color; this is a contrast-satisfied version of the default color.
+         * @param p the template params to inflate this with
+         */
+        private @ColorInt int getNeutralColor(StandardTemplateParams p) {
+            int background = getBackgroundColor(p);
+            int neutralColor = ContrastColorUtil.resolveDefaultColor(mContext, background,
                     mInNightMode);
-            if (Color.alpha(mNeutralColor) < 255) {
+            if (Color.alpha(neutralColor) < 255) {
                 // alpha doesn't go well for color filters, so let's blend it manually
-                mNeutralColor = ContrastColorUtil.compositeColors(mNeutralColor, background);
+                neutralColor = ContrastColorUtil.compositeColors(neutralColor, background);
             }
-            return mNeutralColor;
+            return neutralColor;
         }
 
         /**
@@ -6389,8 +6447,11 @@
             return mN;
         }
 
-        private @ColorInt int obtainBackgroundColor() {
-            int defaultColor = mInNightMode ? Color.BLACK : Color.WHITE;
+        /**
+         * Returns the color for the given Theme.DeviceDefault.DayNight attribute, or
+         * defValue if that could not be completed
+         */
+        private @ColorInt int obtainThemeColor(@AttrRes int attrRes, @ColorInt int defaultColor) {
             Resources.Theme theme = mContext.getTheme();
             if (theme == null) {
                 // Running unit tests with mocked context
@@ -6398,7 +6459,7 @@
             }
             theme = new ContextThemeWrapper(mContext, R.style.Theme_DeviceDefault_DayNight)
                     .getTheme();
-            TypedArray ta = theme.obtainStyledAttributes(new int[]{R.attr.colorBackground});
+            TypedArray ta = theme.obtainStyledAttributes(new int[]{attrRes});
             if (ta == null) {
                 return defaultColor;
             }
@@ -6517,7 +6578,11 @@
             return R.layout.notification_material_action_tombstone;
         }
 
-        private int getBackgroundColor(StandardTemplateParams p) {
+        /**
+         * Gets the background color, with {@link #COLOR_DEFAULT} being a valid return value,
+         * which must be resolved by the caller before being used.
+         */
+        private @ColorInt int getUnresolvedBackgroundColor(StandardTemplateParams p) {
             if (isColorized(p)) {
                 return mBackgroundColor != COLOR_INVALID ? mBackgroundColor : getRawColor(p);
             } else {
@@ -6526,33 +6591,17 @@
         }
 
         /**
-         * Gets a neutral color that can be used for icons or similar that should not stand out.
-         * @param p the template params to inflate this with
+         * Same as {@link #getUnresolvedBackgroundColor(StandardTemplateParams)} except that it
+         * also resolves the default color to the background.
          */
-        private int getNeutralColor(StandardTemplateParams p) {
-            if (isColorized(p)) {
-                return getSecondaryTextColor(p);
-            } else {
-                return resolveNeutralColor();
-            }
-        }
-
-        /**
-         * Same as getBackgroundColor but also resolved the default color to the background.
-         * @param p the template params to inflate this with
-         */
-        private int resolveBackgroundColor(StandardTemplateParams p) {
-            int backgroundColor = getBackgroundColor(p);
+        private @ColorInt int getBackgroundColor(StandardTemplateParams p) {
+            int backgroundColor = getUnresolvedBackgroundColor(p);
             if (backgroundColor == COLOR_DEFAULT) {
-                backgroundColor = obtainBackgroundColor();
+                backgroundColor = getDefaultBackgroundColor();
             }
             return backgroundColor;
         }
 
-        private boolean shouldTintActionButtons() {
-            return mTintActionButtons;
-        }
-
         private boolean textColorsNeedInversion() {
             if (mStyle == null || !MediaStyle.class.equals(mStyle.getClass())) {
                 return false;
@@ -6570,7 +6619,7 @@
          *
          * @hide
          */
-        public void setColorPalette(int backgroundColor, int foregroundColor) {
+        public void setColorPalette(@ColorInt int backgroundColor, @ColorInt int foregroundColor) {
             mBackgroundColor = backgroundColor;
             mForegroundColor = foregroundColor;
             mTextColorsAreForBackground = COLOR_INVALID;
@@ -8200,16 +8249,14 @@
                         TypedValue.COMPLEX_UNIT_DIP);
             }
             contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor",
-                    mBuilder.isColorized(p)
-                            ? mBuilder.getPrimaryTextColor(p)
-                            : mBuilder.resolveContrastColor(p));
+                    mBuilder.getSmallIconColor(p));
             contentView.setInt(R.id.status_bar_latest_event_content, "setSenderTextColor",
                     mBuilder.getPrimaryTextColor(p));
             contentView.setInt(R.id.status_bar_latest_event_content, "setMessageTextColor",
                     mBuilder.getSecondaryTextColor(p));
             contentView.setInt(R.id.status_bar_latest_event_content,
                     "setNotificationBackgroundColor",
-                    mBuilder.resolveBackgroundColor(p));
+                    mBuilder.getBackgroundColor(p));
             contentView.setBoolean(R.id.status_bar_latest_event_content, "setIsCollapsed",
                     isCollapsed);
             contentView.setIcon(R.id.status_bar_latest_event_content, "setAvatarReplacement",
@@ -8964,14 +9011,7 @@
 
             // If the action buttons should not be tinted, then just use the default
             // notification color. Otherwise, just use the passed-in color.
-            Resources resources = mBuilder.mContext.getResources();
-            Configuration currentConfig = resources.getConfiguration();
-            boolean inNightMode = (currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
-                    == Configuration.UI_MODE_NIGHT_YES;
-            int tintColor = mBuilder.shouldTintActionButtons() || mBuilder.isColorized(p)
-                    ? getActionColor(p)
-                    : ContrastColorUtil.resolveColor(mBuilder.mContext,
-                            Notification.COLOR_DEFAULT, inNightMode);
+            int tintColor = mBuilder.getStandardActionColor(p);
 
             container.setDrawableTint(buttonId, false, tintColor,
                     PorterDuff.Mode.SRC_ATOP);
@@ -9027,11 +9067,6 @@
             return view;
         }
 
-        private int getActionColor(StandardTemplateParams p) {
-            return mBuilder.isColorized(p) ? mBuilder.getPrimaryTextColor(p)
-                    : mBuilder.resolveContrastColor(p);
-        }
-
         private RemoteViews makeMediaBigContentView() {
             final int actionCount = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
             // Dont add an expanded view if there is no more content to be revealed
@@ -9373,7 +9408,6 @@
                     .hideLargeIcon(true)
                     .text(text)
                     .summaryText(mBuilder.processLegacyText(mVerificationText));
-            // TODO(b/179178086): hide the snooze button
             RemoteViews contentView = mBuilder.applyStandardTemplate(
                     mBuilder.getCallLayoutResource(), p, null /* result */);
 
@@ -9390,11 +9424,9 @@
 
             // Bind some custom CallLayout properties
             contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor",
-                    mBuilder.isColorized(p)
-                            ? mBuilder.getPrimaryTextColor(p)
-                            : mBuilder.resolveContrastColor(p));
+                    mBuilder.getSmallIconColor(p));
             contentView.setInt(R.id.status_bar_latest_event_content,
-                    "setNotificationBackgroundColor", mBuilder.resolveBackgroundColor(p));
+                    "setNotificationBackgroundColor", mBuilder.getBackgroundColor(p));
             contentView.setIcon(R.id.status_bar_latest_event_content, "setLargeIcon",
                     mBuilder.mN.mLargeIcon);
             contentView.setBundle(R.id.status_bar_latest_event_content, "setData",
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 1b1e0bf..8ecc809 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -32,7 +32,6 @@
 import android.app.RemoteInputHistoryItem;
 import android.content.Context;
 import android.content.res.ColorStateList;
-import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.Typeface;
 import android.graphics.drawable.GradientDrawable;
@@ -62,11 +61,9 @@
 import android.widget.TextView;
 
 import com.android.internal.R;
-import com.android.internal.graphics.ColorUtils;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 import java.util.Objects;
 import java.util.function.Consumer;
 
@@ -118,7 +115,6 @@
     private ViewGroup mExpandButtonAndContentContainer;
     private NotificationExpandButton mExpandButton;
     private MessagingLinearLayout mImageMessageContainer;
-    private int mExpandButtonExpandedTopMargin;
     private int mBadgedSideMargins;
     private int mConversationAvatarSize;
     private int mConversationAvatarSizeExpanded;
@@ -147,7 +143,6 @@
     private int mFacePileProtectionWidth;
     private int mFacePileProtectionWidthExpanded;
     private boolean mImportantConversation;
-    private TextView mUnreadBadge;
     private View mFeedbackIcon;
     private float mMinTouchSize;
     private Icon mConversationIcon;
@@ -245,8 +240,6 @@
         mContentContainer = findViewById(R.id.notification_action_list_margin_target);
         mExpandButtonAndContentContainer = findViewById(R.id.expand_button_and_content_container);
         mExpandButton = findViewById(R.id.expand_button);
-        mExpandButtonExpandedTopMargin = getResources().getDimensionPixelSize(
-                R.dimen.conversation_expand_button_top_margin_expanded);
         mNotificationHeaderExpandedPadding = getResources().getDimensionPixelSize(
                 R.dimen.conversation_header_expanded_padding_end);
         mContentMarginEnd = getResources().getDimensionPixelSize(
@@ -286,7 +279,6 @@
         mAppName.setOnVisibilityChangedListener((visibility) -> {
             onAppNameVisibilityChanged();
         });
-        mUnreadBadge = findViewById(R.id.conversation_unread_count);
         mConversationContentStart = getResources().getDimensionPixelSize(
                 R.dimen.conversation_content_start);
         mInternalButtonPadding
@@ -426,17 +418,7 @@
 
     /** @hide */
     public void setUnreadCount(int unreadCount) {
-        boolean visible = mIsCollapsed && unreadCount > 1;
-        mUnreadBadge.setVisibility(visible ? VISIBLE : GONE);
-        if (visible) {
-            CharSequence text = unreadCount >= 100
-                    ? getResources().getString(R.string.unread_convo_overflow, 99)
-                    : String.format(Locale.getDefault(), "%d", unreadCount);
-            mUnreadBadge.setText(text);
-            mUnreadBadge.setBackgroundTintList(ColorStateList.valueOf(mLayoutColor));
-            boolean needDarkText = ColorUtils.calculateLuminance(mLayoutColor) > 0.5f;
-            mUnreadBadge.setTextColor(needDarkText ? Color.BLACK : Color.WHITE);
-        }
+        mExpandButton.setNumber(unreadCount);
     }
 
     private void addRemoteInputHistoryToMessages(
@@ -1132,15 +1114,16 @@
     }
 
     private void updateExpandButton() {
-        int gravity;
-        int topMargin = 0;
+        int buttonGravity;
+        int containerHeight;
         ViewGroup newContainer;
         if (mIsCollapsed) {
-            gravity = Gravity.CENTER;
+            buttonGravity = Gravity.CENTER;
+            containerHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
             newContainer = mExpandButtonAndContentContainer;
         } else {
-            gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
-            topMargin = mExpandButtonExpandedTopMargin;
+            buttonGravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+            containerHeight = ViewGroup.LayoutParams.MATCH_PARENT;
             newContainer = this;
         }
         mExpandButton.setExpanded(!mIsCollapsed);
@@ -1149,14 +1132,14 @@
         // content when collapsed, but allows the content to flow under it when expanded.
         if (newContainer != mExpandButtonContainer.getParent()) {
             ((ViewGroup) mExpandButtonContainer.getParent()).removeView(mExpandButtonContainer);
+            mExpandButtonContainer.getLayoutParams().height = containerHeight;
             newContainer.addView(mExpandButtonContainer);
         }
 
         // update if the expand button is centered
         LinearLayout.LayoutParams layoutParams =
                 (LinearLayout.LayoutParams) mExpandButton.getLayoutParams();
-        layoutParams.gravity = gravity;
-        layoutParams.topMargin = topMargin;
+        layoutParams.gravity = buttonGravity;
         mExpandButton.setLayoutParams(layoutParams);
     }
 
@@ -1210,6 +1193,7 @@
             mExpandButtonContainer.setVisibility(GONE);
             mConversationIconContainer.setOnClickListener(null);
         }
+        mExpandButton.setVisibility(VISIBLE);
         updateContentEndPaddings();
     }
 
diff --git a/core/java/com/android/internal/widget/NotificationExpandButton.java b/core/java/com/android/internal/widget/NotificationExpandButton.java
index 8add34f..a5b757b 100644
--- a/core/java/com/android/internal/widget/NotificationExpandButton.java
+++ b/core/java/com/android/internal/widget/NotificationExpandButton.java
@@ -16,30 +16,42 @@
 
 package com.android.internal.widget;
 
-import static com.android.internal.widget.ColoredIconHelper.applyGrayTint;
-
+import android.annotation.ColorInt;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.RemotableViewMethod;
+import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.Button;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.RemoteViews;
+import android.widget.TextView;
 
 import com.android.internal.R;
 
+import java.util.Locale;
+
 /**
  * An expand button in a notification
  */
 @RemoteViews.RemoteView
-public class NotificationExpandButton extends ImageView {
+public class NotificationExpandButton extends FrameLayout {
 
-    private final int mMinTouchTargetSize;
+    private View mPillView;
+    private TextView mNumberView;
+    private ImageView mIconView;
     private boolean mExpanded;
-    private int mOriginalNotificationColor;
+    private int mNumber;
+    private int mDefaultPillColor;
+    private int mDefaultTextColor;
+    private int mHighlightPillColor;
+    private int mHighlightTextColor;
+    private boolean mDisallowColor;
 
     public NotificationExpandButton(Context context) {
         this(context, null, 0, 0);
@@ -57,7 +69,14 @@
     public NotificationExpandButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mMinTouchTargetSize = (int) (getResources().getDisplayMetrics().density * 48 + 0.5);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mPillView = findViewById(R.id.expand_button_pill);
+        mNumberView = findViewById(R.id.expand_button_number);
+        mIconView = findViewById(R.id.expand_button_icon);
     }
 
     /**
@@ -72,7 +91,6 @@
         } else {
             super.getBoundsOnScreen(outRect, clipToParent);
         }
-        extendRectToMinTouchSize(outRect);
     }
 
     /**
@@ -89,32 +107,12 @@
         return super.pointInView(localX, localY, slop);
     }
 
-    @RemotableViewMethod
-    public void setOriginalNotificationColor(int color) {
-        mOriginalNotificationColor = color;
-    }
-
-    public int getOriginalNotificationColor() {
-        return mOriginalNotificationColor;
-    }
-
     /**
-     * Set the button's color filter: to gray if true, otherwise colored.
-     * If this button has no original color, this has no effect.
+     * Disable the use of the accent colors for this view, if true.
      */
     public void setGrayedOut(boolean shouldApply) {
-        applyGrayTint(mContext, getDrawable(), shouldApply, mOriginalNotificationColor);
-    }
-
-    private void extendRectToMinTouchSize(Rect rect) {
-        if (rect.width() < mMinTouchTargetSize) {
-            rect.left = rect.centerX() - mMinTouchTargetSize / 2;
-            rect.right = rect.left + mMinTouchTargetSize;
-        }
-        if (rect.height() < mMinTouchTargetSize) {
-            rect.top = rect.centerY() - mMinTouchTargetSize / 2;
-            rect.bottom = rect.top + mMinTouchTargetSize;
-        }
+        mDisallowColor = shouldApply;
+        updateColors();
     }
 
     @Override
@@ -129,10 +127,10 @@
     @RemotableViewMethod
     public void setExpanded(boolean expanded) {
         mExpanded = expanded;
-        updateExpandButton();
+        updateExpandedState();
     }
 
-    private void updateExpandButton() {
+    private void updateExpandedState() {
         int drawableId;
         int contentDescriptionId;
         if (mExpanded) {
@@ -142,8 +140,87 @@
             drawableId = R.drawable.ic_expand_notification;
             contentDescriptionId = R.string.expand_button_content_description_collapsed;
         }
-        setImageDrawable(getContext().getDrawable(drawableId));
-        setColorFilter(mOriginalNotificationColor);
         setContentDescription(mContext.getText(contentDescriptionId));
+        mIconView.setImageDrawable(getContext().getDrawable(drawableId));
+
+        // changing the expanded state can affect the number display
+        updateNumber();
+    }
+
+    private void updateNumber() {
+        if (shouldShowNumber()) {
+            CharSequence text = mNumber >= 100
+                    ? getResources().getString(R.string.unread_convo_overflow, 99)
+                    : String.format(Locale.getDefault(), "%d", mNumber);
+            mNumberView.setText(text);
+            mNumberView.setVisibility(VISIBLE);
+        } else {
+            mNumberView.setVisibility(GONE);
+        }
+
+        // changing number can affect the color
+        updateColors();
+    }
+
+    private void updateColors() {
+        if (shouldShowNumber() && !mDisallowColor) {
+            mPillView.setBackgroundTintList(ColorStateList.valueOf(mHighlightPillColor));
+            mIconView.setColorFilter(mHighlightTextColor);
+            mNumberView.setTextColor(mHighlightTextColor);
+        } else {
+            mPillView.setBackgroundTintList(ColorStateList.valueOf(mDefaultPillColor));
+            mIconView.setColorFilter(mDefaultTextColor);
+            mNumberView.setTextColor(mDefaultTextColor);
+        }
+    }
+
+    private boolean shouldShowNumber() {
+        return !mExpanded && mNumber > 1;
+    }
+
+    /**
+     * Set the color used for the expand chevron and the text
+     */
+    @RemotableViewMethod
+    public void setDefaultTextColor(int color) {
+        mDefaultTextColor = color;
+        updateColors();
+    }
+
+    /**
+     * Sets the color used to for the expander when there is no number shown
+     */
+    @RemotableViewMethod
+    public void setDefaultPillColor(@ColorInt int color) {
+        mDefaultPillColor = color;
+        updateColors();
+    }
+
+    /**
+     * Set the color used for the expand chevron and the text
+     */
+    @RemotableViewMethod
+    public void setHighlightTextColor(int color) {
+        mHighlightTextColor = color;
+        updateColors();
+    }
+
+    /**
+     * Sets the color used to highlight the expander when there is a number shown
+     */
+    @RemotableViewMethod
+    public void setHighlightPillColor(@ColorInt int color) {
+        mHighlightPillColor = color;
+        updateColors();
+    }
+
+    /**
+     * Sets the number shown inside the expand button.
+     * This only appears when the expand button is collapsed, and when greater than 1.
+     */
+    @RemotableViewMethod
+    public void setNumber(int number) {
+        mNumber = number;
+        updateNumber();
     }
 }
diff --git a/core/res/res/drawable/conversation_unread_bg.xml b/core/res/res/drawable/expand_button_pill_bg.xml
similarity index 90%
rename from core/res/res/drawable/conversation_unread_bg.xml
rename to core/res/res/drawable/expand_button_pill_bg.xml
index d3e00cf..f95044a 100644
--- a/core/res/res/drawable/conversation_unread_bg.xml
+++ b/core/res/res/drawable/expand_button_pill_bg.xml
@@ -14,6 +14,6 @@
   ~ limitations under the License.
   -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <corners android:radius="20sp" />
+    <corners android:radius="@dimen/notification_expand_button_pill_height" />
     <solid android:color="@android:color/white" />
 </shape>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_collapse_notification.xml b/core/res/res/drawable/ic_collapse_notification.xml
index ca4f0ed..a06ec9f 100644
--- a/core/res/res/drawable/ic_collapse_notification.xml
+++ b/core/res/res/drawable/ic_collapse_notification.xml
@@ -21,8 +21,5 @@
     android:viewportHeight="24.0">
     <path
         android:fillColor="#FF000000"
-        android:pathData="M18.59,16.41L20.0,15.0l-8.0,-8.0 -8.0,8.0 1.41,1.41L12.0,9.83"/>
-    <path
-        android:pathData="M0 0h24v24H0V0z"
-        android:fillColor="#00000000"/>
+        android:pathData="M18.59,15.41L20.0,14.0l-8.0,-8.0 -8.0,8.0 1.41,1.41L12.0,8.83"/>
 </vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_expand_notification.xml b/core/res/res/drawable/ic_expand_notification.xml
index a080ce4..160a9c2 100644
--- a/core/res/res/drawable/ic_expand_notification.xml
+++ b/core/res/res/drawable/ic_expand_notification.xml
@@ -21,8 +21,5 @@
     android:viewportHeight="24.0">
     <path
         android:fillColor="#FF000000"
-        android:pathData="M5.41,7.59L4.0,9.0l8.0,8.0 8.0,-8.0 -1.41,-1.41L12.0,14.17"/>
-    <path
-        android:pathData="M24 24H0V0h24v24z"
-        android:fillColor="#00000000"/>
+        android:pathData="M5.41,8.59L4.0,10.0l8.0,8.0 8.0,-8.0 -1.41,-1.41L12.0,15.17"/>
 </vector>
\ No newline at end of file
diff --git a/core/res/res/layout/notification_expand_button.xml b/core/res/res/layout/notification_expand_button.xml
new file mode 100644
index 0000000..f92e6d6
--- /dev/null
+++ b/core/res/res/layout/notification_expand_button.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2021 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<com.android.internal.widget.NotificationExpandButton
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/expand_button"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="top|end"
+    android:contentDescription="@string/expand_button_content_description_collapsed"
+    android:padding="16dp"
+    android:visibility="gone"
+    >
+
+    <LinearLayout
+        android:id="@+id/expand_button_pill"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/notification_expand_button_pill_height"
+        android:orientation="horizontal"
+        android:background="@drawable/expand_button_pill_bg"
+        >
+
+        <TextView
+            android:id="@+id/expand_button_number"
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/notification_expand_button_pill_height"
+            android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info"
+            android:gravity="center_vertical"
+            android:paddingLeft="8dp"
+            />
+
+        <ImageView
+            android:id="@+id/expand_button_icon"
+            android:layout_width="@dimen/notification_expand_button_pill_height"
+            android:layout_height="@dimen/notification_expand_button_pill_height"
+            android:padding="2dp"
+            android:scaleType="fitCenter"
+            android:importantForAccessibility="no"
+            />
+
+    </LinearLayout>
+
+</com.android.internal.widget.NotificationExpandButton>
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 1de1d04..150734e 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -75,15 +75,10 @@
         android:importantForAccessibility="no"
         />
 
-    <com.android.internal.widget.NotificationExpandButton
-        android:id="@+id/expand_button"
-        android:layout_width="@dimen/notification_header_expand_icon_size"
-        android:layout_height="@dimen/notification_header_expand_icon_size"
+    <include layout="@layout/notification_expand_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|end"
-        android:contentDescription="@string/expand_button_content_description_collapsed"
-        android:paddingTop="@dimen/notification_expand_button_padding_top"
-        android:scaleType="center"
-        android:visibility="gone"
         />
 
 </NotificationHeaderView>
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index b83611bc..bad9a6b 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -74,14 +74,10 @@
         android:layout_height="match_parent"
         android:layout_gravity="end">
 
-        <com.android.internal.widget.NotificationExpandButton
-            android:id="@+id/expand_button"
-            android:layout_width="@dimen/notification_header_expand_icon_size"
-            android:layout_height="@dimen/notification_header_expand_icon_size"
+        <include layout="@layout/notification_expand_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_gravity="center_vertical|end"
-            android:contentDescription="@string/expand_button_content_description_collapsed"
-            android:paddingTop="@dimen/notification_expand_button_padding_top"
-            android:scaleType="center"
             />
 
     </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_call.xml b/core/res/res/layout/notification_template_material_call.xml
index 471d874..7b52ec3 100644
--- a/core/res/res/layout/notification_template_material_call.xml
+++ b/core/res/res/layout/notification_template_material_call.xml
@@ -72,15 +72,10 @@
             </LinearLayout>
 
             <!-- TODO(b/179178086): remove padding from main column when this is visible -->
-            <com.android.internal.widget.NotificationExpandButton
-                android:id="@+id/expand_button"
-                android:layout_width="@dimen/notification_header_expand_icon_size"
-                android:layout_height="@dimen/notification_header_expand_icon_size"
+            <include layout="@layout/notification_expand_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
                 android:layout_gravity="top|end"
-                android:contentDescription="@string/expand_button_content_description_collapsed"
-                android:paddingTop="@dimen/notification_expand_button_padding_top"
-                android:scaleType="center"
-                android:visibility="gone"
                 />
 
         </LinearLayout>
diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml
index f3aa540..42fb4a2 100644
--- a/core/res/res/layout/notification_template_material_conversation.xml
+++ b/core/res/res/layout/notification_template_material_conversation.xml
@@ -104,11 +104,10 @@
         <LinearLayout
             android:id="@+id/expand_button_touch_container"
             android:layout_width="wrap_content"
-            android:layout_height="@dimen/conversation_expand_button_size"
-            android:paddingStart="@dimen/conversation_expand_button_side_margin"
+            android:layout_height="@dimen/conversation_expand_button_height"
             android:orientation="horizontal"
             android:layout_gravity="end|top"
-            android:paddingEnd="@dimen/conversation_expand_button_side_margin"
+            android:paddingEnd="0dp"
             android:clipToPadding="false"
             android:clipChildren="false"
             >
@@ -118,34 +117,16 @@
                 android:forceHasOverlappingRendering="false"
                 android:layout_width="40dp"
                 android:layout_height="40dp"
-                android:layout_marginEnd="11dp"
+                android:layout_marginStart="@dimen/conversation_image_start_margin"
                 android:spacing="0dp"
                 android:layout_gravity="center"
                 android:clipToPadding="false"
                 android:clipChildren="false"
                 />
-            <!-- Unread Count -->
-            <TextView
-                android:id="@+id/conversation_unread_count"
-                android:layout_width="33sp"
-                android:layout_height="wrap_content"
-                android:layout_marginEnd="11dp"
-                android:layout_gravity="center"
-                android:gravity="center"
-                android:padding="2dp"
-                android:visibility="gone"
-                android:textAppearance="@style/TextAppearance.DeviceDefault.Notification"
-                android:textColor="#FFFFFF"
-                android:textSize="12sp"
-                android:background="@drawable/conversation_unread_bg"
-                />
-            <com.android.internal.widget.NotificationExpandButton
-                android:id="@+id/expand_button"
+            <include layout="@layout/notification_expand_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
-                android:drawable="@drawable/ic_expand_notification"
-                android:contentDescription="@string/expand_button_content_description_collapsed"
                 />
         </LinearLayout>
     </FrameLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b0a4c6e..5ffc4f0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3957,6 +3957,10 @@
          color supplied by the Notification.Builder if present. -->
     <bool name="config_tintNotificationActionButtons">true</bool>
 
+    <!-- Flag indicating that tinted items (actions, expander, etc) are to be tinted using the
+         theme color, rather than the notification color. -->
+    <bool name="config_tintNotificationsWithTheme">true</bool>
+
     <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
     <bool name="config_showAreaUpdateInfoSettings">false</bool>
 
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index b7dd98b..f390462 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -248,7 +248,7 @@
     <dimen name="call_notification_collapsible_indent">64dp</dimen>
 
     <!-- The size of icons for visual actions in the notification_material_action_list -->
-    <dimen name="notification_actions_icon_size">48dp</dimen>
+    <dimen name="notification_actions_icon_size">56dp</dimen>
 
     <!-- The size of icons for visual actions in the notification_material_action_list -->
     <dimen name="notification_actions_icon_drawable_size">20dp</dimen>
@@ -314,10 +314,10 @@
     <dimen name="notification_conversation_header_separating_margin">4dp</dimen>
 
     <!-- The absolute size of the notification expand icon. -->
-    <dimen name="notification_header_expand_icon_size">48dp</dimen>
+    <dimen name="notification_header_expand_icon_size">56dp</dimen>
 
-    <!-- The top padding for the notification expand button. -->
-    <dimen name="notification_expand_button_padding_top">1dp</dimen>
+    <!-- the height of the expand button pill -->
+    <dimen name="notification_expand_button_pill_height">24dp</dimen>
 
     <!-- Vertical margin for the headerless notification content, when content has 1 line -->
     <!-- 16 * 2 (margins) + 24 (1 line) = 56 (notification) -->
@@ -746,7 +746,7 @@
     <dimen name="notification_right_icon_headerless_margin">20dp</dimen>
     <!-- The top margin of the right icon in the "big" notification states -->
     <!--  TODO(b/181048615): Move the large icon below the expander in big states  -->
-    <dimen name="notification_right_icon_big_margin_top">16dp</dimen>
+    <dimen name="notification_right_icon_big_margin_top">20dp</dimen>
     <!-- The size of the left icon -->
     <dimen name="notification_left_icon_size">@dimen/notification_icon_circle_size</dimen>
     <!-- The left padding of the left icon -->
@@ -777,13 +777,10 @@
     <dimen name="conversation_icon_circle_start">28dp</dimen>
     <!-- Start of the content in the conversation template -->
     <dimen name="conversation_content_start">80dp</dimen>
-    <!-- Size of the expand button in the conversation layout -->
-    <dimen name="conversation_expand_button_size">80dp</dimen>
-    <!-- Top margin of the expand button for conversations when expanded -->
-    <dimen name="conversation_expand_button_top_margin_expanded">18dp</dimen>
-    <!-- Side margin of the expand button for conversations.
-         width of expand asset (22) + 2 * this (13) == notification_header_expand_icon_size (48) -->
-    <dimen name="conversation_expand_button_side_margin">13dp</dimen>
+    <!-- Height of the expand button in the conversation layout -->
+    <dimen name="conversation_expand_button_height">80dp</dimen>
+    <!-- this is the margin between the Conversation image and the content -->
+    <dimen name="conversation_image_start_margin">12dp</dimen>
     <!-- Side margins of the conversation badge in relation to the conversation icon -->
     <dimen name="conversation_badge_side_margin">36dp</dimen>
     <!-- size of the notification badge when applied to the conversation icon -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 829c5ab..6723469 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1893,6 +1893,7 @@
   <java-symbol type="bool" name="config_notificationHeaderClickableForExpand" />
   <java-symbol type="bool" name="config_enableNightMode" />
   <java-symbol type="bool" name="config_tintNotificationActionButtons" />
+  <java-symbol type="bool" name="config_tintNotificationsWithTheme" />
   <java-symbol type="bool" name="config_dozeAfterScreenOffByDefault" />
   <java-symbol type="bool" name="config_enableActivityRecognitionHardwareOverlay" />
   <java-symbol type="bool" name="config_enableFusedLocationOverlay" />
@@ -2893,6 +2894,9 @@
   <java-symbol type="id" name="header_text" />
   <java-symbol type="id" name="header_text_secondary" />
   <java-symbol type="id" name="expand_button" />
+  <java-symbol type="id" name="expand_button_pill" />
+  <java-symbol type="id" name="expand_button_number" />
+  <java-symbol type="id" name="expand_button_icon" />
   <java-symbol type="id" name="alternate_expand_target" />
   <java-symbol type="id" name="notification_header" />
   <java-symbol type="id" name="notification_top_line" />
@@ -2913,7 +2917,6 @@
   <java-symbol type="dimen" name="notification_header_background_height" />
   <java-symbol type="dimen" name="notification_header_touchable_height" />
   <java-symbol type="dimen" name="notification_header_expand_icon_size" />
-  <java-symbol type="dimen" name="notification_expand_button_padding_top" />
   <java-symbol type="dimen" name="notification_header_icon_size" />
   <java-symbol type="dimen" name="notification_header_app_name_margin_start" />
   <java-symbol type="dimen" name="notification_header_separating_margin" />
@@ -4034,7 +4037,6 @@
   <java-symbol type="id" name="message_icon_container" />
   <java-symbol type="id" name="conversation_image_message_container" />
   <java-symbol type="id" name="conversation_icon_container" />
-  <java-symbol type="dimen" name="conversation_expand_button_top_margin_expanded" />
   <java-symbol type="dimen" name="messaging_group_singleline_sender_padding_end" />
   <java-symbol type="dimen" name="conversation_badge_side_margin" />
   <java-symbol type="dimen" name="conversation_avatar_size" />
@@ -4055,7 +4057,6 @@
   <java-symbol type="dimen" name="button_padding_horizontal_material" />
   <java-symbol type="dimen" name="button_inset_horizontal_material" />
   <java-symbol type="layout" name="conversation_face_pile_layout" />
-  <java-symbol type="id" name="conversation_unread_count" />
   <java-symbol type="string" name="unread_convo_overflow" />
   <java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Conversation.AppName" />
   <java-symbol type="drawable" name="conversation_badge_background" />
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 7691761..b0b91bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -22,6 +22,8 @@
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
@@ -30,6 +32,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pair;
+import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.NotificationHeaderView;
@@ -1234,6 +1237,7 @@
         mCachedHeadsUpRemoteInput = null;
     }
 
+
     private RemoteInputView applyRemoteInput(View view, NotificationEntry entry,
             boolean hasRemoteInput, PendingIntent existingPendingIntent,
             RemoteInputView cachedView, NotificationViewWrapper wrapper) {
@@ -1271,6 +1275,15 @@
                 if (color == Notification.COLOR_DEFAULT) {
                     color = mContext.getColor(R.color.default_remote_input_background);
                 }
+                if (mContext.getResources().getBoolean(
+                        com.android.internal.R.bool.config_tintNotificationsWithTheme)) {
+                    Resources.Theme theme = new ContextThemeWrapper(mContext,
+                            com.android.internal.R.style.Theme_DeviceDefault_DayNight).getTheme();
+                    TypedArray ta = theme.obtainStyledAttributes(
+                            new int[]{com.android.internal.R.attr.colorAccent});
+                    color = ta.getColor(0, color);
+                    ta.recycle();
+                }
                 existing.setBackgroundColor(ContrastColorUtil.ensureTextBackgroundColor(color,
                         mContext.getColor(R.color.remote_input_text_enabled),
                         mContext.getColor(R.color.remote_input_hint)));
@@ -1342,12 +1355,10 @@
                 && isPersonWithShortcut
                 && entry.getBubbleMetadata() != null;
         if (showButton) {
-            Drawable d = mContext.getResources().getDrawable(entry.isBubble()
+            // explicitly resolve drawable resource using SystemUI's theme
+            Drawable d = mContext.getDrawable(entry.isBubble()
                     ? R.drawable.bubble_ic_stop_bubble
                     : R.drawable.bubble_ic_create_bubble);
-            mContainingNotification.updateNotificationColor();
-            final int tint = mContainingNotification.getNotificationColor();
-            d.setTint(tint);
 
             String contentDescription = mContext.getResources().getString(entry.isBubble()
                     ? R.string.notification_conversation_unbubble
@@ -1381,9 +1392,8 @@
             return;
         }
 
+        // explicitly resolve drawable resource using SystemUI's theme
         Drawable snoozeDrawable = mContext.getDrawable(R.drawable.ic_snooze);
-        mContainingNotification.updateNotificationColor();
-        snoozeDrawable.setTint(mContainingNotification.getNotificationColor());
         snoozeButton.setImageDrawable(snoozeDrawable);
 
         final NotificationSnooze snoozeGuts = (NotificationSnooze) LayoutInflater.from(mContext)