Merge "Fixed a flicker of group notifications" into oc-dev
This commit is contained in:
@@ -146,12 +146,12 @@ public class NotificationData {
|
||||
|
||||
// Construct the icon.
|
||||
icon = new StatusBarIconView(context,
|
||||
sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
|
||||
sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
|
||||
icon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
|
||||
// Construct the expanded icon.
|
||||
expandedIcon = new StatusBarIconView(context,
|
||||
sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
|
||||
sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
|
||||
expandedIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
final StatusBarIcon ic = new StatusBarIcon(
|
||||
sbn.getUser(),
|
||||
@@ -187,9 +187,11 @@ public class NotificationData {
|
||||
* @param n the notification to read the icon from.
|
||||
* @throws InflationException
|
||||
*/
|
||||
public void updateIcons(Context context, Notification n) throws InflationException {
|
||||
public void updateIcons(Context context, StatusBarNotification sbn)
|
||||
throws InflationException {
|
||||
if (icon != null) {
|
||||
// Update the icon
|
||||
Notification n = sbn.getNotification();
|
||||
final StatusBarIcon ic = new StatusBarIcon(
|
||||
notification.getUser(),
|
||||
notification.getPackageName(),
|
||||
@@ -197,8 +199,8 @@ public class NotificationData {
|
||||
n.iconLevel,
|
||||
n.number,
|
||||
StatusBarIconView.contentDescForNotification(context, n));
|
||||
icon.setNotification(n);
|
||||
expandedIcon.setNotification(n);
|
||||
icon.setNotification(sbn);
|
||||
expandedIcon.setNotification(sbn);
|
||||
if (!icon.set(ic) || !expandedIcon.set(ic)) {
|
||||
throw new InflationException("Couldn't update icon: " + ic);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Parcelable;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FloatProperty;
|
||||
@@ -99,7 +100,7 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
private int mNumberX;
|
||||
private int mNumberY;
|
||||
private String mNumberText;
|
||||
private Notification mNotification;
|
||||
private StatusBarNotification mNotification;
|
||||
private final boolean mBlocked;
|
||||
private int mDensity;
|
||||
private float mIconScale = 1.0f;
|
||||
@@ -127,11 +128,11 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
};
|
||||
private final NotificationIconDozeHelper mDozer;
|
||||
|
||||
public StatusBarIconView(Context context, String slot, Notification notification) {
|
||||
this(context, slot, notification, false);
|
||||
public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
|
||||
this(context, slot, sbn, false);
|
||||
}
|
||||
|
||||
public StatusBarIconView(Context context, String slot, Notification notification,
|
||||
public StatusBarIconView(Context context, String slot, StatusBarNotification sbn,
|
||||
boolean blocked) {
|
||||
super(context);
|
||||
mDozer = new NotificationIconDozeHelper(context);
|
||||
@@ -141,7 +142,7 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
mNumberPain.setTextAlign(Paint.Align.CENTER);
|
||||
mNumberPain.setColor(context.getColor(R.drawable.notification_number_text_color));
|
||||
mNumberPain.setAntiAlias(true);
|
||||
setNotification(notification);
|
||||
setNotification(sbn);
|
||||
maybeUpdateIconScaleDimens();
|
||||
setScaleType(ScaleType.CENTER);
|
||||
mDensity = context.getResources().getDisplayMetrics().densityDpi;
|
||||
@@ -207,9 +208,11 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
}
|
||||
}
|
||||
|
||||
public void setNotification(Notification notification) {
|
||||
public void setNotification(StatusBarNotification notification) {
|
||||
mNotification = notification;
|
||||
setContentDescription(notification);
|
||||
if (notification != null) {
|
||||
setContentDescription(notification.getNotification());
|
||||
}
|
||||
}
|
||||
|
||||
public StatusBarIconView(Context context, AttributeSet attrs) {
|
||||
@@ -315,6 +318,10 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Icon getSourceIcon() {
|
||||
return mIcon.icon;
|
||||
}
|
||||
|
||||
private Drawable getIcon(StatusBarIcon icon) {
|
||||
return getIcon(getContext(), icon);
|
||||
}
|
||||
@@ -354,7 +361,7 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
|
||||
super.onInitializeAccessibilityEvent(event);
|
||||
if (mNotification != null) {
|
||||
event.setParcelableData(mNotification);
|
||||
event.setParcelableData(mNotification.getNotification());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,6 +463,10 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
+ " notification=" + mNotification + ")";
|
||||
}
|
||||
|
||||
public StatusBarNotification getNotification() {
|
||||
return mNotification;
|
||||
}
|
||||
|
||||
public String getSlot() {
|
||||
return mSlot;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,15 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.util.ArrayMap;
|
||||
import android.support.v4.util.ArraySet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.internal.statusbar.StatusBarIcon;
|
||||
import com.android.internal.util.NotificationColorUtil;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.ExpandableNotificationRow;
|
||||
@@ -180,14 +184,54 @@ public class NotificationIconAreaController implements DarkReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
// In case we are changing the suppression of a group, the replacement shouldn't flicker
|
||||
// and it should just be replaced instead. We therefore look for notifications that were
|
||||
// just replaced by the child or vice-versa to suppress this.
|
||||
|
||||
ArrayMap<String, ArrayList<StatusBarIcon>> replacingIcons = new ArrayMap<>();
|
||||
ArrayList<View> toRemove = new ArrayList<>();
|
||||
for (int i = 0; i < hostLayout.getChildCount(); i++) {
|
||||
View child = hostLayout.getChildAt(i);
|
||||
if (!(child instanceof StatusBarIconView)) {
|
||||
continue;
|
||||
}
|
||||
if (!toShow.contains(child)) {
|
||||
toRemove.add(child);
|
||||
boolean iconWasReplaced = false;
|
||||
StatusBarIconView removedIcon = (StatusBarIconView) child;
|
||||
String removedGroupKey = removedIcon.getNotification().getGroupKey();
|
||||
for (int j = 0; j < toShow.size(); j++) {
|
||||
StatusBarIconView candidate = toShow.get(j);
|
||||
if (candidate.getSourceIcon().sameAs((removedIcon.getSourceIcon()))
|
||||
&& candidate.getNotification().getGroupKey().equals(removedGroupKey)) {
|
||||
if (!iconWasReplaced) {
|
||||
iconWasReplaced = true;
|
||||
} else {
|
||||
iconWasReplaced = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (iconWasReplaced) {
|
||||
ArrayList<StatusBarIcon> statusBarIcons = replacingIcons.get(removedGroupKey);
|
||||
if (statusBarIcons == null) {
|
||||
statusBarIcons = new ArrayList<>();
|
||||
replacingIcons.put(removedGroupKey, statusBarIcons);
|
||||
}
|
||||
statusBarIcons.add(removedIcon.getStatusBarIcon());
|
||||
}
|
||||
toRemove.add(removedIcon);
|
||||
}
|
||||
}
|
||||
// removing all duplicates
|
||||
ArrayList<String> duplicates = new ArrayList<>();
|
||||
for (String key : replacingIcons.keySet()) {
|
||||
ArrayList<StatusBarIcon> statusBarIcons = replacingIcons.get(key);
|
||||
if (statusBarIcons.size() != 1) {
|
||||
duplicates.add(key);
|
||||
}
|
||||
}
|
||||
replacingIcons.removeAll(duplicates);
|
||||
hostLayout.setReplacingIcons(replacingIcons);
|
||||
|
||||
final int toRemoveCount = toRemove.size();
|
||||
for (int i = 0; i < toRemoveCount; i++) {
|
||||
@@ -217,6 +261,7 @@ public class NotificationIconAreaController implements DarkReceiver {
|
||||
hostLayout.addView(expected, i);
|
||||
}
|
||||
hostLayout.setChangingViewPositions(false);
|
||||
hostLayout.setReplacingIcons(null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,9 +21,13 @@ import android.content.res.Configuration;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.support.v4.util.ArrayMap;
|
||||
import android.support.v4.util.ArraySet;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.statusbar.StatusBarIcon;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
|
||||
@@ -33,6 +37,7 @@ import com.android.systemui.statusbar.stack.AnimationProperties;
|
||||
import com.android.systemui.statusbar.stack.StackStateAnimator;
|
||||
import com.android.systemui.statusbar.stack.ViewState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
@@ -117,6 +122,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
|
||||
private float mVisualOverflowAdaption;
|
||||
private boolean mDisallowNextAnimation;
|
||||
private boolean mAnimationsEnabled = true;
|
||||
private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons;
|
||||
|
||||
public NotificationIconContainer(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -183,11 +189,17 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
|
||||
@Override
|
||||
public void onViewAdded(View child) {
|
||||
super.onViewAdded(child);
|
||||
boolean isReplacingIcon = isReplacingIcon(child);
|
||||
if (!mChangingViewPositions) {
|
||||
mIconStates.put(child, new IconState());
|
||||
IconState v = new IconState();
|
||||
if (isReplacingIcon) {
|
||||
v.justAdded = false;
|
||||
v.justReplaced = true;
|
||||
}
|
||||
mIconStates.put(child, v);
|
||||
}
|
||||
int childIndex = indexOfChild(child);
|
||||
if (childIndex < getChildCount() - 1
|
||||
if (childIndex < getChildCount() - 1 && !isReplacingIcon
|
||||
&& mIconStates.get(getChildAt(childIndex + 1)).iconAppearAmount > 0.0f) {
|
||||
if (mAddAnimationStartIndex < 0) {
|
||||
mAddAnimationStartIndex = childIndex;
|
||||
@@ -200,13 +212,34 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isReplacingIcon(View child) {
|
||||
if (mReplacingIcons == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(child instanceof StatusBarIconView)) {
|
||||
return false;
|
||||
}
|
||||
StatusBarIconView iconView = (StatusBarIconView) child;
|
||||
Icon sourceIcon = iconView.getSourceIcon();
|
||||
String groupKey = iconView.getNotification().getGroupKey();
|
||||
ArrayList<StatusBarIcon> statusBarIcons = mReplacingIcons.get(groupKey);
|
||||
if (statusBarIcons != null) {
|
||||
StatusBarIcon replacedIcon = statusBarIcons.get(0);
|
||||
if (sourceIcon.sameAs(replacedIcon.icon)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewRemoved(View child) {
|
||||
super.onViewRemoved(child);
|
||||
if (child instanceof StatusBarIconView) {
|
||||
boolean isReplacingIcon = isReplacingIcon(child);
|
||||
final StatusBarIconView icon = (StatusBarIconView) child;
|
||||
if (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
|
||||
&& child.getVisibility() == VISIBLE) {
|
||||
&& child.getVisibility() == VISIBLE && isReplacingIcon) {
|
||||
int animationStartIndex = findFirstViewIndexAfter(icon.getTranslationX());
|
||||
if (mAddAnimationStartIndex < 0) {
|
||||
mAddAnimationStartIndex = animationStartIndex;
|
||||
@@ -216,9 +249,11 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
|
||||
}
|
||||
if (!mChangingViewPositions) {
|
||||
mIconStates.remove(child);
|
||||
addTransientView(icon, 0);
|
||||
icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, true /* animate */,
|
||||
() -> removeTransientView(icon));
|
||||
if (!isReplacingIcon) {
|
||||
addTransientView(icon, 0);
|
||||
icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, true /* animate */,
|
||||
() -> removeTransientView(icon));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -473,11 +508,16 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
|
||||
mAnimationsEnabled = enabled;
|
||||
}
|
||||
|
||||
public void setReplacingIcons(ArrayMap<String, ArrayList<StatusBarIcon>> replacingIcons) {
|
||||
mReplacingIcons = replacingIcons;
|
||||
}
|
||||
|
||||
public class IconState extends ViewState {
|
||||
public float iconAppearAmount = 1.0f;
|
||||
public float clampedAppearAmount = 1.0f;
|
||||
public int visibleState;
|
||||
public boolean justAdded = true;
|
||||
private boolean justReplaced;
|
||||
public boolean needsCannedAnimation;
|
||||
public boolean useFullTransitionAmount;
|
||||
public boolean useLinearTransitionAmount;
|
||||
@@ -496,9 +536,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
|
||||
&& !mDisallowNextAnimation
|
||||
&& !noAnimations;
|
||||
if (animationsAllowed) {
|
||||
if (justAdded) {
|
||||
if (justAdded || justReplaced) {
|
||||
super.applyToView(icon);
|
||||
if (iconAppearAmount != 0.0f) {
|
||||
if (justAdded && iconAppearAmount != 0.0f) {
|
||||
icon.setAlpha(0.0f);
|
||||
icon.setVisibleState(StatusBarIconView.STATE_HIDDEN,
|
||||
false /* animate */);
|
||||
@@ -557,6 +597,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
|
||||
}
|
||||
}
|
||||
justAdded = false;
|
||||
justReplaced = false;
|
||||
needsCannedAnimation = false;
|
||||
justUndarkened = false;
|
||||
}
|
||||
|
||||
@@ -6802,7 +6802,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
entry.notification = notification;
|
||||
mGroupManager.onEntryUpdated(entry, oldNotification);
|
||||
|
||||
entry.updateIcons(mContext, n);
|
||||
entry.updateIcons(mContext, notification);
|
||||
inflateViews(entry, mStackScroller);
|
||||
|
||||
mForegroundServiceController.updateNotification(notification,
|
||||
|
||||
Reference in New Issue
Block a user