summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/Notification.java45
-rw-r--r--core/java/android/widget/RemoteViews.java63
-rw-r--r--core/java/com/android/internal/util/NotificationColorUtil.java40
3 files changed, 106 insertions, 42 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ff3603de9725..9511f3fd7cef 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -60,7 +60,6 @@ import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
-import android.text.style.BackgroundColorSpan;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
@@ -3923,7 +3922,7 @@ public class Notification implements Parcelable
private CharSequence processTextSpans(CharSequence text) {
if (hasForegroundColor()) {
- return clearColorSpans(text);
+ return NotificationColorUtil.clearColorSpans(text);
}
return text;
}
@@ -4683,7 +4682,7 @@ public class Notification implements Parcelable
CharSequence title = action.title;
ColorStateList[] outResultColor = null;
if (isLegacy()) {
- title = clearColorSpans(title);
+ title = NotificationColorUtil.clearColorSpans(title);
} else {
outResultColor = new ColorStateList[1];
title = ensureColorSpanContrast(title, bgColor, outResultColor);
@@ -4711,45 +4710,6 @@ public class Notification implements Parcelable
}
/**
- * Clears all color spans of a text
- * @param charSequence the input text
- * @return the same text but without color spans
- */
- private CharSequence clearColorSpans(CharSequence charSequence) {
- if (charSequence instanceof Spanned) {
- Spanned ss = (Spanned) charSequence;
- Object[] spans = ss.getSpans(0, ss.length(), Object.class);
- SpannableStringBuilder builder = new SpannableStringBuilder(ss.toString());
- for (Object span : spans) {
- Object resultSpan = span;
- if (resultSpan instanceof CharacterStyle) {
- resultSpan = ((CharacterStyle) span).getUnderlying();
- }
- if (resultSpan instanceof TextAppearanceSpan) {
- TextAppearanceSpan originalSpan = (TextAppearanceSpan) resultSpan;
- if (originalSpan.getTextColor() != null) {
- resultSpan = new TextAppearanceSpan(
- originalSpan.getFamily(),
- originalSpan.getTextStyle(),
- originalSpan.getTextSize(),
- null,
- originalSpan.getLinkTextColor());
- }
- } else if (resultSpan instanceof ForegroundColorSpan
- || (resultSpan instanceof BackgroundColorSpan)) {
- continue;
- } else {
- resultSpan = span;
- }
- builder.setSpan(resultSpan, ss.getSpanStart(span), ss.getSpanEnd(span),
- ss.getSpanFlags(span));
- }
- return builder;
- }
- return charSequence;
- }
-
- /**
* Ensures contrast on color spans against a background color. also returns the color of the
* text if a span was found that spans over the whole text.
*
@@ -7075,6 +7035,7 @@ public class Notification implements Parcelable
// Need to clone customContent before adding, because otherwise it can no longer be
// parceled independently of remoteViews.
customContent = customContent.clone();
+ customContent.overrideTextColors(mBuilder.getPrimaryTextColor());
remoteViews.removeAllViews(id);
remoteViews.addView(id, customContent);
remoteViews.setReapplyDisallowed();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 5c63c755ce07..5adbdbe8ab4f 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -64,6 +64,7 @@ import android.view.ViewStub;
import android.widget.AdapterView.OnItemClickListener;
import com.android.internal.R;
+import com.android.internal.util.NotificationColorUtil;
import com.android.internal.util.Preconditions;
import libcore.util.Objects;
@@ -75,6 +76,7 @@ import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Stack;
import java.util.concurrent.Executor;
/**
@@ -118,6 +120,7 @@ public class RemoteViews implements Parcelable, Filter {
private static final int TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG = 17;
private static final int SET_REMOTE_INPUTS_ACTION_TAG = 18;
private static final int LAYOUT_PARAM_ACTION_TAG = 19;
+ private static final int OVERRIDE_TEXT_COLORS_TAG = 20;
/**
* Application that hosts the remote views.
@@ -221,6 +224,17 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Override all text colors in this layout and replace them by the given text color.
+ *
+ * @param textColor The color to use.
+ *
+ * @hide
+ */
+ public void overrideTextColors(int textColor) {
+ addAction(new OverrideTextColorsAction(textColor));
+ }
+
+ /**
* Set that it is disallowed to reapply another remoteview with the same layout as this view.
* This should be done if an action is destroying the view tree of the base layout.
*
@@ -2249,6 +2263,52 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Helper action to override all textViewColors
+ */
+ private class OverrideTextColorsAction extends Action {
+
+ private final int textColor;
+
+ public OverrideTextColorsAction(int textColor) {
+ this.textColor = textColor;
+ }
+
+ public OverrideTextColorsAction(Parcel parcel) {
+ textColor = parcel.readInt();
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(OVERRIDE_TEXT_COLORS_TAG);
+ dest.writeInt(textColor);
+ }
+
+ @Override
+ public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
+ // Let's traverse the viewtree and override all textColors!
+ Stack<View> viewsToProcess = new Stack<>();
+ viewsToProcess.add(root);
+ while (!viewsToProcess.isEmpty()) {
+ View v = viewsToProcess.pop();
+ if (v instanceof TextView) {
+ TextView textView = (TextView) v;
+ textView.setText(NotificationColorUtil.clearColorSpans(textView.getText()));
+ textView.setTextColor(textColor);
+ }
+ if (v instanceof ViewGroup) {
+ ViewGroup viewGroup = (ViewGroup) v;
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ viewsToProcess.push(viewGroup.getChildAt(i));
+ }
+ }
+ }
+ }
+
+ public String getActionName() {
+ return "OverrideTextColorsAction";
+ }
+ }
+
+ /**
* Simple class used to keep track of memory usage in a RemoteViews.
*
*/
@@ -2443,6 +2503,9 @@ public class RemoteViews implements Parcelable, Filter {
case LAYOUT_PARAM_ACTION_TAG:
mActions.add(new LayoutParamAction(parcel));
break;
+ case OVERRIDE_TEXT_COLORS_TAG:
+ mActions.add(new OverrideTextColorsAction(parcel));
+ break;
default:
throw new ActionException("Tag " + tag + " not found");
}
diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java
index 2778d93a5388..933cc7af975a 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -33,6 +33,7 @@ import android.graphics.drawable.Icon;
import android.graphics.drawable.VectorDrawable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
+import android.text.style.BackgroundColorSpan;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.TextAppearanceSpan;
@@ -240,6 +241,45 @@ public class NotificationColorUtil {
return span;
}
+ /**
+ * Clears all color spans of a text
+ * @param charSequence the input text
+ * @return the same text but without color spans
+ */
+ public static CharSequence clearColorSpans(CharSequence charSequence) {
+ if (charSequence instanceof Spanned) {
+ Spanned ss = (Spanned) charSequence;
+ Object[] spans = ss.getSpans(0, ss.length(), Object.class);
+ SpannableStringBuilder builder = new SpannableStringBuilder(ss.toString());
+ for (Object span : spans) {
+ Object resultSpan = span;
+ if (resultSpan instanceof CharacterStyle) {
+ resultSpan = ((CharacterStyle) span).getUnderlying();
+ }
+ if (resultSpan instanceof TextAppearanceSpan) {
+ TextAppearanceSpan originalSpan = (TextAppearanceSpan) resultSpan;
+ if (originalSpan.getTextColor() != null) {
+ resultSpan = new TextAppearanceSpan(
+ originalSpan.getFamily(),
+ originalSpan.getTextStyle(),
+ originalSpan.getTextSize(),
+ null,
+ originalSpan.getLinkTextColor());
+ }
+ } else if (resultSpan instanceof ForegroundColorSpan
+ || (resultSpan instanceof BackgroundColorSpan)) {
+ continue;
+ } else {
+ resultSpan = span;
+ }
+ builder.setSpan(resultSpan, ss.getSpanStart(span), ss.getSpanEnd(span),
+ ss.getSpanFlags(span));
+ }
+ return builder;
+ }
+ return charSequence;
+ }
+
private int processColor(int color) {
return Color.argb(Color.alpha(color),
255 - Color.red(color),