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

Commit de3c5a25 authored by Anthony Chen's avatar Anthony Chen Committed by Android (Google) Code Review
Browse files

Merge "Handle night mode for notifications."

parents ecad1822 ad4d158a
Loading
Loading
Loading
Loading
+34 −7
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ShortcutInfo;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -2752,6 +2754,9 @@ public class Notification implements Parcelable
        private ArrayList<Action> mOriginalActions;
        private boolean mRebuildStyledRemoteViews;

        private boolean mTintActionButtons;
        private boolean mInNightMode;

        /**
         * Constructs a new Builder with the defaults:
         *
@@ -2783,6 +2788,14 @@ public class Notification implements Parcelable
         */
        public Builder(Context context, Notification toAdopt) {
            mContext = context;
            Resources res = mContext.getResources();
            mTintActionButtons = res.getBoolean(R.bool.config_tintNotificationActionButtons);

            if (res.getBoolean(R.bool.config_enableNightMode)) {
                Configuration currentConfig = res.getConfiguration();
                mInNightMode = (currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
                        == Configuration.UI_MODE_NIGHT_YES;
            }

            if (toAdopt == null) {
                mN = new Notification();
@@ -4631,14 +4644,14 @@ public class Notification implements Parcelable
                    // We need to set the text color as well since changing a text to uppercase
                    // clears its spans.
                    button.setTextColor(R.id.action0, outResultColor[0]);
                } else if (mN.color != COLOR_DEFAULT && !isColorized()) {
                } else if (mN.color != COLOR_DEFAULT && !isColorized() && mTintActionButtons) {
                    button.setTextColor(R.id.action0,resolveContrastColor());
                }
            } else {
                button.setTextViewText(R.id.action0, processLegacyText(action.title));
                if (isColorized() && !ambient) {
                    setTextViewColorPrimary(button, R.id.action0);
                } else if (mN.color != COLOR_DEFAULT) {
                } else if (mN.color != COLOR_DEFAULT && mTintActionButtons) {
                    button.setTextColor(R.id.action0,
                            ambient ? resolveAmbientColor() : resolveContrastColor());
                }
@@ -4717,7 +4730,7 @@ public class Notification implements Parcelable
                            int[] newColors = new int[colors.length];
                            for (int i = 0; i < newColors.length; i++) {
                                newColors[i] = NotificationColorUtil.ensureLargeTextContrast(
                                        colors[i], background);
                                        colors[i], background, mInNightMode);
                            }
                            textColor = new ColorStateList(textColor.getStates().clone(),
                                    newColors);
@@ -4736,7 +4749,7 @@ public class Notification implements Parcelable
                        ForegroundColorSpan originalSpan = (ForegroundColorSpan) resultSpan;
                        int foregroundColor = originalSpan.getForegroundColor();
                        foregroundColor = NotificationColorUtil.ensureLargeTextContrast(
                                foregroundColor, background);
                                foregroundColor, background, mInNightMode);
                        resultSpan = new ForegroundColorSpan(foregroundColor);
                        if (fullLength) {
                            outResultColor[0] = ColorStateList.valueOf(foregroundColor);
@@ -4831,7 +4844,7 @@ public class Notification implements Parcelable
                color = mSecondaryTextColor;
            } else {
                color = NotificationColorUtil.resolveContrastColor(mContext, mN.color,
                        background);
                        background, mInNightMode);
            }
            if (Color.alpha(color) < 255) {
                // alpha doesn't go well for color filters, so let's blend it manually
@@ -5064,6 +5077,10 @@ public class Notification implements Parcelable
            return mN.isColorized();
        }

        private boolean shouldTintActionButtons() {
            return mTintActionButtons;
        }

        private boolean textColorsNeedInversion() {
            if (mStyle == null || !MediaStyle.class.equals(mStyle.getClass())) {
                return false;
@@ -6067,6 +6084,8 @@ public class Notification implements Parcelable
            BidiFormatter bidi = BidiFormatter.getInstance();
            SpannableStringBuilder sb = new SpannableStringBuilder();
            boolean colorize = builder.isColorized();
            TextAppearanceSpan colorSpan;
            CharSequence messageName;
            if (TextUtils.isEmpty(m.mSender)) {
                CharSequence replyName = mUserDisplayName == null ? "" : mUserDisplayName;
                sb.append(bidi.unicodeWrap(replyName),
@@ -6595,8 +6614,16 @@ public class Notification implements Parcelable
            RemoteViews button = new BuilderRemoteViews(mBuilder.mContext.getApplicationInfo(),
                    R.layout.notification_material_media_action);
            button.setImageViewIcon(R.id.action0, action.getIcon());
            button.setDrawableParameters(R.id.action0, false, -1, color, PorterDuff.Mode.SRC_ATOP,
                    -1);

            // If the action buttons should not be tinted, then just use the default
            // notification color. Otherwise, just use the passed-in color.
            int tintColor = mBuilder.shouldTintActionButtons() || mBuilder.isColorized()
                    ? color
                    : NotificationColorUtil.resolveColor(mBuilder.mContext,
                            Notification.COLOR_DEFAULT);

            button.setDrawableParameters(R.id.action0, false, -1, tintColor,
                    PorterDuff.Mode.SRC_ATOP, -1);
            if (!tombstone) {
                button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
            }
+35 −12
Original line number Diff line number Diff line
@@ -361,19 +361,27 @@ public class NotificationColorUtil {
    }

     /**
     * Finds a text color with sufficient contrast over bg that has the same hue as the original
     * color, assuming it is for large text.
     * Finds a large text color with sufficient contrast over bg that has the same or darker hue as
     * the original color, depending on the value of {@code isBgDarker}.
     *
     * @param isBgDarker {@code true} if {@code bg} is darker than {@code color}.
     */
    public static int ensureLargeTextContrast(int color, int bg) {
        return findContrastColor(color, bg, true, 3);
    public static int ensureLargeTextContrast(int color, int bg, boolean isBgDarker) {
        return isBgDarker
                ? findContrastColorAgainstDark(color, bg, true, 3)
                : findContrastColor(color, bg, true, 3);
    }

    /**
     * Finds a text color with sufficient contrast over bg that has the same hue as the original
     * color.
     * Finds a text color with sufficient contrast over bg that has the same or darker hue as the
     * original color, depending on the value of {@code isBgDarker}.
     *
     * @param isBgDarker {@code true} if {@code bg} is darker than {@code color}.
     */
    private static int ensureTextContrast(int color, int bg) {
        return findContrastColor(color, bg, true, 4.5);
    private static int ensureTextContrast(int color, int bg, boolean isBgDarker) {
        return isBgDarker
                ? findContrastColorAgainstDark(color, bg, true, 4.5)
                : findContrastColor(color, bg, true, 4.5);
    }

    /** Finds a background color for a text view with given text color and hint text color, that
@@ -400,24 +408,39 @@ public class NotificationColorUtil {
        return color;
    }

    /**
     * Resolves a Notification's color such that it has enough contrast to be used as the
     * color for the Notification's action and header text on a background that is lighter than
     * {@code notificationColor}.
     *
     * @see {@link #resolveContrastColor(Context, int, boolean)}
     */
    public static int resolveContrastColor(Context context, int notificationColor,
            int backgroundColor) {
        return NotificationColorUtil.resolveContrastColor(context, notificationColor,
                backgroundColor, false /* isDark */);
    }

    /**
     * Resolves a Notification's color such that it has enough contrast to be used as the
     * color for the Notification's action and header text.
     *
     * @param notificationColor the color of the notification or {@link Notification#COLOR_DEFAULT}
     * @param backgroundColor the background color to ensure the contrast against.
     * @param isDark whether or not the {@code notificationColor} will be placed on a background
     *               that is darker than the color itself
     * @return a color of the same hue with enough contrast against the backgrounds.
     */
    public static int resolveContrastColor(Context context, int notificationColor,
            int backgroundColor) {
            int backgroundColor, boolean isDark) {
        final int resolvedColor = resolveColor(context, notificationColor);

        final int actionBg = context.getColor(
                com.android.internal.R.color.notification_action_list);

        int color = resolvedColor;
        color = NotificationColorUtil.ensureLargeTextContrast(color, actionBg);
        color = NotificationColorUtil.ensureTextContrast(color, backgroundColor);
        color = NotificationColorUtil.ensureLargeTextContrast(color, actionBg, isDark);
        color = NotificationColorUtil.ensureTextContrast(color, backgroundColor, isDark);

        if (color != resolvedColor) {
            if (DEBUG){
+7 −0
Original line number Diff line number Diff line
@@ -2978,4 +2978,11 @@

    <!-- An array of packages that need to be treated as type service in battery settings -->
    <string-array translatable="false" name="config_batteryPackageTypeService"/>

    <!-- Flag indicating whether or not to enable night mode detection. -->
    <bool name="config_enableNightMode">false</bool>

    <!-- Flag indicating that the actions buttons for a notification should be tinted with by the
         color supplied by the Notification.Builder if present. -->
    <bool name="config_tintNotificationActionButtons">true</bool>
</resources>
+2 −0
Original line number Diff line number Diff line
@@ -1749,6 +1749,8 @@
  <java-symbol type="bool" name="config_automatic_brightness_available" />
  <java-symbol type="bool" name="config_autoBrightnessResetAmbientLuxAfterWarmUp" />
  <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_dozeAfterScreenOff" />
  <java-symbol type="bool" name="config_enableActivityRecognitionHardwareOverlay" />
  <java-symbol type="bool" name="config_enableFusedLocationOverlay" />
+11 −2
Original line number Diff line number Diff line
@@ -214,15 +214,24 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
        mFakeShadow = findViewById(R.id.fake_shadow);
        mShadowHidden = mFakeShadow.getVisibility() != VISIBLE;
        mBackgroundDimmed = findViewById(R.id.backgroundDimmed);
        mBackgroundNormal.setCustomBackground(R.drawable.notification_material_bg);
        mBackgroundDimmed.setCustomBackground(R.drawable.notification_material_bg_dim);
        mDimmedAlpha = Color.alpha(mContext.getColor(
                R.color.notification_material_background_dimmed_color));
        initBackground();
        updateBackground();
        updateBackgroundTint();
        updateOutlineAlpha();
    }

    /**
     * Sets the custom backgrounds on {@link #mBackgroundNormal} and {@link #mBackgroundDimmed}.
     * This method can also be used to reload the backgrounds on both of those views, which can
     * be useful in a configuration change.
     */
    protected void initBackground() {
        mBackgroundNormal.setCustomBackground(R.drawable.notification_material_bg);
        mBackgroundDimmed.setCustomBackground(R.drawable.notification_material_bg_dim);
    }

    private final Runnable mTapTimeoutRunnable = new Runnable() {
        @Override
        public void run() {
Loading