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

Commit bc8b6043 authored by Julia Tuttle's avatar Julia Tuttle
Browse files

CallStyle: Evenly divide space for action buttons

Add an "evenly divided" mode to NotificationActionListLayout that
divides the width into even shares and stretches each action button to
fill its share.

Use it in Notification.CallStyle to fulfill the new CallStyle action
button layout.

Bug: 268733030
Test: manual; sUseNewActionLayout = true, post CallStyle with Notify2
Change-Id: I5e8483d9dbe7c7faa723c41e69939fa98e1fc0f0
parent f96a6958
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -5940,6 +5940,12 @@ public class Notification implements Parcelable
                // there is enough space to do so (and fall back to the left edge if not).
                big.setInt(R.id.actions, "setCollapsibleIndentDimen",
                        R.dimen.call_notification_collapsible_indent);
                if (CallStyle.USE_NEW_ACTION_LAYOUT) {
                    if (CallStyle.DEBUG_NEW_ACTION_LAYOUT) {
                        Log.d(TAG, "setting evenly divided mode on action list");
                    }
                    big.setBoolean(R.id.actions, "setEvenlyDividedMode", true);
                }
            }
            big.setBoolean(R.id.actions, "setEmphasizedMode", emphasizedMode);
            if (numActions > 0 && !p.mHideActions) {
+83 −5
Original line number Diff line number Diff line
@@ -16,12 +16,16 @@

package com.android.internal.widget;

import static android.app.Notification.CallStyle.DEBUG_NEW_ACTION_LAYOUT;
import static android.app.Notification.CallStyle.USE_NEW_ACTION_LAYOUT;

import android.annotation.DimenRes;
import android.app.Notification;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.RemotableViewMethod;
import android.view.View;
@@ -41,13 +45,13 @@ import java.util.Comparator;
 */
@RemoteViews.RemoteView
public class NotificationActionListLayout extends LinearLayout {

    private final int mGravity;
    private int mTotalWidth = 0;
    private int mExtraStartPadding = 0;
    private ArrayList<TextViewInfo> mMeasureOrderTextViews = new ArrayList<>();
    private ArrayList<View> mMeasureOrderOther = new ArrayList<>();
    private boolean mEmphasizedMode;
    private boolean mEvenlyDividedMode;
    private int mDefaultPaddingBottom;
    private int mDefaultPaddingTop;
    private int mEmphasizedPaddingTop;
@@ -124,6 +128,42 @@ public class NotificationActionListLayout extends LinearLayout {
        }
    }

    private int measureAndReturnEvenlyDividedWidth(int heightMeasureSpec, int innerWidth) {
        final int numChildren = getChildCount();
        int childMarginSum = 0;
        for (int i = 0; i < numChildren; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
                childMarginSum += lp.leftMargin + lp.rightMargin;
            }
        }

        final int innerWidthMinusChildMargins = innerWidth - childMarginSum;
        final int childWidth = innerWidthMinusChildMargins / mNumNotGoneChildren;
        final int childWidthMeasureSpec =
                MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY);

        if (DEBUG_NEW_ACTION_LAYOUT) {
            Log.v(TAG, "measuring evenly divided width: "
                    + "numChildren = " + numChildren + ", "
                    + "innerWidth = " + innerWidth + "px, "
                    + "childMarginSum = " + childMarginSum + "px, "
                    + "innerWidthMinusChildMargins = " + innerWidthMinusChildMargins + "px, "
                    + "childWidth = " + childWidth + "px, "
                    + "childWidthMeasureSpec = " + MeasureSpec.toString(childWidthMeasureSpec));
        }

        for (int i = 0; i < numChildren; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                child.measure(childWidthMeasureSpec, heightMeasureSpec);
            }
        }

        return innerWidth;
    }

    private int measureAndGetUsedWidth(int widthMeasureSpec, int heightMeasureSpec, int innerWidth,
            boolean collapsePriorityActions) {
        final int numChildren = getChildCount();
@@ -208,12 +248,17 @@ public class NotificationActionListLayout extends LinearLayout {
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        countAndRebuildMeasureOrder();
        final int innerWidth = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight;
        int usedWidth = measureAndGetUsedWidth(widthMeasureSpec, heightMeasureSpec, innerWidth,
        int usedWidth;
        if (mEvenlyDividedMode) {
            usedWidth = measureAndReturnEvenlyDividedWidth(heightMeasureSpec, innerWidth);
        } else {
            usedWidth = measureAndGetUsedWidth(widthMeasureSpec, heightMeasureSpec, innerWidth,
                    false /* collapsePriorityButtons */);
            if (mNumPriorityChildren != 0 && usedWidth >= innerWidth) {
                usedWidth = measureAndGetUsedWidth(widthMeasureSpec, heightMeasureSpec, innerWidth,
                        true /* collapsePriorityButtons */);
            }
        }

        mTotalWidth = usedWidth + mPaddingRight + mPaddingLeft + mExtraStartPadding;
        setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec),
@@ -351,6 +396,38 @@ public class NotificationActionListLayout extends LinearLayout {
        }
    }

    /**
     * Sets whether the available width should be distributed evenly among the action buttons.
     *
     * When enabled, the available width (after subtracting this layout's padding and all of the
     * buttons' margins) is divided by the number of (not-GONE) buttons, and each button is forced
     * to that exact width, even if it is less <em>or more</em> width than they need.
     *
     * When disabled, the available width is allocated as buttons need; if that exceeds the
     * available width, priority buttons are collapsed to just their icon to save space.
     *
     * @param evenlyDividedMode whether to enable evenly divided mode
     */
    @RemotableViewMethod
    public void setEvenlyDividedMode(boolean evenlyDividedMode) {
        if (evenlyDividedMode && !USE_NEW_ACTION_LAYOUT) {
            Log.e(TAG, "setEvenlyDividedMode(true) called with new action layout disabled; "
                    + "leaving evenly divided mode disabled");
            return;
        }

        if (evenlyDividedMode == mEvenlyDividedMode) {
            return;
        }

        if (DEBUG_NEW_ACTION_LAYOUT) {
            Log.v(TAG, "evenlyDividedMode changed to " + evenlyDividedMode + "; "
                    + "requesting layout");
        }
        mEvenlyDividedMode = evenlyDividedMode;
        requestLayout();
    }

    /**
     * Set whether the list is in a mode where some actions are emphasized. This will trigger an
     * equal measuring where all actions are full height and change a few parameters like
@@ -410,4 +487,5 @@ public class NotificationActionListLayout extends LinearLayout {
        }
    }

    private static final String TAG = "NotificationActionListLayout";
}