Make bad notifications crash their application.

Implement notification manager handling of bad notifications, to
call a new activity manager to have the owner's process crashed
(if there is one).

Change-Id: Ib15e8d0c598756f3b39c99cc2045c18e054daf6b
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 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) {