Allow only one bookmark to be added for multiple fast starring
[chromium-blink-merge.git] / chrome / browser / metrics / chrome_metrics_service_client.cc
blob7087add4ead1e7ff20e43a992778e47a428838e0
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/omnibox_metrics_provider.h"
24 #include "chrome/browser/metrics/time_ticks_experiment_win.h"
25 #include "chrome/browser/process_resource_usage.h"
26 #include "chrome/browser/ui/browser_otr_state.h"
27 #include "chrome/common/channel_info.h"
28 #include "chrome/common/chrome_constants.h"
29 #include "chrome/common/chrome_paths.h"
30 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/crash_keys.h"
32 #include "chrome/common/metrics/version_utils.h"
33 #include "chrome/common/pref_names.h"
34 #include "components/metrics/call_stack_profile_metrics_provider.h"
35 #include "components/metrics/drive_metrics_provider.h"
36 #include "components/metrics/gpu/gpu_metrics_provider.h"
37 #include "components/metrics/metrics_service.h"
38 #include "components/metrics/net/net_metrics_log_uploader.h"
39 #include "components/metrics/net/network_metrics_provider.h"
40 #include "components/metrics/profiler/profiler_metrics_provider.h"
41 #include "components/metrics/profiler/tracking_synchronizer.h"
42 #include "components/metrics/url_constants.h"
43 #include "components/variations/variations_associated_data.h"
44 #include "components/version_info/version_info.h"
45 #include "content/public/browser/browser_thread.h"
46 #include "content/public/browser/histogram_fetcher.h"
47 #include "content/public/browser/notification_service.h"
48 #include "content/public/browser/render_process_host.h"
49 #include "content/public/common/service_registry.h"
51 #if defined(OS_ANDROID)
52 #include "chrome/browser/metrics/android_metrics_provider.h"
53 #endif
55 #if defined(ENABLE_PRINT_PREVIEW)
56 #include "chrome/browser/service_process/service_process_control.h"
57 #endif
59 #if defined(ENABLE_EXTENSIONS)
60 #include "chrome/browser/metrics/extensions_metrics_provider.h"
61 #endif
63 #if defined(ENABLE_PLUGINS)
64 #include "chrome/browser/metrics/plugin_metrics_provider.h"
65 #endif
67 #if defined(OS_CHROMEOS)
68 #include "chrome/browser/metrics/chromeos_metrics_provider.h"
69 #include "chrome/browser/metrics/signin_status_metrics_provider_chromeos.h"
70 #endif
72 #if defined(OS_WIN)
73 #include <windows.h>
74 #include "chrome/browser/metrics/google_update_metrics_provider_win.h"
75 #include "components/browser_watcher/watcher_metrics_provider_win.h"
76 #endif
78 #if !defined(OS_CHROMEOS)
79 #include "chrome/browser/metrics/signin_status_metrics_provider.h"
80 #endif // !defined(OS_CHROMEOS)
82 namespace {
84 // This specifies the amount of time to wait for all renderers to send their
85 // data.
86 const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds.
88 // Standard interval between log uploads, in seconds.
89 #if defined(OS_ANDROID) || defined(OS_IOS)
90 const int kStandardUploadIntervalSeconds = 5 * 60; // Five minutes.
91 const int kStandardUploadIntervalCellularSeconds = 15 * 60; // Fifteen minutes.
92 #else
93 const int kStandardUploadIntervalSeconds = 30 * 60; // Thirty minutes.
94 #endif
96 // Returns true if current connection type is cellular and user is assigned to
97 // experimental group for enabled cellular uploads.
98 bool IsCellularLogicEnabled() {
99 if (variations::GetVariationParamValue("UMA_EnableCellularLogUpload",
100 "Enabled") != "true" ||
101 variations::GetVariationParamValue("UMA_EnableCellularLogUpload",
102 "Optimize") == "false") {
103 return false;
106 return net::NetworkChangeNotifier::IsConnectionCellular(
107 net::NetworkChangeNotifier::GetConnectionType());
110 // Checks whether it is the first time that cellular uploads logic should be
111 // enabled based on whether the the preference for that logic is initialized.
112 // This should happen only once as the used preference will be initialized
113 // afterwards in |UmaSessionStats.java|.
114 bool ShouldClearSavedMetrics() {
115 #if defined(OS_ANDROID)
116 PrefService* local_state = g_browser_process->local_state();
117 return !local_state->HasPrefPath(prefs::kMetricsReportingEnabled) &&
118 variations::GetVariationParamValue("UMA_EnableCellularLogUpload",
119 "Enabled") == "true";
120 #else
121 return false;
122 #endif
125 } // namespace
128 ChromeMetricsServiceClient::ChromeMetricsServiceClient(
129 metrics::MetricsStateManager* state_manager)
130 : metrics_state_manager_(state_manager),
131 chromeos_metrics_provider_(nullptr),
132 waiting_for_collect_final_metrics_step_(false),
133 num_async_histogram_fetches_in_progress_(0),
134 profiler_metrics_provider_(nullptr),
135 #if defined(ENABLE_PLUGINS)
136 plugin_metrics_provider_(nullptr),
137 #endif
138 #if defined(OS_WIN)
139 google_update_metrics_provider_(nullptr),
140 #endif
141 drive_metrics_provider_(nullptr),
142 start_time_(base::TimeTicks::Now()),
143 weak_ptr_factory_(this) {
144 DCHECK(thread_checker_.CalledOnValidThread());
145 RecordCommandLineMetrics();
146 RegisterForNotifications();
149 ChromeMetricsServiceClient::~ChromeMetricsServiceClient() {
150 DCHECK(thread_checker_.CalledOnValidThread());
153 // static
154 scoped_ptr<ChromeMetricsServiceClient> ChromeMetricsServiceClient::Create(
155 metrics::MetricsStateManager* state_manager,
156 PrefService* local_state) {
157 // Perform two-phase initialization so that |client->metrics_service_| only
158 // receives pointers to fully constructed objects.
159 scoped_ptr<ChromeMetricsServiceClient> client(
160 new ChromeMetricsServiceClient(state_manager));
161 client->Initialize();
163 return client.Pass();
166 // static
167 void ChromeMetricsServiceClient::RegisterPrefs(PrefRegistrySimple* registry) {
168 registry->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0);
169 registry->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0);
171 metrics::MetricsService::RegisterPrefs(registry);
172 ChromeStabilityMetricsProvider::RegisterPrefs(registry);
174 #if defined(OS_ANDROID)
175 AndroidMetricsProvider::RegisterPrefs(registry);
176 #endif // defined(OS_ANDROID)
178 #if defined(ENABLE_PLUGINS)
179 PluginMetricsProvider::RegisterPrefs(registry);
180 #endif // defined(ENABLE_PLUGINS)
183 void ChromeMetricsServiceClient::SetMetricsClientId(
184 const std::string& client_id) {
185 crash_keys::SetMetricsClientIdFromGUID(client_id);
188 void ChromeMetricsServiceClient::OnRecordingDisabled() {
189 crash_keys::ClearMetricsClientId();
192 bool ChromeMetricsServiceClient::IsOffTheRecordSessionActive() {
193 return chrome::IsOffTheRecordSessionActive();
196 int32 ChromeMetricsServiceClient::GetProduct() {
197 return metrics::ChromeUserMetricsExtension::CHROME;
200 std::string ChromeMetricsServiceClient::GetApplicationLocale() {
201 return g_browser_process->GetApplicationLocale();
204 bool ChromeMetricsServiceClient::GetBrand(std::string* brand_code) {
205 return google_brand::GetBrand(brand_code);
208 metrics::SystemProfileProto::Channel ChromeMetricsServiceClient::GetChannel() {
209 return metrics::AsProtobufChannel(chrome::GetChannel());
212 std::string ChromeMetricsServiceClient::GetVersionString() {
213 return metrics::GetVersionString();
216 void ChromeMetricsServiceClient::OnLogUploadComplete() {
217 // Collect time ticks stats after each UMA upload.
218 #if defined(OS_WIN)
219 chrome::CollectTimeTicksStats();
220 #endif
223 void ChromeMetricsServiceClient::StartGatheringMetrics(
224 const base::Closure& done_callback) {
225 finished_gathering_initial_metrics_callback_ = done_callback;
226 base::Closure got_hardware_class_callback =
227 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotHardwareClass,
228 weak_ptr_factory_.GetWeakPtr());
229 #if defined(OS_CHROMEOS)
230 chromeos_metrics_provider_->InitTaskGetHardwareClass(
231 got_hardware_class_callback);
232 #else
233 got_hardware_class_callback.Run();
234 #endif // defined(OS_CHROMEOS)
237 void ChromeMetricsServiceClient::CollectFinalMetrics(
238 const base::Closure& done_callback) {
239 DCHECK(thread_checker_.CalledOnValidThread());
241 collect_final_metrics_done_callback_ = done_callback;
243 // Begin the multi-step process of collecting memory usage histograms:
244 // First spawn a task to collect the memory details; when that task is
245 // finished, it will call OnMemoryDetailCollectionDone. That will in turn
246 // call HistogramSynchronization to collect histograms from all renderers and
247 // then call OnHistogramSynchronizationDone to continue processing.
248 DCHECK(!waiting_for_collect_final_metrics_step_);
249 waiting_for_collect_final_metrics_step_ = true;
251 base::Closure callback =
252 base::Bind(&ChromeMetricsServiceClient::OnMemoryDetailCollectionDone,
253 weak_ptr_factory_.GetWeakPtr());
255 scoped_refptr<MetricsMemoryDetails> details(
256 new MetricsMemoryDetails(callback, &memory_growth_tracker_));
257 details->StartFetch(MemoryDetails::FROM_CHROME_ONLY);
259 base::ScopedPtrMap<int, scoped_ptr<ProcessResourceUsage>> current_map;
260 host_resource_usage_map_.swap(current_map);
262 // Collect WebCore cache information to put into a histogram.
263 for (content::RenderProcessHost::iterator i(
264 content::RenderProcessHost::AllHostsIterator());
265 !i.IsAtEnd(); i.Advance()) {
266 content::RenderProcessHost* host = i.GetCurrentValue();
267 int host_id = host->GetID();
268 ProcessResourceUsage* resource_usage = nullptr;
269 auto iter = current_map.find(host_id);
270 if (iter != current_map.end()) {
271 resource_usage = iter->second;
272 host_resource_usage_map_.set(host_id, current_map.take_and_erase(iter));
273 } else {
274 content::ServiceRegistry* service_registry = host->GetServiceRegistry();
275 if (service_registry) {
276 ResourceUsageReporterPtr service;
277 service_registry->ConnectToRemoteService(mojo::GetProxy(&service));
278 resource_usage = new ProcessResourceUsage(service.Pass());
279 host_resource_usage_map_.set(host_id, make_scoped_ptr(resource_usage));
282 if (resource_usage) {
283 resource_usage->Refresh(
284 base::Bind(&ChromeMetricsServiceClient::OnWebCacheStatsRefresh,
285 weak_ptr_factory_.GetWeakPtr(), host_id));
290 scoped_ptr<metrics::MetricsLogUploader>
291 ChromeMetricsServiceClient::CreateUploader(
292 const base::Callback<void(int)>& on_upload_complete) {
293 return scoped_ptr<metrics::MetricsLogUploader>(
294 new metrics::NetMetricsLogUploader(
295 g_browser_process->system_request_context(),
296 metrics::kDefaultMetricsServerUrl,
297 metrics::kDefaultMetricsMimeType,
298 on_upload_complete));
301 base::TimeDelta ChromeMetricsServiceClient::GetStandardUploadInterval() {
302 #if defined(OS_ANDROID) || defined(OS_IOS)
303 if (IsCellularLogicEnabled())
304 return base::TimeDelta::FromSeconds(kStandardUploadIntervalCellularSeconds);
305 #endif
306 return base::TimeDelta::FromSeconds(kStandardUploadIntervalSeconds);
309 base::string16 ChromeMetricsServiceClient::GetRegistryBackupKey() {
310 #if defined(OS_WIN)
311 return L"Software\\" PRODUCT_STRING_PATH L"\\StabilityMetrics";
312 #else
313 return base::string16();
314 #endif
317 void ChromeMetricsServiceClient::LogPluginLoadingError(
318 const base::FilePath& plugin_path) {
319 #if defined(ENABLE_PLUGINS)
320 plugin_metrics_provider_->LogPluginLoadingError(plugin_path);
321 #else
322 NOTREACHED();
323 #endif // defined(ENABLE_PLUGINS)
326 void ChromeMetricsServiceClient::Initialize() {
327 // Clear metrics reports if it is the first time cellular upload logic should
328 // apply to avoid sudden bulk uploads. It needs to be done before initializing
329 // metrics service so that metrics log manager is initialized correctly.
330 if (ShouldClearSavedMetrics()) {
331 PrefService* local_state = g_browser_process->local_state();
332 local_state->ClearPref(metrics::prefs::kMetricsInitialLogs);
333 local_state->ClearPref(metrics::prefs::kMetricsOngoingLogs);
336 metrics_service_.reset(new metrics::MetricsService(
337 metrics_state_manager_, this, g_browser_process->local_state()));
339 // Register metrics providers.
340 #if defined(ENABLE_EXTENSIONS)
341 metrics_service_->RegisterMetricsProvider(
342 scoped_ptr<metrics::MetricsProvider>(
343 new ExtensionsMetricsProvider(metrics_state_manager_)));
344 #endif
345 metrics_service_->RegisterMetricsProvider(
346 scoped_ptr<metrics::MetricsProvider>(new metrics::NetworkMetricsProvider(
347 content::BrowserThread::GetBlockingPool())));
349 metrics_service_->RegisterMetricsProvider(
350 scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider));
351 metrics_service_->RegisterMetricsProvider(
352 scoped_ptr<metrics::MetricsProvider>(new ChromeStabilityMetricsProvider));
353 metrics_service_->RegisterMetricsProvider(
354 scoped_ptr<metrics::MetricsProvider>(new metrics::GPUMetricsProvider));
356 drive_metrics_provider_ = new metrics::DriveMetricsProvider(
357 content::BrowserThread::GetMessageLoopProxyForThread(
358 content::BrowserThread::FILE),
359 chrome::FILE_LOCAL_STATE);
360 metrics_service_->RegisterMetricsProvider(
361 scoped_ptr<metrics::MetricsProvider>(drive_metrics_provider_));
363 profiler_metrics_provider_ =
364 new metrics::ProfilerMetricsProvider(base::Bind(&IsCellularLogicEnabled));
365 metrics_service_->RegisterMetricsProvider(
366 scoped_ptr<metrics::MetricsProvider>(profiler_metrics_provider_));
368 metrics_service_->RegisterMetricsProvider(
369 scoped_ptr<metrics::MetricsProvider>(
370 new metrics::CallStackProfileMetricsProvider));
372 #if defined(OS_ANDROID)
373 metrics_service_->RegisterMetricsProvider(
374 scoped_ptr<metrics::MetricsProvider>(
375 new AndroidMetricsProvider(g_browser_process->local_state())));
376 #endif // defined(OS_ANDROID)
378 #if defined(OS_WIN)
379 google_update_metrics_provider_ = new GoogleUpdateMetricsProviderWin;
380 metrics_service_->RegisterMetricsProvider(
381 scoped_ptr<metrics::MetricsProvider>(google_update_metrics_provider_));
383 // Report exit funnels for canary and dev only.
384 bool report_exit_funnels = false;
385 switch (chrome::GetChannel()) {
386 case version_info::Channel::CANARY:
387 case version_info::Channel::DEV:
388 report_exit_funnels = true;
389 break;
392 metrics_service_->RegisterMetricsProvider(
393 scoped_ptr<metrics::MetricsProvider>(
394 new browser_watcher::WatcherMetricsProviderWin(
395 chrome::kBrowserExitCodesRegistryPath, report_exit_funnels)));
396 #endif // defined(OS_WIN)
398 #if defined(ENABLE_PLUGINS)
399 plugin_metrics_provider_ =
400 new PluginMetricsProvider(g_browser_process->local_state());
401 metrics_service_->RegisterMetricsProvider(
402 scoped_ptr<metrics::MetricsProvider>(plugin_metrics_provider_));
403 #endif // defined(ENABLE_PLUGINS)
405 #if defined(OS_CHROMEOS)
406 ChromeOSMetricsProvider* chromeos_metrics_provider =
407 new ChromeOSMetricsProvider;
408 chromeos_metrics_provider_ = chromeos_metrics_provider;
409 metrics_service_->RegisterMetricsProvider(
410 scoped_ptr<metrics::MetricsProvider>(chromeos_metrics_provider));
412 SigninStatusMetricsProviderChromeOS* signin_metrics_provider_cros =
413 new SigninStatusMetricsProviderChromeOS;
414 metrics_service_->RegisterMetricsProvider(
415 scoped_ptr<metrics::MetricsProvider>(signin_metrics_provider_cros));
416 #endif // defined(OS_CHROMEOS)
418 #if !defined(OS_CHROMEOS)
419 metrics_service_->RegisterMetricsProvider(
420 scoped_ptr<metrics::MetricsProvider>(
421 SigninStatusMetricsProvider::CreateInstance()));
422 #endif // !defined(OS_CHROMEOS)
424 // Clear stability metrics if it is the first time cellular upload logic
425 // should apply to avoid sudden bulk uploads. It needs to be done after all
426 // providers are registered.
427 if (ShouldClearSavedMetrics())
428 metrics_service_->ClearSavedStabilityMetrics();
431 void ChromeMetricsServiceClient::OnInitTaskGotHardwareClass() {
432 const base::Closure got_plugin_info_callback =
433 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotPluginInfo,
434 weak_ptr_factory_.GetWeakPtr());
436 #if defined(ENABLE_PLUGINS)
437 plugin_metrics_provider_->GetPluginInformation(got_plugin_info_callback);
438 #else
439 got_plugin_info_callback.Run();
440 #endif // defined(ENABLE_PLUGINS)
443 void ChromeMetricsServiceClient::OnInitTaskGotPluginInfo() {
444 const base::Closure got_metrics_callback =
445 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData,
446 weak_ptr_factory_.GetWeakPtr());
448 #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
449 google_update_metrics_provider_->GetGoogleUpdateData(got_metrics_callback);
450 #else
451 got_metrics_callback.Run();
452 #endif // defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
455 void ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData() {
456 // Start the next part of the init task: fetching performance data. This will
457 // call into |FinishedReceivingProfilerData()| when the task completes.
458 metrics::TrackingSynchronizer::FetchProfilerDataAsynchronously(
459 weak_ptr_factory_.GetWeakPtr());
462 void ChromeMetricsServiceClient::OnWebCacheStatsRefresh(int host_id) {
463 DCHECK(thread_checker_.CalledOnValidThread());
465 auto iter = host_resource_usage_map_.find(host_id);
466 if (iter != host_resource_usage_map_.end()) {
467 blink::WebCache::ResourceTypeStats stats =
468 iter->second->GetWebCoreCacheStats();
469 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.ImagesSizeKB",
470 static_cast<int>(stats.images.size / 1024));
471 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.CSSStylesheetsSizeKB",
472 static_cast<int>(stats.cssStyleSheets.size / 1024));
473 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.ScriptsSizeKB",
474 static_cast<int>(stats.scripts.size / 1024));
475 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.XSLStylesheetsSizeKB",
476 static_cast<int>(stats.xslStyleSheets.size / 1024));
477 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.FontsSizeKB",
478 static_cast<int>(stats.fonts.size / 1024));
482 void ChromeMetricsServiceClient::ReceivedProfilerData(
483 const metrics::ProfilerDataAttributes& attributes,
484 const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase,
485 const metrics::ProfilerEvents& past_events) {
486 profiler_metrics_provider_->RecordProfilerData(
487 process_data_phase, attributes.process_id, attributes.process_type,
488 attributes.profiling_phase, attributes.phase_start - start_time_,
489 attributes.phase_finish - start_time_, past_events);
492 void ChromeMetricsServiceClient::FinishedReceivingProfilerData() {
493 drive_metrics_provider_->GetDriveMetrics(
494 finished_gathering_initial_metrics_callback_);
497 void ChromeMetricsServiceClient::OnMemoryDetailCollectionDone() {
498 DCHECK(thread_checker_.CalledOnValidThread());
500 // This function should only be called as the callback from an ansynchronous
501 // step.
502 DCHECK(waiting_for_collect_final_metrics_step_);
504 // Create a callback_task for OnHistogramSynchronizationDone.
505 base::Closure callback = base::Bind(
506 &ChromeMetricsServiceClient::OnHistogramSynchronizationDone,
507 weak_ptr_factory_.GetWeakPtr());
509 base::TimeDelta timeout =
510 base::TimeDelta::FromMilliseconds(kMaxHistogramGatheringWaitDuration);
512 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 0);
514 #if !defined(ENABLE_PRINT_PREVIEW)
515 num_async_histogram_fetches_in_progress_ = 1;
516 #else // !ENABLE_PRINT_PREVIEW
517 num_async_histogram_fetches_in_progress_ = 2;
518 // Run requests to service and content in parallel.
519 if (!ServiceProcessControl::GetInstance()->GetHistograms(callback, timeout)) {
520 // Assume |num_async_histogram_fetches_in_progress_| is not changed by
521 // |GetHistograms()|.
522 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 2);
523 // Assign |num_async_histogram_fetches_in_progress_| above and decrement it
524 // here to make code work even if |GetHistograms()| fired |callback|.
525 --num_async_histogram_fetches_in_progress_;
527 #endif // !ENABLE_PRINT_PREVIEW
529 // Set up the callback to task to call after we receive histograms from all
530 // child processes. |timeout| specifies how long to wait before absolutely
531 // calling us back on the task.
532 content::FetchHistogramsAsynchronously(base::MessageLoop::current(), callback,
533 timeout);
536 void ChromeMetricsServiceClient::OnHistogramSynchronizationDone() {
537 DCHECK(thread_checker_.CalledOnValidThread());
539 // This function should only be called as the callback from an ansynchronous
540 // step.
541 DCHECK(waiting_for_collect_final_metrics_step_);
542 DCHECK_GT(num_async_histogram_fetches_in_progress_, 0);
544 // Check if all expected requests finished.
545 if (--num_async_histogram_fetches_in_progress_ > 0)
546 return;
548 waiting_for_collect_final_metrics_step_ = false;
549 collect_final_metrics_done_callback_.Run();
552 void ChromeMetricsServiceClient::RecordCommandLineMetrics() {
553 // Get stats on use of command line.
554 const base::CommandLine* command_line(base::CommandLine::ForCurrentProcess());
555 size_t common_commands = 0;
556 if (command_line->HasSwitch(switches::kUserDataDir)) {
557 ++common_commands;
558 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineDatDirCount", 1);
561 if (command_line->HasSwitch(switches::kApp)) {
562 ++common_commands;
563 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineAppModeCount", 1);
566 // TODO(rohitrao): Should these be logged on iOS as well?
567 // http://crbug.com/375794
568 size_t switch_count = command_line->GetSwitches().size();
569 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineFlagCount", switch_count);
570 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineUncommonFlagCount",
571 switch_count - common_commands);
574 void ChromeMetricsServiceClient::RegisterForNotifications() {
575 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_OPENED,
576 content::NotificationService::AllBrowserContextsAndSources());
577 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
578 content::NotificationService::AllSources());
579 registrar_.Add(this, chrome::NOTIFICATION_TAB_PARENTED,
580 content::NotificationService::AllSources());
581 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING,
582 content::NotificationService::AllSources());
583 registrar_.Add(this, content::NOTIFICATION_LOAD_START,
584 content::NotificationService::AllSources());
585 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
586 content::NotificationService::AllSources());
587 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
588 content::NotificationService::AllSources());
589 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_HANG,
590 content::NotificationService::AllSources());
591 registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
592 content::NotificationService::AllSources());
595 void ChromeMetricsServiceClient::Observe(
596 int type,
597 const content::NotificationSource& source,
598 const content::NotificationDetails& details) {
599 DCHECK(thread_checker_.CalledOnValidThread());
601 switch (type) {
602 case chrome::NOTIFICATION_BROWSER_OPENED:
603 case chrome::NOTIFICATION_BROWSER_CLOSED:
604 case chrome::NOTIFICATION_OMNIBOX_OPENED_URL:
605 case chrome::NOTIFICATION_TAB_PARENTED:
606 case chrome::NOTIFICATION_TAB_CLOSING:
607 case content::NOTIFICATION_LOAD_STOP:
608 case content::NOTIFICATION_LOAD_START:
609 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED:
610 case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG:
611 metrics_service_->OnApplicationNotIdle();
612 break;
614 default:
615 NOTREACHED();