Index: chrome/browser/chromeos/boot_times_loader.cc |
diff --git a/chrome/browser/chromeos/boot_times_loader.cc b/chrome/browser/chromeos/boot_times_loader.cc |
index 94a675de5433dbcf712824ddd5fa02b548b1c978..aaa34ab62ab7716baf9a02569bd7f33b4192ab9b 100644 |
--- a/chrome/browser/chromeos/boot_times_loader.cc |
+++ b/chrome/browser/chromeos/boot_times_loader.cc |
@@ -15,6 +15,7 @@ |
#include "base/message_loop/message_loop.h" |
#include "base/message_loop/message_loop_proxy.h" |
#include "base/metrics/histogram.h" |
+#include "base/prefs/pref_service.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
@@ -29,6 +30,7 @@ |
#include "chrome/browser/ui/browser_iterator.h" |
#include "chrome/browser/ui/tabs/tab_strip_model.h" |
#include "chrome/common/chrome_switches.h" |
+#include "chrome/common/pref_names.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/navigation_controller.h" |
#include "content/public/browser/notification_service.h" |
@@ -265,12 +267,97 @@ void BootTimesLoader::WriteLogoutTimes() { |
logout_time_markers_); |
} |
+// static |
+void BootTimesLoader::ClearLogoutStartedLastPreference() { |
+ PrefService* local_state = g_browser_process->local_state(); |
+ local_state->ClearPref(prefs::kLogoutStartedLast); |
+} |
+ |
+void BootTimesLoader::OnBoot() { |
+ PrefService* local_state = g_browser_process->local_state(); |
+ const std::string logout_started_last_str = |
+ local_state->GetString(prefs::kLogoutStartedLast); |
+ if (logout_started_last_str.empty()) |
+ return; |
+ |
+ // Note that kLogoutStartedLast is not cleared on format error to stay in |
+ // logs in case of other fatal system errors. |
+ |
+ const Stats logout_started_last_stats = |
+ Stats::DeserializeFromString(logout_started_last_str); |
+ if (logout_started_last_stats.uptime.empty()) |
+ return; |
+ |
+ // Extract double uptime seconds. |
+ const std::string logout_started_last_uptime_str = |
+ GetUptimeSeconds(logout_started_last_stats); |
+ if (logout_started_last_uptime_str.empty()) |
+ return; |
+ |
+ const std::string uptime_str = GetUptimeSeconds(GetCurrentStats()); |
+ |
+ double logout_started_last; |
+ double uptime; |
+ if (!base::StringToDouble(logout_started_last_uptime_str, |
+ &logout_started_last) || |
+ !base::StringToDouble(uptime_str, &uptime)) { |
+ return; |
+ } |
+ |
+ if (logout_started_last >= uptime) { |
+ // Reboot happened. |
+ ClearLogoutStartedLastPreference(); |
+ return; |
+ } |
+ // Write /tmp/uptime-logout-started as well. |
+ const char kLogoutStarted[] = "logout-started"; |
+ RecordStatsWithCallback( |
+ kLogoutStarted, |
+ logout_started_last_stats, |
+ base::Bind(&BootTimesLoader::ClearLogoutStartedLastPreference)); |
+} |
+ |
+void BootTimesLoader::OnLogoutStarted(PrefService* state) { |
+ const std::string uptime = GetCurrentStats().SerializeToString(); |
+ if (!uptime.empty()) |
+ state->SetString(prefs::kLogoutStartedLast, uptime); |
+} |
+ |
void BootTimesLoader::RecordStats(const std::string& name, const Stats& stats) { |
BrowserThread::PostTask( |
BrowserThread::FILE, FROM_HERE, |
base::Bind(&RecordStatsDelayed, name, stats.uptime, stats.disk)); |
} |
+void BootTimesLoader::RecordStatsWithCallback(const std::string& name, |
+ const Stats& stats, |
+ const base::Closure& callback) { |
+ BrowserThread::PostBlockingPoolTaskAndReply( |
+ FROM_HERE, |
+ base::Bind(&RecordStatsDelayed, name, stats.uptime, stats.disk), |
+ callback); |
+} |
+ |
+std::string BootTimesLoader::Stats::SerializeToString() const { |
+ if (uptime.empty() || disk.empty()) |
+ return std::string(); |
+ |
+ return uptime + '^' + disk; |
Nikita (slow)
2014/05/30 07:07:03
nit: Please extract this divider as a constant.
Alexander Alekseev
2014/05/30 18:44:54
Done.
|
+} |
+ |
+// static |
+BootTimesLoader::Stats BootTimesLoader::Stats::DeserializeFromString( |
+ const std::string& value) { |
+ Stats result; |
+ |
+ const size_t divider_at = value.find_first_of('^'); |
+ if (divider_at != std::string::npos) { |
+ result.uptime = value.substr(0, divider_at); |
+ result.disk = value.substr(divider_at + 1); |
+ } |
+ return result; |
+} |
+ |
BootTimesLoader::Stats BootTimesLoader::GetCurrentStats() { |
const base::FilePath kProcUptime(FPL("/proc/uptime")); |
const base::FilePath kDiskStat(FPL("/sys/block/sda/stat")); |
@@ -281,6 +368,17 @@ BootTimesLoader::Stats BootTimesLoader::GetCurrentStats() { |
return stats; |
} |
+std::string BootTimesLoader::GetUptimeSeconds( |
+ const BootTimesLoader::Stats& stats) { |
+ std::string uptime = stats.uptime; |
+ const size_t space_at = uptime.find_first_of(' '); |
+ if (space_at == std::string::npos) |
+ return std::string(); |
+ |
+ uptime.resize(space_at); |
+ return uptime; |
+} |
+ |
void BootTimesLoader::RecordCurrentStats(const std::string& name) { |
RecordStats(name, GetCurrentStats()); |
} |