diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2017-01-26 02:06:03 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-01-26 02:06:06 +0000 |
| commit | ca19e3278bca7f259002b9ea8ad79f66da4e61eb (patch) | |
| tree | ca14b4ff9acce5173498dbfa3345894e7c5c1150 /core/java/android | |
| parent | 2a27b2ca7c3c6631fb9e7ff4f1999fdbcef3caf6 (diff) | |
| parent | 7b9605b79c4f738ee5b306d8693018e931cda18e (diff) | |
Merge changes I818e8db9,Ie24468be
* changes:
Added a new API to colorize notifications
Modified the interpolators when opening an ambient notification
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/Notification.java | 184 |
1 files changed, 165 insertions, 19 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index b4fe6b84b2cc..34d2039988e6 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -71,7 +71,6 @@ import android.widget.RemoteViews; import com.android.internal.R; import com.android.internal.util.ArrayUtils; import com.android.internal.util.NotificationColorUtil; -import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -982,6 +981,12 @@ public class Notification implements Parcelable public static final String EXTRA_HISTORIC_MESSAGES = "android.messages.historic"; /** + * {@link #extras} key: whether the notification should be colorized as + * supplied to {@link Builder#setColorized(boolean)}}. + */ + public static final String EXTRA_COLORIZED = "android.colorized"; + + /** * {@link #extras} key: the user that built the notification. * * @hide @@ -2438,6 +2443,8 @@ public class Notification implements Parcelable private ArrayList<Action> mActions = new ArrayList<Action>(MAX_ACTION_BUTTONS); private ArrayList<String> mPersonList = new ArrayList<String>(); private NotificationColorUtil mColorUtil; + private boolean mIsLegacy; + private boolean mIsLegacyInitialized; private boolean mColorUtilInited = false; /** @@ -2456,6 +2463,10 @@ public class Notification implements Parcelable * so make sure to call {@link StandardTemplateParams#reset()} before using it. */ StandardTemplateParams mParams = new StandardTemplateParams(); + private int mTextColorsAreForBackground = COLOR_INVALID; + private int mPrimaryTextColor = COLOR_INVALID; + private int mSecondaryTextColor = COLOR_INVALID; + private int mActionBarColor = COLOR_INVALID; /** * Constructs a new Builder with the defaults: @@ -2540,7 +2551,7 @@ public class Notification implements Parcelable private NotificationColorUtil getColorUtil() { if (!mColorUtilInited) { mColorUtilInited = true; - if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.LOLLIPOP) { + if (isLegacy() || isColorized()) { mColorUtil = NotificationColorUtil.getInstance(mContext); } } @@ -3025,6 +3036,22 @@ public class Notification implements Parcelable } /** + * Set whether this notification should be colorized. When set, the color set with + * {@link #setColor(int)} will be used as the background color of this notification. + * <p> + * The coloring will only be applied if the notification is ongoing. + * This should only be used for high priority ongoing tasks like navigation, an ongoing + * call, or other similarly high-priority events for the user. + * + * @see Builder#setOngoing(boolean) + * @see Builder#setColor(int) + */ + public Builder setColorized(boolean colorize) { + mN.extras.putBoolean(EXTRA_COLORIZED, colorize); + return this; + } + + /** * Set this flag if you would only like the sound, vibrate * and ticker to be played if the notification is not already showing. * @@ -3389,6 +3416,10 @@ public class Notification implements Parcelable if (profileBadge != null) { contentView.setImageViewBitmap(R.id.profile_badge, profileBadge); contentView.setViewVisibility(R.id.profile_badge, View.VISIBLE); + if (isColorized()) { + contentView.setDrawableParameters(R.id.profile_badge, false, -1, + getPrimaryTextColor(), PorterDuff.Mode.SRC_ATOP, -1); + } } } @@ -3446,13 +3477,14 @@ public class Notification implements Parcelable resetStandardTemplate(contentView); final Bundle ex = mN.extras; - + updateBackgroundColor(contentView); bindNotificationHeader(contentView, p.ambient); bindLargeIcon(contentView); boolean showProgress = handleProgressBar(p.hasProgress, contentView, ex); if (p.title != null) { contentView.setViewVisibility(R.id.title, View.VISIBLE); contentView.setTextViewText(R.id.title, p.title); + setTextViewColorPrimary(contentView, R.id.title); contentView.setViewLayoutWidth(R.id.title, showProgress ? ViewGroup.LayoutParams.WRAP_CONTENT : ViewGroup.LayoutParams.MATCH_PARENT); @@ -3461,6 +3493,7 @@ public class Notification implements Parcelable int textId = showProgress ? com.android.internal.R.id.text_line_1 : com.android.internal.R.id.text; contentView.setTextViewText(textId, p.text); + setTextViewColorSecondary(contentView, textId); contentView.setViewVisibility(textId, View.VISIBLE); } @@ -3469,6 +3502,52 @@ public class Notification implements Parcelable return contentView; } + private void setTextViewColorPrimary(RemoteViews contentView, int id) { + ensureColors(); + contentView.setTextColor(id, mPrimaryTextColor); + } + + private int getPrimaryTextColor() { + ensureColors(); + return mPrimaryTextColor; + } + + private int getActionBarColor() { + ensureColors(); + return mActionBarColor; + } + + private void setTextViewColorSecondary(RemoteViews contentView, int id) { + ensureColors(); + contentView.setTextColor(id, mSecondaryTextColor); + } + + private void ensureColors() { + int backgroundColor = getBackgroundColor(); + if (mPrimaryTextColor == COLOR_INVALID + || mSecondaryTextColor == COLOR_INVALID + || mActionBarColor == COLOR_INVALID + || mTextColorsAreForBackground != backgroundColor) { + mTextColorsAreForBackground = backgroundColor; + mPrimaryTextColor = NotificationColorUtil.resolvePrimaryColor( + mContext, backgroundColor); + mSecondaryTextColor = NotificationColorUtil.resolveSecondaryColor( + mContext, backgroundColor); + mActionBarColor = NotificationColorUtil.resolveActionBarColor(backgroundColor); + } + } + + private void updateBackgroundColor(RemoteViews contentView) { + if (isColorized()) { + contentView.setInt(R.id.status_bar_latest_event_content, "setBackgroundColor", + getBackgroundColor()); + } else { + // Clear it! + contentView.setInt(R.id.status_bar_latest_event_content, "setBackgroundResource", + 0); + } + } + /** * @param remoteView the remote view to update the minheight in * @param hasMinHeight does it have a mimHeight @@ -3535,15 +3614,17 @@ public class Notification implements Parcelable } private void bindExpandButton(RemoteViews contentView) { - contentView.setDrawableParameters(R.id.expand_button, false, -1, resolveContrastColor(), + int color = isColorized() ? getPrimaryTextColor() : resolveContrastColor(); + contentView.setDrawableParameters(R.id.expand_button, false, -1, color, PorterDuff.Mode.SRC_ATOP, -1); contentView.setInt(R.id.notification_header, "setOriginalNotificationColor", - resolveContrastColor()); + color); } private void bindHeaderChronometerAndTime(RemoteViews contentView) { if (showsTimeOrChronometer()) { contentView.setViewVisibility(R.id.time_divider, View.VISIBLE); + setTextViewColorSecondary(contentView, R.id.time_divider); if (mN.extras.getBoolean(EXTRA_SHOW_CHRONOMETER)) { contentView.setViewVisibility(R.id.chronometer, View.VISIBLE); contentView.setLong(R.id.chronometer, "setBase", @@ -3551,9 +3632,11 @@ public class Notification implements Parcelable contentView.setBoolean(R.id.chronometer, "setStarted", true); boolean countsDown = mN.extras.getBoolean(EXTRA_CHRONOMETER_COUNT_DOWN); contentView.setChronometerCountDown(R.id.chronometer, countsDown); + setTextViewColorSecondary(contentView, R.id.chronometer); } else { contentView.setViewVisibility(R.id.time, View.VISIBLE); contentView.setLong(R.id.time, "setTime", mN.when); + setTextViewColorSecondary(contentView, R.id.time); } } else { // We still want a time to be set but gone, such that we can show and hide it @@ -3576,8 +3659,10 @@ public class Notification implements Parcelable if (headerText != null) { // TODO: Remove the span entirely to only have the string with propper formating. contentView.setTextViewText(R.id.header_text, processLegacyText(headerText)); + setTextViewColorSecondary(contentView, R.id.header_text); contentView.setViewVisibility(R.id.header_text, View.VISIBLE); contentView.setViewVisibility(R.id.header_text_divider, View.VISIBLE); + setTextViewColorSecondary(contentView, R.id.header_text_divider); } } @@ -3616,8 +3701,12 @@ public class Notification implements Parcelable } private void bindHeaderAppName(RemoteViews contentView, boolean ambient) { contentView.setTextViewText(R.id.app_name_text, loadHeaderAppName()); - contentView.setTextColor(R.id.app_name_text, - ambient ? resolveAmbientColor() : resolveContrastColor()); + if (isColorized()) { + setTextViewColorPrimary(contentView, R.id.app_name_text); + } else { + contentView.setTextColor(R.id.app_name_text, + ambient ? resolveAmbientColor() : resolveContrastColor()); + } } private void bindSmallIcon(RemoteViews contentView, boolean ambient) { @@ -3675,6 +3764,11 @@ public class Notification implements Parcelable big.setViewVisibility(R.id.actions, View.VISIBLE); if (p.ambient) { big.setInt(R.id.actions, "setBackgroundColor", Color.TRANSPARENT); + } else if (isColorized()) { + big.setInt(R.id.actions, "setBackgroundColor", getActionBarColor()); + } else { + big.setInt(R.id.actions, "setBackgroundColor", mContext.getColor( + R.color.notification_action_list)); } big.setViewLayoutMarginBottomDimen(R.id.notification_action_list_margin_target, R.dimen.notification_action_list_height); @@ -3696,15 +3790,18 @@ public class Notification implements Parcelable && replyText.length > 0 && !TextUtils.isEmpty(replyText[0])) { big.setViewVisibility(R.id.notification_material_reply_container, View.VISIBLE); big.setTextViewText(R.id.notification_material_reply_text_1, replyText[0]); + setTextViewColorSecondary(big, R.id.notification_material_reply_text_1); if (replyText.length > 1 && !TextUtils.isEmpty(replyText[1])) { big.setViewVisibility(R.id.notification_material_reply_text_2, View.VISIBLE); big.setTextViewText(R.id.notification_material_reply_text_2, replyText[1]); + setTextViewColorSecondary(big, R.id.notification_material_reply_text_2); if (replyText.length > 2 && !TextUtils.isEmpty(replyText[2])) { big.setViewVisibility( R.id.notification_material_reply_text_3, View.VISIBLE); big.setTextViewText(R.id.notification_material_reply_text_3, replyText[2]); + setTextViewColorSecondary(big, R.id.notification_material_reply_text_3); } } } @@ -3930,6 +4027,7 @@ public class Notification implements Parcelable if (action.mRemoteInputs != null) { button.setRemoteInputs(R.id.action0, action.mRemoteInputs); } + // TODO: handle emphasized mode / actions right if (emphazisedMode) { // change the background bgColor int bgColor = mContext.getColor(oddAction ? R.color.notification_action_list @@ -3945,16 +4043,19 @@ public class Notification implements Parcelable title = ensureColorSpanContrast(title, bgColor, outResultColor); } button.setTextViewText(R.id.action0, title); + setTextViewColorPrimary(button, R.id.action0); if (outResultColor != null && outResultColor[0] != null) { // 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) { + } else if (mN.color != COLOR_DEFAULT && !isColorized()) { button.setTextColor(R.id.action0,resolveContrastColor()); } } else { button.setTextViewText(R.id.action0, processLegacyText(action.title)); - if (mN.color != COLOR_DEFAULT) { + if (isColorized()) { + setTextViewColorPrimary(button, R.id.action0); + } else if (mN.color != COLOR_DEFAULT) { button.setTextColor(R.id.action0, ambient ? resolveAmbientColor() : resolveContrastColor()); } @@ -4073,11 +4174,16 @@ public class Notification implements Parcelable * doesn't create material notifications by itself) app. */ private boolean isLegacy() { - return getColorUtil() != null; + if (!mIsLegacyInitialized) { + mIsLegacy = mContext.getApplicationInfo().targetSdkVersion + < Build.VERSION_CODES.LOLLIPOP; + mIsLegacyInitialized = true; + } + return mIsLegacy; } private CharSequence processLegacyText(CharSequence charSequence) { - if (isLegacy()) { + if (isLegacy() || isColorized()) { return getColorUtil().invertCharSequenceColors(charSequence); } else { return charSequence; @@ -4339,6 +4445,37 @@ public class Notification implements Parcelable private int getActionTombstoneLayoutResource() { return R.layout.notification_material_action_tombstone; } + + private int getBackgroundColor() { + if (isColorized()) { + return mN.color; + } else { + return COLOR_DEFAULT; + } + } + + private boolean isColorized() { + return mN.isColorized(); + } + } + + /** + * @return whether this notification is ongoing and can't be dismissed by the user. + */ + private boolean isOngoing() { + final int ongoingFlags = Notification.FLAG_FOREGROUND_SERVICE + | Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; + return (flags & ongoingFlags) != 0; + } + + /** + * @return true if this notification is colorized. This also factors in wheather the + * notification is ongoing. + * + * @hide + */ + public boolean isColorized() { + return extras.getBoolean(EXTRA_COLORIZED) && isOngoing(); } private boolean hasLargeIcon() { @@ -4672,6 +4809,7 @@ public class Notification implements Parcelable RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource()); if (mSummaryTextSet) { contentView.setTextViewText(R.id.text, mBuilder.processLegacyText(mSummaryText)); + mBuilder.setTextViewColorSecondary(contentView, R.id.text); contentView.setViewVisibility(R.id.text, View.VISIBLE); } mBuilder.setContentMinHeight(contentView, mBuilder.mN.hasLargeIcon()); @@ -4827,6 +4965,7 @@ public class Notification implements Parcelable static void applyBigTextContentView(Builder builder, RemoteViews contentView, CharSequence bigTextText) { contentView.setTextViewText(R.id.big_text, bigTextText); + builder.setTextViewColorSecondary(contentView, R.id.big_text); contentView.setViewVisibility(R.id.big_text, TextUtils.isEmpty(bigTextText) ? View.GONE : View.VISIBLE); contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines(builder)); @@ -5070,7 +5209,7 @@ public class Notification implements Parcelable : (m == null) ? null : m.mSender; CharSequence text = (m == null) ? null - : mConversationTitle != null ? makeMessageLine(m) : m.mText; + : mConversationTitle != null ? makeMessageLine(m, mBuilder) : m.mText; return mBuilder.applyStandardTemplateWithActions(mBuilder.getBaseLayoutResource(), mBuilder.mParams.reset().hasProgress(false).title(title).text(text)); @@ -5108,7 +5247,7 @@ public class Notification implements Parcelable CharSequence text; if (hasTitle) { bigTitle = title; - text = makeMessageLine(mMessages.get(0)); + text = makeMessageLine(mMessages.get(0), mBuilder); } else { bigTitle = mMessages.get(0).mSender; text = mMessages.get(0).mText; @@ -5146,7 +5285,7 @@ public class Notification implements Parcelable Message m = mHistoricMessages.get(firstHistoricMessage + i); int rowId = rowIds[i]; - contentView.setTextViewText(rowId, makeMessageLine(m)); + contentView.setTextViewText(rowId, makeMessageLine(m, mBuilder)); if (contractedMessage == m) { contractedChildId = rowId; @@ -5161,7 +5300,8 @@ public class Notification implements Parcelable int rowId = rowIds[i]; contentView.setViewVisibility(rowId, View.VISIBLE); - contentView.setTextViewText(rowId, makeMessageLine(m)); + contentView.setTextViewText(rowId, makeMessageLine(m, mBuilder)); + mBuilder.setTextViewColorSecondary(contentView, rowId); if (contractedMessage == m) { contractedChildId = rowId; @@ -5183,17 +5323,22 @@ public class Notification implements Parcelable return contentView; } - private CharSequence makeMessageLine(Message m) { + private CharSequence makeMessageLine(Message m, Builder builder) { BidiFormatter bidi = BidiFormatter.getInstance(); SpannableStringBuilder sb = new SpannableStringBuilder(); + boolean colorize = builder.isColorized(); if (TextUtils.isEmpty(m.mSender)) { CharSequence replyName = mUserDisplayName == null ? "" : mUserDisplayName; sb.append(bidi.unicodeWrap(replyName), - makeFontColorSpan(mBuilder.resolveContrastColor()), + makeFontColorSpan(colorize + ? builder.getPrimaryTextColor() + : mBuilder.resolveContrastColor()), 0 /* flags */); } else { sb.append(bidi.unicodeWrap(m.mSender), - makeFontColorSpan(Color.BLACK), + makeFontColorSpan(colorize + ? builder.getPrimaryTextColor() + : Color.BLACK), 0 /* flags */); } CharSequence text = m.mText == null ? "" : m.mText; @@ -5212,7 +5357,7 @@ public class Notification implements Parcelable : (m == null) ? null : m.mSender; CharSequence text = (m == null) ? null - : mConversationTitle != null ? makeMessageLine(m) : m.mText; + : mConversationTitle != null ? makeMessageLine(m, mBuilder) : m.mText; return mBuilder.applyStandardTemplateWithActions(mBuilder.getBigBaseLayoutResource(), mBuilder.mParams.reset().hasProgress(false).title(title).text(text)); @@ -5503,6 +5648,7 @@ public class Notification implements Parcelable if (!TextUtils.isEmpty(str)) { contentView.setViewVisibility(rowIds[i], View.VISIBLE); contentView.setTextViewText(rowIds[i], mBuilder.processLegacyText(str)); + mBuilder.setTextViewColorSecondary(contentView, rowIds[i]); contentView.setViewPadding(rowIds[i], 0, topPadding, 0, 0); handleInboxImageMargin(contentView, rowIds[i], first); if (first) { |
