Add DeathReason::CRASH and ERROR.

crosvm now distinguishes crashes from reboots. ERROR is for a crosvm
error, usually meaning it failed to start the VM in the first place.

Also reorder reasons into a more logical order for future expansion.

Bug: 211704107
Test: atest VirtualizationTestCases
Test: Manually ran some VMs
Change-Id: I1903f05eb3783bdd9c5f09bcbdea473d69fbef42
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
index df3ad37..a49c9be 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
@@ -60,11 +60,13 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
         DEATH_REASON_VIRTUALIZATIONSERVICE_DIED,
-        DEATH_REASON_SHUTDOWN,
-        DEATH_REASON_REBOOT,
+        DEATH_REASON_INFRASTRUCTURE_ERROR,
         DEATH_REASON_KILLED,
         DEATH_REASON_UNKNOWN,
-        DEATH_REASON_INFRASTRUCTURE_ERROR
+        DEATH_REASON_SHUTDOWN,
+        DEATH_REASON_ERROR,
+        DEATH_REASON_REBOOT,
+        DEATH_REASON_CRASH
     })
     @interface DeathReason {}
 
@@ -74,20 +76,26 @@
      */
     int DEATH_REASON_VIRTUALIZATIONSERVICE_DIED = -1;
 
-    /** The VM requested to shut down. */
-    int DEATH_REASON_SHUTDOWN = 0;
-
-    /** The VM requested to reboot, possibly as the result of a kernel panic. */
-    int DEATH_REASON_REBOOT = 1;
+    /** There was an error waiting for the VM. */
+    int DEATH_REASON_INFRASTRUCTURE_ERROR = 0;
 
     /** The VM was killed. */
-    int DEATH_REASON_KILLED = 2;
+    int DEATH_REASON_KILLED = 1;
 
     /** The VM died for an unknown reason. */
-    int DEATH_REASON_UNKNOWN = 3;
+    int DEATH_REASON_UNKNOWN = 2;
 
-    /** There was an error waiting for the VM. */
-    int DEATH_REASON_INFRASTRUCTURE_ERROR = 4;
+    /** The VM requested to shut down. */
+    int DEATH_REASON_SHUTDOWN = 3;
+
+    /** crosvm had an error starting the VM. */
+    int DEATH_REASON_ERROR = 4;
+
+    /** The VM requested to reboot, possibly as the result of a kernel panic. */
+    int DEATH_REASON_REBOOT = 5;
+
+    /** The VM or crosvm crashed. */
+    int DEATH_REASON_CRASH = 6;
 
     /** Called when the payload starts in the VM. */
     void onPayloadStarted(@NonNull VirtualMachine vm, @Nullable ParcelFileDescriptor stream);
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
index 2f454a9..d736f1b 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/DeathReason.aidl
@@ -20,14 +20,18 @@
  */
 @Backing(type="int")
 enum DeathReason {
-    /** The VM requested to shut down. */
-    SHUTDOWN = 0,
-    /** The VM requested to reboot, possibly as the result of a kernel panic. */
-    REBOOT = 1,
-    /** The VM was killed. */
-    KILLED = 2,
-    /** The VM died for an unknown reason. */
-    UNKNOWN = 3,
     /** There was an error waiting for the VM. */
-    INFRASTRUCTURE_ERROR = 4,
+    INFRASTRUCTURE_ERROR = 0,
+    /** The VM was killed. */
+    KILLED = 1,
+    /** The VM died for an unknown reason. */
+    UNKNOWN = 2,
+    /** The VM requested to shut down. */
+    SHUTDOWN = 3,
+    /** crosvm had an error starting the VM. */
+    ERROR = 4,
+    /** The VM requested to reboot, possibly as the result of a kernel panic. */
+    REBOOT = 5,
+    /** The VM or crosvm crashed. */
+    CRASH = 6,
 }
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
index 76f4f47..2c50fed 100644
--- a/virtualizationservice/src/crosvm.rs
+++ b/virtualizationservice/src/crosvm.rs
@@ -36,8 +36,12 @@
 
 const CROSVM_PATH: &str = "/apex/com.android.virt/bin/crosvm";
 
+/// The exit status which crosvm returns when it has an error starting a VM.
+const CROSVM_ERROR_STATUS: i32 = 1;
 /// The exit status which crosvm returns when a VM requests a reboot.
 const CROSVM_REBOOT_STATUS: i32 = 32;
+/// The exit status which crosvm returns when it crashes due to an error.
+const CROSVM_CRASH_STATUS: i32 = 33;
 
 /// Configuration for a VM to run with crosvm.
 #[derive(Debug)]
@@ -243,7 +247,9 @@
         match status.code() {
             None => DeathReason::KILLED,
             Some(0) => DeathReason::SHUTDOWN,
+            Some(CROSVM_ERROR_STATUS) => DeathReason::ERROR,
             Some(CROSVM_REBOOT_STATUS) => DeathReason::REBOOT,
+            Some(CROSVM_CRASH_STATUS) => DeathReason::CRASH,
             Some(_) => DeathReason::UNKNOWN,
         }
     } else {
diff --git a/vm/src/run.rs b/vm/src/run.rs
index d558add..6a0fc15 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -293,11 +293,13 @@
         self.dead.raise();
 
         match reason {
-            DeathReason::SHUTDOWN => println!("VM shutdown cleanly."),
-            DeathReason::REBOOT => println!("VM tried to reboot, possibly due to a kernel panic."),
+            DeathReason::INFRASTRUCTURE_ERROR => println!("Error waiting for VM to finish."),
             DeathReason::KILLED => println!("VM was killed."),
             DeathReason::UNKNOWN => println!("VM died for an unknown reason."),
-            DeathReason::INFRASTRUCTURE_ERROR => println!("Error waiting for VM to finish."),
+            DeathReason::SHUTDOWN => println!("VM shutdown cleanly."),
+            DeathReason::ERROR => println!("Error starting VM."),
+            DeathReason::REBOOT => println!("VM tried to reboot, possibly due to a kernel panic."),
+            DeathReason::CRASH => println!("VM crashed."),
             _ => println!("VM died for an unrecognised reason."),
         }
         Ok(())