| // 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(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(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(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(prefs::kStabilityExitedCleanly).c_str(), | 
 |         value ? 1u : 0u); | 
 |   } | 
 | #endif | 
 | } | 
 |  | 
 | }  // namespace metrics |