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:
Kenny Guy
2018-05-02 19:10:36 +01:00
parent 67890e0e1d
commit 14d035c969
15 changed files with 154 additions and 15 deletions

View File

@@ -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",

View File

@@ -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

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View File

@@ -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 -->

View File

@@ -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 -->

View File

@@ -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. -->

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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 {