libcutils: android_reboot: save reboot reason in file

Save a string identifying the reason for last Android reboot or power
off in file /data/misc/recovery/last_reboot_reason .  This file may
be used for informing users of reboot or shutdown reasons at next
boot, and for other diagnostic purposes.

Bug: 30994946
Test: Manual: reboot, setprop sys.powerctl
Change-Id: I01e44473fdd21b33e9e4dced77aba9a66b6d3755
diff --git a/libcutils/android_reboot.c b/libcutils/android_reboot.c
index 6bdcc13..06026d1 100644
--- a/libcutils/android_reboot.c
+++ b/libcutils/android_reboot.c
@@ -189,11 +189,56 @@
     free_entries(&ro_entries);
 }
 
+static void save_reboot_reason(int cmd, const char *arg)
+{
+    FILE *fp;
+    const char *reason = NULL;
+
+    fp = fopen(LAST_REBOOT_REASON_FILE, "w");
+    if (fp == NULL) {
+        KLOG_WARNING(TAG, "Error creating " LAST_REBOOT_REASON_FILE
+                     ": %s\n", strerror(errno));
+        return;
+    }
+    switch (cmd) {
+        case ANDROID_RB_RESTART:
+            reason = "restart";
+            break;
+
+        case ANDROID_RB_POWEROFF:
+            reason = "power-off";
+            break;
+
+        case ANDROID_RB_RESTART2:
+            reason = arg && strlen(arg) ? arg : "restart";
+            break;
+
+        case ANDROID_RB_THERMOFF:
+            reason = "thermal-shutdown";
+            break;
+
+        default:
+            fprintf(fp,"0x%08X\n", cmd);
+            break;
+    }
+
+    if (reason) {
+        if (fprintf(fp, "%s\n", reason) < 0) {
+             KLOG_WARNING(TAG, "Error writing " LAST_REBOOT_REASON_FILE
+                          ": %s\n", strerror(errno));
+        }
+    }
+
+    fclose(fp);
+}
+
 int android_reboot_with_callback(
     int cmd, int flags __unused, const char *arg,
     void (*cb_on_remount)(const struct mntent*))
 {
     int ret;
+
+    save_reboot_reason(cmd, arg);
     remount_ro(cb_on_remount);
     switch (cmd) {
         case ANDROID_RB_RESTART:
diff --git a/libcutils/include/cutils/android_reboot.h b/libcutils/include/cutils/android_reboot.h
index 549f258..1bbb9b9 100644
--- a/libcutils/include/cutils/android_reboot.h
+++ b/libcutils/include/cutils/android_reboot.h
@@ -30,6 +30,9 @@
 /* Properties */
 #define ANDROID_RB_PROPERTY "sys.powerctl"
 
+/* Android reboot reason stored in this file */
+#define LAST_REBOOT_REASON_FILE "/data/misc/recovery/last_reboot_reason"
+
 int android_reboot(int cmd, int flags, const char *arg);
 int android_reboot_with_callback(
     int cmd, int flags, const char *arg,