Fix colored icons in doze mode

Also fixes the issue that small icons promoted to large icons were
not forced to be white, which lead to inconsistent treatment of the
icons.

Bug: 18537470

Change-Id: Ic35e082da12793f3f13c91740bfc345b336c3db4
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9e8a793..a23b0a0 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3055,6 +3055,11 @@
          * Apply any necessary background to smallIcons being used in the largeIcon spot.
          */
         private void processSmallIconAsLarge(int largeIconId, RemoteViews contentView) {
+            if (!isLegacy()) {
+                contentView.setDrawableParameters(R.id.icon, false, -1,
+                        0xFFFFFFFF,
+                        PorterDuff.Mode.SRC_ATOP, -1);
+            }
             if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, largeIconId)) {
                 applyLargeIconBackground(contentView);
             }
@@ -3102,11 +3107,12 @@
          */
         private void processSmallRightIcon(int smallIconDrawableId,
                 RemoteViews contentView) {
-            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, smallIconDrawableId)) {
+            if (!isLegacy()) {
                 contentView.setDrawableParameters(R.id.right_icon, false, -1,
                         0xFFFFFFFF,
                         PorterDuff.Mode.SRC_ATOP, -1);
-
+            }
+            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, smallIconDrawableId)) {
                 contentView.setInt(R.id.right_icon,
                         "setBackgroundResource",
                         R.drawable.notification_icon_legacy_bg);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
index fbcba0b..59b62e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
@@ -53,6 +53,9 @@
     private ImageView mIcon;
     protected ImageView mPicture;
 
+    /** Whether the icon needs to be forced grayscale when in dark mode. */
+    private boolean mIconForceGraysaleWhenDark;
+
     protected NotificationTemplateViewWrapper(Context ctx, View view) {
         super(view);
         mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
@@ -73,11 +76,15 @@
         mIcon = resolveIcon(largeIcon, rightIcon);
         mPicture = resolvePicture(largeIcon);
         mIconBackgroundColor = resolveBackgroundColor(mIcon);
+
+        // If the icon already has a color filter, we assume that we already forced the icon to be
+        // white when we created the notification.
+        mIconForceGraysaleWhenDark = mIcon != null && mIcon.getDrawable().getColorFilter() != null;
     }
 
     private ImageView resolveIcon(ImageView largeIcon, ImageView rightIcon) {
         return largeIcon != null && largeIcon.getBackground() != null ? largeIcon
-                : rightIcon != null && rightIcon.getBackground() != null ? rightIcon
+                : rightIcon != null && rightIcon.getVisibility() == View.VISIBLE ? rightIcon
                 : null;
     }
 
@@ -118,9 +125,15 @@
             if (fade) {
                 fadeIconColorFilter(mIcon, dark, delay);
                 fadeIconAlpha(mIcon, dark, delay);
+                if (!mIconForceGraysaleWhenDark) {
+                    fadeGrayscale(mIcon, dark, delay);
+                }
             } else {
                 updateIconColorFilter(mIcon, dark);
                 updateIconAlpha(mIcon, dark);
+                if (!mIconForceGraysaleWhenDark) {
+                    updateGrayscale(mIcon, dark);
+                }
             }
         }
         setPictureGrayscale(dark, fade, delay);
@@ -196,8 +209,8 @@
         mIconColorFilter.setColor(color);
         Drawable background = target.getBackground();
 
-        // The notification might have been modified during the animation, so background might be
-        // null here.
+        // The background might be null for legacy notifications. Also, the notification might have
+        // been modified during the animation, so background might be null here.
         if (background != null) {
             background.mutate().setColorFilter(mIconColorFilter);
         }