bootstat: Disambiguate boot time on encrypted devices.
This change introduces new metrics to discern boot time on encrypted devices:
* post_decrypt_time_elapsed
* boot_decryption_complete
* boot_complete_post_decrypt
* boot_complete_no_encryption
Bug: 27497357
Change-Id: I8d3a411029bd6a45f80589ff67c408593e133a87
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index c59a191..9214e6d 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -32,6 +32,7 @@
#include <log/log.h>
#include "boot_event_record_store.h"
#include "event_log_list_builder.h"
+#include "uptime_parser.h"
namespace {
@@ -174,6 +175,37 @@
return kUnknownBootReason;
}
+// Records several metrics related to the time it takes to boot the device,
+// including disambiguating boot time on encrypted or non-encrypted devices.
+void RecordBootComplete() {
+ BootEventRecordStore boot_event_store;
+ time_t uptime = bootstat::ParseUptime();
+
+ BootEventRecordStore::BootEventRecord record;
+
+ // post_decrypt_time_elapsed is only logged on encrypted devices.
+ if (boot_event_store.GetBootEvent("post_decrypt_time_elapsed", &record)) {
+ // Log the amount of time elapsed until the device is decrypted, which
+ // includes the variable amount of time the user takes to enter the
+ // decryption password.
+ boot_event_store.AddBootEventWithValue("boot_decryption_complete", uptime);
+
+ // Subtract the decryption time to normalize the boot cycle timing.
+ time_t boot_complete = uptime - record.second;
+ boot_event_store.AddBootEventWithValue("boot_complete_post_decrypt",
+ boot_complete);
+
+
+ } else {
+ boot_event_store.AddBootEventWithValue("boot_complete_no_encryption",
+ uptime);
+ }
+
+ // Record the total time from device startup to boot complete, regardless of
+ // encryption state.
+ boot_event_store.AddBootEventWithValue("boot_complete", uptime);
+}
+
// Records the boot_reason metric by querying the ro.boot.bootreason system
// property.
void RecordBootReason() {
@@ -229,6 +261,7 @@
LOG(INFO) << "Service started: " << cmd_line;
int option_index = 0;
+ static const char boot_complete_str[] = "record_boot_complete";
static const char boot_reason_str[] = "record_boot_reason";
static const char factory_reset_str[] = "record_time_since_factory_reset";
static const struct option long_options[] = {
@@ -236,6 +269,7 @@
{ "log", no_argument, NULL, 'l' },
{ "print", no_argument, NULL, 'p' },
{ "record", required_argument, NULL, 'r' },
+ { boot_complete_str, no_argument, NULL, 0 },
{ boot_reason_str, no_argument, NULL, 0 },
{ factory_reset_str, no_argument, NULL, 0 },
{ NULL, 0, NULL, 0 }
@@ -247,7 +281,9 @@
// This case handles long options which have no single-character mapping.
case 0: {
const std::string option_name = long_options[option_index].name;
- if (option_name == boot_reason_str) {
+ if (option_name == boot_complete_str) {
+ RecordBootComplete();
+ } else if (option_name == boot_reason_str) {
RecordBootReason();
} else if (option_name == factory_reset_str) {
RecordFactoryReset();