Deal with broken notifications.

Change-Id: I21582ba4db70677f411a7e14bcdd7eac7d5a643e
diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/NotificationData.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/NotificationData.java
index 5499cc4..9252a33 100644
--- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/NotificationData.java
+++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/NotificationData.java
@@ -32,8 +32,9 @@
         public IBinder key;
         public StatusBarNotification notification;
         public StatusBarIconView icon;
-        public View expanded; // the outer expanded view
-        public View contents; // the inflated RemoteViews
+        public View row; // the outer expanded view
+        public View content; // takes the click events and sends the PendingIntent
+        public View expanded; // the inflated RemoteViews
     }
     private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
 
@@ -56,11 +57,13 @@
         return -1;
     }
 
-    public int add(IBinder key, StatusBarNotification notification, View expanded,
-            StatusBarIconView icon) {
+    public int add(IBinder key, StatusBarNotification notification, View row, View content,
+            View expanded, StatusBarIconView icon) {
         Entry entry = new Entry();
         entry.key = key;
         entry.notification = notification;
+        entry.row = row;
+        entry.content = content;
         entry.expanded = expanded;
         entry.icon = icon;
         final int index = chooseIndex(notification.notification.when);
@@ -95,7 +98,14 @@
      * Return whether there are any visible items (i.e. items without an error).
      */
     public boolean hasVisibleItems() {
-        return mEntries.size() != 0; // TODO
+        final int N = mEntries.size();
+        for (int i=0; i<N; i++) {
+            Entry entry = mEntries.get(i);
+            if (entry.expanded != null) { // the view successfully inflated
+                return true;
+            }
+        }
+        return false;
     }
 
     /**
@@ -105,9 +115,10 @@
         final int N = mEntries.size();
         for (int i=0; i<N; i++) {
             Entry entry = mEntries.get(i);
-            // TODO: if (!entry.error)
-            if ((entry.notification.notification.flags & Notification.FLAG_NO_CLEAR) == 0) {
-                return true;
+            if (entry.expanded != null) { // the view successfully inflated
+                if ((entry.notification.notification.flags & Notification.FLAG_NO_CLEAR) == 0) {
+                    return true;
+                }
             }
         }
         return false;
diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java
index 4acd57c..10d31be 100644
--- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java
+++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java
@@ -354,7 +354,7 @@
         // didn't change.
         if (notification.notification.when == oldNotification.notification.when
                 && notification.isOngoing() == oldNotification.isOngoing()
-                && oldEntry.contents != null
+                && oldEntry.expanded != null
                 && contentView != null && oldContentView != null
                 && contentView.getPackage() != null
                 && oldContentView.getPackage() != null
@@ -364,19 +364,17 @@
             oldEntry.notification = notification;
             try {
                 // Reapply the RemoteViews
-                contentView.reapply(this, oldEntry.contents);
+                contentView.reapply(this, oldEntry.content);
                 // update the contentIntent
-                ViewGroup clickView = (ViewGroup)oldEntry.expanded.findViewById(
-                        com.android.internal.R.id.content);
                 final PendingIntent contentIntent = notification.notification.contentIntent;
                 if (contentIntent != null) {
-                    clickView.setOnClickListener(new Launcher(contentIntent, notification.pkg,
-                                notification.tag, notification.id));
+                    oldEntry.content.setOnClickListener(new Launcher(contentIntent,
+                                notification.pkg, notification.tag, notification.id));
                 }
             }
             catch (RuntimeException e) {
                 // It failed to add cleanly.  Log, and remove the view from the panel.
-                Slog.w(TAG, "couldn't reapply views for package " + contentView.getPackage(), e);
+                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
                 removeNotificationViews(key);
                 addNotificationViews(key, notification);
             }
@@ -418,7 +416,7 @@
         return (ongoingSize + latestSize) - index - 1;
     }
 
-    View makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
+    View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
         Notification n = notification.notification;
         RemoteViews remoteViews = n.contentView;
         if (remoteViews == null) {
@@ -440,23 +438,23 @@
                         notification.tag, notification.id));
         }
 
-        View child = null;
+        View expanded = null;
         Exception exception = null;
         try {
-            child = remoteViews.apply(this, content);
+            expanded = remoteViews.apply(this, content);
         }
         catch (RuntimeException e) {
             exception = e;
         }
-        if (child == null) {
+        if (expanded == null) {
             Slog.e(TAG, "couldn't inflate view for package " + notification.pkg, exception);
-            return null;
+            row.setVisibility(View.GONE);
+        } else {
+            content.addView(expanded);
+            row.setDrawingCacheEnabled(true);
         }
-        content.addView(child);
 
-        row.setDrawingCacheEnabled(true);
-
-        return row;
+        return new View[] { row, content, expanded };
     }
 
     void addNotificationViews(IBinder key, StatusBarNotification notification) {
@@ -471,15 +469,18 @@
             parent = mLatestItems;
         }
         // Construct the expanded view.
-        final View view = makeNotificationView(notification, parent);
+        final View[] views = makeNotificationView(notification, parent);
+        final View row = views[0];
+        final View content = views[1];
+        final View expanded = views[2];
         // Construct the icon.
         StatusBarIconView iconView = new StatusBarIconView(this,
                 notification.pkg + "/" + notification.id);
         iconView.set(new StatusBarIcon(notification.pkg, notification.notification.icon,
                     notification.notification.iconLevel, notification.notification.number));
         // Add the expanded view.
-        final int viewIndex = list.add(key, notification, view, iconView);
-        parent.addView(view, viewIndex);
+        final int viewIndex = list.add(key, notification, row, content, expanded, iconView);
+        parent.addView(row, viewIndex);
         // Add the icon.
         final int iconIndex = chooseIconIndex(isOngoing, viewIndex);
         mNotificationIcons.addView(iconView, iconIndex,
@@ -496,7 +497,7 @@
             }
         }
         // Remove the expanded view.
-        ((ViewGroup)entry.expanded.getParent()).removeView(entry.expanded);
+        ((ViewGroup)entry.row.getParent()).removeView(entry.row);
         // Remove the icon.
         ((ViewGroup)entry.icon.getParent()).removeView(entry.icon);
     }