Parse system_server java crashes better

Change-Id: I6e22091aa054677049598bf64769d2f445a6aae8
diff --git a/src/com/android/loganalysis/parser/LogcatParser.java b/src/com/android/loganalysis/parser/LogcatParser.java
index 9638402..4a709a0 100644
--- a/src/com/android/loganalysis/parser/LogcatParser.java
+++ b/src/com/android/loganalysis/parser/LogcatParser.java
@@ -69,6 +69,11 @@
                 "(\\w)/(.+?)\\(\\s*(\\d+)\\): (.*)$");  /* level, tag, pid, msg [2-5] */
 
     /**
+     * Match: "*** FATAL EXCEPTION IN SYSTEM PROCESS: message"
+     */
+    private static final Pattern SYSTEM_SERVER_CRASH = Pattern.compile(
+            "\\*\\*\\* FATAL EXCEPTION IN SYSTEM PROCESS:.*");
+    /**
      * Match "Process: com.android.package, PID: 123" or "PID: 123"
      */
     private static final Pattern JAVA_CRASH_PROCESS_PID = Pattern.compile(
@@ -283,6 +288,12 @@
                         data.mLines = data.mLines.subList(i + 1, data.mLines.size());
                         break;
                     }
+                    m = SYSTEM_SERVER_CRASH.matcher(line);
+                    if (m.matches()) {
+                        app = "system_server";
+                        data.mLines = data.mLines.subList(i + 1, data.mLines.size());
+                        break;
+                    }
                 }
                 item = new JavaCrashParser().parse(data.mLines);
                 if (item != null) {
diff --git a/tests/src/com/android/loganalysis/parser/LogcatParserTest.java b/tests/src/com/android/loganalysis/parser/LogcatParserTest.java
index 1da3044..f0932da 100644
--- a/tests/src/com/android/loganalysis/parser/LogcatParserTest.java
+++ b/tests/src/com/android/loganalysis/parser/LogcatParserTest.java
@@ -105,6 +105,32 @@
     }
 
     /**
+     * Test that Java crashes from system server can be parsed.
+     */
+    public void testParse_java_crash_system_server() throws ParseException {
+        List<String> lines = Arrays.asList(
+                "04-25 09:55:47.799  3064  3082 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: message",
+                "04-25 09:55:47.799  3064  3082 E AndroidRuntime: java.lang.Exception",
+                "04-25 09:55:47.799  3064  3082 E AndroidRuntime: \tat class.method1(Class.java:1)",
+                "04-25 09:55:47.799  3064  3082 E AndroidRuntime: \tat class.method2(Class.java:2)",
+                "04-25 09:55:47.799  3064  3082 E AndroidRuntime: \tat class.method3(Class.java:3)");
+
+        LogcatItem logcat = new LogcatParser("2012").parse(lines);
+        assertNotNull(logcat);
+        assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStartTime());
+        assertEquals(parseTime("2012-04-25 09:55:47.799"), logcat.getStopTime());
+        assertEquals(1, logcat.getEvents().size());
+        assertEquals(1, logcat.getJavaCrashes().size());
+        assertEquals("system_server", logcat.getJavaCrashes().get(0).getApp());
+        assertEquals(3064, logcat.getJavaCrashes().get(0).getPid().intValue());
+        assertEquals(3082, logcat.getJavaCrashes().get(0).getTid().intValue());
+        assertEquals("", logcat.getJavaCrashes().get(0).getLastPreamble());
+        assertEquals("", logcat.getJavaCrashes().get(0).getProcessPreamble());
+        assertEquals(parseTime("2012-04-25 09:55:47.799"),
+                logcat.getJavaCrashes().get(0).getEventTime());
+    }
+
+    /**
      * Test that Java crashes with process and pid can be parsed.
      */
     public void testParse_java_crash_process_pid() throws ParseException {