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

Commit 60a09546 authored by Selim Cinek's avatar Selim Cinek Committed by Android (Google) Code Review
Browse files

Merge "Transforming all texts of decorated media custom views" into oc-mr1-dev

parents f7964b15 87c3153d
Loading
Loading
Loading
Loading
+3 −42
Original line number Diff line number Diff line
@@ -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);
@@ -4710,45 +4709,6 @@ public class Notification implements Parcelable
            return button;
        }

        /**
         * 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();
+63 −0
Original line number Diff line number Diff line
@@ -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.
@@ -220,6 +223,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.
@@ -2248,6 +2262,52 @@ public class RemoteViews implements Parcelable, Filter {
        final Parcelable[] remoteInputs;
    }

    /**
     * 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");
                    }
+40 −0
Original line number Diff line number Diff line
@@ -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),