diff options
author | Dianne Hackborn <hackbod@google.com> | 2010-06-24 17:30:42 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2010-06-24 17:30:42 -0700 |
commit | ea8eafad4f5438ec1291d45376959a996d36e15e (patch) | |
tree | 9a43826f17176d336a3f6dbf07e41d1922d63a0f /services/java | |
parent | cac3126c6109854640266c4807e5aa8e6a87142f (diff) | |
parent | 2529a45339b7e02d9d2b813358bcecd144a971ea (diff) | |
download | frameworks_base-ea8eafad4f5438ec1291d45376959a996d36e15e.zip frameworks_base-ea8eafad4f5438ec1291d45376959a996d36e15e.tar.gz frameworks_base-ea8eafad4f5438ec1291d45376959a996d36e15e.tar.bz2 |
am 2529a453: Merge "Make bad notifications crash their application." into gingerbread
Merge commit '2529a45339b7e02d9d2b813358bcecd144a971ea' into gingerbread-plus-aosp
* commit '2529a45339b7e02d9d2b813358bcecd144a971ea':
Make bad notifications crash their application.
Diffstat (limited to 'services/java')
3 files changed, 82 insertions, 8 deletions
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index 6f44e8e..3e2c122 100755 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -164,16 +164,21 @@ class NotificationManagerService extends INotificationManager.Stub final String pkg; final String tag; final int id; + final int uid; + final int initialPid; ITransientNotification callback; int duration; final Notification notification; IBinder statusBarKey; - NotificationRecord(String pkg, String tag, int id, Notification notification) + NotificationRecord(String pkg, String tag, int id, int uid, int initialPid, + Notification notification) { this.pkg = pkg; this.tag = tag; this.id = id; + this.uid = uid; + this.initialPid = initialPid; this.notification = notification; } @@ -304,10 +309,18 @@ class NotificationManagerService extends INotificationManager.Stub } } - public void onNotificationError(String pkg, String tag, int id, String message) { + public void onNotificationError(String pkg, String tag, int id, + int uid, int initialPid, String message) { Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id); cancelNotification(pkg, tag, id, 0, 0); - // TODO: Tell the activity manager. + long ident = Binder.clearCallingIdentity(); + try { + ActivityManagerNative.getDefault().crashApplication(uid, initialPid, pkg, + "Bad notification posted from package " + pkg + + ": " + message); + } catch (RemoteException e) { + } + Binder.restoreCallingIdentity(ident); } }; @@ -663,6 +676,9 @@ class NotificationManagerService extends INotificationManager.Stub public void enqueueNotificationWithTag(String pkg, String tag, int id, Notification notification, int[] idOut) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + checkIncomingCall(pkg); // Limit the number of notifications that any given package except the android @@ -708,7 +724,8 @@ class NotificationManagerService extends INotificationManager.Stub } synchronized (mNotificationList) { - NotificationRecord r = new NotificationRecord(pkg, tag, id, notification); + NotificationRecord r = new NotificationRecord(pkg, tag, id, + callingUid, callingPid, notification); NotificationRecord old = null; int index = indexOfNotificationLocked(pkg, tag, id); @@ -732,7 +749,8 @@ class NotificationManagerService extends INotificationManager.Stub } if (notification.icon != 0) { - StatusBarNotification n = new StatusBarNotification(pkg, id, tag, notification); + StatusBarNotification n = new StatusBarNotification(pkg, id, tag, + r.uid, r.initialPid, notification); if (old != null && old.statusBarKey != null) { r.statusBarKey = old.statusBarKey; long identity = Binder.clearCallingIdentity(); diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java index 1a16387..4177432 100644 --- a/services/java/com/android/server/StatusBarManagerService.java +++ b/services/java/com/android/server/StatusBarManagerService.java @@ -85,7 +85,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub void onClearAll(); void onNotificationClick(String pkg, String tag, int id); void onPanelRevealed(); - void onNotificationError(String pkg, String tag, int id, String message); + void onNotificationError(String pkg, String tag, int id, + int uid, int initialPid, String message); } /** @@ -293,11 +294,12 @@ public class StatusBarManagerService extends IStatusBarService.Stub mNotificationCallbacks.onNotificationClick(pkg, tag, id); } - public void onNotificationError(String pkg, String tag, int id, String message) { + public void onNotificationError(String pkg, String tag, int id, + int uid, int initialPid, String message) { enforceStatusBarService(); // WARNING: this will call back into us to do the remove. Don't hold any locks. - mNotificationCallbacks.onNotificationError(pkg, tag, id, message); + mNotificationCallbacks.onNotificationError(pkg, tag, id, uid, initialPid, message); } public void onClearAllNotifications() { diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 0e1eb6f..252392b 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -4562,6 +4562,60 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } + public void crashApplication(int uid, int initialPid, String packageName, + String message) { + if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) + != PackageManager.PERMISSION_GRANTED) { + String msg = "Permission Denial: crashApplication() from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid() + + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + + synchronized(this) { + ProcessRecord proc = null; + + // Figure out which process to kill. We don't trust that initialPid + // still has any relation to current pids, so must scan through the + // list. + synchronized (mPidsSelfLocked) { + for (int i=0; i<mPidsSelfLocked.size(); i++) { + ProcessRecord p = mPidsSelfLocked.valueAt(i); + if (p.info.uid != uid) { + continue; + } + if (p.pid == initialPid) { + proc = p; + break; + } + for (String str : p.pkgList) { + if (str.equals(packageName)) { + proc = p; + } + } + } + } + + if (proc == null) { + Log.w(TAG, "crashApplication: nothing for uid=" + uid + + " initialPid=" + initialPid + + " packageName=" + packageName); + return; + } + + if (proc.thread != null) { + long ident = Binder.clearCallingIdentity(); + try { + proc.thread.scheduleCrash(message); + } catch (RemoteException e) { + } + Binder.restoreCallingIdentity(ident); + } + } + } + void sendActivityResultLocked(int callingUid, ActivityRecord r, String resultWho, int requestCode, int resultCode, Intent data) { |