chrome_metrics_service_client.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/metrics/chrome_metrics_service_client.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/callback.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/command_line.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/metrics/histogram.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string16.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_util.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/threading/platform_thread.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/time/time.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/browser_process.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/google/google_util.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/memory_details.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/metrics/extensions_metrics_provider.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/metrics/metrics_service.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/ui/browser_otr_state.h"
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/crash_keys.h"
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/render_messages.h"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/histogram_fetcher.h"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/notification_service.h"
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(OS_ANDROID)
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/service_process/service_process_control.h"
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_CHROMEOS)
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/metrics/chromeos_metrics_provider.h"
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <windows.h>
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/win/registry.h"
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/metrics/google_update_metrics_provider_win.h"
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This specifies the amount of time to wait for all renderers to send their
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// data.
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kMaxHistogramGatheringWaitDuration = 60000;  // 60 seconds.
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)metrics::SystemProfileProto::Channel AsProtobufChannel(
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    chrome::VersionInfo::Channel channel) {
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (channel) {
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_UNKNOWN:
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_UNKNOWN;
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_CANARY:
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_CANARY;
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_DEV:
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_DEV;
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_BETA:
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_BETA;
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_STABLE:
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_STABLE;
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NOTREACHED();
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return metrics::SystemProfileProto::CHANNEL_UNKNOWN;
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Handles asynchronous fetching of memory details.
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Will run the provided task after finished.
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class MetricsMemoryDetails : public MemoryDetails {
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  explicit MetricsMemoryDetails(const base::Closure& callback)
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : callback_(callback) {}
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnDetailsAvailable() OVERRIDE {
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE, callback_);
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~MetricsMemoryDetails() {}
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::Closure callback_;
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MetricsMemoryDetails);
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ChromeMetricsServiceClient::ChromeMetricsServiceClient(
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    metrics::MetricsStateManager* state_manager)
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : metrics_state_manager_(state_manager),
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      chromeos_metrics_provider_(NULL),
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      waiting_for_collect_final_metrics_step_(false),
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      num_async_histogram_fetches_in_progress_(0),
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      weak_ptr_factory_(this) {
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RecordCommandLineMetrics();
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RegisterForNotifications();
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CountBrowserCrashDumpAttempts();
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // defined(OS_WIN)
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ChromeMetricsServiceClient::~ChromeMetricsServiceClient() {
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<ChromeMetricsServiceClient> ChromeMetricsServiceClient::Create(
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    metrics::MetricsStateManager* state_manager,
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PrefService* local_state) {
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Perform two-phase initialization so that |client->metrics_service_| only
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // receives pointers to fully constructed objects.
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<ChromeMetricsServiceClient> client(
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new ChromeMetricsServiceClient(state_manager));
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client->Initialize();
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return client.Pass();
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::Initialize() {
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  metrics_service_.reset(new MetricsService(
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      metrics_state_manager_, this, g_browser_process->local_state()));
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Register metrics providers.
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          new ExtensionsMetricsProvider(metrics_state_manager_)));
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_CHROMEOS)
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ChromeOSMetricsProvider* chromeos_metrics_provider =
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new ChromeOSMetricsProvider;
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chromeos_metrics_provider_ = chromeos_metrics_provider;
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(chromeos_metrics_provider));
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::SetClientID(const std::string& client_id) {
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  crash_keys::SetClientID(client_id);
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ChromeMetricsServiceClient::IsOffTheRecordSessionActive() {
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return !chrome::IsOffTheRecordSessionActive();
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string ChromeMetricsServiceClient::GetApplicationLocale() {
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return g_browser_process->GetApplicationLocale();
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ChromeMetricsServiceClient::GetBrand(std::string* brand_code) {
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return google_util::GetBrand(brand_code);
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)metrics::SystemProfileProto::Channel ChromeMetricsServiceClient::GetChannel() {
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return AsProtobufChannel(chrome::VersionInfo::GetChannel());
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string ChromeMetricsServiceClient::GetVersionString() {
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome::VersionInfo version_info;
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!version_info.is_valid()) {
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NOTREACHED();
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return std::string();
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string version = version_info.Version();
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(ARCH_CPU_64_BITS)
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  version += "-64";
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // defined(ARCH_CPU_64_BITS)
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!version_info.IsOfficialBuild())
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    version.append("-devel");
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return version;
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::OnLogUploadComplete() {
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Collect network stats after each UMA upload.
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  network_stats_uploader_.CollectAndReportNetworkStats();
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::CollectFinalMetrics(
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::Closure& done_callback) {
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  collect_final_metrics_done_callback_ = done_callback;
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Begin the multi-step process of collecting memory usage histograms:
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // First spawn a task to collect the memory details; when that task is
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // finished, it will call OnMemoryDetailCollectionDone. That will in turn
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // call HistogramSynchronization to collect histograms from all renderers and
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // then call OnHistogramSynchronizationDone to continue processing.
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!waiting_for_collect_final_metrics_step_);
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  waiting_for_collect_final_metrics_step_ = true;
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::Closure callback =
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ChromeMetricsServiceClient::OnMemoryDetailCollectionDone,
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr());
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<MetricsMemoryDetails> details(
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new MetricsMemoryDetails(callback));
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  details->StartFetch(MemoryDetails::UPDATE_USER_METRICS);
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Collect WebCore cache information to put into a histogram.
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (content::RenderProcessHost::iterator i(
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          content::RenderProcessHost::AllHostsIterator());
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       !i.IsAtEnd(); i.Advance()) {
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    i.GetCurrentValue()->Send(new ChromeViewMsg_GetCacheResourceStats());
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::OnMemoryDetailCollectionDone() {
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This function should only be called as the callback from an ansynchronous
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // step.
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(waiting_for_collect_final_metrics_step_);
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create a callback_task for OnHistogramSynchronizationDone.
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::Closure callback = base::Bind(
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &ChromeMetricsServiceClient::OnHistogramSynchronizationDone,
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      weak_ptr_factory_.GetWeakPtr());
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeDelta timeout =
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kMaxHistogramGatheringWaitDuration);
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(num_async_histogram_fetches_in_progress_, 0);
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_ANDROID)
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Android has no service process.
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  num_async_histogram_fetches_in_progress_ = 1;
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else  // OS_ANDROID
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  num_async_histogram_fetches_in_progress_ = 2;
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Run requests to service and content in parallel.
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!ServiceProcessControl::GetInstance()->GetHistograms(callback, timeout)) {
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Assume |num_async_histogram_fetches_in_progress_| is not changed by
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // |GetHistograms()|.
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(num_async_histogram_fetches_in_progress_, 2);
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Assign |num_async_histogram_fetches_in_progress_| above and decrement it
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // here to make code work even if |GetHistograms()| fired |callback|.
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    --num_async_histogram_fetches_in_progress_;
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // OS_ANDROID
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Set up the callback to task to call after we receive histograms from all
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // child processes. |timeout| specifies how long to wait before absolutely
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // calling us back on the task.
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::FetchHistogramsAsynchronously(base::MessageLoop::current(), callback,
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         timeout);
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::OnHistogramSynchronizationDone() {
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This function should only be called as the callback from an ansynchronous
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // step.
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(waiting_for_collect_final_metrics_step_);
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_GT(num_async_histogram_fetches_in_progress_, 0);
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check if all expected requests finished.
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (--num_async_histogram_fetches_in_progress_ > 0)
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  waiting_for_collect_final_metrics_step_ = false;
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  collect_final_metrics_done_callback_.Run();
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::RecordCommandLineMetrics() {
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Get stats on use of command line.
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const CommandLine* command_line(CommandLine::ForCurrentProcess());
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t common_commands = 0;
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (command_line->HasSwitch(switches::kUserDataDir)) {
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++common_commands;
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineDatDirCount", 1);
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (command_line->HasSwitch(switches::kApp)) {
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++common_commands;
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineAppModeCount", 1);
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(rohitrao): Should these be logged on iOS as well?
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // http://crbug.com/375794
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t switch_count = command_line->GetSwitches().size();
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineFlagCount", switch_count);
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineUncommonFlagCount",
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           switch_count - common_commands);
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::RegisterForNotifications() {
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED,
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllBrowserContextsAndSources());
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_TAB_PARENTED,
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING,
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_LOAD_START,
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_HANG,
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::Observe(
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int type,
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::NotificationSource& source,
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::NotificationDetails& details) {
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (type) {
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_BROWSER_OPENED:
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_BROWSER_CLOSED:
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_OMNIBOX_OPENED_URL:
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_TAB_PARENTED:
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_TAB_CLOSING:
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case content::NOTIFICATION_LOAD_STOP:
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case content::NOTIFICATION_LOAD_START:
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case content::NOTIFICATION_RENDERER_PROCESS_CLOSED:
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG:
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      metrics_service_->OnApplicationNotIdle();
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    default:
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      NOTREACHED();
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::StartGatheringMetrics(
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::Closure& done_callback) {
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// TODO(blundell): Move all metrics gathering tasks from MetricsService to
341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// here.
342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_CHROMEOS)
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chromeos_metrics_provider_->InitTaskGetHardwareClass(done_callback);
344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else
345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  done_callback.Run();
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::CountBrowserCrashDumpAttempts() {
351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Open the registry key for iteration.
352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::win::RegKey regkey;
353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (regkey.Open(HKEY_CURRENT_USER,
354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  chrome::kBrowserCrashDumpAttemptsRegistryPath,
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  KEY_ALL_ACCESS) != ERROR_SUCCESS) {
356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The values we're interested in counting are all prefixed with the version.
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::string16 chrome_version(base::ASCIIToUTF16(chrome::kChromeVersion));
361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Track a list of values to delete. We don't modify the registry key while
363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // we're iterating over its values.
364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef std::vector<base::string16> StringVector;
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StringVector to_delete;
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Iterate over the values in the key counting dumps with and without crashes.
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We directly walk the values instead of using RegistryValueIterator in order
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // to read all of the values as DWORDS instead of strings.
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::string16 name;
371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DWORD value = 0;
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int dumps_with_crash = 0;
373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int dumps_with_no_crash = 0;
374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int i = regkey.GetValueCount() - 1; i >= 0; --i) {
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (regkey.GetValueNameAt(i, &name) == ERROR_SUCCESS &&
376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        StartsWith(name, chrome_version, false) &&
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        regkey.ReadValueDW(name.c_str(), &value) == ERROR_SUCCESS) {
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      to_delete.push_back(name);
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (value == 0)
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ++dumps_with_no_crash;
381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      else
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ++dumps_with_crash;
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Delete the registry keys we've just counted.
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (StringVector::iterator i = to_delete.begin(); i != to_delete.end(); ++i)
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    regkey.DeleteValue(i->c_str());
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Capture the histogram samples.
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (dumps_with_crash != 0)
392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("Chrome.BrowserDumpsWithCrash", dumps_with_crash);
393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (dumps_with_no_crash != 0)
394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("Chrome.BrowserDumpsWithNoCrash", dumps_with_no_crash);
395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int total_dumps = dumps_with_crash + dumps_with_no_crash;
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (total_dumps != 0)
397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("Chrome.BrowserCrashDumpAttempts", total_dumps);
398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // defined(OS_WIN)
400