Merge "init: Reworked how we wait for COLDBOOT_DONE" am: 57c31d0f17
am: 6be1d976f6

Change-Id: Ibcd178a0173e45ba32dbdd724436f0a4389df021
diff --git a/init/init.cpp b/init/init.cpp
index 734f129..3f5e731 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -163,14 +163,28 @@
     Timer t;
 
     LOG(VERBOSE) << "Waiting for " COLDBOOT_DONE "...";
+
+    // History:
     // Any longer than 1s is an unreasonable length of time to delay booting.
     // If you're hitting this timeout, check that you didn't make your
     // sepolicy regular expressions too expensive (http://b/19899875).
-    if (wait_for_file(COLDBOOT_DONE, 1s)) {
-        LOG(ERROR) << "Timed out waiting for " COLDBOOT_DONE;
+    // Update:
+    // It is bad to allow device to randomly fail to boot. So, we should
+    // instead log an error and abandon boot process if we have waited
+    // for a *considerably* long period of time. For attempts that do not
+    // exceed the treshold, we keep a record of how long it took for further
+    // optimization work.
+    // Also, a longer wait period before timeout gives slower builds like
+    // heavily instrumented debug builds (e.g. KASan) a chance to fully boot.
+    if (wait_for_file(COLDBOOT_DONE, 45s) < 0) {
+        LOG(ERROR) << "Timed out waiting for " COLDBOOT_DONE "; rebooting into recovery mode...";
+        android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
+        while (true) { pause(); }   // in case reboot is denied
     }
 
-    LOG(VERBOSE) << "Waiting for " COLDBOOT_DONE " took " << t.duration() << "s.";
+    double duration = t.duration();
+    property_set("ro.bootstats.cold_boot_duration", StringPrintf("%fs", duration).c_str());
+    LOG(VERBOSE) << "Waiting for " COLDBOOT_DONE " took " << duration << "s.";
     return 0;
 }