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..595d05c084069b676a94fa9ee383429de3ad0a05 |
--- /dev/null |
+++ b/components/metrics/clean_exit_beacon.cc |
@@ -0,0 +1,80 @@ |
+// 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_service.h" |
+#include "components/metrics/metrics_pref_names.h" |
+ |
+#if defined(OS_WIN) |
+#include "base/metrics/histogram.h" |
+#include "base/strings/utf_string_conversions.h" |
+#include "base/win/registry.h" |
+#endif |
+ |
+namespace metrics { |
+ |
+CleanExitBeacon::CleanExitBeacon(const base::string16& backup_registry_key, |
+ PrefService* local_state) |
+ : local_state_(local_state), |
+ initial_value_( |
+ local_state->GetBoolean(metrics::prefs::kStabilityExitedCleanly)), |
+ backup_registry_key_(backup_registry_key) { |
+ DCHECK_NE(PrefService::INITIALIZATION_STATUS_WAITING, |
+ local_state_->GetInitializationStatus()); |
+ |
+#if defined(OS_WIN) |
+ // An enumeration of all possible permutations of the the beacon state in the |
+ // registry and in Local State. |
+ 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(metrics::prefs::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); |
+#endif |
+} |
+ |
+CleanExitBeacon::~CleanExitBeacon() { |
+} |
+ |
+void CleanExitBeacon::WriteBeaconValue(bool value) { |
+ local_state_->SetBoolean(metrics::prefs::kStabilityExitedCleanly, value); |
+ |
+#if defined(OS_WIN) |
+ base::win::RegKey regkey; |
+ if (regkey.Create(HKEY_CURRENT_USER, |
+ backup_registry_key_.c_str(), |
+ KEY_ALL_ACCESS) == ERROR_SUCCESS) { |
+ regkey.WriteValue( |
+ base::ASCIIToUTF16(metrics::prefs::kStabilityExitedCleanly).c_str(), |
+ value ? 1u : 0u); |
+ } |
+#endif |
+} |
+ |
+} // namespace metrics |