Index: components/metrics/clean_exit_beacon.cc |
diff --git a/components/metrics/clean_exit_beacon.cc b/components/metrics/clean_exit_beacon.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..79ec8bc7467feb9805af3803f78584957f4c85b4 |
--- /dev/null |
+++ b/components/metrics/clean_exit_beacon.cc |
@@ -0,0 +1,90 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "components/metrics/clean_exit_beacon.h" |
+ |
+#include "base/logging.h" |
+#include "base/prefs/pref_registry_simple.h" |
+#include "base/prefs/pref_service.h" |
+ |
+#if defined(OS_WIN) |
+#include "base/metrics/histogram.h" |
+#include "base/strings/utf_string_conversions.h" |
+#include "base/win/registry.h" |
+#endif |
+ |
+namespace { |
+ |
+// True if the previous run of the program exited cleanly. |
+const char kStabilityExitedCleanly[] = |
+ "user_experience_metrics.stability.exited_cleanly"; |
Alexei Svitkine (slow)
2014/09/11 15:23:28
What's the reason for moving the pref? I think we
erikwright (departed)
2014/09/11 15:39:14
Exposing the name of a preference permits violatio
Alexei Svitkine (slow)
2014/09/11 15:57:28
I agree in principle, but at the same time we lose
erikwright (departed)
2014/09/11 19:00:29
Done. I didn't add a comment, as it's not really a
|
+ |
+} // namespace |
+ |
+#if defined(OS_WIN) |
Alexei Svitkine (slow)
2014/09/11 15:23:28
There's too many ifdefs for my preference.
How ab
erikwright (departed)
2014/09/11 15:39:14
It seems a bit strange to declare and implement (e
Alexei Svitkine (slow)
2014/09/11 15:57:28
My original thought would have been for the method
erikwright (departed)
2014/09/11 16:03:14
I think the location used for storage in the regis
Alexei Svitkine (slow)
2014/09/11 17:07:19
Okay, then let's go with the with my suggestion of
erikwright (departed)
2014/09/11 19:00:28
Done.
|
+CleanExitBeacon::CleanExitBeacon(const base::string16& backup_registry_key, |
+ PrefService* local_state) |
+ : backup_registry_key_(backup_registry_key), |
+ local_state_(local_state), |
+ initial_value_(local_state->GetBoolean(kStabilityExitedCleanly)) { |
+ DCHECK_NE(PrefService::INITIALIZATION_STATUS_WAITING, |
+ local_state_->GetInitializationStatus()); |
+ enum { |
+ DIRTY_DIRTY, |
+ DIRTY_CLEAN, |
+ CLEAN_DIRTY, |
+ CLEAN_CLEAN, |
+ MISSING_DIRTY, |
+ MISSING_CLEAN, |
+ NUM_CONSISTENCY_ENUMS |
+ } consistency = DIRTY_DIRTY; |
+ |
+ base::win::RegKey regkey; |
+ DWORD value = 0u; |
+ if (regkey.Open(HKEY_CURRENT_USER, |
+ backup_registry_key_.c_str(), |
+ KEY_ALL_ACCESS) == ERROR_SUCCESS && |
+ regkey.ReadValueDW(base::ASCIIToUTF16(kStabilityExitedCleanly).c_str(), |
+ &value) == ERROR_SUCCESS) { |
+ if (value) |
+ consistency = initial_value_ ? CLEAN_CLEAN : CLEAN_DIRTY; |
+ else |
+ consistency = initial_value_ ? DIRTY_CLEAN : DIRTY_DIRTY; |
+ } else { |
+ consistency = initial_value_ ? MISSING_CLEAN : MISSING_DIRTY; |
+ } |
+ |
+ UMA_HISTOGRAM_ENUMERATION( |
+ "UMA.CleanExitBeaconConsistency", consistency, NUM_CONSISTENCY_ENUMS); |
+} |
+#else |
+CleanExitBeacon::CleanExitBeacon(PrefService* local_state) |
+ : local_state_(local_state), |
+ initial_value_(local_state->GetBoolean(kStabilityExitedCleanly)) { |
+ DCHECK_NE(PrefService::INITIALIZATION_STATUS_WAITING, |
+ local_state_->GetInitializationStatus()); |
+} |
+#endif |
+ |
+CleanExitBeacon::~CleanExitBeacon() { |
+} |
+ |
+void CleanExitBeacon::RegisterPrefs(PrefRegistrySimple* registry) { |
+ registry->RegisterBooleanPref(kStabilityExitedCleanly, true); |
+} |
+ |
+void CleanExitBeacon::WriteBeaconValue(bool value) { |
+ local_state_->SetBoolean(kStabilityExitedCleanly, value); |
+ local_state_->CommitPendingWrite(); |
+ |
+#if defined(OS_WIN) |
+ base::win::RegKey regkey; |
+ if (regkey.Open(HKEY_CURRENT_USER, |
+ backup_registry_key_.c_str(), |
+ KEY_ALL_ACCESS) == ERROR_SUCCESS) { |
+ regkey.WriteValue(base::ASCIIToUTF16(kStabilityExitedCleanly).c_str(), |
+ value ? 1u : 0u); |
+ } |
+#endif |
+} |