diff options
| -rw-r--r-- | core/java/android/app/Notification.java | 45 | ||||
| -rw-r--r-- | core/java/android/widget/RemoteViews.java | 63 | ||||
| -rw-r--r-- | core/java/com/android/internal/util/NotificationColorUtil.java | 40 |
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), |