Fix colorized messaging layout and smart replies.
Modify messaging style and smart replies view to cope with colorized backgrounds. Bug: 78928664 Bug: 77927019 Test: atest SystemUITests (with patch from ag/3992401) Test: visual - see bug for screenshots Change-Id: Iee66931574fb48d0340986bf520532f798ef59fc
This commit is contained in:
@@ -7015,7 +7015,12 @@ public class Notification implements Parcelable
|
||||
contentView.setViewLayoutMarginEnd(R.id.notification_messaging,
|
||||
bindResult.getIconMarginEnd());
|
||||
contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor",
|
||||
mBuilder.resolveContrastColor());
|
||||
mBuilder.isColorized() ? mBuilder.getPrimaryTextColor()
|
||||
: mBuilder.resolveContrastColor());
|
||||
contentView.setInt(R.id.status_bar_latest_event_content, "setSenderTextColor",
|
||||
mBuilder.getPrimaryTextColor());
|
||||
contentView.setInt(R.id.status_bar_latest_event_content, "setMessageTextColor",
|
||||
mBuilder.getSecondaryTextColor());
|
||||
contentView.setBoolean(R.id.status_bar_latest_event_content, "setDisplayImagesAtEnd",
|
||||
displayImagesAtEnd);
|
||||
contentView.setIcon(R.id.status_bar_latest_event_content, "setLargeIcon",
|
||||
|
||||
@@ -418,10 +418,23 @@ public class NotificationColorUtil {
|
||||
*
|
||||
* @param isBgDarker {@code true} if {@code bg} is darker than {@code color}.
|
||||
*/
|
||||
private static int ensureTextContrast(int color, int bg, boolean isBgDarker) {
|
||||
public static int ensureTextContrast(int color, int bg, boolean isBgDarker) {
|
||||
return ensureContrast(color, bg, isBgDarker, 4.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a color with sufficient contrast over bg that has the same or darker hue as the
|
||||
* original color, depending on the value of {@code isBgDarker}.
|
||||
*
|
||||
* @param color the color to start searching from
|
||||
* @param bg the color to ensure contrast against
|
||||
* @param isBgDarker {@code true} if {@code bg} is darker than {@code color}
|
||||
* @param minRatio the minimum contrast ratio required
|
||||
*/
|
||||
public static int ensureContrast(int color, int bg, boolean isBgDarker, double minRatio) {
|
||||
return isBgDarker
|
||||
? findContrastColorAgainstDark(color, bg, true, 4.5)
|
||||
: findContrastColor(color, bg, true, 4.5);
|
||||
? findContrastColorAgainstDark(color, bg, true, minRatio)
|
||||
: findContrastColor(color, bg, true, minRatio);
|
||||
}
|
||||
|
||||
/** Finds a background color for a text view with given text color and hint text color, that
|
||||
|
||||
@@ -148,8 +148,6 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
}
|
||||
mAvatarView.setVisibility(VISIBLE);
|
||||
mSenderName.setVisibility(TextUtils.isEmpty(nameOverride) ? GONE : VISIBLE);
|
||||
mTextColor = getNormalTextColor();
|
||||
mSendingTextColor = calculateSendingTextColor();
|
||||
}
|
||||
|
||||
public void setSending(boolean sending) {
|
||||
@@ -160,10 +158,6 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
}
|
||||
}
|
||||
|
||||
private int getNormalTextColor() {
|
||||
return mContext.getColor(R.color.notification_secondary_text_color_light);
|
||||
}
|
||||
|
||||
private int calculateSendingTextColor() {
|
||||
TypedValue alphaValue = new TypedValue();
|
||||
mContext.getResources().getValue(
|
||||
@@ -363,6 +357,13 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
}
|
||||
}
|
||||
|
||||
public void setTextColors(int senderTextColor, int messageTextColor) {
|
||||
mTextColor = messageTextColor;
|
||||
mSendingTextColor = calculateSendingTextColor();
|
||||
updateMessageColor();
|
||||
mSenderName.setTextColor(senderTextColor);
|
||||
}
|
||||
|
||||
public void setLayoutColor(int layoutColor) {
|
||||
if (layoutColor != mLayoutColor){
|
||||
mLayoutColor = layoutColor;
|
||||
|
||||
@@ -73,6 +73,8 @@ public class MessagingLayout extends FrameLayout {
|
||||
private ArrayList<MessagingGroup> mGroups = new ArrayList<>();
|
||||
private TextView mTitleView;
|
||||
private int mLayoutColor;
|
||||
private int mSenderTextColor;
|
||||
private int mMessageTextColor;
|
||||
private int mAvatarSize;
|
||||
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private Paint mTextPaint = new Paint();
|
||||
@@ -301,6 +303,16 @@ public class MessagingLayout extends FrameLayout {
|
||||
mIsOneToOne = oneToOne;
|
||||
}
|
||||
|
||||
@RemotableViewMethod
|
||||
public void setSenderTextColor(int color) {
|
||||
mSenderTextColor = color;
|
||||
}
|
||||
|
||||
@RemotableViewMethod
|
||||
public void setMessageTextColor(int color) {
|
||||
mMessageTextColor = color;
|
||||
}
|
||||
|
||||
public void setUser(Person user) {
|
||||
mUser = user;
|
||||
if (mUser.getIcon() == null) {
|
||||
@@ -344,6 +356,7 @@ public class MessagingLayout extends FrameLayout {
|
||||
}
|
||||
newGroup.setDisplayImagesAtEnd(mDisplayImagesAtEnd);
|
||||
newGroup.setLayoutColor(mLayoutColor);
|
||||
newGroup.setTextColors(mSenderTextColor, mMessageTextColor);
|
||||
Person sender = senders.get(groupIndex);
|
||||
CharSequence nameOverride = null;
|
||||
if (sender != mUser && mNameReplacement != null) {
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
<color name="notification_primary_text_color_light">@color/primary_text_default_material_light</color>
|
||||
<color name="notification_primary_text_color_dark">@color/primary_text_default_material_dark</color>
|
||||
<color name="notification_secondary_text_color_light">@color/primary_text_default_material_light</color>
|
||||
<item name="notification_secondary_text_disabled_alpha" format="float" type="dimen">0.30</item>
|
||||
<item name="notification_secondary_text_disabled_alpha" format="float" type="dimen">0.38</item>
|
||||
<color name="notification_secondary_text_color_dark">@color/primary_text_default_material_dark</color>
|
||||
<color name="notification_default_color_dark">@color/primary_text_default_material_light</color>
|
||||
<color name="notification_default_color_light">#a3202124</color>
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
android:insetBottom="8dp">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="8dp" />
|
||||
<stroke android:width="1dp" android:color="@color/smart_reply_button_stroke" />
|
||||
<stroke android:width="@dimen/smart_reply_button_stroke_width"
|
||||
android:color="@color/smart_reply_button_stroke" />
|
||||
<solid android:color="@color/smart_reply_button_background"/>
|
||||
</shape>
|
||||
</inset>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<!-- android:paddingHorizontal is set dynamically in SmartReplyView. -->
|
||||
<Button xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@android:style/Widget.Material.Button"
|
||||
android:stateListAnimator="@null"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:minWidth="0dp"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
systemui:spacing="@dimen/smart_reply_button_spacing"
|
||||
systemui:singleLineButtonPaddingHorizontal="@dimen/smart_reply_button_padding_horizontal_single_line"
|
||||
systemui:doubleLineButtonPaddingHorizontal="@dimen/smart_reply_button_padding_horizontal_double_line">
|
||||
systemui:doubleLineButtonPaddingHorizontal="@dimen/smart_reply_button_padding_horizontal_double_line"
|
||||
systemui:buttonStrokeWidth="@dimen/smart_reply_button_stroke_width">
|
||||
<!-- smart_reply_button(s) will be added here. -->
|
||||
</com.android.systemui.statusbar.policy.SmartReplyView>
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
<attr name="spacing" format="dimension" />
|
||||
<attr name="singleLineButtonPaddingHorizontal" format="dimension" />
|
||||
<attr name="doubleLineButtonPaddingHorizontal" format="dimension" />
|
||||
<attr name="buttonStrokeWidth" format="dimension" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- Used to style rotate suggestion button AVD animations -->
|
||||
|
||||
@@ -151,7 +151,8 @@
|
||||
<color name="zen_introduction">#ffffffff</color>
|
||||
|
||||
<color name="smart_reply_button_text">#5F6368</color>
|
||||
<color name="smart_reply_button_background">#feffffff</color>
|
||||
<color name="smart_reply_button_text_dark_bg">@*android:color/notification_primary_text_color_dark</color>
|
||||
<color name="smart_reply_button_background">#ffffffff</color>
|
||||
<color name="smart_reply_button_stroke">#ffdadce0</color>
|
||||
|
||||
<!-- Fingerprint dialog colors -->
|
||||
|
||||
@@ -951,6 +951,7 @@
|
||||
<dimen name="smart_reply_button_padding_horizontal_single_line">20dp</dimen>
|
||||
<dimen name="smart_reply_button_padding_horizontal_double_line">19dp</dimen>
|
||||
<dimen name="smart_reply_button_min_height">48dp</dimen>
|
||||
<dimen name="smart_reply_button_stroke_width">1dp</dimen>
|
||||
<dimen name="smart_reply_button_font_size">14sp</dimen>
|
||||
<dimen name="smart_reply_button_line_spacing_extra">6sp</dimen> <!-- Total line height 20sp. -->
|
||||
|
||||
|
||||
@@ -581,7 +581,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
}
|
||||
}
|
||||
|
||||
private void setBackgroundTintColor(int color) {
|
||||
protected void setBackgroundTintColor(int color) {
|
||||
if (color != mCurrentBackgroundTint) {
|
||||
mCurrentBackgroundTint = color;
|
||||
if (color == mNormalColor) {
|
||||
|
||||
@@ -1090,6 +1090,15 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setBackgroundTintColor(int color) {
|
||||
super.setBackgroundTintColor(color);
|
||||
NotificationContentView view = getShowingLayout();
|
||||
if (view != null) {
|
||||
view.setBackgroundTintColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public void closeRemoteInput() {
|
||||
for (NotificationContentView l : mLayouts) {
|
||||
l.closeRemoteInput();
|
||||
|
||||
@@ -887,6 +887,12 @@ public class NotificationContentView extends FrameLayout {
|
||||
mContainingNotification.setContentBackground(customBackgroundColor, animate, this);
|
||||
}
|
||||
|
||||
public void setBackgroundTintColor(int color) {
|
||||
if (mExpandedSmartReplyView != null) {
|
||||
mExpandedSmartReplyView.setBackgroundTintColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public int getVisibleType() {
|
||||
return mVisibleType;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
package com.android.systemui.statusbar.policy;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.RemoteInput;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.Layout;
|
||||
@@ -22,6 +27,7 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.NotificationColorUtil;
|
||||
import com.android.keyguard.KeyguardHostView.OnDismissAction;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
@@ -75,6 +81,23 @@ public class SmartReplyView extends ViewGroup {
|
||||
|
||||
private View mSmartReplyContainer;
|
||||
|
||||
@ColorInt
|
||||
private int mCurrentBackgroundColor;
|
||||
@ColorInt
|
||||
private final int mDefaultBackgroundColor;
|
||||
@ColorInt
|
||||
private final int mDefaultStrokeColor;
|
||||
@ColorInt
|
||||
private final int mDefaultTextColor;
|
||||
@ColorInt
|
||||
private final int mDefaultTextColorDarkBg;
|
||||
@ColorInt
|
||||
private final int mRippleColorDarkBg;
|
||||
@ColorInt
|
||||
private final int mRippleColor;
|
||||
private final int mStrokeWidth;
|
||||
private final double mMinStrokeContrast;
|
||||
|
||||
public SmartReplyView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mConstants = Dependency.get(SmartReplyConstants.class);
|
||||
@@ -83,9 +106,21 @@ public class SmartReplyView extends ViewGroup {
|
||||
mHeightUpperLimit = NotificationUtils.getFontScaledHeight(mContext,
|
||||
R.dimen.smart_reply_button_max_height);
|
||||
|
||||
mCurrentBackgroundColor = context.getColor(R.color.smart_reply_button_background);
|
||||
mDefaultBackgroundColor = mCurrentBackgroundColor;
|
||||
mDefaultTextColor = mContext.getColor(R.color.smart_reply_button_text);
|
||||
mDefaultTextColorDarkBg = mContext.getColor(R.color.smart_reply_button_text_dark_bg);
|
||||
mDefaultStrokeColor = mContext.getColor(R.color.smart_reply_button_stroke);
|
||||
mRippleColor = mContext.getColor(R.color.notification_ripple_untinted_color);
|
||||
mRippleColorDarkBg = Color.argb(Color.alpha(mRippleColor),
|
||||
255 /* red */, 255 /* green */, 255 /* blue */);
|
||||
mMinStrokeContrast = NotificationColorUtil.calculateContrast(mDefaultStrokeColor,
|
||||
mDefaultBackgroundColor);
|
||||
|
||||
int spacing = 0;
|
||||
int singleLineButtonPaddingHorizontal = 0;
|
||||
int doubleLineButtonPaddingHorizontal = 0;
|
||||
int strokeWidth = 0;
|
||||
|
||||
final TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.SmartReplyView,
|
||||
0, 0);
|
||||
@@ -102,10 +137,14 @@ public class SmartReplyView extends ViewGroup {
|
||||
case R.styleable.SmartReplyView_doubleLineButtonPaddingHorizontal:
|
||||
doubleLineButtonPaddingHorizontal = arr.getDimensionPixelSize(i, 0);
|
||||
break;
|
||||
case R.styleable.SmartReplyView_buttonStrokeWidth:
|
||||
strokeWidth = arr.getDimensionPixelSize(i, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
arr.recycle();
|
||||
|
||||
mStrokeWidth = strokeWidth;
|
||||
mSpacing = spacing;
|
||||
mSingleLineButtonPaddingHorizontal = singleLineButtonPaddingHorizontal;
|
||||
mDoubleLineButtonPaddingHorizontal = doubleLineButtonPaddingHorizontal;
|
||||
@@ -139,6 +178,7 @@ public class SmartReplyView extends ViewGroup {
|
||||
View smartReplyContainer) {
|
||||
mSmartReplyContainer = smartReplyContainer;
|
||||
removeAllViews();
|
||||
mCurrentBackgroundColor = mDefaultBackgroundColor;
|
||||
if (remoteInput != null && pendingIntent != null) {
|
||||
CharSequence[] choices = remoteInput.getChoices();
|
||||
if (choices != null) {
|
||||
@@ -194,6 +234,7 @@ public class SmartReplyView extends ViewGroup {
|
||||
}
|
||||
});
|
||||
|
||||
setColors(b, mCurrentBackgroundColor, mDefaultStrokeColor, mDefaultTextColor, mRippleColor);
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -523,6 +564,51 @@ public class SmartReplyView extends ViewGroup {
|
||||
return lp.show && super.drawChild(canvas, child, drawingTime);
|
||||
}
|
||||
|
||||
public void setBackgroundTintColor(int backgroundColor) {
|
||||
if (backgroundColor == mCurrentBackgroundColor) {
|
||||
// Same color ignoring.
|
||||
return;
|
||||
}
|
||||
mCurrentBackgroundColor = backgroundColor;
|
||||
|
||||
final boolean dark = !NotificationColorUtil.isColorLight(backgroundColor);
|
||||
|
||||
int textColor = NotificationColorUtil.ensureTextContrast(
|
||||
dark ? mDefaultTextColorDarkBg : mDefaultTextColor,
|
||||
backgroundColor | 0xff000000, dark);
|
||||
int strokeColor = NotificationColorUtil.ensureContrast(
|
||||
mDefaultStrokeColor, backgroundColor | 0xff000000, dark, mMinStrokeContrast);
|
||||
int rippleColor = dark ? mRippleColorDarkBg : mRippleColor;
|
||||
|
||||
int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final Button child = (Button) getChildAt(i);
|
||||
setColors(child, backgroundColor, strokeColor, textColor, rippleColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void setColors(Button button, int backgroundColor, int strokeColor, int textColor,
|
||||
int rippleColor) {
|
||||
Drawable drawable = button.getBackground();
|
||||
if (drawable instanceof RippleDrawable) {
|
||||
// Mutate in case other notifications are using this drawable.
|
||||
drawable = drawable.mutate();
|
||||
RippleDrawable ripple = (RippleDrawable) drawable;
|
||||
ripple.setColor(ColorStateList.valueOf(rippleColor));
|
||||
Drawable inset = ripple.getDrawable(0);
|
||||
if (inset instanceof InsetDrawable) {
|
||||
Drawable background = ((InsetDrawable) inset).getDrawable();
|
||||
if (background instanceof GradientDrawable) {
|
||||
GradientDrawable gradientDrawable = (GradientDrawable) background;
|
||||
gradientDrawable.setColor(backgroundColor);
|
||||
gradientDrawable.setStroke(mStrokeWidth, strokeColor);
|
||||
}
|
||||
}
|
||||
button.setBackground(drawable);
|
||||
}
|
||||
button.setTextColor(textColor);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class LayoutParams extends ViewGroup.LayoutParams {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user