Minimize use of header in adjusting notification colors.
Also adds support for 'inverted' icons. Test: atest SystemUITests Test: manual testing of numerous notification configurations Change-Id: I6fd9aeec9f5971495d514add2bbb30b50db7d3c1
This commit is contained in:
@@ -82,7 +82,6 @@ import android.util.Pair;
|
||||
import android.util.SparseArray;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.Gravity;
|
||||
import android.view.NotificationHeaderView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.contentcapture.ContentCaptureContext;
|
||||
@@ -5862,24 +5861,16 @@ public class Notification implements Parcelable
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply any necessariy colors to the small icon
|
||||
* Apply any necessary colors to the small icon
|
||||
*/
|
||||
private void processSmallIconColor(Icon smallIcon, RemoteViews contentView,
|
||||
StandardTemplateParams p) {
|
||||
boolean colorable = !isLegacy() || getColorUtil().isGrayscaleIcon(mContext, smallIcon);
|
||||
int color;
|
||||
if (isColorized(p)) {
|
||||
color = getPrimaryTextColor(p);
|
||||
} else {
|
||||
color = resolveContrastColor(p);
|
||||
}
|
||||
if (colorable) {
|
||||
contentView.setDrawableTint(R.id.icon, false, color,
|
||||
PorterDuff.Mode.SRC_ATOP);
|
||||
|
||||
}
|
||||
int color = isColorized(p) ? getPrimaryTextColor(p) : resolveContrastColor(p);
|
||||
contentView.setInt(R.id.icon, "setBackgroundColor",
|
||||
resolveBackgroundColor(p));
|
||||
contentView.setInt(R.id.icon, "setOriginalIconColor",
|
||||
colorable ? color : NotificationHeaderView.NO_COLOR);
|
||||
colorable ? color : COLOR_INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5892,8 +5883,8 @@ public class Notification implements Parcelable
|
||||
if (largeIcon != null && isLegacy()
|
||||
&& getColorUtil().isGrayscaleIcon(mContext, largeIcon)) {
|
||||
// resolve color will fall back to the default when legacy
|
||||
contentView.setDrawableTint(R.id.icon, false, resolveContrastColor(p),
|
||||
PorterDuff.Mode.SRC_ATOP);
|
||||
int color = resolveContrastColor(p);
|
||||
contentView.setInt(R.id.icon, "setOriginalIconColor", color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package android.view;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Notification;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
@@ -42,7 +41,6 @@ import java.util.ArrayList;
|
||||
*/
|
||||
@RemoteViews.RemoteView
|
||||
public class NotificationHeaderView extends ViewGroup {
|
||||
public static final int NO_COLOR = Notification.COLOR_INVALID;
|
||||
private final int mChildMinWidth;
|
||||
private final int mContentEndMargin;
|
||||
private final int mGravity;
|
||||
@@ -294,14 +292,6 @@ public class NotificationHeaderView extends ViewGroup {
|
||||
updateTouchListener();
|
||||
}
|
||||
|
||||
public int getOriginalIconColor() {
|
||||
return mIcon.getOriginalIconColor();
|
||||
}
|
||||
|
||||
public int getOriginalNotificationColor() {
|
||||
return mExpandButton.getOriginalNotificationColor();
|
||||
}
|
||||
|
||||
public void setShowWorkBadgeAtEnd(boolean showWorkBadgeAtEnd) {
|
||||
if (showWorkBadgeAtEnd != mShowWorkBadgeAtEnd) {
|
||||
setClipToPadding(!showWorkBadgeAtEnd);
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
package com.android.internal.widget;
|
||||
|
||||
import static com.android.internal.widget.ColoredIconHelper.applyGrayTint;
|
||||
|
||||
import android.annotation.DrawableRes;
|
||||
import android.annotation.Nullable;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
@@ -48,6 +51,7 @@ public class CachingIconView extends ImageView {
|
||||
private Consumer<Integer> mOnVisibilityChangedListener;
|
||||
private Consumer<Boolean> mOnForceHiddenChangedListener;
|
||||
private int mIconColor;
|
||||
private int mBackgroundColor;
|
||||
private boolean mWillBeForceHidden;
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@@ -230,9 +234,55 @@ public class CachingIconView extends ImageView {
|
||||
return mForceHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the notification's background color to the icon. This is only used when the icon
|
||||
* is "inverted". This should be called before calling {@link #setOriginalIconColor(int)}.
|
||||
*/
|
||||
@RemotableViewMethod
|
||||
public void setBackgroundColor(int color) {
|
||||
mBackgroundColor = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the icon color. If COLOR_INVALID is set, the icon's color filter will
|
||||
* not be altered. If there is a background drawable, this method uses the value from
|
||||
* {@link #setBackgroundColor(int)} which must have been already called.
|
||||
*/
|
||||
@RemotableViewMethod
|
||||
public void setOriginalIconColor(int color) {
|
||||
mIconColor = color;
|
||||
Drawable background = getBackground();
|
||||
Drawable icon = getDrawable();
|
||||
boolean hasColor = color != ColoredIconHelper.COLOR_INVALID;
|
||||
if (background == null) {
|
||||
// This is the pre-S style -- colored icon with no background.
|
||||
if (hasColor) {
|
||||
icon.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
} else {
|
||||
// When there is a background drawable, color it with the foreground color and
|
||||
// colorize the icon itself with the background color, creating an inverted effect.
|
||||
if (hasColor) {
|
||||
background.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
icon.mutate().setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP);
|
||||
} else {
|
||||
background.mutate().setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the icon's color filter: to gray if true, otherwise colored.
|
||||
* If this icon has no original color, this has no effect.
|
||||
*/
|
||||
public void setGrayedOut(boolean grayedOut) {
|
||||
// If there is a background drawable, then it has the foreground color and the image
|
||||
// drawable has the background color, creating an inverted efffect.
|
||||
Drawable drawable = getBackground();
|
||||
if (drawable == null) {
|
||||
drawable = getDrawable();
|
||||
}
|
||||
applyGrayTint(mContext, drawable, grayedOut, mIconColor);
|
||||
}
|
||||
|
||||
public int getOriginalIconColor() {
|
||||
|
||||
57
core/java/com/android/internal/widget/ColoredIconHelper.java
Normal file
57
core/java/com/android/internal/widget/ColoredIconHelper.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
|
||||
package com.android.internal.widget;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.internal.util.ContrastColorUtil;
|
||||
|
||||
/** Helpers for colored icons */
|
||||
final class ColoredIconHelper {
|
||||
|
||||
@ColorInt
|
||||
static final int COLOR_INVALID = Notification.COLOR_INVALID;
|
||||
|
||||
private ColoredIconHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a gray tint or the original color to a drawable, accounting for the night mode in
|
||||
* selecting the gray.
|
||||
*/
|
||||
static void applyGrayTint(Context ctx, Drawable drawable, boolean apply, int originalColor) {
|
||||
if (originalColor == COLOR_INVALID) {
|
||||
return;
|
||||
}
|
||||
if (apply) {
|
||||
// lets gray it out
|
||||
Configuration config = ctx.getResources().getConfiguration();
|
||||
boolean inNightMode = (config.uiMode & Configuration.UI_MODE_NIGHT_MASK)
|
||||
== Configuration.UI_MODE_NIGHT_YES;
|
||||
int grey = ContrastColorUtil.resolveColor(ctx, Notification.COLOR_DEFAULT, inNightMode);
|
||||
drawable.mutate().setColorFilter(grey, PorterDuff.Mode.SRC_ATOP);
|
||||
} else {
|
||||
// lets reset it
|
||||
drawable.mutate().setColorFilter(originalColor, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.internal.widget;
|
||||
|
||||
import static com.android.internal.widget.ColoredIconHelper.applyGrayTint;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
@@ -70,6 +72,14 @@ public class NotificationExpandButton extends ImageView {
|
||||
return mOriginalNotificationColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the button's color filter: to gray if true, otherwise colored.
|
||||
* If this button has no original color, this has no effect.
|
||||
*/
|
||||
public void setGrayedOut(boolean shouldApply) {
|
||||
applyGrayTint(mContext, getDrawable(), shouldApply, mOriginalNotificationColor);
|
||||
}
|
||||
|
||||
private void extendRectToMinTouchSize(Rect rect) {
|
||||
int touchTargetSize = (int) (getResources().getDisplayMetrics().density * 48);
|
||||
rect.left = rect.centerX() - touchTargetSize / 2;
|
||||
|
||||
@@ -17,18 +17,16 @@
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.text.TextUtils;
|
||||
import android.view.NotificationHeaderView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.util.ContrastColorUtil;
|
||||
import com.android.internal.widget.CachingIconView;
|
||||
import com.android.internal.widget.ConversationLayout;
|
||||
import com.android.internal.widget.NotificationExpandButton;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationContentView;
|
||||
|
||||
@@ -67,30 +65,14 @@ public class NotificationHeaderUtil {
|
||||
private final static ResultApplicator mGreyApplicator = new ResultApplicator() {
|
||||
@Override
|
||||
public void apply(View parent, View view, boolean apply, boolean reset) {
|
||||
NotificationHeaderView header = (NotificationHeaderView) view;
|
||||
ImageView icon = view.findViewById(com.android.internal.R.id.icon);
|
||||
ImageView expand = view.findViewById(com.android.internal.R.id.expand_button);
|
||||
applyToChild(icon, apply, header.getOriginalIconColor());
|
||||
applyToChild(expand, apply, header.getOriginalNotificationColor());
|
||||
}
|
||||
|
||||
private void applyToChild(View view, boolean shouldApply, int originalColor) {
|
||||
if (originalColor != NotificationHeaderView.NO_COLOR) {
|
||||
ImageView imageView = (ImageView) view;
|
||||
imageView.getDrawable().mutate();
|
||||
if (shouldApply) {
|
||||
// lets gray it out
|
||||
Configuration config = view.getContext().getResources().getConfiguration();
|
||||
boolean inNightMode = (config.uiMode & Configuration.UI_MODE_NIGHT_MASK)
|
||||
== Configuration.UI_MODE_NIGHT_YES;
|
||||
int grey = ContrastColorUtil.resolveColor(view.getContext(),
|
||||
Notification.COLOR_DEFAULT, inNightMode);
|
||||
imageView.getDrawable().setColorFilter(grey, PorterDuff.Mode.SRC_ATOP);
|
||||
} else {
|
||||
// lets reset it
|
||||
imageView.getDrawable().setColorFilter(originalColor,
|
||||
PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
CachingIconView icon = view.findViewById(com.android.internal.R.id.icon);
|
||||
if (icon != null) {
|
||||
icon.setGrayedOut(apply);
|
||||
}
|
||||
NotificationExpandButton expand =
|
||||
view.findViewById(com.android.internal.R.id.expand_button);
|
||||
if (expand != null) {
|
||||
expand.setGrayedOut(apply);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user