SysUI: Fix notification leak

Fix bug where we kept a reference to the old Notification when
we re-use notification entries on updates.

Bug: 16513124
Change-Id: I066ff7447952516e27e122df57d4e6e67ee1cea3
Conflicts:
	packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 48fc4ec..8482aa3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1330,31 +1330,30 @@
         return entry.notification;
     }
 
-    protected NotificationData.Entry createNotificationViews(StatusBarNotification notification) {
+    protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn) {
         if (DEBUG) {
-            Log.d(TAG, "createNotificationViews(notification=" + notification);
+            Log.d(TAG, "createNotificationViews(notification=" + sbn);
         }
         // Construct the icon.
+        Notification n = sbn.getNotification();
         final StatusBarIconView iconView = new StatusBarIconView(mContext,
-                notification.getPackageName() + "/0x" + Integer.toHexString(notification.getId()),
-                notification.getNotification());
+                sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
         iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 
-        final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
-                notification.getUser(),
-                    notification.getNotification().icon,
-                    notification.getNotification().iconLevel,
-                    notification.getNotification().number,
-                    notification.getNotification().tickerText);
+        final StatusBarIcon ic = new StatusBarIcon(sbn.getPackageName(),
+                sbn.getUser(),
+                    n.icon,
+                    n.iconLevel,
+                    n.number,
+                    n.tickerText);
         if (!iconView.set(ic)) {
-            handleNotificationError(notification, "Couldn't create icon: " + ic);
+            handleNotificationError(sbn, "Couldn't create icon: " + ic);
             return null;
         }
         // Construct the expanded view.
-        NotificationData.Entry entry = new NotificationData.Entry(notification, iconView);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn, iconView);
         if (!inflateViews(entry, mStackScroller)) {
-            handleNotificationError(notification, "Couldn't expand RemoteViews for: "
-                    + notification);
+            handleNotificationError(sbn, "Couldn't expand RemoteViews for: " + sbn);
             return null;
         }
         return entry;
@@ -1474,15 +1473,16 @@
 
         // XXX: modify when we do something more intelligent with the two content views
         final RemoteViews oldContentView = oldNotification.getNotification().contentView;
-        final RemoteViews contentView = notification.getNotification().contentView;
+        Notification n = notification.getNotification();
+        final RemoteViews contentView = n.contentView;
         final RemoteViews oldBigContentView = oldNotification.getNotification().bigContentView;
-        final RemoteViews bigContentView = notification.getNotification().bigContentView;
+        final RemoteViews bigContentView = n.bigContentView;
         final RemoteViews oldHeadsUpContentView = oldNotification.getNotification().headsUpContentView;
-        final RemoteViews headsUpContentView = notification.getNotification().headsUpContentView;
+        final RemoteViews headsUpContentView = n.headsUpContentView;
         final Notification oldPublicNotification = oldNotification.getNotification().publicVersion;
         final RemoteViews oldPublicContentView = oldPublicNotification != null
                 ? oldPublicNotification.contentView : null;
-        final Notification publicNotification = notification.getNotification().publicVersion;
+        final Notification publicNotification = n.publicVersion;
         final RemoteViews publicContentView = publicNotification != null
                 ? publicNotification.contentView : null;
 
@@ -1494,7 +1494,7 @@
                     + " bigContentView=" + oldBigContentView
                     + " publicView=" + oldPublicContentView
                     + " rowParent=" + oldEntry.row.getParent());
-            Log.d(TAG, "new notification: when=" + notification.getNotification().when
+            Log.d(TAG, "new notification: when=" + n.when
                     + " ongoing=" + oldNotification.isOngoing()
                     + " contentView=" + contentView
                     + " bigContentView=" + bigContentView
@@ -1531,8 +1531,8 @@
                         && oldPublicContentView.getPackage() != null
                         && oldPublicContentView.getPackage().equals(publicContentView.getPackage())
                         && oldPublicContentView.getLayoutId() == publicContentView.getLayoutId());
-        boolean updateTicker = notification.getNotification().tickerText != null
-                && !TextUtils.equals(notification.getNotification().tickerText,
+        boolean updateTicker = n.tickerText != null
+                && !TextUtils.equals(n.tickerText,
                 oldEntry.notification.getNotification().tickerText);
 
         final boolean shouldInterrupt = shouldInterrupt(notification);
@@ -1547,10 +1547,11 @@
                     // Update the icon
                     final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
                             notification.getUser(),
-                            notification.getNotification().icon,
-                            notification.getNotification().iconLevel,
-                            notification.getNotification().number,
-                            notification.getNotification().tickerText);
+                            n.icon,
+                            n.iconLevel,
+                            n.number,
+                            n.tickerText);
+                    oldEntry.icon.setNotification(n);
                     if (!oldEntry.icon.set(ic)) {
                         handleNotificationError(notification, "Couldn't update icon: " + ic);
                         return;
@@ -1615,6 +1616,14 @@
                 } else {
                     if (DEBUG) Log.d(TAG, "rebuilding update in place for key: " + key);
                     oldEntry.notification = notification;
+                    final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
+                            notification.getUser(),
+                            n.icon,
+                            n.iconLevel,
+                            n.number,
+                            n.tickerText);
+                    oldEntry.icon.setNotification(n);
+                    oldEntry.icon.set(ic);
                     inflateViews(oldEntry, mStackScroller, wasHeadsUp);
                     updateNotifications();
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 6f839bd..20dd3e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -57,8 +57,7 @@
         mNumberPain.setTextAlign(Paint.Align.CENTER);
         mNumberPain.setColor(res.getColor(R.drawable.notification_number_text_color));
         mNumberPain.setAntiAlias(true);
-        mNotification = notification;
-        setContentDescription(notification);
+        setNotification(notification);
 
         // We do not resize and scale system icons (on the right), only notification icons (on the
         // left).
@@ -73,6 +72,11 @@
         setScaleType(ImageView.ScaleType.CENTER);
     }
 
+    public void setNotification(Notification notification) {
+        mNotification = notification;
+        setContentDescription(notification);
+    }
+
     public StatusBarIconView(Context context, AttributeSet attrs) {
         super(context, attrs);
         final Resources res = context.getResources();