Merge "Adding important people avatars to AoD"

This commit is contained in:
Alex Mang
2020-02-20 00:22:52 +00:00
committed by Android (Google) Code Review
2 changed files with 180 additions and 32 deletions

View File

@@ -159,6 +159,7 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
private boolean mDismissed;
private Runnable mOnDismissListener;
private boolean mIncreasedSize;
private boolean mTintIcons = true;
public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
this(context, slot, sbn, false);
@@ -612,6 +613,11 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
}
private void updateIconColor() {
if (!mTintIcons) {
setColorFilter(null);
return;
}
if (mCurrentSetColor != NO_COLOR) {
if (mMatrixColorFilter == null) {
mMatrix = new float[4 * 5];
@@ -953,6 +959,19 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
maybeUpdateIconScaleDimens();
}
/**
* Sets whether the icon should be tinted. If the state differs from the supplied setting, this
* will update the icon colors.
*
* @param shouldTint Whether the icon should be tinted.
*/
public void setTintIcons(boolean shouldTint) {
if (mTintIcons != shouldTint) {
mTintIcons = shouldTint;
updateIconColor();
}
}
public interface OnVisibilityChangedListener {
void onVisibilityChanged(int newVisibility);
}

View File

@@ -29,6 +29,8 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCRE
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED;
import static com.android.systemui.statusbar.notification.collection.NotifCollection.REASON_NOT_CANCELED;
import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING;
@@ -42,6 +44,9 @@ import android.app.NotificationManager.Policy;
import android.app.Person;
import android.app.RemoteInputHistoryItem;
import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.ShortcutQuery;
import android.content.pm.ShortcutInfo;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
@@ -50,6 +55,7 @@ import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
@@ -75,6 +81,8 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -94,11 +102,15 @@ import java.util.Objects;
* clean this up in the future.
*/
public final class NotificationEntry extends ListEntry {
private static final String TAG = "NotificationEntry";
private final String mKey;
private StatusBarNotification mSbn;
private Ranking mRanking;
private StatusBarIcon mSmallIcon;
private StatusBarIcon mPeopleAvatar;
/*
* Bookkeeping members
*/
@@ -459,12 +471,7 @@ public final class NotificationEntry extends ListEntry {
*/
public void createIcons(Context context, StatusBarNotification sbn)
throws InflationException {
Notification n = sbn.getNotification();
final Icon smallIcon = n.getSmallIcon();
if (smallIcon == null) {
throw new InflationException("No small icon in notification from "
+ sbn.getPackageName());
}
StatusBarIcon ic = getIcon(context, sbn, false /* redact */);
// Construct the icon.
icon = new StatusBarIconView(context,
@@ -482,21 +489,20 @@ public final class NotificationEntry extends ListEntry {
aodIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
aodIcon.setIncreasedSize(true);
final StatusBarIcon ic = new StatusBarIcon(
sbn.getUser(),
sbn.getPackageName(),
smallIcon,
n.iconLevel,
n.number,
StatusBarIconView.contentDescForNotification(context, n));
if (!icon.set(ic) || !expandedIcon.set(ic) || !aodIcon.set(ic)) {
try {
setIcons(ic, Collections.singletonList(icon));
if (isSensitive()) {
ic = getIcon(context, sbn, true /* redact */);
}
setIcons(ic, Arrays.asList(expandedIcon, aodIcon));
} catch (InflationException e) {
icon = null;
expandedIcon = null;
centeredIcon = null;
aodIcon = null;
throw new InflationException("Couldn't create icon: " + ic);
throw e;
}
expandedIcon.setVisibility(View.INVISIBLE);
expandedIcon.setOnVisibilityChangedListener(
newVisibility -> {
@@ -510,10 +516,130 @@ public final class NotificationEntry extends ListEntry {
centeredIcon = new StatusBarIconView(context,
sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
centeredIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
if (!centeredIcon.set(ic)) {
try {
setIcons(ic, Collections.singletonList(centeredIcon));
} catch (InflationException e) {
centeredIcon = null;
throw new InflationException("Couldn't update centered icon: " + ic);
throw e;
}
}
}
/**
* Determines if this icon should be tinted based on the sensitivity of the icon, its context
* and the user's indicated sensitivity preference.
*
* @param ic The icon that should/should not be tinted.
* @return
*/
private boolean shouldTintIcon(StatusBarIconView ic) {
boolean usedInSensitiveContext = (ic == expandedIcon || ic == aodIcon);
return !isImportantConversation() || (usedInSensitiveContext && isSensitive());
}
private void setIcons(StatusBarIcon ic, List<StatusBarIconView> icons)
throws InflationException {
for (StatusBarIconView icon: icons) {
if (icon == null) {
continue;
}
icon.setTintIcons(shouldTintIcon(icon));
if (!icon.set(ic)) {
throw new InflationException("Couldn't create icon" + ic);
}
}
}
private StatusBarIcon getIcon(Context context, StatusBarNotification sbn, boolean redact)
throws InflationException {
Notification n = sbn.getNotification();
final boolean showPeopleAvatar = isImportantConversation() && !redact;
// If cached, return corresponding cached values
if (showPeopleAvatar && mPeopleAvatar != null) {
return mPeopleAvatar;
} else if (!showPeopleAvatar && mSmallIcon != null) {
return mSmallIcon;
}
Icon icon = showPeopleAvatar ? createPeopleAvatar(context) : n.getSmallIcon();
if (icon == null) {
throw new InflationException("No icon in notification from " + sbn.getPackageName());
}
StatusBarIcon ic = new StatusBarIcon(
sbn.getUser(),
sbn.getPackageName(),
icon,
n.iconLevel,
n.number,
StatusBarIconView.contentDescForNotification(context, n));
// Cache if important conversation.
if (isImportantConversation()) {
if (showPeopleAvatar) {
mPeopleAvatar = ic;
} else {
mSmallIcon = ic;
}
}
return ic;
}
private Icon createPeopleAvatar(Context context) throws InflationException {
// Attempt to extract form shortcut.
String conversationId = getChannel().getConversationId();
ShortcutQuery query = new ShortcutQuery()
.setPackage(mSbn.getPackageName())
.setQueryFlags(FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED)
.setShortcutIds(Collections.singletonList(conversationId));
List<ShortcutInfo> shortcuts = context.getSystemService(LauncherApps.class)
.getShortcuts(query, mSbn.getUser());
Icon ic = null;
if (shortcuts != null && !shortcuts.isEmpty()) {
ic = shortcuts.get(0).getIcon();
}
// Fall back to notification large icon if available
if (ic == null) {
ic = mSbn.getNotification().getLargeIcon();
}
// Fall back to extract from message
if (ic == null) {
Bundle extras = mSbn.getNotification().extras;
List<Message> messages = Message.getMessagesFromBundleArray(
extras.getParcelableArray(Notification.EXTRA_MESSAGES));
Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON);
for (int i = messages.size() - 1; i >= 0; i--) {
Message message = messages.get(i);
Person sender = message.getSenderPerson();
if (sender != null && sender != user) {
ic = message.getSenderPerson().getIcon();
break;
}
}
}
// Revert to small icon if still not available
if (ic == null) {
ic = mSbn.getNotification().getSmallIcon();
}
if (ic == null) {
throw new InflationException("No icon in notification from " + mSbn.getPackageName());
}
return ic;
}
private void updateSensitiveIconState() {
try {
StatusBarIcon ic = getIcon(getRow().getContext(), mSbn, isSensitive());
setIcons(ic, Arrays.asList(expandedIcon, aodIcon));
} catch (InflationException e) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Unable to update icon", e);
}
}
}
@@ -544,30 +670,32 @@ public final class NotificationEntry extends ListEntry {
throws InflationException {
if (icon != null) {
// Update the icon
Notification n = sbn.getNotification();
final StatusBarIcon ic = new StatusBarIcon(
mSbn.getUser(),
mSbn.getPackageName(),
n.getSmallIcon(),
n.iconLevel,
n.number,
StatusBarIconView.contentDescForNotification(context, n));
mSmallIcon = null;
mPeopleAvatar = null;
StatusBarIcon ic = getIcon(context, sbn, false /* redact */);
icon.setNotification(sbn);
expandedIcon.setNotification(sbn);
aodIcon.setNotification(sbn);
if (!icon.set(ic) || !expandedIcon.set(ic) || !aodIcon.set(ic)) {
throw new InflationException("Couldn't update icon: " + ic);
setIcons(ic, Arrays.asList(icon, expandedIcon));
if (isSensitive()) {
ic = getIcon(context, sbn, true /* redact */);
}
setIcons(ic, Collections.singletonList(aodIcon));
if (centeredIcon != null) {
centeredIcon.setNotification(sbn);
if (!centeredIcon.set(ic)) {
throw new InflationException("Couldn't update centered icon: " + ic);
}
setIcons(ic, Collections.singletonList(centeredIcon));
}
}
}
private boolean isImportantConversation() {
return getChannel() != null && getChannel().isImportantConversation();
}
public int getContrastedColor(Context context, boolean isLowPriority,
int backgroundColor) {
int rawColor = isLowPriority ? Notification.COLOR_DEFAULT :
@@ -996,6 +1124,7 @@ public final class NotificationEntry extends ListEntry {
getRow().setSensitive(sensitive, deviceSensitive);
if (sensitive != mSensitive) {
mSensitive = sensitive;
updateSensitiveIconState();
if (mOnSensitiveChangedListener != null) {
mOnSensitiveChangedListener.run();
}