Manage heads up state during notification update.
Notifications can now get the heads up slot on updates. FLAG_ONLY_ALERT_ONCE suppresses this behavior. Bug: 15534198 Change-Id: Ie27b7c7d93c590d777670c538fb796a04252046f
This commit is contained in:
@@ -311,7 +311,8 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mNotificationData.findByKey(sbn.getKey()) != null) {
|
||||
if (mNotificationData.findByKey(sbn.getKey()) != null ||
|
||||
isHeadsUp(sbn.getKey())) {
|
||||
updateNotificationInternal(sbn, rankingMap);
|
||||
} else {
|
||||
addNotificationInternal(sbn, rankingMap);
|
||||
@@ -467,6 +468,10 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
// should be overridden
|
||||
}
|
||||
|
||||
public boolean isHeadsUp(String key) {
|
||||
return mHeadsUpNotificationView != null && mHeadsUpNotificationView.isShowing(key);
|
||||
}
|
||||
|
||||
public boolean notificationIsForCurrentProfiles(StatusBarNotification n) {
|
||||
final int thisUserId = mCurrentUserId;
|
||||
final int notificationUserId = n.getUserId();
|
||||
@@ -892,10 +897,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}
|
||||
|
||||
public boolean inflateViews(NotificationData.Entry entry, ViewGroup parent, boolean isHeadsUp) {
|
||||
int minHeight =
|
||||
mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height);
|
||||
int maxHeight =
|
||||
mContext.getResources().getDimensionPixelSize(R.dimen.notification_max_height);
|
||||
int maxHeight = mRowMaxHeight;
|
||||
StatusBarNotification sbn = entry.notification;
|
||||
RemoteViews contentView = sbn.getNotification().contentView;
|
||||
RemoteViews bigContentView = sbn.getNotification().bigContentView;
|
||||
@@ -1058,7 +1060,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}
|
||||
}
|
||||
entry.row = row;
|
||||
entry.row.setHeightRange(mRowMinHeight, mRowMaxHeight);
|
||||
entry.row.setHeightRange(mRowMinHeight, maxHeight);
|
||||
entry.row.setOnActivatedListener(this);
|
||||
entry.row.setIsBelowSpeedBump(isBelowSpeedBump(entry.notification));
|
||||
entry.expanded = contentViewLocal;
|
||||
@@ -1333,9 +1335,15 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
|
||||
if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
|
||||
|
||||
final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey());
|
||||
final String key = notification.getKey();
|
||||
boolean wasHeadsUp = isHeadsUp(key);
|
||||
NotificationData.Entry oldEntry;
|
||||
if (wasHeadsUp) {
|
||||
oldEntry = mHeadsUpNotificationView.getEntry();
|
||||
} else {
|
||||
oldEntry = mNotificationData.findByKey(key);
|
||||
}
|
||||
if (oldEntry == null) {
|
||||
Log.w(TAG, "updateNotification for unknown key: " + notification.getKey());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1401,39 +1409,49 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
&& oldPublicContentView.getPackage() != null
|
||||
&& oldPublicContentView.getPackage().equals(publicContentView.getPackage())
|
||||
&& oldPublicContentView.getLayoutId() == publicContentView.getLayoutId());
|
||||
|
||||
|
||||
boolean updateTicker = notification.getNotification().tickerText != null
|
||||
&& !TextUtils.equals(notification.getNotification().tickerText,
|
||||
oldEntry.notification.getNotification().tickerText);
|
||||
|
||||
if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged
|
||||
&& publicUnchanged) {
|
||||
if (DEBUG) Log.d(TAG, "reusing notification for key: " + notification.getKey());
|
||||
if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
|
||||
oldEntry.notification = notification;
|
||||
try {
|
||||
updateNotificationViews(oldEntry, notification);
|
||||
|
||||
if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null
|
||||
&& oldNotification == mHeadsUpNotificationView.getEntry().notification) {
|
||||
if (!shouldInterrupt(notification)) {
|
||||
if (DEBUG) Log.d(TAG, "no longer interrupts!");
|
||||
scheduleHeadsUpClose();
|
||||
} else {
|
||||
if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification);
|
||||
mHeadsUpNotificationView.getEntry().notification = notification;
|
||||
updateHeadsUpViews(mHeadsUpNotificationView.getEntry(), notification);
|
||||
if (oldEntry.icon != null) {
|
||||
// Update the icon
|
||||
final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
|
||||
notification.getUser(),
|
||||
notification.getNotification().icon,
|
||||
notification.getNotification().iconLevel,
|
||||
notification.getNotification().number,
|
||||
notification.getNotification().tickerText);
|
||||
if (!oldEntry.icon.set(ic)) {
|
||||
handleNotificationError(notification, "Couldn't update icon: " + ic);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the icon.
|
||||
final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
|
||||
notification.getUser(),
|
||||
notification.getNotification().icon, notification.getNotification().iconLevel,
|
||||
notification.getNotification().number,
|
||||
notification.getNotification().tickerText);
|
||||
if (!oldEntry.icon.set(ic)) {
|
||||
handleNotificationError(notification, "Couldn't update icon: " + ic);
|
||||
return;
|
||||
final boolean shouldInterrupt = shouldInterrupt(notification);
|
||||
final boolean alertAgain = alertAgain(oldEntry);
|
||||
if (wasHeadsUp) {
|
||||
if (shouldInterrupt) {
|
||||
updateHeadsUpViews(oldEntry, notification);
|
||||
if (alertAgain) {
|
||||
resetHeadsUpDecayTimer();
|
||||
}
|
||||
} else {
|
||||
// we updated the notification above, so release to build a new shade entry
|
||||
mHeadsUpNotificationView.releaseAndClose();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (shouldInterrupt && alertAgain) {
|
||||
removeNotificationViews(key, ranking);
|
||||
addNotificationInternal(notification, ranking); //this will pop the headsup
|
||||
} else {
|
||||
updateNotificationViews(oldEntry, notification);
|
||||
}
|
||||
}
|
||||
mNotificationData.updateRanking(ranking);
|
||||
updateNotifications();
|
||||
@@ -1441,16 +1459,15 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
catch (RuntimeException e) {
|
||||
// It failed to add cleanly. Log, and remove the view from the panel.
|
||||
Log.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
|
||||
removeNotificationViews(notification.getKey(), ranking);
|
||||
removeNotificationViews(key, ranking);
|
||||
addNotificationViews(notification, ranking);
|
||||
}
|
||||
} else {
|
||||
if (DEBUG) Log.d(TAG, "not reusing notification for key: " + notification.getKey());
|
||||
if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
|
||||
if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
|
||||
removeNotificationViews(notification.getKey(), ranking);
|
||||
addNotificationViews(notification, ranking); // will also replace the heads up
|
||||
final NotificationData.Entry newEntry = mNotificationData.findByKey(
|
||||
notification.getKey());
|
||||
removeNotificationViews(key, ranking);
|
||||
addNotificationViews(notification, ranking);
|
||||
final NotificationData.Entry newEntry = mNotificationData.findByKey(key);
|
||||
final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion();
|
||||
if (userChangedExpansion) {
|
||||
boolean userExpanded = oldEntry.row.isUserExpanded();
|
||||
@@ -1535,6 +1552,12 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}
|
||||
}
|
||||
|
||||
private boolean alertAgain(Entry entry) {
|
||||
final StatusBarNotification sbn = entry.notification;
|
||||
return entry == null || !entry.hasInterrupted()
|
||||
|| (sbn.getNotification().flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
|
||||
}
|
||||
|
||||
protected boolean shouldInterrupt(StatusBarNotification sbn) {
|
||||
Notification notification = sbn.getNotification();
|
||||
// some predicates to make the boolean logic legible
|
||||
|
||||
@@ -68,6 +68,10 @@ public class NotificationData {
|
||||
public void setInterruption() {
|
||||
interruption = true;
|
||||
}
|
||||
|
||||
public boolean hasInterrupted() {
|
||||
return interruption;
|
||||
}
|
||||
}
|
||||
|
||||
private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
|
||||
|
||||
@@ -101,6 +101,8 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
|
||||
mSwipeHelper.snapChild(mContentHolder, 1f);
|
||||
mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
|
||||
|
||||
mHeadsUp.setInterruption();
|
||||
|
||||
// 2. Animate mHeadsUpNotificationView in
|
||||
mBar.scheduleHeadsUpOpen();
|
||||
|
||||
@@ -110,6 +112,10 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isShowing(String key) {
|
||||
return mHeadsUp != null && mHeadsUp.key.equals(key);
|
||||
}
|
||||
|
||||
/** Discard the Heads Up notification. */
|
||||
public void clear() {
|
||||
mHeadsUp = null;
|
||||
@@ -136,6 +142,11 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
|
||||
mHeadsUp = null;
|
||||
}
|
||||
|
||||
public void releaseAndClose() {
|
||||
release();
|
||||
mBar.scheduleHeadsUpClose();
|
||||
}
|
||||
|
||||
public NotificationData.Entry getEntry() {
|
||||
return mHeadsUp;
|
||||
}
|
||||
@@ -378,4 +389,4 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
|
||||
return mConsuming;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user