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

Commit 6cf6be36 authored by Ioana Alexandru's avatar Ioana Alexandru
Browse files

[Notif redesign] Update spacing of smart replies & actions

Changing the spacing around smart replies, smart actions and regular
notification actions to match the specs.

Note that notification_2025_action_list.xml is a fork of
notification_action_list.xml.

Bug: 378660052
Test: manual + screenshot tests
Flag: android.app.notifications_redesign_templates
Change-Id: Idf101b714690f290ca68bb0cc842592a66e58cdc
parent f25b2fa6
Loading
Loading
Loading
Loading
+62 −22
Original line number Diff line number Diff line
@@ -6470,12 +6470,12 @@ public class Notification implements Parcelable
            contentView.setViewVisibility(R.id.notification_material_reply_text_3, View.GONE);
            contentView.setTextViewText(R.id.notification_material_reply_text_3, null);
            // This may get erased by bindSnoozeAction
            // This may get erased by bindSnoozeAction, or if we're showing the bubble icon
            contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
                    RemoteViews.MARGIN_BOTTOM, R.dimen.notification_content_margin);
        }
        private void bindSnoozeAction(RemoteViews contentView, StandardTemplateParams p) {
        private boolean bindSnoozeAction(RemoteViews contentView, StandardTemplateParams p) {
            boolean hideSnoozeButton = mN.isFgsOrUij()
                    || mN.fullScreenIntent != null
                    || isBackgroundColorized(p)
@@ -6493,6 +6493,7 @@ public class Notification implements Parcelable
                contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
                        RemoteViews.MARGIN_BOTTOM, 0);
            }
            return snoozeEnabled;
        }
        private boolean isSnoozeSettingEnabled() {
@@ -6530,14 +6531,12 @@ public class Notification implements Parcelable
            RemoteViews contentView = applyStandardTemplate(layoutId, p, result);
            resetStandardTemplateWithActions(contentView);
            bindSnoozeAction(contentView, p);
            boolean snoozeEnabled = bindSnoozeAction(contentView, p);
            // color the snooze and bubble actions with the theme color
            ColorStateList actionColor = ColorStateList.valueOf(getStandardActionColor(p));
            contentView.setColorStateList(R.id.snooze_button, "setImageTintList", actionColor);
            contentView.setColorStateList(R.id.bubble_button, "setImageTintList", actionColor);
            boolean validRemoteInput = false;
            // In the UI, contextual actions appear separately from the standard actions, so we
            // filter them out here.
            List<Notification.Action> nonContextualActions = getNonContextualActions();
@@ -6565,32 +6564,49 @@ public class Notification implements Parcelable
                    contentView.setBoolean(R.id.actions, "setEvenlyDividedMode", true);
                }
            }
            if (!notificationsRedesignTemplates()) {
                contentView.setBoolean(R.id.actions, "setEmphasizedMode", emphasizedMode);
            }
            boolean validRemoteInput = false;
            if (numActions > 0 && !p.mHideActions) {
                contentView.setViewVisibility(R.id.actions_container, View.VISIBLE);
                contentView.setViewVisibility(R.id.actions, View.VISIBLE);
                contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
                        RemoteViews.MARGIN_BOTTOM, 0);
                for (int i = 0; i < numActions; i++) {
                    Action action = nonContextualActions.get(i);
                    boolean actionHasValidInput = hasValidRemoteInput(action);
                    validRemoteInput |= actionHasValidInput;
                    final RemoteViews button = generateActionButton(action, emphasizedMode, p);
                    if (actionHasValidInput && !emphasizedMode) {
                        // Clear the drawable
                        button.setInt(R.id.action0, "setBackgroundResource", 0);
                    }
                    if (emphasizedMode && i > 0) {
                        // Clear start margin from non-first buttons to reduce the gap between them.
                        //  (8dp remaining gap is from all buttons' standard 4dp inset).
                        button.setViewLayoutMarginDimen(R.id.action0, RemoteViews.MARGIN_START, 0);
                if (notificationsRedesignTemplates()) {
                    // No need for additional space under smart replies/smart actions.
                    contentView.setViewLayoutMarginDimen(R.id.smart_reply_container,
                            RemoteViews.MARGIN_BOTTOM, 0);
                    if (emphasizedMode) {
                        // Emphasized actions look similar to smart replies, so let's use the same
                        // margins.
                        contentView.setViewLayoutMarginDimen(R.id.actions_container,
                                RemoteViews.MARGIN_TOP,
                                R.dimen.notification_2025_smart_reply_container_margin);
                        contentView.setViewLayoutMarginDimen(R.id.actions_container,
                                RemoteViews.MARGIN_BOTTOM,
                                R.dimen.notification_2025_smart_reply_container_margin);
                    } else {
                        contentView.setViewLayoutMarginDimen(R.id.actions_container,
                                RemoteViews.MARGIN_TOP, 0);
                        contentView.setViewLayoutMarginDimen(R.id.actions_container,
                                RemoteViews.MARGIN_BOTTOM,
                                R.dimen.notification_2025_action_list_margin_bottom);
                    }
                    contentView.addView(R.id.actions, button);
                }
                validRemoteInput = populateActionsContainer(contentView, p, nonContextualActions,
                        numActions, emphasizedMode);
            } else {
                contentView.setViewVisibility(R.id.actions_container, View.GONE);
                if (notificationsRedesignTemplates() && !snoozeEnabled) {
                    // Make sure smart replies & smart actions have enough space at the bottom
                    // (if present) when there are no actions. This should be set to 0 if we're
                    // showing the snooze or bubble buttons.
                    contentView.setViewLayoutMarginDimen(R.id.smart_reply_container,
                            RemoteViews.MARGIN_BOTTOM,
                            R.dimen.notification_2025_smart_reply_container_margin);
                }
            }
            RemoteInputHistoryItem[] replyText = getParcelableArrayFromBundle(
@@ -6636,6 +6652,30 @@ public class Notification implements Parcelable
            return contentView;
        }
        private boolean populateActionsContainer(RemoteViews contentView, StandardTemplateParams p,
                List<Action> nonContextualActions, int numActions, boolean emphasizedMode) {
            boolean validRemoteInput = false;
            for (int i = 0; i < numActions; i++) {
                Action action = nonContextualActions.get(i);
                boolean actionHasValidInput = hasValidRemoteInput(action);
                validRemoteInput |= actionHasValidInput;
                final RemoteViews button = generateActionButton(action, emphasizedMode, p);
                if (actionHasValidInput && !emphasizedMode) {
                    // Clear the drawable
                    button.setInt(R.id.action0, "setBackgroundResource", 0);
                }
                if (emphasizedMode && i > 0) {
                    // Clear start margin from non-first buttons to reduce the gap between them.
                    //  (8dp remaining gap is from all buttons' standard 4dp inset).
                    button.setViewLayoutMarginDimen(R.id.action0, RemoteViews.MARGIN_START, 0);
                }
                contentView.addView(R.id.actions, button);
            }
            return validRemoteInput;
        }
        /**
         * Calculate the top margin for the content in px, to allow enough space for the top line
         * above, using the given resource ID for the desired spacing.
+15 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.widget;

import static android.app.Flags.notificationsRedesignTemplates;
import static android.app.Notification.CallStyle.DEBUG_NEW_ACTION_LAYOUT;
import static android.app.Flags.evenlyDividedCallStyleActionLayout;

@@ -368,12 +369,17 @@ public class NotificationActionListLayout extends LinearLayout {
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if (!notificationsRedesignTemplates()) {
            mDefaultPaddingBottom = getPaddingBottom();
            mDefaultPaddingTop = getPaddingTop();
            updateHeights();
        }
    }

    private void updateHeights() {
        if (notificationsRedesignTemplates()) {
            return;
        }
        int inset = getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.button_inset_vertical_material);
        mEmphasizedPaddingTop = getResources().getDimensionPixelSize(
@@ -440,6 +446,9 @@ public class NotificationActionListLayout extends LinearLayout {
     */
    @RemotableViewMethod
    public void setEmphasizedMode(boolean emphasizedMode) {
        if (notificationsRedesignTemplates()) {
            return;
        }
        mEmphasizedMode = emphasizedMode;
        int height;
        if (emphasizedMode) {
@@ -462,7 +471,9 @@ public class NotificationActionListLayout extends LinearLayout {
    }

    public int getExtraMeasureHeight() {
        if (mEmphasizedMode) {
        // Note: the emphasized height is no longer different from the regular height when the
        // notificationsRedesignTemplates flag is on.
        if (!notificationsRedesignTemplates() && mEmphasizedMode) {
            return mEmphasizedHeight - mRegularHeight;
        }
        return 0;
+84 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2025 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License
  -->

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/actions_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:layout_marginBottom="@dimen/notification_2025_action_list_margin_bottom"
    >

    <LinearLayout
        android:id="@+id/actions_container_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="end"
        android:layout_gravity="bottom"
        android:orientation="horizontal"
        android:background="@color/notification_action_list_background_color"
        >

        <com.android.internal.widget.NotificationActionListLayout
            android:id="@+id/actions"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:minHeight="@dimen/notification_2025_action_list_height"
            android:orientation="horizontal"
            android:gravity="center_vertical"
            android:visibility="gone"
            >
            <!-- actions will be added here -->
        </com.android.internal.widget.NotificationActionListLayout>

        <!--
        This nested linear layout exists to ensure that if the neither of the contained
        actions is visible we have some minimum padding at the end of the actions is present,
        then there will be 12dp of padding at the end of the actions list.

        The end padding exists to match the bottom margin of the actions, for symmetry when the icon
        is shown in the corner of the notification.
        -->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            android:paddingEnd="@dimen/notification_2025_action_list_margin_bottom"
            android:minWidth="@dimen/snooze_and_bubble_gone_padding_end"
            >
            <ImageView
                android:id="@+id/snooze_button"
                android:layout_width="@dimen/notification_2025_actions_icon_size"
                android:layout_height="@dimen/notification_2025_actions_icon_size"
                android:layout_gravity="center_vertical|end"
                android:visibility="gone"
                android:scaleType="centerInside"
                />

            <ImageView
                android:id="@+id/bubble_button"
                android:layout_width="@dimen/notification_2025_actions_icon_size"
                android:layout_height="@dimen/notification_2025_actions_icon_size"
                android:layout_gravity="center_vertical|end"
                android:visibility="gone"
                android:scaleType="centerInside"
                />
        </LinearLayout>
    </LinearLayout>
</FrameLayout>
+2 −2
Original line number Diff line number Diff line
@@ -182,10 +182,10 @@
            <include layout="@layout/notification_template_smart_reply_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/notification_content_margin"
                android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
                android:layout_marginStart="@dimen/notification_2025_content_margin_start"
                android:layout_marginEnd="@dimen/notification_content_margin_end" />
            <include layout="@layout/notification_material_action_list" />
            <include layout="@layout/notification_2025_action_list" />
        </LinearLayout>
    </LinearLayout>

+2 −2
Original line number Diff line number Diff line
@@ -206,10 +206,10 @@
        <include layout="@layout/notification_template_smart_reply_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/notification_content_margin"
                android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
                android:layout_marginStart="@dimen/notification_2025_content_margin_start"
                android:layout_marginEnd="@dimen/notification_content_margin_end" />
        <include layout="@layout/notification_material_action_list" />
        <include layout="@layout/notification_2025_action_list" />
    </LinearLayout>
</LinearLayout>
</com.android.internal.widget.ConversationLayout>
Loading