summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI
diff options
context:
space:
mode:
authorJoe Onorato <joeo@android.com>2010-06-04 16:08:02 -0400
committerJoe Onorato <joeo@android.com>2010-06-09 09:15:25 -0700
commit005847b03b2ebe3eb1a974a8a04ad51bca6636cd (patch)
tree1664f30f2320bddcf44b0af581b492589a38fcda /packages/SystemUI
parentd956ae8b813da893ab6a9357acfe287c529d6ac2 (diff)
downloadframeworks_base-005847b03b2ebe3eb1a974a8a04ad51bca6636cd.zip
frameworks_base-005847b03b2ebe3eb1a974a8a04ad51bca6636cd.tar.gz
frameworks_base-005847b03b2ebe3eb1a974a8a04ad51bca6636cd.tar.bz2
Handle errors inflating notifications (and their icons).
On an inflation error, the StatusBarService cleans up, removes / doesn't add the views, and calls into the StatusBarManagerService, which tells the NotificationManagerService to remove the notification. That then calls all the way back into the StatusBarService, but I think being extra careful is okay. Throughout the status bar, it's all keyed off of the IBinder key, so if the app comes in with a good notification while we're cleaning up, we won't lose the new notification or anything like that. Change-Id: Iea78a637495a8b67810c214b951d5ddb93becacb
Diffstat (limited to 'packages/SystemUI')
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java57
2 files changed, 63 insertions, 40 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
index ad59a0c..ca589cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
@@ -373,6 +373,14 @@ public class PhoneStatusBarService extends StatusBarService {
oldEntry.content.setOnClickListener(new Launcher(contentIntent,
notification.pkg, notification.tag, notification.id));
}
+ // Update the icon.
+ final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
+ notification.notification.icon, notification.notification.iconLevel,
+ notification.notification.number);
+ if (!oldEntry.icon.set(ic)) {
+ handleNotificationError(key, notification, "Couldn't update icon: " + ic);
+ return;
+ }
}
catch (RuntimeException e) {
// It failed to add cleanly. Log, and remove the view from the panel.
@@ -380,9 +388,6 @@ public class PhoneStatusBarService extends StatusBarService {
removeNotificationViews(key);
addNotificationViews(key, notification);
}
- // Update the icon.
- oldEntry.icon.set(new StatusBarIcon(notification.pkg, notification.notification.icon,
- notification.notification.iconLevel, notification.notification.number));
} else {
Slog.d(TAG, "not reusing notification");
removeNotificationViews(key);
@@ -451,8 +456,9 @@ public class PhoneStatusBarService extends StatusBarService {
exception = e;
}
if (expanded == null) {
- Slog.e(TAG, "couldn't inflate view for package " + notification.pkg, exception);
- row.setVisibility(View.GONE);
+ String ident = notification.pkg + "/0x" + Integer.toHexString(notification.id);
+ Slog.e(TAG, "couldn't inflate view for notification " + ident);
+ return null;
} else {
content.addView(expanded);
row.setDrawingCacheEnabled(true);
@@ -474,14 +480,23 @@ public class PhoneStatusBarService extends StatusBarService {
}
// Construct the expanded view.
final View[] views = makeNotificationView(notification, parent);
+ if (views == null) {
+ handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
+ + notification);
+ return;
+ }
final View row = views[0];
final View content = views[1];
final View expanded = views[2];
// Construct the icon.
- StatusBarIconView iconView = new StatusBarIconView(this,
+ final StatusBarIconView iconView = new StatusBarIconView(this,
notification.pkg + "/0x" + Integer.toHexString(notification.id));
- iconView.set(new StatusBarIcon(notification.pkg, notification.notification.icon,
- notification.notification.iconLevel, notification.notification.number));
+ final StatusBarIcon ic = new StatusBarIcon(notification.pkg, notification.notification.icon,
+ notification.notification.iconLevel, notification.notification.number);
+ if (!iconView.set(ic)) {
+ handleNotificationError(key, notification, "Coulding create icon: " + ic);
+ return;
+ }
// Add the expanded view.
final int viewIndex = list.add(key, notification, row, content, expanded, iconView);
parent.addView(row, viewIndex);
@@ -967,6 +982,21 @@ public class PhoneStatusBarService extends StatusBarService {
}
}
+ /**
+ * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
+ * about the failure.
+ *
+ * WARNING: this will call back into us. Don't hold any locks.
+ */
+ void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
+ removeNotification(key);
+ try {
+ mBarService.onNotificationError(n.pkg, n.tag, n.id, message);
+ } catch (RemoteException ex) {
+ // The end is nigh.
+ }
+ }
+
private class MyTicker extends Ticker {
MyTicker(Context context, StatusBarView sb) {
super(context, sb);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 5eb0d68..bc1e798 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -32,7 +32,6 @@ public class StatusBarIconView extends AnimatedImageView {
private StatusBarIcon mIcon;
@ViewDebug.ExportedProperty private String mSlot;
- @ViewDebug.ExportedProperty private boolean mError;
public StatusBarIconView(Context context, String slot) {
super(context);
@@ -52,39 +51,33 @@ public class StatusBarIconView extends AnimatedImageView {
return a.equals(b);
}
- public void set(StatusBarIcon icon) {
- error: {
- final boolean iconEquals = !mError
- && mIcon != null
- && streq(mIcon.iconPackage, icon.iconPackage)
- && mIcon.iconId == icon.iconId;
- final boolean levelEquals = !mError
- && iconEquals
- && mIcon.iconLevel == icon.iconLevel;
- final boolean visibilityEquals = !mError
- && mIcon != null
- && mIcon.visible == icon.visible;
- mError = false;
- if (!iconEquals) {
- Drawable drawable = getIcon(icon);
- if (drawable == null) {
- mError = true;
- Slog.w(PhoneStatusBarService.TAG, "No icon ID for slot " + mSlot);
- break error;
- }
- setImageDrawable(drawable);
- }
- if (!levelEquals) {
- setImageLevel(icon.iconLevel);
- }
- if (!visibilityEquals) {
- setVisibility(icon.visible ? VISIBLE : GONE);
+ /**
+ * Returns whether the set succeeded.
+ */
+ public boolean set(StatusBarIcon icon) {
+ final boolean iconEquals = mIcon != null
+ && streq(mIcon.iconPackage, icon.iconPackage)
+ && mIcon.iconId == icon.iconId;
+ final boolean levelEquals = iconEquals
+ && mIcon.iconLevel == icon.iconLevel;
+ final boolean visibilityEquals = mIcon != null
+ && mIcon.visible == icon.visible;
+ if (!iconEquals) {
+ Drawable drawable = getIcon(icon);
+ if (drawable == null) {
+ Slog.w(PhoneStatusBarService.TAG, "No icon for slot " + mSlot);
+ return false;
}
- mIcon = icon.clone();
+ setImageDrawable(drawable);
+ }
+ if (!levelEquals) {
+ setImageLevel(icon.iconLevel);
}
- if (mError) {
- setVisibility(GONE);
+ if (!visibilityEquals) {
+ setVisibility(icon.visible ? VISIBLE : GONE);
}
+ mIcon = icon.clone();
+ return true;
}
private Drawable getIcon(StatusBarIcon icon) {
@@ -106,7 +99,7 @@ public class StatusBarIconView extends AnimatedImageView {
try {
r = context.getPackageManager().getResourcesForApplication(icon.iconPackage);
} catch (PackageManager.NameNotFoundException ex) {
- Slog.e(PhoneStatusBarService.TAG, "Icon package not found: "+icon.iconPackage, ex);
+ Slog.e(PhoneStatusBarService.TAG, "Icon package not found: " + icon.iconPackage);
return null;
}
} else {