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)
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <vector>
846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/callback.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/command_line.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/files/file_path.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/metrics/histogram.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/prefs/pref_service.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string16.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_util.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/threading/platform_thread.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/browser_process.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/google/google_brand.h"
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/metrics/chrome_stability_metrics_provider.h"
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/metrics/omnibox_metrics_provider.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/ui/browser_otr_state.h"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/crash_keys.h"
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/common/pref_names.h"
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/render_messages.h"
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/metrics/gpu/gpu_metrics_provider.h"
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/metrics/metrics_service.h"
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/metrics/net/net_metrics_log_uploader.h"
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/metrics/net/network_metrics_provider.h"
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/metrics/profiler/profiler_metrics_provider.h"
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/metrics/profiler/tracking_synchronizer.h"
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/histogram_fetcher.h"
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/notification_service.h"
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_ANDROID)
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/metrics/android_metrics_provider.h"
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_FULL_PRINTING)
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/service_process/service_process_control.h"
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(ENABLE_EXTENSIONS)
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/metrics/extensions_metrics_provider.h"
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(ENABLE_PLUGINS)
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/metrics/plugin_metrics_provider.h"
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_CHROMEOS)
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/metrics/chromeos_metrics_provider.h"
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <windows.h>
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/win/registry.h"
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/metrics/google_update_metrics_provider_win.h"
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if !defined(OS_CHROMEOS) && !defined(OS_IOS)
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/metrics/signin_status_metrics_provider.h"
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This specifies the amount of time to wait for all renderers to send their
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// data.
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kMaxHistogramGatheringWaitDuration = 60000;  // 60 seconds.
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)metrics::SystemProfileProto::Channel AsProtobufChannel(
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    chrome::VersionInfo::Channel channel) {
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (channel) {
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_UNKNOWN:
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_UNKNOWN;
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_CANARY:
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_CANARY;
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_DEV:
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_DEV;
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_BETA:
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_BETA;
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::VersionInfo::CHANNEL_STABLE:
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return metrics::SystemProfileProto::CHANNEL_STABLE;
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NOTREACHED();
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return metrics::SystemProfileProto::CHANNEL_UNKNOWN;
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Handles asynchronous fetching of memory details.
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Will run the provided task after finished.
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class MetricsMemoryDetails : public MemoryDetails {
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MetricsMemoryDetails(
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const base::Closure& callback,
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MemoryGrowthTracker* memory_growth_tracker)
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : callback_(callback) {
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SetMemoryGrowthTracker(memory_growth_tracker);
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnDetailsAvailable() OVERRIDE {
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE, callback_);
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~MetricsMemoryDetails() {}
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::Closure callback_;
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MetricsMemoryDetails);
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ChromeMetricsServiceClient::ChromeMetricsServiceClient(
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    metrics::MetricsStateManager* state_manager)
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : metrics_state_manager_(state_manager),
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      chromeos_metrics_provider_(NULL),
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      waiting_for_collect_final_metrics_step_(false),
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      num_async_histogram_fetches_in_progress_(0),
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      weak_ptr_factory_(this) {
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RecordCommandLineMetrics();
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RegisterForNotifications();
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CountBrowserCrashDumpAttempts();
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // defined(OS_WIN)
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ChromeMetricsServiceClient::~ChromeMetricsServiceClient() {
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<ChromeMetricsServiceClient> ChromeMetricsServiceClient::Create(
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    metrics::MetricsStateManager* state_manager,
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PrefService* local_state) {
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Perform two-phase initialization so that |client->metrics_service_| only
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // receives pointers to fully constructed objects.
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<ChromeMetricsServiceClient> client(
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new ChromeMetricsServiceClient(state_manager));
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client->Initialize();
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return client.Pass();
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// static
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChromeMetricsServiceClient::RegisterPrefs(PrefRegistrySimple* registry) {
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0);
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0);
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  metrics::MetricsService::RegisterPrefs(registry);
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ChromeStabilityMetricsProvider::RegisterPrefs(registry);
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_ANDROID)
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AndroidMetricsProvider::RegisterPrefs(registry);
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(OS_ANDROID)
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(ENABLE_PLUGINS)
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PluginMetricsProvider::RegisterPrefs(registry);
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(ENABLE_PLUGINS)
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ChromeMetricsServiceClient::SetMetricsClientId(
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& client_id) {
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  crash_keys::SetCrashClientIdFromGUID(client_id);
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ChromeMetricsServiceClient::IsOffTheRecordSessionActive() {
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return chrome::IsOffTheRecordSessionActive();
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string ChromeMetricsServiceClient::GetApplicationLocale() {
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return g_browser_process->GetApplicationLocale();
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ChromeMetricsServiceClient::GetBrand(std::string* brand_code) {
18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return google_brand::GetBrand(brand_code);
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)metrics::SystemProfileProto::Channel ChromeMetricsServiceClient::GetChannel() {
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return AsProtobufChannel(chrome::VersionInfo::GetChannel());
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string ChromeMetricsServiceClient::GetVersionString() {
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome::VersionInfo version_info;
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!version_info.is_valid()) {
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NOTREACHED();
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return std::string();
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string version = version_info.Version();
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(ARCH_CPU_64_BITS)
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  version += "-64";
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // defined(ARCH_CPU_64_BITS)
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!version_info.IsOfficialBuild())
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    version.append("-devel");
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return version;
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::OnLogUploadComplete() {
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Collect network stats after each UMA upload.
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  network_stats_uploader_.CollectAndReportNetworkStats();
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ChromeMetricsServiceClient::StartGatheringMetrics(
21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::Closure& done_callback) {
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  finished_gathering_initial_metrics_callback_ = done_callback;
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::Closure got_hardware_class_callback =
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotHardwareClass,
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr());
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_CHROMEOS)
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  chromeos_metrics_provider_->InitTaskGetHardwareClass(
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      got_hardware_class_callback);
22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  got_hardware_class_callback.Run();
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(OS_CHROMEOS)
22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::CollectFinalMetrics(
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::Closure& done_callback) {
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  collect_final_metrics_done_callback_ = done_callback;
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Begin the multi-step process of collecting memory usage histograms:
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // First spawn a task to collect the memory details; when that task is
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // finished, it will call OnMemoryDetailCollectionDone. That will in turn
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // call HistogramSynchronization to collect histograms from all renderers and
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // then call OnHistogramSynchronizationDone to continue processing.
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!waiting_for_collect_final_metrics_step_);
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  waiting_for_collect_final_metrics_step_ = true;
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::Closure callback =
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ChromeMetricsServiceClient::OnMemoryDetailCollectionDone,
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr());
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<MetricsMemoryDetails> details(
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new MetricsMemoryDetails(callback, &memory_growth_tracker_));
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  details->StartFetch(MemoryDetails::UPDATE_USER_METRICS);
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Collect WebCore cache information to put into a histogram.
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (content::RenderProcessHost::iterator i(
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          content::RenderProcessHost::AllHostsIterator());
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       !i.IsAtEnd(); i.Advance()) {
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    i.GetCurrentValue()->Send(new ChromeViewMsg_GetCacheResourceStats());
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)scoped_ptr<metrics::MetricsLogUploader>
26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ChromeMetricsServiceClient::CreateUploader(
26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& server_url,
26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& mime_type,
26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::Callback<void(int)>& on_upload_complete) {
26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return scoped_ptr<metrics::MetricsLogUploader>(
26546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new metrics::NetMetricsLogUploader(
26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          g_browser_process->system_request_context(), server_url, mime_type,
26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          on_upload_complete));
26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::string16 ChromeMetricsServiceClient::GetRegistryBackupKey() {
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_WIN)
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return L"Software\\" PRODUCT_STRING_PATH L"\\StabilityMetrics";
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return base::string16();
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChromeMetricsServiceClient::LogPluginLoadingError(
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::FilePath& plugin_path) {
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(ENABLE_PLUGINS)
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  plugin_metrics_provider_->LogPluginLoadingError(plugin_path);
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else
283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NOTREACHED();
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(ENABLE_PLUGINS)
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChromeMetricsServiceClient::Initialize() {
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  metrics_service_.reset(new metrics::MetricsService(
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      metrics_state_manager_, this, g_browser_process->local_state()));
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Register metrics providers.
2926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(ENABLE_EXTENSIONS)
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          new ExtensionsMetricsProvider(metrics_state_manager_)));
2966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_ptr<metrics::MetricsProvider>(new NetworkMetricsProvider(
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          content::BrowserThread::GetBlockingPool())));
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider));
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(new ChromeStabilityMetricsProvider));
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_ptr<metrics::MetricsProvider>(new metrics::GPUMetricsProvider()));
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  profiler_metrics_provider_ = new metrics::ProfilerMetricsProvider;
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(profiler_metrics_provider_));
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_ANDROID)
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          new AndroidMetricsProvider(g_browser_process->local_state())));
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(OS_ANDROID)
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_WIN)
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  google_update_metrics_provider_ = new GoogleUpdateMetricsProviderWin;
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(google_update_metrics_provider_));
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(OS_WIN)
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(ENABLE_PLUGINS)
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  plugin_metrics_provider_ =
324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new PluginMetricsProvider(g_browser_process->local_state());
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(plugin_metrics_provider_));
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(ENABLE_PLUGINS)
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_CHROMEOS)
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ChromeOSMetricsProvider* chromeos_metrics_provider =
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new ChromeOSMetricsProvider;
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  chromeos_metrics_provider_ = chromeos_metrics_provider;
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<metrics::MetricsProvider>(chromeos_metrics_provider));
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(OS_CHROMEOS)
3366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if !defined(OS_CHROMEOS) && !defined(OS_IOS)
3386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  metrics_service_->RegisterMetricsProvider(
339ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch      scoped_ptr<metrics::MetricsProvider>(
340ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch          SigninStatusMetricsProvider::CreateInstance()));
3416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif
342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChromeMetricsServiceClient::OnInitTaskGotHardwareClass() {
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const base::Closure got_plugin_info_callback =
346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotPluginInfo,
347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr());
348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(ENABLE_PLUGINS)
350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  plugin_metrics_provider_->GetPluginInformation(got_plugin_info_callback);
351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  got_plugin_info_callback.Run();
353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(ENABLE_PLUGINS)
354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChromeMetricsServiceClient::OnInitTaskGotPluginInfo() {
357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const base::Closure got_metrics_callback =
358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData,
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr());
360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  google_update_metrics_provider_->GetGoogleUpdateData(got_metrics_callback);
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else
364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  got_metrics_callback.Run();
365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData() {
369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Start the next part of the init task: fetching performance data.  This will
370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // call into |FinishedReceivingProfilerData()| when the task completes.
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  metrics::TrackingSynchronizer::FetchProfilerDataAsynchronously(
372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      weak_ptr_factory_.GetWeakPtr());
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChromeMetricsServiceClient::ReceivedProfilerData(
376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const tracked_objects::ProcessDataSnapshot& process_data,
377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int process_type) {
378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  profiler_metrics_provider_->RecordProfilerData(process_data, process_type);
379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
381f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChromeMetricsServiceClient::FinishedReceivingProfilerData() {
382f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  finished_gathering_initial_metrics_callback_.Run();
383f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
384f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::OnMemoryDetailCollectionDone() {
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This function should only be called as the callback from an ansynchronous
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // step.
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(waiting_for_collect_final_metrics_step_);
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create a callback_task for OnHistogramSynchronizationDone.
393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::Closure callback = base::Bind(
394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      &ChromeMetricsServiceClient::OnHistogramSynchronizationDone,
395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      weak_ptr_factory_.GetWeakPtr());
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeDelta timeout =
398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kMaxHistogramGatheringWaitDuration);
399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(num_async_histogram_fetches_in_progress_, 0);
401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(ENABLE_FULL_PRINTING)
403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  num_async_histogram_fetches_in_progress_ = 1;
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else  // !ENABLE_FULL_PRINTING
405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  num_async_histogram_fetches_in_progress_ = 2;
406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Run requests to service and content in parallel.
407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!ServiceProcessControl::GetInstance()->GetHistograms(callback, timeout)) {
408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Assume |num_async_histogram_fetches_in_progress_| is not changed by
409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // |GetHistograms()|.
410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(num_async_histogram_fetches_in_progress_, 2);
411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Assign |num_async_histogram_fetches_in_progress_| above and decrement it
412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // here to make code work even if |GetHistograms()| fired |callback|.
413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    --num_async_histogram_fetches_in_progress_;
414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // !ENABLE_FULL_PRINTING
416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Set up the callback to task to call after we receive histograms from all
418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // child processes. |timeout| specifies how long to wait before absolutely
419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // calling us back on the task.
420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::FetchHistogramsAsynchronously(base::MessageLoop::current(), callback,
421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         timeout);
422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::OnHistogramSynchronizationDone() {
425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This function should only be called as the callback from an ansynchronous
428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // step.
429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(waiting_for_collect_final_metrics_step_);
430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_GT(num_async_histogram_fetches_in_progress_, 0);
431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check if all expected requests finished.
433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (--num_async_histogram_fetches_in_progress_ > 0)
434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  waiting_for_collect_final_metrics_step_ = false;
437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  collect_final_metrics_done_callback_.Run();
438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::RecordCommandLineMetrics() {
441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Get stats on use of command line.
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const CommandLine* command_line(CommandLine::ForCurrentProcess());
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t common_commands = 0;
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (command_line->HasSwitch(switches::kUserDataDir)) {
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++common_commands;
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineDatDirCount", 1);
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (command_line->HasSwitch(switches::kApp)) {
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++common_commands;
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineAppModeCount", 1);
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(rohitrao): Should these be logged on iOS as well?
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // http://crbug.com/375794
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t switch_count = command_line->GetSwitches().size();
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineFlagCount", switch_count);
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineUncommonFlagCount",
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           switch_count - common_commands);
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::RegisterForNotifications() {
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED,
464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllBrowserContextsAndSources());
465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_TAB_PARENTED,
468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING,
470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_LOAD_START,
472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_HANG,
478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 content::NotificationService::AllSources());
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::Observe(
484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int type,
485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::NotificationSource& source,
486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::NotificationDetails& details) {
487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  switch (type) {
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_BROWSER_OPENED:
491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_BROWSER_CLOSED:
492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_OMNIBOX_OPENED_URL:
493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_TAB_PARENTED:
494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case chrome::NOTIFICATION_TAB_CLOSING:
495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case content::NOTIFICATION_LOAD_STOP:
496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case content::NOTIFICATION_LOAD_START:
497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case content::NOTIFICATION_RENDERER_PROCESS_CLOSED:
498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG:
499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      metrics_service_->OnApplicationNotIdle();
500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    default:
503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      NOTREACHED();
504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_WIN)
508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChromeMetricsServiceClient::CountBrowserCrashDumpAttempts() {
509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Open the registry key for iteration.
510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::win::RegKey regkey;
511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (regkey.Open(HKEY_CURRENT_USER,
512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  chrome::kBrowserCrashDumpAttemptsRegistryPath,
513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  KEY_ALL_ACCESS) != ERROR_SUCCESS) {
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The values we're interested in counting are all prefixed with the version.
518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::string16 chrome_version(base::ASCIIToUTF16(chrome::kChromeVersion));
519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Track a list of values to delete. We don't modify the registry key while
521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // we're iterating over its values.
522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef std::vector<base::string16> StringVector;
523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StringVector to_delete;
524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Iterate over the values in the key counting dumps with and without crashes.
526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We directly walk the values instead of using RegistryValueIterator in order
527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // to read all of the values as DWORDS instead of strings.
528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::string16 name;
529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DWORD value = 0;
530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int dumps_with_crash = 0;
531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int dumps_with_no_crash = 0;
532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int i = regkey.GetValueCount() - 1; i >= 0; --i) {
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (regkey.GetValueNameAt(i, &name) == ERROR_SUCCESS &&
534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        StartsWith(name, chrome_version, false) &&
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        regkey.ReadValueDW(name.c_str(), &value) == ERROR_SUCCESS) {
536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      to_delete.push_back(name);
537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (value == 0)
538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ++dumps_with_no_crash;
539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      else
540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ++dumps_with_crash;
541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Delete the registry keys we've just counted.
545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (StringVector::iterator i = to_delete.begin(); i != to_delete.end(); ++i)
546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    regkey.DeleteValue(i->c_str());
547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Capture the histogram samples.
549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (dumps_with_crash != 0)
550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("Chrome.BrowserDumpsWithCrash", dumps_with_crash);
551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (dumps_with_no_crash != 0)
552cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("Chrome.BrowserDumpsWithNoCrash", dumps_with_no_crash);
553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int total_dumps = dumps_with_crash + dumps_with_no_crash;
554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (total_dumps != 0)
555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS("Chrome.BrowserCrashDumpAttempts", total_dumps);
556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // defined(OS_WIN)
558