// 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 "chrome/browser/metrics/chrome_metrics_service_client.h"

#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/google/google_brand.h"
#include "chrome/browser/metrics/chrome_stability_metrics_provider.h"
#include "chrome/browser/metrics/drive_metrics_provider.h"
#include "chrome/browser/metrics/omnibox_metrics_provider.h"
#include "chrome/browser/ui/browser_otr_state.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/crash_keys.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/render_messages.h"
#include "components/metrics/call_stack_profile_metrics_provider.h"
#include "components/metrics/gpu/gpu_metrics_provider.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/net/net_metrics_log_uploader.h"
#include "components/metrics/net/network_metrics_provider.h"
#include "components/metrics/profiler/profiler_metrics_provider.h"
#include "components/metrics/profiler/tracking_synchronizer.h"
#include "components/metrics/url_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/histogram_fetcher.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"

#if defined(OS_ANDROID)
#include "chrome/browser/metrics/android_metrics_provider.h"
#endif

#if defined(ENABLE_PRINT_PREVIEW)
#include "chrome/browser/service_process/service_process_control.h"
#endif

#if defined(ENABLE_EXTENSIONS)
#include "chrome/browser/metrics/extensions_metrics_provider.h"
#endif

#if defined(ENABLE_PLUGINS)
#include "chrome/browser/metrics/plugin_metrics_provider.h"
#endif

#if defined(OS_CHROMEOS)
#include "chrome/browser/metrics/chromeos_metrics_provider.h"
#include "chrome/browser/metrics/signin_status_metrics_provider_chromeos.h"
#endif

#if defined(OS_WIN)
#include <windows.h>
#include "base/win/registry.h"
#include "chrome/browser/metrics/google_update_metrics_provider_win.h"
#include "components/browser_watcher/watcher_metrics_provider_win.h"
#endif

#if !defined(OS_CHROMEOS) && !defined(OS_IOS)
#include "chrome/browser/metrics/signin_status_metrics_provider.h"
#endif  // !defined(OS_CHROMEOS) && !defined(OS_IOS)

namespace {

// This specifies the amount of time to wait for all renderers to send their
// data.
const int kMaxHistogramGatheringWaitDuration = 60000;  // 60 seconds.

metrics::SystemProfileProto::Channel AsProtobufChannel(
    chrome::VersionInfo::Channel channel) {
  switch (channel) {
    case chrome::VersionInfo::CHANNEL_UNKNOWN:
      return metrics::SystemProfileProto::CHANNEL_UNKNOWN;
    case chrome::VersionInfo::CHANNEL_CANARY:
      return metrics::SystemProfileProto::CHANNEL_CANARY;
    case chrome::VersionInfo::CHANNEL_DEV:
      return metrics::SystemProfileProto::CHANNEL_DEV;
    case chrome::VersionInfo::CHANNEL_BETA:
      return metrics::SystemProfileProto::CHANNEL_BETA;
    case chrome::VersionInfo::CHANNEL_STABLE:
      return metrics::SystemProfileProto::CHANNEL_STABLE;
  }
  NOTREACHED();
  return metrics::SystemProfileProto::CHANNEL_UNKNOWN;
}

// Standard interval between log uploads, in seconds.
#if defined(OS_ANDROID) || defined(OS_IOS)
const int kStandardUploadIntervalSeconds = 5 * 60;  // Five minutes.
const int kStandardUploadIntervalCellularSeconds = 15 * 60;  // Fifteen minutes.
#else
const int kStandardUploadIntervalSeconds = 30 * 60;  // Thirty minutes.
#endif

#if defined(OS_ANDROID) || defined(OS_IOS)
// Returns true if the user is assigned to the experiment group for enabled
// cellular uploads.
bool IsCellularEnabledByExperiment() {
  const std::string group_name =
      base::FieldTrialList::FindFullName("UMA_EnableCellularLogUpload");
  return group_name == "Enabled";
}
#endif

}  // namespace

ChromeMetricsServiceClient::ChromeMetricsServiceClient(
    metrics::MetricsStateManager* state_manager)
    : metrics_state_manager_(state_manager),
      chromeos_metrics_provider_(nullptr),
      waiting_for_collect_final_metrics_step_(false),
      num_async_histogram_fetches_in_progress_(0),
      profiler_metrics_provider_(nullptr),
#if defined(ENABLE_PLUGINS)
      plugin_metrics_provider_(nullptr),
#endif
#if defined(OS_WIN)
      google_update_metrics_provider_(nullptr),
#endif
      drive_metrics_provider_(nullptr),
      weak_ptr_factory_(this) {
  DCHECK(thread_checker_.CalledOnValidThread());
  RecordCommandLineMetrics();
  RegisterForNotifications();

#if defined(OS_WIN)
  CountBrowserCrashDumpAttempts();
#endif  // defined(OS_WIN)
}

ChromeMetricsServiceClient::~ChromeMetricsServiceClient() {
  DCHECK(thread_checker_.CalledOnValidThread());
}

// static
scoped_ptr<ChromeMetricsServiceClient> ChromeMetricsServiceClient::Create(
    metrics::MetricsStateManager* state_manager,
    PrefService* local_state) {
  // Perform two-phase initialization so that |client->metrics_service_| only
  // receives pointers to fully constructed objects.
  scoped_ptr<ChromeMetricsServiceClient> client(
      new ChromeMetricsServiceClient(state_manager));
  client->Initialize();

  return client.Pass();
}

// static
void ChromeMetricsServiceClient::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0);
  registry->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0);

  metrics::MetricsService::RegisterPrefs(registry);
  ChromeStabilityMetricsProvider::RegisterPrefs(registry);

#if defined(OS_ANDROID)
  AndroidMetricsProvider::RegisterPrefs(registry);
#endif  // defined(OS_ANDROID)

#if defined(ENABLE_PLUGINS)
  PluginMetricsProvider::RegisterPrefs(registry);
#endif  // defined(ENABLE_PLUGINS)
}

void ChromeMetricsServiceClient::SetMetricsClientId(
    const std::string& client_id) {
  crash_keys::SetCrashClientIdFromGUID(client_id);
}

bool ChromeMetricsServiceClient::IsOffTheRecordSessionActive() {
  return chrome::IsOffTheRecordSessionActive();
}

int32 ChromeMetricsServiceClient::GetProduct() {
  return metrics::ChromeUserMetricsExtension::CHROME;
}

std::string ChromeMetricsServiceClient::GetApplicationLocale() {
  return g_browser_process->GetApplicationLocale();
}

bool ChromeMetricsServiceClient::GetBrand(std::string* brand_code) {
  return google_brand::GetBrand(brand_code);
}

metrics::SystemProfileProto::Channel ChromeMetricsServiceClient::GetChannel() {
  return AsProtobufChannel(chrome::VersionInfo::GetChannel());
}

std::string ChromeMetricsServiceClient::GetVersionString() {
  chrome::VersionInfo version_info;
  std::string version = version_info.Version();
#if defined(ARCH_CPU_64_BITS)
  version += "-64";
#endif  // defined(ARCH_CPU_64_BITS)
  if (!version_info.IsOfficialBuild())
    version.append("-devel");
  return version;
}

void ChromeMetricsServiceClient::OnLogUploadComplete() {
  // Collect network stats after each UMA upload.
  network_stats_uploader_.CollectAndReportNetworkStats();
}

void ChromeMetricsServiceClient::StartGatheringMetrics(
    const base::Closure& done_callback) {
  finished_gathering_initial_metrics_callback_ = done_callback;
  base::Closure got_hardware_class_callback =
      base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotHardwareClass,
                 weak_ptr_factory_.GetWeakPtr());
#if defined(OS_CHROMEOS)
  chromeos_metrics_provider_->InitTaskGetHardwareClass(
      got_hardware_class_callback);
#else
  got_hardware_class_callback.Run();
#endif  // defined(OS_CHROMEOS)
}

void ChromeMetricsServiceClient::CollectFinalMetrics(
    const base::Closure& done_callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  collect_final_metrics_done_callback_ = done_callback;

  // Begin the multi-step process of collecting memory usage histograms:
  // First spawn a task to collect the memory details; when that task is
  // finished, it will call OnMemoryDetailCollectionDone. That will in turn
  // call HistogramSynchronization to collect histograms from all renderers and
  // then call OnHistogramSynchronizationDone to continue processing.
  DCHECK(!waiting_for_collect_final_metrics_step_);
  waiting_for_collect_final_metrics_step_ = true;

  base::Closure callback =
      base::Bind(&ChromeMetricsServiceClient::OnMemoryDetailCollectionDone,
                 weak_ptr_factory_.GetWeakPtr());

  scoped_refptr<MetricsMemoryDetails> details(
      new MetricsMemoryDetails(callback, &memory_growth_tracker_));
  details->StartFetch(MemoryDetails::FROM_CHROME_ONLY);

  // Collect WebCore cache information to put into a histogram.
  for (content::RenderProcessHost::iterator i(
          content::RenderProcessHost::AllHostsIterator());
       !i.IsAtEnd(); i.Advance()) {
    i.GetCurrentValue()->Send(new ChromeViewMsg_GetCacheResourceStats());
  }
}

scoped_ptr<metrics::MetricsLogUploader>
ChromeMetricsServiceClient::CreateUploader(
    const base::Callback<void(int)>& on_upload_complete) {
  return scoped_ptr<metrics::MetricsLogUploader>(
      new metrics::NetMetricsLogUploader(
          g_browser_process->system_request_context(),
          metrics::kDefaultMetricsServerUrl,
          metrics::kDefaultMetricsMimeType,
          on_upload_complete));
}

base::TimeDelta ChromeMetricsServiceClient::GetStandardUploadInterval() {
#if defined(OS_ANDROID) || defined(OS_IOS)
  bool is_cellular = false;
  cellular_callback_.Run(&is_cellular);

  if (is_cellular && IsCellularEnabledByExperiment())
    return base::TimeDelta::FromSeconds(kStandardUploadIntervalCellularSeconds);
#endif
  return base::TimeDelta::FromSeconds(kStandardUploadIntervalSeconds);
}

base::string16 ChromeMetricsServiceClient::GetRegistryBackupKey() {
#if defined(OS_WIN)
  return L"Software\\" PRODUCT_STRING_PATH L"\\StabilityMetrics";
#else
  return base::string16();
#endif
}

void ChromeMetricsServiceClient::LogPluginLoadingError(
    const base::FilePath& plugin_path) {
#if defined(ENABLE_PLUGINS)
  plugin_metrics_provider_->LogPluginLoadingError(plugin_path);
#else
  NOTREACHED();
#endif  // defined(ENABLE_PLUGINS)
}

void ChromeMetricsServiceClient::Initialize() {
  metrics_service_.reset(new metrics::MetricsService(
      metrics_state_manager_, this, g_browser_process->local_state()));

  // Register metrics providers.
#if defined(ENABLE_EXTENSIONS)
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(
          new ExtensionsMetricsProvider(metrics_state_manager_)));
#endif
  scoped_ptr<metrics::NetworkMetricsProvider> network_metrics_provider(
      new metrics::NetworkMetricsProvider(
          content::BrowserThread::GetBlockingPool()));
  cellular_callback_ = network_metrics_provider->GetConnectionCallback();
  metrics_service_->RegisterMetricsProvider(network_metrics_provider.Pass());

  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider));
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(new ChromeStabilityMetricsProvider));
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(new metrics::GPUMetricsProvider));

  drive_metrics_provider_ = new DriveMetricsProvider;
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(drive_metrics_provider_));

  profiler_metrics_provider_ =
      new metrics::ProfilerMetricsProvider(cellular_callback_);
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(profiler_metrics_provider_));

  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(
          new metrics::CallStackProfileMetricsProvider));

#if defined(OS_ANDROID)
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(
          new AndroidMetricsProvider(g_browser_process->local_state())));
#endif  // defined(OS_ANDROID)

#if defined(OS_WIN)
  google_update_metrics_provider_ = new GoogleUpdateMetricsProviderWin;
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(google_update_metrics_provider_));

  // Report exit funnels for canary and dev only.
  bool report_exit_funnels = false;
  switch (chrome::VersionInfo::GetChannel()) {
    case chrome::VersionInfo::CHANNEL_CANARY:
    case chrome::VersionInfo::CHANNEL_DEV:
      report_exit_funnels = true;
      break;
  }

  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(
          new browser_watcher::WatcherMetricsProviderWin(
              chrome::kBrowserExitCodesRegistryPath, report_exit_funnels)));
#endif  // defined(OS_WIN)

#if defined(ENABLE_PLUGINS)
  plugin_metrics_provider_ =
      new PluginMetricsProvider(g_browser_process->local_state());
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(plugin_metrics_provider_));
#endif  // defined(ENABLE_PLUGINS)

#if defined(OS_CHROMEOS)
  ChromeOSMetricsProvider* chromeos_metrics_provider =
      new ChromeOSMetricsProvider;
  chromeos_metrics_provider_ = chromeos_metrics_provider;
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(chromeos_metrics_provider));

  SigninStatusMetricsProviderChromeOS* signin_metrics_provider_cros =
      new SigninStatusMetricsProviderChromeOS;
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(signin_metrics_provider_cros));
#endif  // defined(OS_CHROMEOS)

#if !defined(OS_CHROMEOS) && !defined(OS_IOS)
  metrics_service_->RegisterMetricsProvider(
      scoped_ptr<metrics::MetricsProvider>(
          SigninStatusMetricsProvider::CreateInstance()));
#endif  // !defined(OS_CHROMEOS) && !defined(OS_IOS)
}

void ChromeMetricsServiceClient::OnInitTaskGotHardwareClass() {
  const base::Closure got_plugin_info_callback =
      base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotPluginInfo,
                 weak_ptr_factory_.GetWeakPtr());

#if defined(ENABLE_PLUGINS)
  plugin_metrics_provider_->GetPluginInformation(got_plugin_info_callback);
#else
  got_plugin_info_callback.Run();
#endif  // defined(ENABLE_PLUGINS)
}

void ChromeMetricsServiceClient::OnInitTaskGotPluginInfo() {
  const base::Closure got_metrics_callback =
      base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData,
                 weak_ptr_factory_.GetWeakPtr());

#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
  google_update_metrics_provider_->GetGoogleUpdateData(got_metrics_callback);
#else
  got_metrics_callback.Run();
#endif  // defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
}

void ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData() {
  // Start the next part of the init task: fetching performance data.  This will
  // call into |FinishedReceivingProfilerData()| when the task completes.
  metrics::TrackingSynchronizer::FetchProfilerDataAsynchronously(
      weak_ptr_factory_.GetWeakPtr());
}

void ChromeMetricsServiceClient::ReceivedProfilerData(
    const tracked_objects::ProcessDataSnapshot& process_data,
    int process_type) {
  profiler_metrics_provider_->RecordProfilerData(process_data, process_type);
}

void ChromeMetricsServiceClient::FinishedReceivingProfilerData() {
  drive_metrics_provider_->GetDriveMetrics(
      finished_gathering_initial_metrics_callback_);
}

void ChromeMetricsServiceClient::OnMemoryDetailCollectionDone() {
  DCHECK(thread_checker_.CalledOnValidThread());

  // This function should only be called as the callback from an ansynchronous
  // step.
  DCHECK(waiting_for_collect_final_metrics_step_);

  // Create a callback_task for OnHistogramSynchronizationDone.
  base::Closure callback = base::Bind(
      &ChromeMetricsServiceClient::OnHistogramSynchronizationDone,
      weak_ptr_factory_.GetWeakPtr());

  base::TimeDelta timeout =
      base::TimeDelta::FromMilliseconds(kMaxHistogramGatheringWaitDuration);

  DCHECK_EQ(num_async_histogram_fetches_in_progress_, 0);

#if !defined(ENABLE_PRINT_PREVIEW)
  num_async_histogram_fetches_in_progress_ = 1;
#else   // !ENABLE_PRINT_PREVIEW
  num_async_histogram_fetches_in_progress_ = 2;
  // Run requests to service and content in parallel.
  if (!ServiceProcessControl::GetInstance()->GetHistograms(callback, timeout)) {
    // Assume |num_async_histogram_fetches_in_progress_| is not changed by
    // |GetHistograms()|.
    DCHECK_EQ(num_async_histogram_fetches_in_progress_, 2);
    // Assign |num_async_histogram_fetches_in_progress_| above and decrement it
    // here to make code work even if |GetHistograms()| fired |callback|.
    --num_async_histogram_fetches_in_progress_;
  }
#endif  // !ENABLE_PRINT_PREVIEW

  // Set up the callback to task to call after we receive histograms from all
  // child processes. |timeout| specifies how long to wait before absolutely
  // calling us back on the task.
  content::FetchHistogramsAsynchronously(base::MessageLoop::current(), callback,
                                         timeout);
}

void ChromeMetricsServiceClient::OnHistogramSynchronizationDone() {
  DCHECK(thread_checker_.CalledOnValidThread());

  // This function should only be called as the callback from an ansynchronous
  // step.
  DCHECK(waiting_for_collect_final_metrics_step_);
  DCHECK_GT(num_async_histogram_fetches_in_progress_, 0);

  // Check if all expected requests finished.
  if (--num_async_histogram_fetches_in_progress_ > 0)
    return;

  waiting_for_collect_final_metrics_step_ = false;
  collect_final_metrics_done_callback_.Run();
}

void ChromeMetricsServiceClient::RecordCommandLineMetrics() {
  // Get stats on use of command line.
  const base::CommandLine* command_line(base::CommandLine::ForCurrentProcess());
  size_t common_commands = 0;
  if (command_line->HasSwitch(switches::kUserDataDir)) {
    ++common_commands;
    UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineDatDirCount", 1);
  }

  if (command_line->HasSwitch(switches::kApp)) {
    ++common_commands;
    UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineAppModeCount", 1);
  }

  // TODO(rohitrao): Should these be logged on iOS as well?
  // http://crbug.com/375794
  size_t switch_count = command_line->GetSwitches().size();
  UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineFlagCount", switch_count);
  UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineUncommonFlagCount",
                           switch_count - common_commands);
}

void ChromeMetricsServiceClient::RegisterForNotifications() {
  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED,
                 content::NotificationService::AllBrowserContextsAndSources());
  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
                 content::NotificationService::AllSources());
  registrar_.Add(this, chrome::NOTIFICATION_TAB_PARENTED,
                 content::NotificationService::AllSources());
  registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING,
                 content::NotificationService::AllSources());
  registrar_.Add(this, content::NOTIFICATION_LOAD_START,
                 content::NotificationService::AllSources());
  registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
                 content::NotificationService::AllSources());
  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
                 content::NotificationService::AllSources());
  registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_HANG,
                 content::NotificationService::AllSources());
  registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
                 content::NotificationService::AllSources());
}

void ChromeMetricsServiceClient::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  DCHECK(thread_checker_.CalledOnValidThread());

  switch (type) {
    case chrome::NOTIFICATION_BROWSER_OPENED:
    case chrome::NOTIFICATION_BROWSER_CLOSED:
    case chrome::NOTIFICATION_OMNIBOX_OPENED_URL:
    case chrome::NOTIFICATION_TAB_PARENTED:
    case chrome::NOTIFICATION_TAB_CLOSING:
    case content::NOTIFICATION_LOAD_STOP:
    case content::NOTIFICATION_LOAD_START:
    case content::NOTIFICATION_RENDERER_PROCESS_CLOSED:
    case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG:
      metrics_service_->OnApplicationNotIdle();
      break;

    default:
      NOTREACHED();
  }
}

#if defined(OS_WIN)
void ChromeMetricsServiceClient::CountBrowserCrashDumpAttempts() {
  // Open the registry key for iteration.
  base::win::RegKey regkey;
  if (regkey.Open(HKEY_CURRENT_USER,
                  chrome::kBrowserCrashDumpAttemptsRegistryPath,
                  KEY_ALL_ACCESS) != ERROR_SUCCESS) {
    return;
  }

  // The values we're interested in counting are all prefixed with the version.
  base::string16 chrome_version(base::ASCIIToUTF16(chrome::kChromeVersion));

  // Track a list of values to delete. We don't modify the registry key while
  // we're iterating over its values.
  typedef std::vector<base::string16> StringVector;
  StringVector to_delete;

  // Iterate over the values in the key counting dumps with and without crashes.
  // We directly walk the values instead of using RegistryValueIterator in order
  // to read all of the values as DWORDS instead of strings.
  base::string16 name;
  DWORD value = 0;
  int dumps_with_crash = 0;
  int dumps_with_no_crash = 0;
  for (int i = regkey.GetValueCount() - 1; i >= 0; --i) {
    if (regkey.GetValueNameAt(i, &name) == ERROR_SUCCESS &&
        StartsWith(name, chrome_version, false) &&
        regkey.ReadValueDW(name.c_str(), &value) == ERROR_SUCCESS) {
      to_delete.push_back(name);
      if (value == 0)
        ++dumps_with_no_crash;
      else
        ++dumps_with_crash;
    }
  }

  // Delete the registry keys we've just counted.
  for (StringVector::iterator i = to_delete.begin(); i != to_delete.end(); ++i)
    regkey.DeleteValue(i->c_str());

  // Capture the histogram samples.
  if (dumps_with_crash != 0)
    UMA_HISTOGRAM_COUNTS("Chrome.BrowserDumpsWithCrash", dumps_with_crash);
  if (dumps_with_no_crash != 0)
    UMA_HISTOGRAM_COUNTS("Chrome.BrowserDumpsWithNoCrash", dumps_with_no_crash);
  int total_dumps = dumps_with_crash + dumps_with_no_crash;
  if (total_dumps != 0)
    UMA_HISTOGRAM_COUNTS("Chrome.BrowserCrashDumpAttempts", total_dumps);
}
#endif  // defined(OS_WIN)
