diff options
| author | Joe Onorato <joeo@android.com> | 2010-02-03 20:21:41 -0800 |
|---|---|---|
| committer | Joe Onorato <joeo@android.com> | 2010-02-03 20:21:41 -0800 |
| commit | 68065e0a1980ab6abf8963b48b011efa017fe1c2 (patch) | |
| tree | 3d6d4184f359e3bfea6783a97d0de7c2d99d7ab5 | |
| parent | 378a1488bb76d4786025a10e36c2d638cbd2cb6a (diff) | |
| download | frameworks_base-68065e0a1980ab6abf8963b48b011efa017fe1c2.zip frameworks_base-68065e0a1980ab6abf8963b48b011efa017fe1c2.tar.gz frameworks_base-68065e0a1980ab6abf8963b48b011efa017fe1c2.tar.bz2 | |
Fix 1667521 - system process crash after bad notification
The steps to reproduce this were kind of interesting. You needed to have
a notification with a bogus RemoteViews in the first position in the list,
and then have another notification come in with an earlier timestampe. In
that case, it would get a bad index for the new (not bogus) view that was
being added.
4 files changed, 65 insertions, 6 deletions
diff --git a/services/java/com/android/server/status/NotificationData.java b/services/java/com/android/server/status/NotificationData.java index 0a3411a..784b781 100644 --- a/services/java/com/android/server/status/NotificationData.java +++ b/services/java/com/android/server/status/NotificationData.java @@ -19,7 +19,7 @@ public class NotificationData { public PendingIntent deleteIntent; public String toString() { - return "NotificationData(package=" + pkg + " tickerText=" + tickerText + return "NotificationData(package=" + pkg + " id=" + id + " tickerText=" + tickerText + " ongoingEvent=" + ongoingEvent + " contentIntent=" + contentIntent + " deleteIntent=" + deleteIntent + " clearable=" + clearable diff --git a/services/java/com/android/server/status/NotificationViewList.java b/services/java/com/android/server/status/NotificationViewList.java index 6229292..8f1633f 100644 --- a/services/java/com/android/server/status/NotificationViewList.java +++ b/services/java/com/android/server/status/NotificationViewList.java @@ -104,10 +104,25 @@ class NotificationViewList { return null; } - // gets the index of the notification in its expanded parent view + // gets the index of the notification's view in its expanded parent view int getExpandedIndex(StatusBarNotification notification) { ArrayList<StatusBarNotification> list = notification.data.ongoingEvent ? mOngoing : mLatest; - return list.size() - indexForKey(list, notification.key) - 1; + final IBinder key = notification.key; + int index = 0; + // (the view order is backwards from this list order) + for (int i=list.size()-1; i>=0; i--) { + StatusBarNotification item = list.get(i); + if (item.key == key) { + return index; + } + if (item.view != null) { + index++; + } + } + Log.e(StatusBarService.TAG, "Couldn't find notification in NotificationViewList."); + Log.e(StatusBarService.TAG, "notification=" + notification); + dump(notification); + return 0; } void clearViews() { @@ -156,6 +171,13 @@ class NotificationViewList { list.add(index, notification); if (StatusBarService.SPEW) { + Log.d(StatusBarService.TAG, "NotificationViewList index=" + index); + dump(notification); + } + } + + void dump(StatusBarNotification notification) { + if (StatusBarService.SPEW) { String s = ""; for (int i=0; i<mOngoing.size(); i++) { StatusBarNotification that = mOngoing.get(i); @@ -168,7 +190,7 @@ class NotificationViewList { } s += " "; } - Log.d(StatusBarService.TAG, "NotificationViewList ongoing index=" + index + ": " + s); + Log.d(StatusBarService.TAG, "NotificationViewList ongoing: " + s); s = ""; for (int i=0; i<mLatest.size(); i++) { @@ -182,7 +204,7 @@ class NotificationViewList { } s += " "; } - Log.d(StatusBarService.TAG, "NotificationViewList latest index=" + index + ": " + s); + Log.d(StatusBarService.TAG, "NotificationViewList latest: " + s); } } diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java index 7b722a5..ab29575 100644 --- a/services/java/com/android/server/status/StatusBarService.java +++ b/services/java/com/android/server/status/StatusBarService.java @@ -886,7 +886,8 @@ public class StatusBarService extends IStatusBar.Stub && n.contentView.getPackage() != null && oldData.contentView.getPackage() != null && oldData.contentView.getPackage().equals(n.contentView.getPackage()) - && oldData.contentView.getLayoutId() == n.contentView.getLayoutId()) { + && oldData.contentView.getLayoutId() == n.contentView.getLayoutId() + && notification.view != null) { mNotificationData.update(notification); try { n.contentView.reapply(mContext, notification.contentView); diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java index ffc2cbc..f548145 100644 --- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java +++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java @@ -121,6 +121,32 @@ public class NotificationTestList extends TestActivity } }, + new Test("Bad resource #2") { + public void run() + { + Notification n = new Notification(NotificationTestList.this, + R.drawable.ic_statusbar_missedcall, + null, System.currentTimeMillis()-(1000*60*60*24), + "(453) 123-2328", + "", null); + n.contentView.setInt(1 /*bogus*/, "bogus method", 666); + mNM.notify(2, n); + } + }, + + new Test("Bad resource #3") { + public void run() + { + Notification n = new Notification(NotificationTestList.this, + R.drawable.ic_statusbar_missedcall, + null, System.currentTimeMillis()-(1000*60*60*24), + "(453) 123-2328", + "", null); + n.contentView.setInt(1 /*bogus*/, "bogus method", 666); + mNM.notify(3, n); + } + }, + new Test("Times") { public void run() { @@ -405,6 +431,16 @@ public class NotificationTestList extends TestActivity } }, + new Test("Persistent #3") { + public void run() { + Notification n = new Notification(R.drawable.icon2, "tock tock tock", + System.currentTimeMillis()); + n.setLatestEventInfo(NotificationTestList.this, "Persistent #3", + "Notify me!!!", makeIntent()); + mNM.notify(3, n); + } + }, + new Test("Persistent #2 Vibrate") { public void run() { Notification n = new Notification(R.drawable.icon2, "tock tock tock", |
