Log java crashes & native crashes in critical event log

Change-Id: I9efe1ff6c98dec47edbc95974d0959c343c7474f
Test: atest CriticalEventLogTest
Bug: 200263868
diff --git a/proto/src/criticalevents/critical_event_log.proto b/proto/src/criticalevents/critical_event_log.proto
index 0e03434..25814ec 100644
--- a/proto/src/criticalevents/critical_event_log.proto
+++ b/proto/src/criticalevents/critical_event_log.proto
@@ -57,6 +57,8 @@
     Watchdog watchdog = 2;
     HalfWatchdog half_watchdog = 3;
     AppNotResponding anr = 4;
+    JavaCrash java_crash = 5;
+    NativeCrash native_crash = 6;
   }
 
   message Watchdog {
@@ -99,6 +101,47 @@
     optional ProcessClass process_class = 5;
   }
 
+  message JavaCrash {
+    // The crash exception class.
+    // Optional, may be redacted for privacy.
+    optional string exception_class = 1;
+
+    // Name of the crashed process.
+    // Optional, may be redacted for privacy.
+    optional string process = 2;
+
+    // PID of the crashed process.
+    // Required.
+    optional int32 pid = 3;
+
+    // UID of the crashed process.
+    // Required.
+    optional int32 uid = 4;
+
+    // Category of the crashed process (DATA_APP, SYSTEM_APP, etc).
+    // Required.
+    optional ProcessClass process_class = 5;
+  }
+
+  message NativeCrash {
+    // Name of the crashed process.
+    // Optional, may be redacted for privacy.
+    optional string process = 1;
+
+    // PID of the crashed process.
+    // Required.
+    optional int32 pid = 2;
+
+    // UID of the crashed process.
+    // Required.
+    optional int32 uid = 3;
+
+    // Category of the crashed process (DATA_APP, SYSTEM_APP, etc).
+    // Required.
+    optional ProcessClass process_class = 4;
+  }
+
+
   // Mirrors definition & values in {@link android.server.ServerProtoEnums}.
   enum ProcessClass {
     PROCESS_CLASS_UNKNOWN = 0;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b1a1e0d..191feec 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8018,11 +8018,16 @@
                 crashInfo.throwFileName,
                 crashInfo.throwLineNumber);
 
+        int processClassEnum = processName.equals("system_server") ? ServerProtoEnums.SYSTEM_SERVER
+                : (r != null) ? r.getProcessClassEnum()
+                        : ServerProtoEnums.ERROR_SOURCE_UNKNOWN;
+        int uid = (r != null) ? r.uid : -1;
+        int pid = (r != null) ? r.getPid() : -1;
         FrameworkStatsLog.write(FrameworkStatsLog.APP_CRASH_OCCURRED,
-                (r != null) ? r.uid : -1,
+                uid,
                 eventType,
                 processName,
-                (r != null) ? r.getPid() : -1,
+                pid,
                 (r != null && r.info != null) ? r.info.packageName : "",
                 (r != null && r.info != null) ? (r.info.isInstantApp()
                         ? FrameworkStatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__TRUE
@@ -8032,9 +8037,7 @@
                         ? FrameworkStatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__FOREGROUND
                         : FrameworkStatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__BACKGROUND)
                         : FrameworkStatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN,
-                processName.equals("system_server") ? ServerProtoEnums.SYSTEM_SERVER
-                        : (r != null) ? r.getProcessClassEnum()
-                                      : ServerProtoEnums.ERROR_SOURCE_UNKNOWN,
+                processClassEnum,
                 incrementalMetrics != null /* isIncremental */, loadingProgress,
                 incrementalMetrics != null ? incrementalMetrics.getMillisSinceOldestPendingRead()
                         : -1,
@@ -8061,6 +8064,13 @@
                         : -1
         );
 
+        if (eventType.equals("native_crash")) {
+            CriticalEventLog.getInstance().logNativeCrash(processClassEnum, processName, uid, pid);
+        } else if (eventType.equals("crash")) {
+            CriticalEventLog.getInstance().logJavaCrash(crashInfo.exceptionClassName,
+                    processClassEnum, processName, uid, pid);
+        }
+
         final int relaunchReason = r == null ? RELAUNCH_REASON_NONE
                         : r.getWindowProcessController().computeRelaunchReason();
         final String relaunchReasonString = relaunchReasonToString(relaunchReason);
diff --git a/services/core/java/com/android/server/criticalevents/CriticalEventLog.java b/services/core/java/com/android/server/criticalevents/CriticalEventLog.java
index 30b3524..ab480e8 100644
--- a/services/core/java/com/android/server/criticalevents/CriticalEventLog.java
+++ b/services/core/java/com/android/server/criticalevents/CriticalEventLog.java
@@ -29,6 +29,8 @@
 import com.android.server.criticalevents.nano.CriticalEventProto;
 import com.android.server.criticalevents.nano.CriticalEventProto.AppNotResponding;
 import com.android.server.criticalevents.nano.CriticalEventProto.HalfWatchdog;
+import com.android.server.criticalevents.nano.CriticalEventProto.JavaCrash;
+import com.android.server.criticalevents.nano.CriticalEventProto.NativeCrash;
 import com.android.server.criticalevents.nano.CriticalEventProto.Watchdog;
 
 import java.io.File;
@@ -179,8 +181,56 @@
         log(event);
     }
 
+    /**
+     * Logs a java crash.
+     *
+     * @param exceptionClass   the crash exception class.
+     * @param processClassEnum {@link android.server.ServerProtoEnums} value for the crashed
+     *                         process.
+     * @param processName      name of the crashed process.
+     * @param uid              uid of the crashed process.
+     * @param pid              pid of the crashed process.
+     */
+    public void logJavaCrash(String exceptionClass, int processClassEnum, String processName,
+            int uid, int pid) {
+        JavaCrash crash = new JavaCrash();
+        crash.exceptionClass = exceptionClass;
+        crash.processClass = processClassEnum;
+        crash.process = processName;
+        crash.uid = uid;
+        crash.pid = pid;
+        CriticalEventProto event = new CriticalEventProto();
+        event.setJavaCrash(crash);
+        log(event);
+    }
+
+    /**
+     * Logs a native crash.
+     *
+     * @param processClassEnum {@link android.server.ServerProtoEnums} value for the crashed
+     *                         process.
+     * @param processName      name of the crashed process.
+     * @param uid              uid of the crashed process.
+     * @param pid              pid of the crashed process.
+     */
+    public void logNativeCrash(int processClassEnum, String processName, int uid, int pid) {
+        NativeCrash crash = new NativeCrash();
+        crash.processClass = processClassEnum;
+        crash.process = processName;
+        crash.uid = uid;
+        crash.pid = pid;
+        CriticalEventProto event = new CriticalEventProto();
+        event.setNativeCrash(crash);
+        log(event);
+    }
+
     private void log(CriticalEventProto event) {
         event.timestampMs = getWallTimeMillis();
+        appendAndSave(event);
+    }
+
+    @VisibleForTesting
+    void appendAndSave(CriticalEventProto event) {
         mEvents.append(event);
         saveLogToFile();
     }
@@ -420,7 +470,18 @@
                 if (shouldSanitize(anr.processClass, anr.process, anr.uid)) {
                     return sanitizeAnr(event);
                 }
+            } else if (event.hasJavaCrash()) {
+                JavaCrash crash = event.getJavaCrash();
+                if (shouldSanitize(crash.processClass, crash.process, crash.uid)) {
+                    return sanitizeJavaCrash(event);
+                }
+            } else if (event.hasNativeCrash()) {
+                NativeCrash crash = event.getNativeCrash();
+                if (shouldSanitize(crash.processClass, crash.process, crash.uid)) {
+                    return sanitizeNativeCrash(event);
+                }
             }
+            // No redaction needed.
             return event;
         }
 
@@ -428,21 +489,52 @@
             boolean sameApp = processName != null && processName.equals(mTraceProcessName)
                     && mTraceUid == uid;
 
-            // Only sanitize when both the ANR event and trace file are for different data apps.
+            // Only sanitize when both the critical event and trace file are for different data
+            // apps.
             return processClassEnum == CriticalEventProto.DATA_APP
                     && mTraceProcessClassEnum == CriticalEventProto.DATA_APP
                     && !sameApp;
         }
 
         private static CriticalEventProto sanitizeAnr(CriticalEventProto base) {
-            CriticalEventProto sanitized = new CriticalEventProto();
-            sanitized.timestampMs = base.timestampMs;
             AppNotResponding anr = new AppNotResponding();
-            sanitized.setAnr(anr);
             // Do not set subject and process.
             anr.processClass = base.getAnr().processClass;
             anr.uid = base.getAnr().uid;
             anr.pid = base.getAnr().pid;
+
+            CriticalEventProto sanitized = sanitizeCriticalEventProto(base);
+            sanitized.setAnr(anr);
+            return sanitized;
+        }
+
+        private static CriticalEventProto sanitizeJavaCrash(CriticalEventProto base) {
+            JavaCrash crash = new JavaCrash();
+            // Do not set exceptionClass and process.
+            crash.processClass = base.getJavaCrash().processClass;
+            crash.uid = base.getJavaCrash().uid;
+            crash.pid = base.getJavaCrash().pid;
+
+            CriticalEventProto sanitized = sanitizeCriticalEventProto(base);
+            sanitized.setJavaCrash(crash);
+            return sanitized;
+        }
+
+        private static CriticalEventProto sanitizeNativeCrash(CriticalEventProto base) {
+            NativeCrash crash = new NativeCrash();
+            // Do not set process.
+            crash.processClass = base.getNativeCrash().processClass;
+            crash.uid = base.getNativeCrash().uid;
+            crash.pid = base.getNativeCrash().pid;
+
+            CriticalEventProto sanitized = sanitizeCriticalEventProto(base);
+            sanitized.setNativeCrash(crash);
+            return sanitized;
+        }
+
+        private static CriticalEventProto sanitizeCriticalEventProto(CriticalEventProto base) {
+            CriticalEventProto sanitized = new CriticalEventProto();
+            sanitized.timestampMs = base.timestampMs;
             return sanitized;
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/criticalevents/CriticalEventLogTest.java b/services/tests/servicestests/src/com/android/server/criticalevents/CriticalEventLogTest.java
index 54e75aa..bf7c587 100644
--- a/services/tests/servicestests/src/com/android/server/criticalevents/CriticalEventLogTest.java
+++ b/services/tests/servicestests/src/com/android/server/criticalevents/CriticalEventLogTest.java
@@ -29,6 +29,8 @@
 import com.android.server.criticalevents.nano.CriticalEventProto;
 import com.android.server.criticalevents.nano.CriticalEventProto.AppNotResponding;
 import com.android.server.criticalevents.nano.CriticalEventProto.HalfWatchdog;
+import com.android.server.criticalevents.nano.CriticalEventProto.JavaCrash;
+import com.android.server.criticalevents.nano.CriticalEventProto.NativeCrash;
 import com.android.server.criticalevents.nano.CriticalEventProto.Watchdog;
 
 import org.junit.Before;
@@ -255,24 +257,39 @@
     }
 
     @Test
-    public void privacyRedaction_anr() {
+    public void logJavaCrash() {
         mCriticalEventLog.incTimeSeconds(1);
-        mCriticalEventLog.logAnr("Subject 1", ServerProtoEnums.SYSTEM_SERVER, "AID_SYSTEM",
-                SYSTEM_SERVER_UID, 0);
-        mCriticalEventLog.incTimeSeconds(1);
-        mCriticalEventLog.logAnr("Subject 2", ServerProtoEnums.SYSTEM_APP, "AID_RADIO",
-                SYSTEM_APP_UID, 1);
-        mCriticalEventLog.incTimeSeconds(1);
-        mCriticalEventLog.logAnr("Subject 3", ServerProtoEnums.DATA_APP, "com.foo",
-                DATA_APP_UID, 2);
-        mCriticalEventLog.incTimeSeconds(1);
-        mCriticalEventLog.logAnr("Subject 4", ServerProtoEnums.DATA_APP, "com.foo",
-                DATA_APP_UID_2, 3);
-        mCriticalEventLog.incTimeSeconds(1);
-        mCriticalEventLog.logAnr("Subject 5", ServerProtoEnums.DATA_APP, "com.bar",
-                DATA_APP_UID_3, 4);
+        mCriticalEventLog.logJavaCrash("com.android.MyClass", ServerProtoEnums.SYSTEM_APP,
+                "AID_RADIO", SYSTEM_APP_UID, 1);
         mCriticalEventLog.incTimeSeconds(1);
 
+        CriticalEventLogProto logProto = getLogOutput();
+
+        assertThat(logProto.timestampMs).isEqualTo(START_TIME_MS + 2000);
+        assertProtoArrayEquals(logProto.events, new CriticalEventProto[]{
+                javaCrash(START_TIME_MS + 1000, "com.android.MyClass", ServerProtoEnums.SYSTEM_APP,
+                        "AID_RADIO", SYSTEM_APP_UID, 1)
+        });
+    }
+
+    @Test
+    public void logNativeCrash() {
+        mCriticalEventLog.incTimeSeconds(1);
+        mCriticalEventLog.logNativeCrash(ServerProtoEnums.SYSTEM_APP, "AID_RADIO", SYSTEM_APP_UID,
+                1);
+        mCriticalEventLog.incTimeSeconds(1);
+
+        CriticalEventLogProto logProto = getLogOutput();
+
+        assertThat(logProto.timestampMs).isEqualTo(START_TIME_MS + 2000);
+        assertProtoArrayEquals(logProto.events, new CriticalEventProto[]{
+                nativeCrash(START_TIME_MS + 1000, ServerProtoEnums.SYSTEM_APP, "AID_RADIO",
+                        SYSTEM_APP_UID, 1)
+        });
+    }
+
+    @Test
+    public void privacyRedaction_anr() {
         CriticalEventProto systemServerAnr = anr(START_TIME_MS + 1000, "Subject 1",
                 CriticalEventProto.SYSTEM_SERVER, "AID_SYSTEM", SYSTEM_SERVER_UID, 0);
         CriticalEventProto systemAppAnr = anr(START_TIME_MS + 2000, "Subject 2",
@@ -289,6 +306,8 @@
         CriticalEventProto barAppAnrRedacted = anr(START_TIME_MS + 5000, "",
                 CriticalEventProto.DATA_APP, "", DATA_APP_UID_3, 4);
 
+        addToLog(systemServerAnr, systemAppAnr, fooAppAnr, fooAppAnrUid2, barAppAnr);
+
         assertProtoArrayEquals(
                 getLogOutput(ServerProtoEnums.DATA_APP, "com.foo", DATA_APP_UID).events,
                 new CriticalEventProto[]{
@@ -325,9 +344,123 @@
     }
 
     @Test
-    public void privacyRedaction_anr_doesNotMutateLogState() {
-        mCriticalEventLog.logAnr("Subject", ServerProtoEnums.DATA_APP, "com.foo",
+    public void privacyRedaction_javaCrash() {
+        CriticalEventProto systemServerCrash = javaCrash(START_TIME_MS + 1000, "Exception class 1",
+                CriticalEventProto.SYSTEM_SERVER, "AID_SYSTEM",
+                SYSTEM_SERVER_UID, 0);
+        CriticalEventProto systemAppCrash = javaCrash(START_TIME_MS + 2000, "Exception class 2",
+                CriticalEventProto.SYSTEM_APP, "AID_RADIO", SYSTEM_APP_UID, 1);
+        CriticalEventProto fooAppCrash = javaCrash(START_TIME_MS + 3000, "Exception class 3",
+                CriticalEventProto.DATA_APP, "com.foo", DATA_APP_UID, 2);
+        CriticalEventProto fooAppCrashUid2 = javaCrash(START_TIME_MS + 4000, "Exception class 4",
+                CriticalEventProto.DATA_APP, "com.foo", DATA_APP_UID_2, 3);
+        CriticalEventProto fooAppCrashUid2Redacted = javaCrash(START_TIME_MS + 4000, "",
+                CriticalEventProto.DATA_APP, "", DATA_APP_UID_2, 3);
+        CriticalEventProto barAppCrash = javaCrash(START_TIME_MS + 5000, "Exception class 5",
+                CriticalEventProto.DATA_APP, "com.bar", DATA_APP_UID_3, 4);
+        CriticalEventProto barAppCrashRedacted = javaCrash(START_TIME_MS + 5000, "",
+                CriticalEventProto.DATA_APP, "", DATA_APP_UID_3, 4);
+
+        addToLog(systemServerCrash, systemAppCrash, fooAppCrash, fooAppCrashUid2, barAppCrash);
+
+        assertProtoArrayEquals(
+                getLogOutput(ServerProtoEnums.DATA_APP, "com.foo", DATA_APP_UID).events,
+                new CriticalEventProto[]{
+                        systemServerCrash,
+                        systemAppCrash,
+                        fooAppCrash,
+                        // Redacted since the trace file and crash are for different uids.
+                        fooAppCrashUid2Redacted,
+                        // Redacted since the trace file and crash are for different data apps.
+                        barAppCrashRedacted
+                });
+
+        assertProtoArrayEquals(
+                getLogOutput(ServerProtoEnums.SYSTEM_SERVER, "AID_SYSTEM",
+                        SYSTEM_SERVER_UID).events,
+                new CriticalEventProto[]{
+                        systemServerCrash,
+                        systemAppCrash,
+                        fooAppCrash,
+                        fooAppCrashUid2,
+                        barAppCrash
+                });
+
+        assertProtoArrayEquals(
+                getLogOutput(ServerProtoEnums.SYSTEM_APP, "AID_RADIO",
+                        SYSTEM_APP_UID).events,
+                new CriticalEventProto[]{
+                        systemServerCrash,
+                        systemAppCrash,
+                        fooAppCrash,
+                        fooAppCrashUid2,
+                        barAppCrash
+                });
+    }
+
+    @Test
+    public void privacyRedaction_nativeCrash() {
+        CriticalEventProto systemServerCrash = nativeCrash(START_TIME_MS + 1000,
+                CriticalEventProto.SYSTEM_SERVER, "AID_SYSTEM",
+                SYSTEM_SERVER_UID, 0);
+        CriticalEventProto systemAppCrash = nativeCrash(START_TIME_MS + 2000,
+                CriticalEventProto.SYSTEM_APP, "AID_RADIO", SYSTEM_APP_UID, 1);
+        CriticalEventProto fooAppCrash = nativeCrash(START_TIME_MS + 3000,
+                CriticalEventProto.DATA_APP, "com.foo", DATA_APP_UID, 2);
+        CriticalEventProto fooAppCrashUid2 = nativeCrash(START_TIME_MS + 4000,
+                CriticalEventProto.DATA_APP, "com.foo", DATA_APP_UID_2, 3);
+        CriticalEventProto fooAppCrashUid2Redacted = nativeCrash(START_TIME_MS + 4000,
+                CriticalEventProto.DATA_APP, "", DATA_APP_UID_2, 3);
+        CriticalEventProto barAppCrash = nativeCrash(START_TIME_MS + 5000,
+                CriticalEventProto.DATA_APP, "com.bar", DATA_APP_UID_3, 4);
+        CriticalEventProto barAppCrashRedacted = nativeCrash(START_TIME_MS + 5000,
+                CriticalEventProto.DATA_APP, "", DATA_APP_UID_3, 4);
+
+        addToLog(systemServerCrash, systemAppCrash, fooAppCrash, fooAppCrashUid2, barAppCrash);
+
+        assertProtoArrayEquals(
+                getLogOutput(ServerProtoEnums.DATA_APP, "com.foo", DATA_APP_UID).events,
+                new CriticalEventProto[]{
+                        systemServerCrash,
+                        systemAppCrash,
+                        fooAppCrash,
+                        // Redacted since the trace file and crash are for different uids.
+                        fooAppCrashUid2Redacted,
+                        // Redacted since the trace file and crash are for different data apps.
+                        barAppCrashRedacted
+                });
+
+        assertProtoArrayEquals(
+                getLogOutput(ServerProtoEnums.SYSTEM_SERVER, "AID_SYSTEM",
+                        SYSTEM_SERVER_UID).events,
+                new CriticalEventProto[]{
+                        systemServerCrash,
+                        systemAppCrash,
+                        fooAppCrash,
+                        fooAppCrashUid2,
+                        barAppCrash
+                });
+
+        assertProtoArrayEquals(
+                getLogOutput(ServerProtoEnums.SYSTEM_APP, "AID_RADIO",
+                        SYSTEM_APP_UID).events,
+                new CriticalEventProto[]{
+                        systemServerCrash,
+                        systemAppCrash,
+                        fooAppCrash,
+                        fooAppCrashUid2,
+                        barAppCrash
+                });
+    }
+
+    @Test
+    public void privacyRedaction_doesNotMutateLogState() {
+        mCriticalEventLog.logAnr("ANR Subject", ServerProtoEnums.DATA_APP, "com.foo",
                 10_001, DATA_APP_UID);
+        mCriticalEventLog.logJavaCrash("com.foo.MyClass", ServerProtoEnums.DATA_APP, "com.foo",
+                10_001, DATA_APP_UID);
+        mCriticalEventLog.logNativeCrash(ServerProtoEnums.DATA_APP, "com.foo", 10_001,
+                DATA_APP_UID);
 
         CriticalEventLogProto unredactedLogBefore = getLogOutput(ServerProtoEnums.SYSTEM_SERVER,
                 "AID_SYSTEM", SYSTEM_SERVER_UID);
@@ -488,6 +621,12 @@
                 ServerProtoEnums.SYSTEM_SERVER);
     }
 
+    private void addToLog(CriticalEventProto... events) {
+        for (CriticalEventProto event : events) {
+            mCriticalEventLog.appendAndSave(event);
+        }
+    }
+
     private CriticalEventLogProto getLogOutput() {
         return getLogOutput(mCriticalEventLog);
     }
@@ -533,9 +672,29 @@
         }
     }
 
+    private static CriticalEventProto watchdog(long timestampMs, String subject) {
+        return watchdog(timestampMs, subject, "A UUID");
+    }
+
+    private static CriticalEventProto watchdog(long timestampMs, String subject, String uuid) {
+        CriticalEventProto event = new CriticalEventProto();
+        event.timestampMs = timestampMs;
+        event.setWatchdog(new Watchdog());
+        event.getWatchdog().subject = subject;
+        event.getWatchdog().uuid = uuid;
+        return event;
+    }
+
+    private static CriticalEventProto halfWatchdog(long timestampMs, String subject) {
+        CriticalEventProto event = new CriticalEventProto();
+        event.timestampMs = timestampMs;
+        event.setHalfWatchdog(new HalfWatchdog());
+        event.getHalfWatchdog().subject = subject;
+        return event;
+    }
+
     private static CriticalEventProto anr(long timestampMs, String subject, int processClass,
-            String processName,
-            int uid, int pid) {
+            String processName, int uid, int pid) {
         CriticalEventProto event = new CriticalEventProto();
         event.timestampMs = timestampMs;
         event.setAnr(new AppNotResponding());
@@ -547,24 +706,28 @@
         return event;
     }
 
-    private CriticalEventProto watchdog(long timestampMs, String subject) {
-        return watchdog(timestampMs, subject, "A UUID");
-    }
-
-    private CriticalEventProto watchdog(long timestampMs, String subject, String uuid) {
+    private static CriticalEventProto javaCrash(long timestampMs, String exceptionClass,
+            int processClass, String processName, int uid, int pid) {
         CriticalEventProto event = new CriticalEventProto();
         event.timestampMs = timestampMs;
-        event.setWatchdog(new Watchdog());
-        event.getWatchdog().subject = subject;
-        event.getWatchdog().uuid = uuid;
+        event.setJavaCrash(new JavaCrash());
+        event.getJavaCrash().exceptionClass = exceptionClass;
+        event.getJavaCrash().processClass = processClass;
+        event.getJavaCrash().process = processName;
+        event.getJavaCrash().uid = uid;
+        event.getJavaCrash().pid = pid;
         return event;
     }
 
-    private CriticalEventProto halfWatchdog(long timestampMs, String subject) {
+    private static CriticalEventProto nativeCrash(long timestampMs, int processClass,
+            String processName, int uid, int pid) {
         CriticalEventProto event = new CriticalEventProto();
         event.timestampMs = timestampMs;
-        event.setHalfWatchdog(new HalfWatchdog());
-        event.getHalfWatchdog().subject = subject;
+        event.setNativeCrash(new NativeCrash());
+        event.getNativeCrash().processClass = processClass;
+        event.getNativeCrash().process = processName;
+        event.getNativeCrash().uid = uid;
+        event.getNativeCrash().pid = pid;
         return event;
     }