Fix notification update path for structural updates.

Similar logic is required for the replacement case, as is already in place
for the update case, although the actions are different.

Bug: 15588056
Change-Id: I9ad115237c589716772e569fa1979a206b77097b
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 7196b62..97123fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -132,7 +132,6 @@
     // for heads up notifications
     protected HeadsUpNotificationView mHeadsUpNotificationView;
     protected int mHeadsUpNotificationDecay;
-    protected long mInterruptingNotificationTime;
 
     // used to notify status bar for suppressing notification LED
     protected boolean mPanelSlightlyVisible;
@@ -1413,6 +1412,9 @@
                 && !TextUtils.equals(notification.getNotification().tickerText,
                 oldEntry.notification.getNotification().tickerText);
 
+        final boolean shouldInterrupt = shouldInterrupt(notification);
+        final boolean alertAgain = alertAgain(oldEntry);
+        boolean updateSuccessful = false;
         if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged
                 && publicUnchanged) {
             if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
@@ -1432,8 +1434,6 @@
                     }
                 }
 
-                final boolean shouldInterrupt = shouldInterrupt(notification);
-                final boolean alertAgain = alertAgain(oldEntry);
                 if (wasHeadsUp) {
                     if (shouldInterrupt) {
                         updateHeadsUpViews(oldEntry, notification);
@@ -1455,24 +1455,52 @@
                 }
                 mNotificationData.updateRanking(ranking);
                 updateNotifications();
+                updateSuccessful = true;
             }
             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(key, ranking);
-                addNotificationViews(notification, ranking);
             }
-        } else {
+        }
+        if (!updateSuccessful) {
             if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
-            if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
-            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();
-                newEntry.row.setUserExpanded(userExpanded);
-                newEntry.row.notifyHeightChanged();
+            if (wasHeadsUp) {
+                if (shouldInterrupt) {
+                    if (DEBUG) Log.d(TAG, "rebuilding heads up for key: " + key);
+                    Entry newEntry = new Entry(notification, null);
+                    ViewGroup holder = mHeadsUpNotificationView.getHolder();
+                    if (inflateViewsForHeadsUp(newEntry, holder)) {
+                        mHeadsUpNotificationView.showNotification(newEntry);
+                        if (alertAgain) {
+                            resetHeadsUpDecayTimer();
+                        }
+                    } else {
+                        Log.w(TAG, "Couldn't create new updated headsup for package "
+                                + contentView.getPackage());
+                    }
+                } else {
+                    if (DEBUG) Log.d(TAG, "releasing heads up for key: " + key);
+                    oldEntry.notification = notification;
+                    mHeadsUpNotificationView.releaseAndClose();
+                    return;
+                }
+            } else {
+                if (shouldInterrupt && alertAgain) {
+                    if (DEBUG) Log.d(TAG, "reposting to invoke heads up for key: " + key);
+                    removeNotificationViews(key, ranking);
+                    addNotificationInternal(notification, ranking);  //this will pop the headsup
+                } else {
+                    if (DEBUG) Log.d(TAG, "rebuilding update in place for key: " + key);
+                    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();
+                        newEntry.row.setUserExpanded(userExpanded);
+                        newEntry.row.notifyHeightChanged();
+                    }
+                }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index d413f63..8a57ce6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1081,8 +1081,6 @@
             Entry interruptionCandidate = new Entry(notification, null);
             ViewGroup holder = mHeadsUpNotificationView.getHolder();
             if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
-                mInterruptingNotificationTime = System.currentTimeMillis();
-
                 // 1. Populate mHeadsUpNotificationView
                 mHeadsUpNotificationView.showNotification(interruptionCandidate);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index 0f6c4b2..0a48e34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -78,8 +78,10 @@
     }
 
     public boolean showNotification(NotificationData.Entry headsUp) {
-        // bump any previous heads up back to the shade
-        release();
+        if (mHeadsUp != null && headsUp != null && !mHeadsUp.key.equals(headsUp.key)) {
+            // bump any previous heads up back to the shade
+            release();
+        }
 
         mHeadsUp = headsUp;
         if (mContentHolder != null) {