Introduce "StrictMode"

This is a new public API for developers to opt-in to strict rules
about what they're allowed to do on certain threads.  (this is the
public face of the @hide dalvik.system.BlockGuard, added recently...)

In practice this will be used for developers to opt-in to declaring
that they don't want to be allowed to do various operations (such as
disk I/O or network operations) on their main UI threads.  (these
operations are often accidental, or even when they are fast come with
a good chance of being slow or very slow in some cases....)

Implementation wise, this is just a thread-local integer that has a
bitmask of the things that aren't allowed, and more bits for saying
what the violation penalty is.  The penalties, of which multiple can
be chosen, include:

  * logging
  * dropbox uploading for analysis/reporting
  * annoying dialog
  * full-on crashing

These are all only very roughly implemented at this point, but all
parts now minimally work end-to-end now, so this is a good checkpoint
commit before this gets too large.

Future CLs will polish all the above 4 penalties, including
checksumming of stacktraces and minimizing penalties for duplicate
violations.

Change-Id: Icbe61a2e950119519e7364030b10c3c28d243abe
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b78d22f..b4c7edc 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1062,6 +1062,15 @@
             return true;
         }
 
+        case HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder app = data.readStrongBinder();
+            ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
+            handleApplicationStrictModeViolation(app, ci);
+            reply.writeNoException();
+            return true;
+        }
+
         case SIGNAL_PERSISTENT_PROCESSES_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int sig = data.readInt();
@@ -2523,6 +2532,7 @@
         reply.recycle();
         data.recycle();
     }
+
     public boolean handleApplicationWtf(IBinder app, String tag,
             ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
     {
@@ -2540,6 +2550,20 @@
         return res;
     }
 
+    public void handleApplicationStrictModeViolation(IBinder app,
+            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(app);
+        crashInfo.writeToParcel(data, 0);
+        mRemote.transact(HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION, data, reply, 0);
+        reply.readException();
+        reply.recycle();
+        data.recycle();
+    }
+
     public void signalPersistentProcesses(int sig) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();