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

Commit cdf6b6b4 authored by Jeff DeCew's avatar Jeff DeCew
Browse files

Flow text around the large icon.

This is only necessary when a notification is posted without a title.

Fixes: 177976174
Test: Manual inspection of various staes.
Change-Id: I15fdc31e1557b7e5d6fb99e410f4bf37d6734ac4
parent d6209d4e
Loading
Loading
Loading
Loading
+39 −26
Original line number Diff line number Diff line
@@ -5015,11 +5015,14 @@ public class Notification implements Parcelable
            }
            if (p.text != null && p.text.length() != 0
                    && (!showProgress || p.mAllowTextWithProgress)) {
                int textId = com.android.internal.R.id.text;
                contentView.setTextViewText(textId, processTextSpans(p.text));
                setTextViewColorSecondary(contentView, textId, p);
                contentView.setViewVisibility(textId, View.VISIBLE);
                contentView.setViewVisibility(p.mTextViewId, View.VISIBLE);
                contentView.setTextViewText(p.mTextViewId, processTextSpans(p.text));
                setTextViewColorSecondary(contentView, p.mTextViewId, p);
                hasSecondLine = true;
            } else if (p.mTextViewId != R.id.text) {
                // This alternate text view ID is not cleared by resetStandardTemplate
                contentView.setViewVisibility(p.mTextViewId, View.GONE);
                contentView.setTextViewText(p.mTextViewId, null);
            }
            setHeaderlessVerticalMargins(contentView, p, hasSecondLine);

@@ -5211,6 +5214,9 @@ public class Notification implements Parcelable
                // views in states with a header (big states)
                result.mHeadingExtraMarginSet.applyToView(contentView, R.id.notification_header);
                result.mTitleMarginSet.applyToView(contentView, R.id.title);
                // If there is no title, the text (or big_text) needs to wrap around the image
                result.mTitleMarginSet.applyToView(contentView, p.mTextViewId);
                contentView.setInt(p.mTextViewId, "setNumIndentLines", p.hasTitle() ? 0 : 1);
            }
        }

@@ -7011,16 +7017,7 @@ public class Notification implements Parcelable
                p.title = mBigContentTitle;
            }

            RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(layoutId, p,
                    result);

            if (mBigContentTitle != null && mBigContentTitle.equals("")) {
                contentView.setViewVisibility(R.id.title, View.GONE);
            } else {
                contentView.setViewVisibility(R.id.title, View.VISIBLE);
            }

            return contentView;
            return mBuilder.applyStandardTemplateWithActions(layoutId, p, result);
        }

        /**
@@ -7613,22 +7610,16 @@ public class Notification implements Parcelable
        public RemoteViews makeBigContentView() {
            StandardTemplateParams p = mBuilder.mParams.reset()
                    .viewType(StandardTemplateParams.VIEW_TYPE_BIG)
                    .fillTextsFrom(mBuilder).text(null);
            RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource(), p, null);
                    .textViewId(R.id.big_text)
                    .fillTextsFrom(mBuilder);

            // Replace the text with the big text, but only if the big text is not empty.
            CharSequence bigTextText = mBuilder.processLegacyText(mBigText);
            if (TextUtils.isEmpty(bigTextText)) {
                // In case the bigtext is null / empty fall back to the normal text to avoid a weird
                // experience
                bigTextText = mBuilder.processLegacyText(
                        mBuilder.getAllExtras().getCharSequence(EXTRA_TEXT));
            if (!TextUtils.isEmpty(bigTextText)) {
                p.text(bigTextText);
            }
            contentView.setTextViewText(R.id.big_text, mBuilder.processTextSpans(bigTextText));
            mBuilder.setTextViewColorSecondary(contentView, R.id.big_text, p);
            contentView.setViewVisibility(R.id.big_text,
                    TextUtils.isEmpty(bigTextText) ? View.GONE : View.VISIBLE);

            return contentView;
            return getStandardView(mBuilder.getBigTextLayoutResource(), p, null /* result */);
        }

        /**
@@ -12021,6 +12012,21 @@ public class Notification implements Parcelable
                if (viewId == R.id.notification_header) {
                    views.setFloat(R.id.notification_header,
                            "setTopLineExtraMarginEndDp", marginEndDp);
                } else if (viewId == R.id.text || viewId == R.id.big_text) {
                    if (mValueIfGone != 0) {
                        throw new RuntimeException("Programming error: `text` and `big_text` use "
                                + "ImageFloatingTextView which can either show a margin or not; "
                                + "thus mValueIfGone must be 0, but it was " + mValueIfGone);
                    }
                    // Note that the caller must set "setNumIndentLines" to a positive int in order
                    //  for this margin to do anything at all.
                    views.setFloat(viewId, "setImageEndMarginDp", mValueIfVisible);
                    views.setBoolean(viewId, "setHasImage", mRightIconVisible);
                    // Apply just the *extra* margin as the view layout margin; this will be
                    //  unchanged depending on the visibility of the image, but it means that the
                    //  extra margin applies to *every* line of text instead of just indented lines.
                    views.setViewLayoutMargin(viewId, RemoteViews.MARGIN_END,
                            extraMarginDp, TypedValue.COMPLEX_UNIT_DIP);
                } else {
                    views.setViewLayoutMargin(viewId, RemoteViews.MARGIN_END,
                                    marginEndDp, TypedValue.COMPLEX_UNIT_DIP);
@@ -12059,6 +12065,7 @@ public class Notification implements Parcelable
        boolean mPromotePicture;
        boolean mAllowActionIcons;
        boolean mAllowTextWithProgress;
        int mTextViewId;
        CharSequence title;
        CharSequence text;
        CharSequence headerTextSecondary;
@@ -12078,6 +12085,7 @@ public class Notification implements Parcelable
            mPromotePicture = false;
            mAllowActionIcons = false;
            mAllowTextWithProgress = false;
            mTextViewId = R.id.text;
            title = null;
            text = null;
            summaryText = null;
@@ -12137,6 +12145,11 @@ public class Notification implements Parcelable
            return this;
        }

        public StandardTemplateParams textViewId(int textViewId) {
            mTextViewId = textViewId;
            return this;
        }

        final StandardTemplateParams title(CharSequence title) {
            this.title = title;
            return this;
+48 −19
Original line number Diff line number Diff line
@@ -36,8 +36,10 @@ import android.widget.TextView;
@RemoteViews.RemoteView
public class ImageFloatingTextView extends TextView {

    /** Number of lines from the top to indent */
    private int mIndentLines;
    /** Number of lines from the top to indent. */
    private int mIndentLines = 0;
    /** Whether or not there is an image to indent for. */
    private boolean mHasImage = false;

    /** Resolved layout direction */
    private int mResolvedDirection = LAYOUT_DIRECTION_UNDEFINED;
@@ -96,7 +98,7 @@ public class ImageFloatingTextView extends TextView {

        // we set the endmargin on the requested number of lines.
        int[] margins = null;
        if (mIndentLines > 0) {
        if (mHasImage && mIndentLines > 0) {
            margins = new int[mIndentLines + 1];
            for (int i = 0; i < mIndentLines; i++) {
                margins[i] = mImageEndMargin;
@@ -111,9 +113,24 @@ public class ImageFloatingTextView extends TextView {
        return builder.build();
    }

    /**
     * @param imageEndMargin the end margin (in pixels) to indent the first few lines of the text
     */
    @RemotableViewMethod
    public void setImageEndMargin(int imageEndMargin) {
        if (mImageEndMargin != imageEndMargin) {
            mImageEndMargin = imageEndMargin;
            invalidateTextIfIndenting();
        }
    }

    /**
     * @param imageEndMarginDp the end margin (in dp) to indent the first few lines of the text
     */
    @RemotableViewMethod
    public void setImageEndMarginDp(float imageEndMarginDp) {
        setImageEndMargin(
                (int) (imageEndMarginDp * getResources().getDisplayMetrics().density));
    }

    @Override
@@ -121,7 +138,7 @@ public class ImageFloatingTextView extends TextView {
        int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mPaddingTop - mPaddingBottom;
        if (getLayout() != null && getLayout().getHeight() != availableHeight) {
            // We've been measured before and the new size is different than before, lets make sure
            // we reset the maximum lines, otherwise we may be cut short
            // we reset the maximum lines, otherwise the last line of text may be partially cut off
            mMaxLinesForHeight = -1;
            nullLayouts();
        }
@@ -130,7 +147,7 @@ public class ImageFloatingTextView extends TextView {
        if (layout.getHeight() > availableHeight) {
            // With the existing layout, not all of our lines fit on the screen, let's find the
            // first one that fits and ellipsize at that one.
            int maxLines = layout.getLineCount() - 1;
            int maxLines = layout.getLineCount();
            while (maxLines > 1 && layout.getLineBottom(maxLines - 1) > availableHeight) {
                maxLines--;
            }
@@ -152,31 +169,43 @@ public class ImageFloatingTextView extends TextView {

        if (layoutDirection != mResolvedDirection && isLayoutDirectionResolved()) {
            mResolvedDirection = layoutDirection;
            if (mIndentLines > 0) {
            invalidateTextIfIndenting();
        }
    }

    private void invalidateTextIfIndenting() {
        if (mHasImage && mIndentLines > 0) {
            // Invalidate layout.
            nullLayouts();
            requestLayout();
        }
    }
    }

    /**
     * @param hasImage whether there is an image to wrap text around.
     */
    @RemotableViewMethod
    public void setHasImage(boolean hasImage) {
        setNumIndentLines(hasImage ? 2 : 0);
        setHasImageAndNumIndentLines(hasImage, mIndentLines);
    }

    /**
     * @param lines the number of lines at the top that should be indented by indentEnd
     * @return whether a change was made
     */
    public boolean setNumIndentLines(int lines) {
        if (mIndentLines != lines) {
    @RemotableViewMethod
    public void setNumIndentLines(int lines) {
        setHasImageAndNumIndentLines(mHasImage, lines);
    }

    private void setHasImageAndNumIndentLines(boolean hasImage, int lines) {
        int oldEffectiveLines = mHasImage ? mIndentLines : 0;
        int newEffectiveLines = hasImage ? lines : 0;
        mIndentLines = lines;
            // Invalidate layout.
        mHasImage = hasImage;
        if (oldEffectiveLines != newEffectiveLines) {
            // always invalidate layout.
            nullLayouts();
            requestLayout();
            return true;
        }
        return false;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
    android:layout_gravity="top"
    android:layout_marginTop="@dimen/notification_text_margin_top"
    android:minHeight="@dimen/notification_text_height"
    android:ellipsize="marquee"
    android:ellipsize="end"
    android:fadingEdge="horizontal"
    android:gravity="top"
    android:maxLines="2"
+7 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.widget.TextView;
import com.android.internal.R;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.ConversationLayout;
import com.android.internal.widget.ImageFloatingTextView;
import com.android.internal.widget.NotificationExpandButton;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationContentView;
@@ -430,6 +431,8 @@ public class NotificationGroupingUtil {

        public static final int[] MARGIN_ADJUSTED_VIEWS = {
                R.id.notification_headerless_view_column,
                R.id.text,
                R.id.big_text,
                R.id.title,
                R.id.notification_main_column,
                R.id.notification_header};
@@ -458,6 +461,10 @@ public class NotificationGroupingUtil {
            if (target == null) {
                return;
            }
            if (target instanceof ImageFloatingTextView) {
                ((ImageFloatingTextView) target).setHasImage(iconVisible);
                return;
            }
            final Integer data = (Integer) target.getTag(iconVisible
                    ? com.android.internal.R.id.tag_margin_end_when_icon_visible
                    : com.android.internal.R.id.tag_margin_end_when_icon_gone);