Fix some crashes that are happening in the system process.

- When shutting down, if the screen goes to sleep there is code
  that tries to do a notifyAll without holding the lock:

java.lang.IllegalMonitorStateException: object not locked by thread before notifyAll()
	at java.lang.Object.notifyAll(Native Method)
	at com.android.server.am.ActivityStack.checkReadyForSleepLocked(ActivityStack.java:776)
	at com.android.server.am.ActivityStack$1.handleMessage(ActivityStack.java:282)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:137)
	at com.android.server.ServerThread.run(SystemServer.java:603)

- If an invalid Uri object is sent to the system process it can crash because
  the Uri class throws an assertion while unmarshalling.  Change this to an
  IllegalArgumentException so it gets sent back to the caller:

java.lang.AssertionError
	at android.net.Uri$PathPart.readFrom(Uri.java:2224)
	at android.net.Uri$HierarchicalUri.readFrom(Uri.java:1106)
	at android.net.Uri$1.createFromParcel(Uri.java:1689)
	at android.net.Uri$1.createFromParcel(Uri.java:1681)
	at android.content.IContentService$Stub.onTransact(IContentService.java:53)
	at android.content.ContentService.onTransact(ContentService.java:120)
	at android.os.Binder.execTransact(Binder.java:338)
	at dalvik.system.NativeStart.run(Native Method)

- StrictMode can try to access the first index in the stack crawl of a stack crawl
  array of length 0.  Not sure why this happens, but make the code more robust:

java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
	at android.app.ApplicationErrorReport$CrashInfo.<init>(ApplicationErrorReport.java:341)
	at android.os.StrictMode$ViolationInfo.<init>(StrictMode.java:1978)
	at android.os.StrictMode$AndroidBlockGuardPolicy.startHandlingViolationException(StrictMode.java:1097)
	at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1068)
	at libcore.io.BlockGuardOs.read(BlockGuardOs.java:137)
	at libcore.io.IoBridge.read(IoBridge.java:426)
	at java.io.FileInputStream.read(FileInputStream.java:179)
	at java.io.InputStream.read(InputStream.java:148)
	at com.android.internal.os.ProcessStats.readFile(ProcessStats.java:804)
	at com.android.internal.os.ProcessStats.getCpuSpeedTimes(ProcessStats.java:564)
	at com.android.internal.os.ProcessStats.getLastCpuSpeedTimes(ProcessStats.java:545)
	at com.android.server.am.ActivityManagerService.updateCpuStatsNow(ActivityManagerService.java:1470)
	at com.android.server.am.ActivityManagerService.batteryNeedsCpuUpdate(ActivityManagerService.java:1522)
	at com.android.internal.os.BatteryStatsImpl$MyHandler.handleMessage(BatteryStatsImpl.java:110)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:137)
	at com.android.server.am.ActivityManagerService$AThread.run(ActivityManagerService.java:1302)

(Also fix this code to not cause strict mode to trigger at all, because there is
no need, because this is just reading stuff from /proc.)

- The system seems to crash during boot if it thinks it needs to rotate
  the screen, when it is trying to take the freeze snapshot way too early.
  There is no need to freeze the screen during boot or if the screen is off:

java.lang.NullPointerException
	at android.view.Surface.init(Native Method)
	at android.view.Surface.<init>(Surface.java:256)
	at com.android.server.wm.ScreenRotationAnimation.<init>(ScreenRotationAnimation.java:91)
	at com.android.server.wm.WindowManagerService.startFreezingDisplayLocked(WindowManagerService.java:8758)
	at com.android.server.wm.WindowManagerService.startAppFreezingScreenLocked(WindowManagerService.java:3971)
	at com.android.server.wm.WindowManagerService.startAppFreezingScreen(WindowManagerService.java:4003)
	at com.android.server.am.ActivityRecord.startFreezingScreenLocked(ActivityRecord.java:515)
	at com.android.server.am.ActivityStack.ensureActivityConfigurationLocked(ActivityStack.java:3997)
	at com.android.server.am.ActivityManagerService.updateConfigurationLocked(ActivityManagerService.java:12535)
	at com.android.server.am.ActivityManagerService.updateConfiguration(ActivityManagerService.java:12439)
	at com.android.server.wm.WindowManagerService.systemReady(WindowManagerService.java:6161)
	at com.android.server.ServerThread.run(SystemServer.java:521)

Change-Id: I85062bb5f6b0909a0f52feedaa75e7611d9d7fbd
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 6524c9a..588125d 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -332,20 +332,31 @@
             exceptionMessage = tr.getMessage();
 
             // Populate fields with the "root cause" exception
+            Throwable rootTr = tr;
             while (tr.getCause() != null) {
                 tr = tr.getCause();
+                if (tr.getStackTrace() != null && tr.getStackTrace().length > 0) {
+                    rootTr = tr;
+                }
                 String msg = tr.getMessage();
                 if (msg != null && msg.length() > 0) {
                     exceptionMessage = msg;
                 }
             }
 
-            exceptionClassName = tr.getClass().getName();
-            StackTraceElement trace = tr.getStackTrace()[0];
-            throwFileName = trace.getFileName();
-            throwClassName = trace.getClassName();
-            throwMethodName = trace.getMethodName();
-            throwLineNumber = trace.getLineNumber();
+            exceptionClassName = rootTr.getClass().getName();
+            if (rootTr.getStackTrace().length > 0) {
+                StackTraceElement trace = rootTr.getStackTrace()[0];
+                throwFileName = trace.getFileName();
+                throwClassName = trace.getClassName();
+                throwMethodName = trace.getMethodName();
+                throwLineNumber = trace.getLineNumber();
+            } else {
+                throwFileName = "unknown";
+                throwClassName = "unknown";
+                throwMethodName = "unknown";
+                throwLineNumber = 0;
+            }
         }
 
         /**
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 3b21590..2c875c8 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1689,7 +1689,7 @@
                     return HierarchicalUri.readFrom(in);
             }
 
-            throw new AssertionError("Unknown URI type: " + type);
+            throw new IllegalArgumentException("Unknown URI type: " + type);
         }
 
         public Uri[] newArray(int size) {
@@ -1996,7 +1996,7 @@
                 parcel.writeInt(Representation.DECODED);
                 parcel.writeString(decoded);
             } else {
-                throw new AssertionError();
+                throw new IllegalArgumentException("Neither encoded nor decoded");
             }
         }
     }
@@ -2037,7 +2037,8 @@
                 case Representation.DECODED:
                     return fromDecoded(parcel.readString());
                 default:
-                    throw new AssertionError();
+                    throw new IllegalArgumentException("Unknown representation: "
+                            + representation);
             }
         }
 
@@ -2221,7 +2222,7 @@
                 case Representation.DECODED:
                     return fromDecoded(parcel.readString());
                 default:
-                    throw new AssertionError();
+                    throw new IllegalArgumentException("Bad representation: " + representation);
             }
         }
 
diff --git a/core/java/com/android/internal/os/ProcessStats.java b/core/java/com/android/internal/os/ProcessStats.java
index ea5ce09..e0e9a29 100644
--- a/core/java/com/android/internal/os/ProcessStats.java
+++ b/core/java/com/android/internal/os/ProcessStats.java
@@ -19,6 +19,7 @@
 import static android.os.Process.*;
 
 import android.os.Process;
+import android.os.StrictMode;
 import android.os.SystemClock;
 import android.util.Slog;
 
@@ -798,6 +799,10 @@
     }
     
     private String readFile(String file, char endChar) {
+        // Permit disk reads here, as /proc/meminfo isn't really "on
+        // disk" and should be fast.  TODO: make BlockGuard ignore
+        // /proc/ and /sys/ files perhaps?
+        StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
         FileInputStream is = null;
         try {
             is = new FileInputStream(file);
@@ -822,6 +827,7 @@
                 } catch (java.io.IOException e) {
                 }
             }
+            StrictMode.setThreadPolicy(savedPolicy);
         }
         return null;
     }
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 33b21ab..ee0937d 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -276,10 +276,12 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case SLEEP_TIMEOUT_MSG: {
-                    if (mService.isSleeping()) {
-                        Slog.w(TAG, "Sleep timeout!  Sleeping now.");
-                        mSleepTimeout = true;
-                        checkReadyForSleepLocked();
+                    synchronized (mService) {
+                        if (mService.isSleeping()) {
+                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
+                            mSleepTimeout = true;
+                            checkReadyForSleepLocked();
+                        }
                     }
                 } break;
                 case PAUSE_TIMEOUT_MSG: {
@@ -775,7 +777,6 @@
         if (mService.mShuttingDown) {
             mService.notifyAll();
         }
-
     }
     
     public final Bitmap screenshotActivities(ActivityRecord who) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 5bc5f30..6c95e353 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -8736,6 +8736,12 @@
             return;
         }
 
+        if (mDisplay == null || !mPolicy.isScreenOn()) {
+            // No need to freeze the screen before the system is ready or if
+            // the screen is off.
+            return;
+        }
+
         mScreenFrozenLock.acquire();
 
         mDisplayFrozen = true;