Merge changes Ia1c401b8,I571fb7da,I47999569 am: c2cdaf1840 am: 511e05f893
am: e6c3367e4f

Change-Id: I8a49bdceb213064fa46b1094a27bfd7062ed5cda
diff --git a/bootstat/boot_reason_test.sh b/bootstat/boot_reason_test.sh
index af65135..e69db12 100755
--- a/bootstat/boot_reason_test.sh
+++ b/bootstat/boot_reason_test.sh
@@ -873,17 +873,30 @@
 - NB: should report reboot,its_just_so_hard
 - NB: expect log \"... I bootstat: Unknown boot reason: reboot,its_just_so_hard\"" ]
 test_Its_Just_So_Hard_reboot() {
-  duration_test
+  if isDebuggable; then       # see below
+    duration_test
+  else
+    duration_test `expr ${DURATION_DEFAULT} + ${DURATION_DEFAULT}`
+  fi
   adb shell 'reboot "Its Just So Hard"'
   wait_for_screen
   EXPECT_PROPERTY sys.boot.reason reboot,its_just_so_hard
   EXPECT_PROPERTY persist.sys.boot.reason "reboot,Its Just So Hard"
-  adb shell su root setprop persist.sys.boot.reason reboot,its_just_so_hard
-  if checkDebugBuild; then
-    flag=""
+  # Do not leave this test with an illegal value in persist.sys.boot.reason
+  save_ret=${?}           # hold on to error code from above two lines
+  if isDebuggable; then   # can do this easy, or we can do this hard.
+    adb shell su root setprop persist.sys.boot.reason reboot,its_just_so_hard
+    ( exit ${save_ret} )  # because one can not just do ?=${save_ret}
   else
-    flag="--allow_failure"
+    report_bootstat_logs reboot,its_just_so_hard  # report what we have so far
+    # user build mitigation
+    adb shell reboot its_just_so_hard
+    wait_for_screen
+    ( exit ${save_ret} )  # because one can not just do ?=${save_ret}
+    EXPECT_PROPERTY sys.boot.reason reboot,its_just_so_hard
   fi
+  # Ensure persist.sys.boot.reason now valid, failure here acts as a signal
+  # that we could choke up following tests.  For example test_properties.
   EXPECT_PROPERTY persist.sys.boot.reason reboot,its_just_so_hard ${flag}
   report_bootstat_logs reboot,its_just_so_hard
 }
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index c1d799e..07d410c 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -225,6 +225,8 @@
     {"reboot,longkey", 85},
     {"reboot,2sec", 86},
     {"shutdown,thermal,battery", 87},
+    {"reboot,its_just_so_hard", 88},  // produced by boot_reason_test
+    {"reboot,Its Just So Hard", 89},  // produced by boot_reason_test
 };
 
 // Converts a string value representing the reason the system booted to an
@@ -351,10 +353,18 @@
 char tounderline(char c) {
   return ::isblank(c) ? '_' : c;
 }
+
 char toprintable(char c) {
   return ::isprint(c) ? c : '?';
 }
 
+// Cleanup boot_reason regarding acceptable character set
+void transformReason(std::string& reason) {
+  std::transform(reason.begin(), reason.end(), reason.begin(), ::tolower);
+  std::transform(reason.begin(), reason.end(), reason.begin(), tounderline);
+  std::transform(reason.begin(), reason.end(), reason.begin(), toprintable);
+}
+
 const char system_reboot_reason_property[] = "sys.boot.reason";
 const char last_reboot_reason_property[] = LAST_REBOOT_REASON_PROPERTY;
 const char bootloader_reboot_reason_property[] = "ro.boot.bootreason";
@@ -368,10 +378,7 @@
   // If sys.boot.reason == ro.boot.bootreason, let's re-evaluate
   if (reason == ret) ret = "";
 
-  // Cleanup boot_reason regarding acceptable character set
-  std::transform(reason.begin(), reason.end(), reason.begin(), ::tolower);
-  std::transform(reason.begin(), reason.end(), reason.begin(), tounderline);
-  std::transform(reason.begin(), reason.end(), reason.begin(), toprintable);
+  transformReason(reason);
 
   // Is the current system boot reason sys.boot.reason valid?
   if (!isKnownRebootReason(ret)) ret = "";
@@ -460,18 +467,20 @@
         pos += strlen(cmd);
         std::string subReason(content.substr(pos, max_reason_length));
         for (pos = 0; pos < subReason.length(); ++pos) {
-          char c = tounderline(subReason[pos]);
+          char c = subReason[pos];
           if (!::isprint(c) || (c == '\'')) {
             subReason.erase(pos);
             break;
           }
-          subReason[pos] = ::tolower(c);
         }
+        transformReason(subReason);
         if (subReason != "") {  // Will not land "reboot" as that is too blunt.
           if (isKernelRebootReason(subReason)) {
             ret = "reboot," + subReason;  // User space can't talk kernel reasons.
-          } else {
+          } else if (isKnownRebootReason(subReason)) {
             ret = subReason;
+          } else {
+            ret = "reboot," + subReason;  // legitimize unknown reasons
           }
         }
       }
@@ -563,10 +572,7 @@
       // Content buffer no longer will have console data. Beware if more
       // checks added below, that depend on parsing console content.
       content = GetProperty(last_reboot_reason_property);
-      // Cleanup last_boot_reason regarding acceptable character set
-      std::transform(content.begin(), content.end(), content.begin(), ::tolower);
-      std::transform(content.begin(), content.end(), content.begin(), tounderline);
-      std::transform(content.begin(), content.end(), content.begin(), toprintable);
+      transformReason(content);
 
       // Anything in last is better than 'super-blunt' reboot or shutdown.
       if ((ret == "") || (ret == "reboot") || (ret == "shutdown") || !isBluntRebootReason(content)) {