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

Commit 66b31065 authored by Ioana Alexandru's avatar Ioana Alexandru Committed by Android (Google) Code Review
Browse files

Merge "[Notif redesign] Make text flow below expander in collapsed notifs" into main

parents b77d192c bfae1961
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -6321,6 +6321,13 @@ public class Notification implements Parcelable
                // 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);
            } else if (notificationsRedesignTemplates() && !p.mCompact) {
                // In the collapsed view (except for compact HUNs), the top line needs to
                // accommodate both the expander and large icon (when present)
                result.mHeadingFullMarginSet.applyToView(contentView, R.id.notification_top_line);
                // The text underneath can flow below the expander, but only if there's no large
                // icon to leave space for (similar to the title in the expanded version).
                result.mTitleMarginSet.applyToView(contentView, R.id.notification_main_column);
            }
            // The expand button uses paddings rather than margins, so we'll adjust it
            // separately.
@@ -6435,7 +6442,7 @@ public class Notification implements Parcelable
                contentView.setImageViewIcon(R.id.right_icon, rightIcon);
                contentView.setIntTag(R.id.right_icon, R.id.tag_keep_when_showing_left_icon,
                        isPromotedPicture ? 1 : 0);
                if ((notificationsRedesignTemplates() || Flags.uiRichOngoing()) && !p.mHeaderless) {
                if (notificationsRedesignTemplates() || Flags.uiRichOngoing()) {
                    contentView.setViewLayoutMargin(R.id.right_icon,
                            RemoteViews.MARGIN_END, getLargeIconMarginEnd(p), COMPLEX_UNIT_PX);
                }
@@ -6464,7 +6471,7 @@ public class Notification implements Parcelable
            if (notificationsRedesignTemplates()) {
                int rightIconMarginPx = res.getDimensionPixelSize(
                        R.dimen.notification_2025_right_icon_expanded_margin_end);
                        R.dimen.notification_2025_right_icon_margin_end);
                int extraSpaceForExpanderPx = res.getDimensionPixelSize(
                        R.dimen.notification_2025_extra_space_for_expander);
                return rightIconMarginPx + extraSpaceForExpanderPx;
@@ -7172,6 +7179,7 @@ public class Notification implements Parcelable
            final StandardTemplateParams p = mParams.reset()
                    .viewType(StandardTemplateParams.VIEW_TYPE_HEADS_UP)
                    .compact(true)
                    .fillTextsFrom(this);
            // Notification text is shown as secondary header text
            // for the minimal hun when it is provided.
@@ -8435,8 +8443,12 @@ public class Notification implements Parcelable
                // ensures that we don't under-pad the content, which could lead to abuse, at the
                // cost of making single-line custom content over-padded.
                Builder.setHeaderlessVerticalMargins(template, p, true /* hasSecondLine */);
            } else {
                if (notificationsRedesignTemplates()) {
                    // also update the end margin to account for the large icon or expander
                    result.mHeadingFullMarginSet.applyToView(template,
                            R.id.notification_main_column);
                }
            } else {
                Resources resources = context.getResources();
                result.mTitleMarginSet.applyToView(template, R.id.notification_main_column,
                        resources.getDimension(R.dimen.notification_content_margin_end)
@@ -16505,6 +16517,7 @@ public class Notification implements Parcelable
        int mViewType = VIEW_TYPE_UNSPECIFIED;
        boolean mHeaderless;
        boolean mCompact;
        boolean mHideAppName;
        boolean mHideTitle;
        boolean mHideSubText;
@@ -16530,6 +16543,7 @@ public class Notification implements Parcelable
        final StandardTemplateParams reset() {
            mViewType = VIEW_TYPE_UNSPECIFIED;
            mHeaderless = false;
            mCompact = false;
            mHideAppName = false;
            mHideTitle = false;
            mHideSubText = false;
@@ -16568,6 +16582,11 @@ public class Notification implements Parcelable
            return this;
        }
        public StandardTemplateParams compact(boolean compact) {
            mCompact = compact;
            return this;
        }
        public StandardTemplateParams hideAppName(boolean hideAppName) {
            mHideAppName = hideAppName;
            return this;
+65 −14
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import android.app.Person;
import android.app.RemoteInputHistoryItem;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
@@ -49,8 +48,10 @@ import android.text.style.StyleSpan;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.NotificationTopLineView;
import android.view.RemotableViewMethod;
import android.view.TouchDelegate;
import android.view.View;
@@ -86,6 +87,7 @@ public class ConversationLayout extends FrameLayout
    public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
    public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
    public static final Interpolator OVERSHOOT = new PathInterpolator(0.4f, 0f, 0.2f, 1.4f);
    private static final String TAG = "ConversationLayout";
    private static final int MAX_SUMMARIZATION_LINES = 3;
    public static final int IMPORTANCE_ANIM_GROW_DURATION = 250;
    public static final int IMPORTANCE_ANIM_SHRINK_DURATION = 200;
@@ -123,6 +125,7 @@ public class ConversationLayout extends FrameLayout
    private ViewGroup mExpandButtonAndContentContainer;
    private ViewGroup mExpandButtonContainerA11yContainer;
    private NotificationExpandButton mExpandButton;
    private NotificationTopLineView mTopLine;
    private MessagingLinearLayout mImageMessageContainer;
    private ImageView mRightIconView;
    private int mBadgeProtrusion;
@@ -271,6 +274,7 @@ public class ConversationLayout extends FrameLayout
        mContentContainer = findViewById(R.id.notification_action_list_margin_target);
        mExpandButtonAndContentContainer = findViewById(R.id.expand_button_and_content_container);
        mExpandButton = findViewById(R.id.expand_button);
        mTopLine = findViewById(R.id.notification_top_line);
        mMessageSpacingStandard = getResources().getDimensionPixelSize(
                R.dimen.notification_messaging_spacing);
        mMessageSpacingGroup = getResources().getDimensionPixelSize(
@@ -753,7 +757,7 @@ public class ConversationLayout extends FrameLayout
                mImageMessageContainer.addView(newMessage);
            }
        }
        mImageMessageContainer.setVisibility(newMessage != null ? VISIBLE : GONE);
        mImageMessageContainer.setVisibility(isShowingImage ? VISIBLE : GONE);

        if (mRightIconView != null && mRightIconView.getDrawable() != null) {
            // When showing an image message, do not show the large icon.  Removing the drawable
@@ -763,23 +767,70 @@ public class ConversationLayout extends FrameLayout
                mRightIconView.setVisibility(GONE);
            }
        } else {
            // Only alter the padding if we're not showing the large icon; otherwise it's already
            // Only alter the spacing if we're not showing the large icon; otherwise it's already
            // been adjusted in Notification.java and we shouldn't override it.
            adjustExpandButtonPadding(isShowingImage);
            adjustSpacingForImage();
        }
    }

    /**
     * When showing an isolated image message similar to the large icon, adjust the padding of the
     * expand button in the same way we do for large icons.
     * When showing an isolated image message similar to the large icon, adjust the margin of the
     * text in the same way we do for large icons, to leave space for the image.
     */
    private void adjustExpandButtonPadding(boolean isShowingImage) {
        if (notificationsRedesignTemplates() && mExpandButton != null) {
            final Resources res = mContext.getResources();
            int normalPadding = res.getDimensionPixelSize(R.dimen.notification_2025_margin);
            int iconSpacing = res.getDimensionPixelSize(
                    R.dimen.notification_2025_expand_button_right_icon_spacing);
            mExpandButton.setStartPadding(isShowingImage ? iconSpacing : normalPadding);
    private void adjustSpacingForImage() {
        if (notificationsRedesignTemplates()) {
            int spacingForExpander = getSpacingForExpander();
            updateMarginEnd(mImageMessageContainer, spacingForExpander);

            int spacingForImage = getSpacingForImage();
            int textMargin = spacingForImage + spacingForExpander;
            updateMarginEnd(mTopLine, textMargin);
            // Only apply spacing to second line if there's an image - otherwise the text should
            // flow under the expander.
            if (spacingForImage > 0) {
                updateMarginEnd(mMessagingLinearLayout, textMargin);
            }
        }
    }

    /**
     * Calculate the amount of space necessary for the expander (adjusted with the font size).
     */
    private int getSpacingForExpander() {
        int iconMarginEnd = getResources().getDimensionPixelSize(
                R.dimen.notification_2025_right_icon_margin_end);
        int extraSpaceForExpander = getResources().getDimensionPixelSize(
                R.dimen.notification_2025_extra_space_for_expander);

        return iconMarginEnd + extraSpaceForExpander;
    }

    /**
     * Calculate the amount of space necessary for the image if present.
     */
    private int getSpacingForImage() {
        if (mImageMessageContainer != null && mImageMessageContainer.getVisibility() == VISIBLE) {
            // Unlike large icons which can be wider than tall, isolated image messages can only
            // be square, so we can use the fixed width directly.
            int imageWidth = getResources().getDimensionPixelSize(
                    R.dimen.notification_right_icon_size);
            int iconMarginStart = getResources().getDimensionPixelSize(
                    R.dimen.notification_2025_right_icon_content_margin);
            return iconMarginStart + imageWidth;
        }
        return 0;
    }

    private void updateMarginEnd(ViewGroup view, int marginEnd) {
        if (view == null) {
            Log.wtf(TAG, "The view passed to updateMarginEnd should not be null");
            return;
        }

        MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
        if (lp.getMarginEnd() != marginEnd) {
            lp.setMarginEnd(marginEnd);
            view.setLayoutParams(lp);
        }
    }

+71 −18
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import android.app.Notification;
import android.app.Person;
import android.app.RemoteInputHistoryItem;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.os.Bundle;
@@ -38,6 +37,8 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.NotificationTopLineView;
import android.view.RemotableViewMethod;
import android.view.View;
import android.view.ViewGroup;
@@ -66,6 +67,7 @@ public class MessagingLayout extends FrameLayout
    public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
    public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
    public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
    private static final String TAG = "MessagingLayout";
    private static final int MAX_SUMMARIZATION_LINES = 3;
    public static final OnLayoutChangeListener MESSAGING_PROPERTY_ANIMATOR
            = new MessagingPropertyAnimator();
@@ -77,7 +79,7 @@ public class MessagingLayout extends FrameLayout
    private final ArrayList<MessagingGroup> mGroups = new ArrayList<>();
    private MessagingLinearLayout mImageMessageContainer;
    private ImageView mRightIconView;
    private NotificationExpandButton mExpandButton;
    private NotificationTopLineView mTopLine;
    private Rect mMessagingClipRect;
    private int mLayoutColor;
    private int mSenderTextColor;
@@ -119,7 +121,7 @@ public class MessagingLayout extends FrameLayout
        mMessagingLinearLayout = findViewById(R.id.notification_messaging);
        mImageMessageContainer = findViewById(R.id.conversation_image_message_container);
        mRightIconView = findViewById(R.id.right_icon);
        mExpandButton = findViewById(R.id.expand_button);
        mTopLine = findViewById(R.id.notification_top_line);
        if (notificationsRedesignTemplates()) {
            // The left_icon in the header has the default rounded square background. Make sure
            // we're using the circular background instead.
@@ -211,6 +213,7 @@ public class MessagingLayout extends FrameLayout

    /**
     * Set Messaging data
     *
     * @param extras Bundle contains messaging data
     */
    @RemotableViewMethod(asyncImpl = "setDataAsync")
@@ -267,6 +270,7 @@ public class MessagingLayout extends FrameLayout
     * RemotableViewMethod's asyncImpl of {@link #setData(Bundle)}.
     * This should be called on a background thread, and returns a Runnable which is then must be
     * called on the main thread to complete the operation and set text.
     *
     * @param extras Bundle contains messaging data
     * @hide
     */
@@ -288,6 +292,7 @@ public class MessagingLayout extends FrameLayout

    /**
     * enable/disable precomputed text usage
     *
     * @hide
     */
    public void setPrecomputedTextEnabled(boolean precomputedTextEnabled) {
@@ -381,23 +386,70 @@ public class MessagingLayout extends FrameLayout
                mRightIconView.setVisibility(GONE);
            }
        } else {
            // Only alter the padding if we're not showing the large icon; otherwise it's already
            // Only alter the spacing if we're not showing the large icon; otherwise it's already
            // been adjusted in Notification.java and we shouldn't override it.
            adjustExpandButtonPadding(isShowingImage);
            adjustSpacingForImage();
        }
    }

    /**
     * When showing an isolated image message similar to the large icon, adjust the margin of the
     * text in the same way we do for large icons, to leave space for the image.
     */
    private void adjustSpacingForImage() {
        if (notificationsRedesignTemplates()) {
            int spacingForExpander = getSpacingForExpander();
            updateMarginEnd(mImageMessageContainer, spacingForExpander);

            int spacingForImage = getSpacingForImage();
            int textMargin = spacingForImage + spacingForExpander;
            updateMarginEnd(mTopLine, textMargin);
            // Only apply spacing to second line if there's an image - otherwise the text should
            // flow under the expander.
            if (spacingForImage > 0) {
                updateMarginEnd(mMessagingLinearLayout, textMargin);
            }
        }
    }

    /**
     * Calculate the amount of space necessary for the expander (adjusted with the font size).
     */
    private int getSpacingForExpander() {
        int iconMarginEnd = getResources().getDimensionPixelSize(
                R.dimen.notification_2025_right_icon_margin_end);
        int extraSpaceForExpander = getResources().getDimensionPixelSize(
                R.dimen.notification_2025_extra_space_for_expander);

        return iconMarginEnd + extraSpaceForExpander;
    }

    /**
     * When showing an isolated image message similar to the large icon, adjust the padding of the
     * expand button in the same way we do for large icons.
     * Calculate the amount of space necessary for the image if present.
     */
    private void adjustExpandButtonPadding(boolean isShowingImage) {
        if (notificationsRedesignTemplates() && mExpandButton != null) {
            final Resources res = mContext.getResources();
            int normalPadding = res.getDimensionPixelSize(R.dimen.notification_2025_margin);
            int iconSpacing = res.getDimensionPixelSize(
                    R.dimen.notification_2025_expand_button_right_icon_spacing);
            mExpandButton.setStartPadding(isShowingImage ? iconSpacing : normalPadding);
    private int getSpacingForImage() {
        if (mImageMessageContainer != null && mImageMessageContainer.getVisibility() == VISIBLE) {
            // Unlike large icons which can be wider than tall, isolated image messages can only
            // be square, so we can use the fixed width directly.
            int imageWidth = getResources().getDimensionPixelSize(
                    R.dimen.notification_right_icon_size);
            int iconMarginStart = getResources().getDimensionPixelSize(
                    R.dimen.notification_2025_right_icon_content_margin);
            return iconMarginStart + imageWidth;
        }
        return 0;
    }

    private void updateMarginEnd(ViewGroup view, int marginEnd) {
        if (view == null) {
            Log.wtf(TAG, "The view passed to updateMarginEnd should not be null");
            return;
        }

        MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
        if (lp.getMarginEnd() != marginEnd) {
            lp.setMarginEnd(marginEnd);
            view.setLayoutParams(lp);
        }
    }

@@ -525,6 +577,7 @@ public class MessagingLayout extends FrameLayout
        mSenderTextColor = color;
        return () -> {};
    }

    /**
     * @param color the color of the notification background
     */
+2 −2
Original line number Diff line number Diff line
@@ -13,14 +13,14 @@
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License
  -->
<!-- Large icon to be used in expanded notification layouts. -->
<!-- Large icon to be used in notification layouts. -->
<com.android.internal.widget.CachingIconView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/right_icon"
    android:layout_width="@dimen/notification_right_icon_size"
    android:layout_height="@dimen/notification_right_icon_size"
    android:layout_gravity="top|end"
    android:layout_marginEnd="@dimen/notification_2025_right_icon_expanded_margin_end"
    android:layout_marginEnd="@dimen/notification_2025_right_icon_margin_end"
    android:layout_marginTop="@dimen/notification_2025_right_icon_vertical_margin"
    android:background="@drawable/notification_large_icon_outline"
    android:clipToOutline="true"
+9 −20
Original line number Diff line number Diff line
@@ -58,12 +58,11 @@
        android:focusable="false"
        />

    <LinearLayout
    <FrameLayout
        android:id="@+id/notification_headerless_view_row"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginStart="@dimen/notification_2025_content_margin_start"
        android:orientation="horizontal"
        >

        <!--
@@ -72,19 +71,19 @@
        -->
        <LinearLayout
            android:id="@+id/notification_headerless_view_column"
            android:layout_width="0px"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:layout_marginVertical="@dimen/notification_2025_reduced_margin"
            android:orientation="vertical"
            >

            <NotificationTopLineView
                android:id="@+id/notification_top_line"
                android:layout_width="wrap_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/notification_2025_additional_margin"
                android:layout_marginEnd="@dimen/notification_2025_content_margin_end"
                android:minHeight="@dimen/notification_2025_content_min_height"
                android:clipChildren="false"
                android:theme="@style/Theme.DeviceDefault.Notification"
@@ -123,6 +122,7 @@
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="@dimen/notification_2025_additional_margin"
                    android:layout_marginEnd="@dimen/notification_2025_margin"
                    android:minHeight="@dimen/notification_headerless_line_height"
                    >
                    <include layout="@layout/notification_2025_text" />
@@ -132,32 +132,21 @@
                    layout="@layout/notification_template_progress"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/notification_headerless_line_height"
                    android:layout_marginEnd="@dimen/notification_2025_margin"
                    />

            </LinearLayout>

        </LinearLayout>

        <com.android.internal.widget.CachingIconView
            android:id="@+id/right_icon"
            android:layout_width="@dimen/notification_right_icon_size"
            android:layout_height="@dimen/notification_right_icon_size"
            android:layout_gravity="center_vertical|end"
            android:layout_marginVertical="@dimen/notification_2025_right_icon_vertical_margin"
            android:layout_marginStart="@dimen/notification_2025_right_icon_content_margin"
            android:background="@drawable/notification_large_icon_outline"
            android:clipToOutline="true"
            android:importantForAccessibility="no"
            android:scaleType="centerCrop"
            android:maxDrawableWidth="@dimen/notification_right_icon_size"
            android:maxDrawableHeight="@dimen/notification_right_icon_size"
            />
        <include layout="@layout/notification_2025_right_icon" />

        <FrameLayout
            android:id="@+id/expand_button_touch_container"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:minWidth="@dimen/notification_2025_margin"
            android:layout_gravity="top|end"
            >

            <include layout="@layout/notification_2025_expand_button"
@@ -168,7 +157,7 @@

        </FrameLayout>

    </LinearLayout>
    </FrameLayout>

    <include layout="@layout/notification_close_button"
        android:id="@+id/close_button"
Loading