Merge "fastboot: fix TCP protocol version check."
diff --git a/bootstat/boot_event_record_store.cpp b/bootstat/boot_event_record_store.cpp
index 22a67bb..8282b40 100644
--- a/bootstat/boot_event_record_store.cpp
+++ b/bootstat/boot_event_record_store.cpp
@@ -50,7 +50,7 @@
SetStorePath(BOOTSTAT_DATA_DIR);
}
-void BootEventRecordStore::AddBootEvent(const std::string& name) {
+void BootEventRecordStore::AddBootEvent(const std::string& event) {
std::string uptime_str;
if (!android::base::ReadFileToString("/proc/uptime", &uptime_str)) {
LOG(ERROR) << "Failed to read /proc/uptime";
@@ -58,15 +58,15 @@
// Cast intentionally rounds down.
int32_t uptime = static_cast<int32_t>(strtod(uptime_str.c_str(), NULL));
- AddBootEventWithValue(name, uptime);
+ AddBootEventWithValue(event, uptime);
}
// The implementation of AddBootEventValue makes use of the mtime file
// attribute to store the value associated with a boot event in order to
// optimize on-disk size requirements and small-file thrashing.
void BootEventRecordStore::AddBootEventWithValue(
- const std::string& name, int32_t value) {
- std::string record_path = GetBootEventPath(name);
+ const std::string& event, int32_t value) {
+ std::string record_path = GetBootEventPath(event);
if (creat(record_path.c_str(), S_IRUSR | S_IWUSR) == -1) {
PLOG(ERROR) << "Failed to create " << record_path;
}
@@ -86,6 +86,22 @@
}
}
+bool BootEventRecordStore::GetBootEvent(
+ const std::string& event, BootEventRecord* record) const {
+ CHECK_NE(static_cast<BootEventRecord*>(nullptr), record);
+ CHECK(!event.empty());
+
+ const std::string record_path = GetBootEventPath(event);
+ int32_t uptime;
+ if (!ParseRecordEventTime(record_path, &uptime)) {
+ LOG(ERROR) << "Failed to parse boot time record: " << record_path;
+ return false;
+ }
+
+ *record = std::make_pair(event, uptime);
+ return true;
+}
+
std::vector<BootEventRecordStore::BootEventRecord> BootEventRecordStore::
GetAllBootEvents() const {
std::vector<BootEventRecord> events;
@@ -104,14 +120,13 @@
}
const std::string event = entry->d_name;
- const std::string record_path = GetBootEventPath(event);
- int32_t uptime;
- if (!ParseRecordEventTime(record_path, &uptime)) {
- LOG(ERROR) << "Failed to parse boot time record: " << record_path;
+ BootEventRecord record;
+ if (!GetBootEvent(event, &record)) {
+ LOG(ERROR) << "Failed to parse boot time event: " << event;
continue;
}
- events.push_back(std::make_pair(event, uptime));
+ events.push_back(record);
}
return events;
diff --git a/bootstat/boot_event_record_store.h b/bootstat/boot_event_record_store.h
index d1b7835..4d5deee 100644
--- a/bootstat/boot_event_record_store.h
+++ b/bootstat/boot_event_record_store.h
@@ -34,12 +34,16 @@
BootEventRecordStore();
- // Persists the boot event named |name| in the record store.
- void AddBootEvent(const std::string& name);
+ // Persists the boot |event| in the record store.
+ void AddBootEvent(const std::string& event);
- // Persists the boot event named |name| with the associated |value| in the
- // record store.
- void AddBootEventWithValue(const std::string& name, int32_t value);
+ // Persists the boot |event| with the associated |value| in the record store.
+ void AddBootEventWithValue(const std::string& event, int32_t value);
+
+ // Queries the named boot |event|. |record| must be non-null. |record|
+ // contains the boot event data on success. Returns true iff the query is
+ // successful.
+ bool GetBootEvent(const std::string& event, BootEventRecord* record) const;
// Returns a list of all of the boot events persisted in the record store.
std::vector<BootEventRecord> GetAllBootEvents() const;
@@ -50,6 +54,7 @@
FRIEND_TEST(BootEventRecordStoreTest, AddSingleBootEvent);
FRIEND_TEST(BootEventRecordStoreTest, AddMultipleBootEvents);
FRIEND_TEST(BootEventRecordStoreTest, AddBootEventWithValue);
+ FRIEND_TEST(BootEventRecordStoreTest, GetBootEvent);
// Sets the filesystem path of the record store.
void SetStorePath(const std::string& path);
diff --git a/bootstat/boot_event_record_store_test.cpp b/bootstat/boot_event_record_store_test.cpp
index 3e6d706..0d7bbb0 100644
--- a/bootstat/boot_event_record_store_test.cpp
+++ b/bootstat/boot_event_record_store_test.cpp
@@ -165,4 +165,27 @@
ASSERT_EQ(1U, events.size());
EXPECT_EQ("permian", events[0].first);
EXPECT_EQ(42, events[0].second);
+}
+
+TEST_F(BootEventRecordStoreTest, GetBootEvent) {
+ BootEventRecordStore store;
+ store.SetStorePath(GetStorePathForTesting());
+
+ // Event does not exist.
+ BootEventRecordStore::BootEventRecord record;
+ bool result = store.GetBootEvent("nonexistent", &record);
+ EXPECT_EQ(false, result);
+
+ // Empty path.
+ EXPECT_DEATH(store.GetBootEvent(std::string(), &record), std::string());
+
+ // Success case.
+ store.AddBootEventWithValue("carboniferous", 314);
+ result = store.GetBootEvent("carboniferous", &record);
+ EXPECT_EQ(true, result);
+ EXPECT_EQ("carboniferous", record.first);
+ EXPECT_EQ(314, record.second);
+
+ // Null |record|.
+ EXPECT_DEATH(store.GetBootEvent("carboniferous", nullptr), std::string());
}
\ No newline at end of file
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 1d16f69..0c49f82 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <cstddef>
#include <cstdio>
+#include <ctime>
#include <map>
#include <memory>
#include <string>
@@ -155,6 +156,32 @@
boot_event_store.AddBootEventWithValue("boot_reason", boot_reason);
}
+// Records two metrics related to the user resetting a device: the time at
+// which the device is reset, and the time since the user last reset the
+// device. The former is only set once per-factory reset.
+void RecordFactoryReset() {
+ BootEventRecordStore boot_event_store;
+ BootEventRecordStore::BootEventRecord record;
+
+ time_t current_time_utc = time(nullptr);
+
+ // The factory_reset boot event does not exist after the device is reset, so
+ // use this signal to mark the time of the factory reset.
+ if (!boot_event_store.GetBootEvent("factory_reset", &record)) {
+ boot_event_store.AddBootEventWithValue("factory_reset", current_time_utc);
+ boot_event_store.AddBootEventWithValue("time_since_factory_reset", 0);
+ return;
+ }
+
+ // Calculate and record the difference in time between now and the
+ // factory_reset time.
+ time_t factory_reset_utc = record.second;
+ time_t time_since_factory_reset = difftime(current_time_utc,
+ factory_reset_utc);
+ boot_event_store.AddBootEventWithValue("time_since_factory_reset",
+ time_since_factory_reset);
+}
+
} // namespace
int main(int argc, char **argv) {
@@ -165,12 +192,14 @@
int option_index = 0;
static const char boot_reason_str[] = "record_boot_reason";
+ static const char factory_reset_str[] = "record_factory_reset";
static const struct option long_options[] = {
{ "help", no_argument, NULL, 'h' },
{ "log", no_argument, NULL, 'l' },
{ "print", no_argument, NULL, 'p' },
{ "record", required_argument, NULL, 'r' },
{ boot_reason_str, no_argument, NULL, 0 },
+ { factory_reset_str, no_argument, NULL, 0 },
{ NULL, 0, NULL, 0 }
};
@@ -182,6 +211,8 @@
const std::string option_name = long_options[option_index].name;
if (option_name == boot_reason_str) {
RecordBootReason();
+ } else if (option_name == factory_reset_str) {
+ RecordFactoryReset();
} else {
LOG(ERROR) << "Invalid option: " << option_name;
}