Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / metrics / chrome_metrics_service_client.cc
blobb5c5e2c2f45f1f59547a05c64e3cfa89726dc59b
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/metrics/chrome_metrics_service_client.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/logging.h"
14 #include "base/metrics/histogram.h"
15 #include "base/prefs/pref_registry_simple.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/strings/string16.h"
18 #include "base/threading/platform_thread.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/chrome_notification_types.h"
21 #include "chrome/browser/google/google_brand.h"
22 #include "chrome/browser/metrics/chrome_stability_metrics_provider.h"
23 #include "chrome/browser/metrics/drive_metrics_provider.h"
24 #include "chrome/browser/metrics/omnibox_metrics_provider.h"
25 #include "chrome/browser/metrics/time_ticks_experiment_win.h"
26 #include "chrome/browser/process_resource_usage.h"
27 #include "chrome/browser/ui/browser_otr_state.h"
28 #include "chrome/common/chrome_constants.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/crash_keys.h"
31 #include "chrome/common/metrics/version_utils.h"
32 #include "chrome/common/pref_names.h"
33 #include "chrome/common/render_messages.h"
34 #include "components/metrics/call_stack_profile_metrics_provider.h"
35 #include "components/metrics/gpu/gpu_metrics_provider.h"
36 #include "components/metrics/metrics_service.h"
37 #include "components/metrics/net/net_metrics_log_uploader.h"
38 #include "components/metrics/net/network_metrics_provider.h"
39 #include "components/metrics/profiler/profiler_metrics_provider.h"
40 #include "components/metrics/profiler/tracking_synchronizer.h"
41 #include "components/metrics/url_constants.h"
42 #include "components/variations/variations_associated_data.h"
43 #include "content/public/browser/browser_thread.h"
44 #include "content/public/browser/histogram_fetcher.h"
45 #include "content/public/browser/notification_service.h"
46 #include "content/public/browser/render_process_host.h"
47 #include "content/public/common/service_registry.h"
49 #if defined(OS_ANDROID)
50 #include "chrome/browser/metrics/android_metrics_provider.h"
51 #endif
53 #if defined(ENABLE_PRINT_PREVIEW)
54 #include "chrome/browser/service_process/service_process_control.h"
55 #endif
57 #if defined(ENABLE_EXTENSIONS)
58 #include "chrome/browser/metrics/extensions_metrics_provider.h"
59 #endif
61 #if defined(ENABLE_PLUGINS)
62 #include "chrome/browser/metrics/plugin_metrics_provider.h"
63 #endif
65 #if defined(OS_CHROMEOS)
66 #include "chrome/browser/metrics/chromeos_metrics_provider.h"
67 #include "chrome/browser/metrics/signin_status_metrics_provider_chromeos.h"
68 #endif
70 #if defined(OS_WIN)
71 #include <windows.h>
72 #include "chrome/browser/metrics/google_update_metrics_provider_win.h"
73 #include "components/browser_watcher/watcher_metrics_provider_win.h"
74 #endif
76 #if !defined(OS_CHROMEOS)
77 #include "chrome/browser/metrics/signin_status_metrics_provider.h"
78 #endif // !defined(OS_CHROMEOS)
80 namespace {
82 // This specifies the amount of time to wait for all renderers to send their
83 // data.
84 const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds.
86 // Standard interval between log uploads, in seconds.
87 #if defined(OS_ANDROID) || defined(OS_IOS)
88 const int kStandardUploadIntervalSeconds = 5 * 60; // Five minutes.
89 const int kStandardUploadIntervalCellularSeconds = 15 * 60; // Fifteen minutes.
90 #else
91 const int kStandardUploadIntervalSeconds = 30 * 60; // Thirty minutes.
92 #endif
94 // Returns true if current connection type is cellular and user is assigned to
95 // experimental group for enabled cellular uploads.
96 bool IsCellularLogicEnabled() {
97 if (variations::GetVariationParamValue("UMA_EnableCellularLogUpload",
98 "Enabled") != "true" ||
99 variations::GetVariationParamValue("UMA_EnableCellularLogUpload",
100 "Optimize") == "false") {
101 return false;
104 return net::NetworkChangeNotifier::IsConnectionCellular(
105 net::NetworkChangeNotifier::GetConnectionType());
108 // Checks whether it is the first time that cellular uploads logic should be
109 // enabled based on whether the the preference for that logic is initialized.
110 // This should happen only once as the used preference will be initialized
111 // afterwards in |UmaSessionStats.java|.
112 bool ShouldClearSavedMetrics() {
113 #if defined(OS_ANDROID)
114 PrefService* local_state = g_browser_process->local_state();
115 return !local_state->HasPrefPath(prefs::kMetricsReportingEnabled) &&
116 variations::GetVariationParamValue("UMA_EnableCellularLogUpload",
117 "Enabled") == "true";
118 #else
119 return false;
120 #endif
123 } // namespace
126 ChromeMetricsServiceClient::ChromeMetricsServiceClient(
127 metrics::MetricsStateManager* state_manager)
128 : metrics_state_manager_(state_manager),
129 chromeos_metrics_provider_(nullptr),
130 waiting_for_collect_final_metrics_step_(false),
131 num_async_histogram_fetches_in_progress_(0),
132 profiler_metrics_provider_(nullptr),
133 #if defined(ENABLE_PLUGINS)
134 plugin_metrics_provider_(nullptr),
135 #endif
136 #if defined(OS_WIN)
137 google_update_metrics_provider_(nullptr),
138 #endif
139 drive_metrics_provider_(nullptr),
140 start_time_(base::TimeTicks::Now()),
141 weak_ptr_factory_(this) {
142 DCHECK(thread_checker_.CalledOnValidThread());
143 RecordCommandLineMetrics();
144 RegisterForNotifications();
147 ChromeMetricsServiceClient::~ChromeMetricsServiceClient() {
148 DCHECK(thread_checker_.CalledOnValidThread());
151 // static
152 scoped_ptr<ChromeMetricsServiceClient> ChromeMetricsServiceClient::Create(
153 metrics::MetricsStateManager* state_manager,
154 PrefService* local_state) {
155 // Perform two-phase initialization so that |client->metrics_service_| only
156 // receives pointers to fully constructed objects.
157 scoped_ptr<ChromeMetricsServiceClient> client(
158 new ChromeMetricsServiceClient(state_manager));
159 client->Initialize();
161 return client.Pass();
164 // static
165 void ChromeMetricsServiceClient::RegisterPrefs(PrefRegistrySimple* registry) {
166 registry->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0);
167 registry->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0);
169 metrics::MetricsService::RegisterPrefs(registry);
170 ChromeStabilityMetricsProvider::RegisterPrefs(registry);
172 #if defined(OS_ANDROID)
173 AndroidMetricsProvider::RegisterPrefs(registry);
174 #endif // defined(OS_ANDROID)
176 #if defined(ENABLE_PLUGINS)
177 PluginMetricsProvider::RegisterPrefs(registry);
178 #endif // defined(ENABLE_PLUGINS)
181 void ChromeMetricsServiceClient::SetMetricsClientId(
182 const std::string& client_id) {
183 crash_keys::SetMetricsClientIdFromGUID(client_id);
186 void ChromeMetricsServiceClient::OnRecordingDisabled() {
187 crash_keys::ClearMetricsClientId();
190 bool ChromeMetricsServiceClient::IsOffTheRecordSessionActive() {
191 return chrome::IsOffTheRecordSessionActive();
194 int32 ChromeMetricsServiceClient::GetProduct() {
195 return metrics::ChromeUserMetricsExtension::CHROME;
198 std::string ChromeMetricsServiceClient::GetApplicationLocale() {
199 return g_browser_process->GetApplicationLocale();
202 bool ChromeMetricsServiceClient::GetBrand(std::string* brand_code) {
203 return google_brand::GetBrand(brand_code);
206 metrics::SystemProfileProto::Channel ChromeMetricsServiceClient::GetChannel() {
207 return metrics::AsProtobufChannel(chrome::VersionInfo::GetChannel());
210 std::string ChromeMetricsServiceClient::GetVersionString() {
211 return metrics::GetVersionString();
214 void ChromeMetricsServiceClient::OnLogUploadComplete() {
215 // Collect time ticks stats after each UMA upload.
216 #if defined(OS_WIN)
217 chrome::CollectTimeTicksStats();
218 #endif
221 void ChromeMetricsServiceClient::StartGatheringMetrics(
222 const base::Closure& done_callback) {
223 finished_gathering_initial_metrics_callback_ = done_callback;
224 base::Closure got_hardware_class_callback =
225 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotHardwareClass,
226 weak_ptr_factory_.GetWeakPtr());
227 #if defined(OS_CHROMEOS)
228 chromeos_metrics_provider_->InitTaskGetHardwareClass(
229 got_hardware_class_callback);
230 #else
231 got_hardware_class_callback.Run();
232 #endif // defined(OS_CHROMEOS)
235 void ChromeMetricsServiceClient::CollectFinalMetrics(
236 const base::Closure& done_callback) {
237 DCHECK(thread_checker_.CalledOnValidThread());
239 collect_final_metrics_done_callback_ = done_callback;
241 // Begin the multi-step process of collecting memory usage histograms:
242 // First spawn a task to collect the memory details; when that task is
243 // finished, it will call OnMemoryDetailCollectionDone. That will in turn
244 // call HistogramSynchronization to collect histograms from all renderers and
245 // then call OnHistogramSynchronizationDone to continue processing.
246 DCHECK(!waiting_for_collect_final_metrics_step_);
247 waiting_for_collect_final_metrics_step_ = true;
249 base::Closure callback =
250 base::Bind(&ChromeMetricsServiceClient::OnMemoryDetailCollectionDone,
251 weak_ptr_factory_.GetWeakPtr());
253 scoped_refptr<MetricsMemoryDetails> details(
254 new MetricsMemoryDetails(callback, &memory_growth_tracker_));
255 details->StartFetch(MemoryDetails::FROM_CHROME_ONLY);
257 base::ScopedPtrMap<int, scoped_ptr<ProcessResourceUsage>> current_map;
258 host_resource_usage_map_.swap(current_map);
260 // Collect WebCore cache information to put into a histogram.
261 for (content::RenderProcessHost::iterator i(
262 content::RenderProcessHost::AllHostsIterator());
263 !i.IsAtEnd(); i.Advance()) {
264 content::RenderProcessHost* host = i.GetCurrentValue();
265 int host_id = host->GetID();
266 ProcessResourceUsage* resource_usage = nullptr;
267 auto iter = current_map.find(host_id);
268 if (iter != current_map.end()) {
269 resource_usage = iter->second;
270 host_resource_usage_map_.set(host_id, current_map.take_and_erase(iter));
271 } else {
272 content::ServiceRegistry* service_registry = host->GetServiceRegistry();
273 if (service_registry) {
274 ResourceUsageReporterPtr service;
275 service_registry->ConnectToRemoteService(mojo::GetProxy(&service));
276 resource_usage = new ProcessResourceUsage(service.Pass());
277 host_resource_usage_map_.set(host_id, make_scoped_ptr(resource_usage));
280 if (resource_usage) {
281 resource_usage->Refresh(
282 base::Bind(&ChromeMetricsServiceClient::OnWebCacheStatsRefresh,
283 weak_ptr_factory_.GetWeakPtr(), host_id));
288 scoped_ptr<metrics::MetricsLogUploader>
289 ChromeMetricsServiceClient::CreateUploader(
290 const base::Callback<void(int)>& on_upload_complete) {
291 return scoped_ptr<metrics::MetricsLogUploader>(
292 new metrics::NetMetricsLogUploader(
293 g_browser_process->system_request_context(),
294 metrics::kDefaultMetricsServerUrl,
295 metrics::kDefaultMetricsMimeType,
296 on_upload_complete));
299 base::TimeDelta ChromeMetricsServiceClient::GetStandardUploadInterval() {
300 #if defined(OS_ANDROID) || defined(OS_IOS)
301 if (IsCellularLogicEnabled())
302 return base::TimeDelta::FromSeconds(kStandardUploadIntervalCellularSeconds);
303 #endif
304 return base::TimeDelta::FromSeconds(kStandardUploadIntervalSeconds);
307 base::string16 ChromeMetricsServiceClient::GetRegistryBackupKey() {
308 #if defined(OS_WIN)
309 return L"Software\\" PRODUCT_STRING_PATH L"\\StabilityMetrics";
310 #else
311 return base::string16();
312 #endif
315 void ChromeMetricsServiceClient::LogPluginLoadingError(
316 const base::FilePath& plugin_path) {
317 #if defined(ENABLE_PLUGINS)
318 plugin_metrics_provider_->LogPluginLoadingError(plugin_path);
319 #else
320 NOTREACHED();
321 #endif // defined(ENABLE_PLUGINS)
324 void ChromeMetricsServiceClient::Initialize() {
325 // Clear metrics reports if it is the first time cellular upload logic should
326 // apply to avoid sudden bulk uploads. It needs to be done before initializing
327 // metrics service so that metrics log manager is initialized correctly.
328 if (ShouldClearSavedMetrics()) {
329 PrefService* local_state = g_browser_process->local_state();
330 local_state->ClearPref(metrics::prefs::kMetricsInitialLogs);
331 local_state->ClearPref(metrics::prefs::kMetricsOngoingLogs);
334 metrics_service_.reset(new metrics::MetricsService(
335 metrics_state_manager_, this, g_browser_process->local_state()));
337 // Register metrics providers.
338 #if defined(ENABLE_EXTENSIONS)
339 metrics_service_->RegisterMetricsProvider(
340 scoped_ptr<metrics::MetricsProvider>(
341 new ExtensionsMetricsProvider(metrics_state_manager_)));
342 #endif
343 metrics_service_->RegisterMetricsProvider(
344 scoped_ptr<metrics::MetricsProvider>(new metrics::NetworkMetricsProvider(
345 content::BrowserThread::GetBlockingPool())));
347 metrics_service_->RegisterMetricsProvider(
348 scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider));
349 metrics_service_->RegisterMetricsProvider(
350 scoped_ptr<metrics::MetricsProvider>(new ChromeStabilityMetricsProvider));
351 metrics_service_->RegisterMetricsProvider(
352 scoped_ptr<metrics::MetricsProvider>(new metrics::GPUMetricsProvider));
354 drive_metrics_provider_ = new DriveMetricsProvider;
355 metrics_service_->RegisterMetricsProvider(
356 scoped_ptr<metrics::MetricsProvider>(drive_metrics_provider_));
358 profiler_metrics_provider_ =
359 new metrics::ProfilerMetricsProvider(base::Bind(&IsCellularLogicEnabled));
360 metrics_service_->RegisterMetricsProvider(
361 scoped_ptr<metrics::MetricsProvider>(profiler_metrics_provider_));
363 metrics_service_->RegisterMetricsProvider(
364 scoped_ptr<metrics::MetricsProvider>(
365 new metrics::CallStackProfileMetricsProvider));
367 #if defined(OS_ANDROID)
368 metrics_service_->RegisterMetricsProvider(
369 scoped_ptr<metrics::MetricsProvider>(
370 new AndroidMetricsProvider(g_browser_process->local_state())));
371 #endif // defined(OS_ANDROID)
373 #if defined(OS_WIN)
374 google_update_metrics_provider_ = new GoogleUpdateMetricsProviderWin;
375 metrics_service_->RegisterMetricsProvider(
376 scoped_ptr<metrics::MetricsProvider>(google_update_metrics_provider_));
378 // Report exit funnels for canary and dev only.
379 bool report_exit_funnels = false;
380 switch (chrome::VersionInfo::GetChannel()) {
381 case chrome::VersionInfo::CHANNEL_CANARY:
382 case chrome::VersionInfo::CHANNEL_DEV:
383 report_exit_funnels = true;
384 break;
387 metrics_service_->RegisterMetricsProvider(
388 scoped_ptr<metrics::MetricsProvider>(
389 new browser_watcher::WatcherMetricsProviderWin(
390 chrome::kBrowserExitCodesRegistryPath, report_exit_funnels)));
391 #endif // defined(OS_WIN)
393 #if defined(ENABLE_PLUGINS)
394 plugin_metrics_provider_ =
395 new PluginMetricsProvider(g_browser_process->local_state());
396 metrics_service_->RegisterMetricsProvider(
397 scoped_ptr<metrics::MetricsProvider>(plugin_metrics_provider_));
398 #endif // defined(ENABLE_PLUGINS)
400 #if defined(OS_CHROMEOS)
401 ChromeOSMetricsProvider* chromeos_metrics_provider =
402 new ChromeOSMetricsProvider;
403 chromeos_metrics_provider_ = chromeos_metrics_provider;
404 metrics_service_->RegisterMetricsProvider(
405 scoped_ptr<metrics::MetricsProvider>(chromeos_metrics_provider));
407 SigninStatusMetricsProviderChromeOS* signin_metrics_provider_cros =
408 new SigninStatusMetricsProviderChromeOS;
409 metrics_service_->RegisterMetricsProvider(
410 scoped_ptr<metrics::MetricsProvider>(signin_metrics_provider_cros));
411 #endif // defined(OS_CHROMEOS)
413 #if !defined(OS_CHROMEOS)
414 metrics_service_->RegisterMetricsProvider(
415 scoped_ptr<metrics::MetricsProvider>(
416 SigninStatusMetricsProvider::CreateInstance()));
417 #endif // !defined(OS_CHROMEOS)
419 // Clear stability metrics if it is the first time cellular upload logic
420 // should apply to avoid sudden bulk uploads. It needs to be done after all
421 // providers are registered.
422 if (ShouldClearSavedMetrics())
423 metrics_service_->ClearSavedStabilityMetrics();
426 void ChromeMetricsServiceClient::OnInitTaskGotHardwareClass() {
427 const base::Closure got_plugin_info_callback =
428 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotPluginInfo,
429 weak_ptr_factory_.GetWeakPtr());
431 #if defined(ENABLE_PLUGINS)
432 plugin_metrics_provider_->GetPluginInformation(got_plugin_info_callback);
433 #else
434 got_plugin_info_callback.Run();
435 #endif // defined(ENABLE_PLUGINS)
438 void ChromeMetricsServiceClient::OnInitTaskGotPluginInfo() {
439 const base::Closure got_metrics_callback =
440 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData,
441 weak_ptr_factory_.GetWeakPtr());
443 #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
444 google_update_metrics_provider_->GetGoogleUpdateData(got_metrics_callback);
445 #else
446 got_metrics_callback.Run();
447 #endif // defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
450 void ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData() {
451 // Start the next part of the init task: fetching performance data. This will
452 // call into |FinishedReceivingProfilerData()| when the task completes.
453 metrics::TrackingSynchronizer::FetchProfilerDataAsynchronously(
454 weak_ptr_factory_.GetWeakPtr());
457 void ChromeMetricsServiceClient::OnWebCacheStatsRefresh(int host_id) {
458 DCHECK(thread_checker_.CalledOnValidThread());
460 auto iter = host_resource_usage_map_.find(host_id);
461 if (iter != host_resource_usage_map_.end()) {
462 blink::WebCache::ResourceTypeStats stats =
463 iter->second->GetWebCoreCacheStats();
464 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.ImagesSizeKB",
465 static_cast<int>(stats.images.size / 1024));
466 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.CSSStylesheetsSizeKB",
467 static_cast<int>(stats.cssStyleSheets.size / 1024));
468 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.ScriptsSizeKB",
469 static_cast<int>(stats.scripts.size / 1024));
470 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.XSLStylesheetsSizeKB",
471 static_cast<int>(stats.xslStyleSheets.size / 1024));
472 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.FontsSizeKB",
473 static_cast<int>(stats.fonts.size / 1024));
477 void ChromeMetricsServiceClient::ReceivedProfilerData(
478 const metrics::ProfilerDataAttributes& attributes,
479 const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase,
480 const metrics::ProfilerEvents& past_events) {
481 profiler_metrics_provider_->RecordProfilerData(
482 process_data_phase, attributes.process_id, attributes.process_type,
483 attributes.profiling_phase, attributes.phase_start - start_time_,
484 attributes.phase_finish - start_time_, past_events);
487 void ChromeMetricsServiceClient::FinishedReceivingProfilerData() {
488 drive_metrics_provider_->GetDriveMetrics(
489 finished_gathering_initial_metrics_callback_);
492 void ChromeMetricsServiceClient::OnMemoryDetailCollectionDone() {
493 DCHECK(thread_checker_.CalledOnValidThread());
495 // This function should only be called as the callback from an ansynchronous
496 // step.
497 DCHECK(waiting_for_collect_final_metrics_step_);
499 // Create a callback_task for OnHistogramSynchronizationDone.
500 base::Closure callback = base::Bind(
501 &ChromeMetricsServiceClient::OnHistogramSynchronizationDone,
502 weak_ptr_factory_.GetWeakPtr());
504 base::TimeDelta timeout =
505 base::TimeDelta::FromMilliseconds(kMaxHistogramGatheringWaitDuration);
507 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 0);
509 #if !defined(ENABLE_PRINT_PREVIEW)
510 num_async_histogram_fetches_in_progress_ = 1;
511 #else // !ENABLE_PRINT_PREVIEW
512 num_async_histogram_fetches_in_progress_ = 2;
513 // Run requests to service and content in parallel.
514 if (!ServiceProcessControl::GetInstance()->GetHistograms(callback, timeout)) {
515 // Assume |num_async_histogram_fetches_in_progress_| is not changed by
516 // |GetHistograms()|.
517 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 2);
518 // Assign |num_async_histogram_fetches_in_progress_| above and decrement it
519 // here to make code work even if |GetHistograms()| fired |callback|.
520 --num_async_histogram_fetches_in_progress_;
522 #endif // !ENABLE_PRINT_PREVIEW
524 // Set up the callback to task to call after we receive histograms from all
525 // child processes. |timeout| specifies how long to wait before absolutely
526 // calling us back on the task.
527 content::FetchHistogramsAsynchronously(base::MessageLoop::current(), callback,
528 timeout);
531 void ChromeMetricsServiceClient::OnHistogramSynchronizationDone() {
532 DCHECK(thread_checker_.CalledOnValidThread());
534 // This function should only be called as the callback from an ansynchronous
535 // step.
536 DCHECK(waiting_for_collect_final_metrics_step_);
537 DCHECK_GT(num_async_histogram_fetches_in_progress_, 0);
539 // Check if all expected requests finished.
540 if (--num_async_histogram_fetches_in_progress_ > 0)
541 return;
543 waiting_for_collect_final_metrics_step_ = false;
544 collect_final_metrics_done_callback_.Run();
547 void ChromeMetricsServiceClient::RecordCommandLineMetrics() {
548 // Get stats on use of command line.
549 const base::CommandLine* command_line(base::CommandLine::ForCurrentProcess());
550 size_t common_commands = 0;
551 if (command_line->HasSwitch(switches::kUserDataDir)) {
552 ++common_commands;
553 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineDatDirCount", 1);
556 if (command_line->HasSwitch(switches::kApp)) {
557 ++common_commands;
558 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineAppModeCount", 1);
561 // TODO(rohitrao): Should these be logged on iOS as well?
562 // http://crbug.com/375794
563 size_t switch_count = command_line->GetSwitches().size();
564 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineFlagCount", switch_count);
565 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineUncommonFlagCount",
566 switch_count - common_commands);
569 void ChromeMetricsServiceClient::RegisterForNotifications() {
570 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED,
571 content::NotificationService::AllBrowserContextsAndSources());
572 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
573 content::NotificationService::AllSources());
574 registrar_.Add(this, chrome::NOTIFICATION_TAB_PARENTED,
575 content::NotificationService::AllSources());
576 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING,
577 content::NotificationService::AllSources());
578 registrar_.Add(this, content::NOTIFICATION_LOAD_START,
579 content::NotificationService::AllSources());
580 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
581 content::NotificationService::AllSources());
582 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
583 content::NotificationService::AllSources());
584 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_HANG,
585 content::NotificationService::AllSources());
586 registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
587 content::NotificationService::AllSources());
590 void ChromeMetricsServiceClient::Observe(
591 int type,
592 const content::NotificationSource& source,
593 const content::NotificationDetails& details) {
594 DCHECK(thread_checker_.CalledOnValidThread());
596 switch (type) {
597 case chrome::NOTIFICATION_BROWSER_OPENED:
598 case chrome::NOTIFICATION_BROWSER_CLOSED:
599 case chrome::NOTIFICATION_OMNIBOX_OPENED_URL:
600 case chrome::NOTIFICATION_TAB_PARENTED:
601 case chrome::NOTIFICATION_TAB_CLOSING:
602 case content::NOTIFICATION_LOAD_STOP:
603 case content::NOTIFICATION_LOAD_START:
604 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED:
605 case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG:
606 metrics_service_->OnApplicationNotIdle();
607 break;
609 default:
610 NOTREACHED();