summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2017-01-26 02:06:03 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-01-26 02:06:06 +0000
commitca19e3278bca7f259002b9ea8ad79f66da4e61eb (patch)
treeca14b4ff9acce5173498dbfa3345894e7c5c1150 /core/java/android
parent2a27b2ca7c3c6631fb9e7ff4f1999fdbcef3caf6 (diff)
parent7b9605b79c4f738ee5b306d8693018e931cda18e (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.java184
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) {