summaryrefslogtreecommitdiffstats
path: root/services/java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-06-24 17:30:42 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2010-06-24 17:30:42 -0700
commitea8eafad4f5438ec1291d45376959a996d36e15e (patch)
tree9a43826f17176d336a3f6dbf07e41d1922d63a0f /services/java
parentcac3126c6109854640266c4807e5aa8e6a87142f (diff)
parent2529a45339b7e02d9d2b813358bcecd144a971ea (diff)
downloadframeworks_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')
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java28
-rw-r--r--services/java/com/android/server/StatusBarManagerService.java8
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java54
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) {