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"
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/rand_util.h"
18 #include "base/strings/string16.h"
19 #include "base/threading/platform_thread.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chrome_notification_types.h"
22 #include "chrome/browser/google/google_brand.h"
23 #include "chrome/browser/metrics/chrome_stability_metrics_provider.h"
24 #include "chrome/browser/metrics/time_ticks_experiment_win.h"
25 #include "chrome/browser/ui/browser_otr_state.h"
26 #include "chrome/common/channel_info.h"
27 #include "chrome/common/chrome_constants.h"
28 #include "chrome/common/chrome_paths.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 "components/metrics/call_stack_profile_metrics_provider.h"
34 #include "components/metrics/drive_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/omnibox/browser/omnibox_metrics_provider.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"
49 #if defined(OS_ANDROID)
50 #include "chrome/browser/metrics/android_metrics_provider.h"
53 #if defined(ENABLE_PRINT_PREVIEW)
54 #include "chrome/browser/service_process/service_process_control.h"
57 #if defined(ENABLE_EXTENSIONS)
58 #include "chrome/browser/metrics/extensions_metrics_provider.h"
61 #if defined(ENABLE_PLUGINS)
62 #include "chrome/browser/metrics/plugin_metrics_provider.h"
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"
72 #include "chrome/browser/metrics/google_update_metrics_provider_win.h"
73 #include "components/browser_watcher/watcher_metrics_provider_win.h"
76 #if !defined(OS_CHROMEOS)
77 #include "chrome/browser/metrics/signin_status_metrics_provider.h"
78 #endif // !defined(OS_CHROMEOS)
82 // This specifies the amount of time to wait for all renderers to send their
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.
91 const int kStandardUploadIntervalSeconds
= 30 * 60; // Thirty minutes.
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") {
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";
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),
137 google_update_metrics_provider_(nullptr),
139 drive_metrics_provider_(nullptr),
140 start_time_(base::TimeTicks::Now()),
141 has_uploaded_profiler_data_(false),
142 weak_ptr_factory_(this) {
143 DCHECK(thread_checker_
.CalledOnValidThread());
144 RecordCommandLineMetrics();
145 RegisterForNotifications();
148 ChromeMetricsServiceClient::~ChromeMetricsServiceClient() {
149 DCHECK(thread_checker_
.CalledOnValidThread());
153 scoped_ptr
<ChromeMetricsServiceClient
> ChromeMetricsServiceClient::Create(
154 metrics::MetricsStateManager
* state_manager
,
155 PrefService
* local_state
) {
156 // Perform two-phase initialization so that |client->metrics_service_| only
157 // receives pointers to fully constructed objects.
158 scoped_ptr
<ChromeMetricsServiceClient
> client(
159 new ChromeMetricsServiceClient(state_manager
));
160 client
->Initialize();
162 return client
.Pass();
166 void ChromeMetricsServiceClient::RegisterPrefs(PrefRegistrySimple
* registry
) {
167 registry
->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec
, 0);
168 registry
->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec
, 0);
170 metrics::MetricsService::RegisterPrefs(registry
);
171 ChromeStabilityMetricsProvider::RegisterPrefs(registry
);
173 #if defined(OS_ANDROID)
174 AndroidMetricsProvider::RegisterPrefs(registry
);
175 #endif // defined(OS_ANDROID)
177 #if defined(ENABLE_PLUGINS)
178 PluginMetricsProvider::RegisterPrefs(registry
);
179 #endif // defined(ENABLE_PLUGINS)
182 void ChromeMetricsServiceClient::SetMetricsClientId(
183 const std::string
& client_id
) {
184 crash_keys::SetMetricsClientIdFromGUID(client_id
);
187 void ChromeMetricsServiceClient::OnRecordingDisabled() {
188 crash_keys::ClearMetricsClientId();
191 bool ChromeMetricsServiceClient::IsOffTheRecordSessionActive() {
192 return chrome::IsOffTheRecordSessionActive();
195 int32
ChromeMetricsServiceClient::GetProduct() {
196 return metrics::ChromeUserMetricsExtension::CHROME
;
199 std::string
ChromeMetricsServiceClient::GetApplicationLocale() {
200 return g_browser_process
->GetApplicationLocale();
203 bool ChromeMetricsServiceClient::GetBrand(std::string
* brand_code
) {
204 return google_brand::GetBrand(brand_code
);
207 metrics::SystemProfileProto::Channel
ChromeMetricsServiceClient::GetChannel() {
208 return metrics::AsProtobufChannel(chrome::GetChannel());
211 std::string
ChromeMetricsServiceClient::GetVersionString() {
212 return metrics::GetVersionString();
215 void ChromeMetricsServiceClient::OnLogUploadComplete() {
216 // Collect time ticks stats after each UMA upload.
218 chrome::CollectTimeTicksStats();
222 void ChromeMetricsServiceClient::InitializeSystemProfileMetrics(
223 const base::Closure
& done_callback
) {
224 finished_init_task_callback_
= done_callback
;
225 base::Closure got_hardware_class_callback
=
226 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotHardwareClass
,
227 weak_ptr_factory_
.GetWeakPtr());
228 #if defined(OS_CHROMEOS)
229 chromeos_metrics_provider_
->InitTaskGetHardwareClass(
230 got_hardware_class_callback
);
232 got_hardware_class_callback
.Run();
233 #endif // defined(OS_CHROMEOS)
236 void ChromeMetricsServiceClient::CollectFinalMetricsForLog(
237 const base::Closure
& done_callback
) {
238 DCHECK(thread_checker_
.CalledOnValidThread());
240 collect_final_metrics_done_callback_
= done_callback
;
242 if (ShouldIncludeProfilerDataInLog()) {
243 // Fetch profiler data. This will call into
244 // |FinishedReceivingProfilerData()| when the task completes.
245 metrics::TrackingSynchronizer::FetchProfilerDataAsynchronously(
246 weak_ptr_factory_
.GetWeakPtr());
248 CollectFinalHistograms();
252 scoped_ptr
<metrics::MetricsLogUploader
>
253 ChromeMetricsServiceClient::CreateUploader(
254 const base::Callback
<void(int)>& on_upload_complete
) {
255 return scoped_ptr
<metrics::MetricsLogUploader
>(
256 new metrics::NetMetricsLogUploader(
257 g_browser_process
->system_request_context(),
258 metrics::kDefaultMetricsServerUrl
,
259 metrics::kDefaultMetricsMimeType
,
260 on_upload_complete
));
263 base::TimeDelta
ChromeMetricsServiceClient::GetStandardUploadInterval() {
264 #if defined(OS_ANDROID) || defined(OS_IOS)
265 if (IsCellularLogicEnabled())
266 return base::TimeDelta::FromSeconds(kStandardUploadIntervalCellularSeconds
);
268 return base::TimeDelta::FromSeconds(kStandardUploadIntervalSeconds
);
271 base::string16
ChromeMetricsServiceClient::GetRegistryBackupKey() {
273 return L
"Software\\" PRODUCT_STRING_PATH L
"\\StabilityMetrics";
275 return base::string16();
279 void ChromeMetricsServiceClient::LogPluginLoadingError(
280 const base::FilePath
& plugin_path
) {
281 #if defined(ENABLE_PLUGINS)
282 plugin_metrics_provider_
->LogPluginLoadingError(plugin_path
);
285 #endif // defined(ENABLE_PLUGINS)
288 void ChromeMetricsServiceClient::Initialize() {
289 // Clear metrics reports if it is the first time cellular upload logic should
290 // apply to avoid sudden bulk uploads. It needs to be done before initializing
291 // metrics service so that metrics log manager is initialized correctly.
292 if (ShouldClearSavedMetrics()) {
293 PrefService
* local_state
= g_browser_process
->local_state();
294 local_state
->ClearPref(metrics::prefs::kMetricsInitialLogs
);
295 local_state
->ClearPref(metrics::prefs::kMetricsOngoingLogs
);
298 metrics_service_
.reset(new metrics::MetricsService(
299 metrics_state_manager_
, this, g_browser_process
->local_state()));
301 // Register metrics providers.
302 #if defined(ENABLE_EXTENSIONS)
303 metrics_service_
->RegisterMetricsProvider(
304 scoped_ptr
<metrics::MetricsProvider
>(
305 new ExtensionsMetricsProvider(metrics_state_manager_
)));
307 metrics_service_
->RegisterMetricsProvider(
308 scoped_ptr
<metrics::MetricsProvider
>(new metrics::NetworkMetricsProvider(
309 content::BrowserThread::GetBlockingPool())));
311 // Currently, we configure OmniboxMetricsProvider to not log events to UMA
312 // if there is a single incognito session visible. In the future, it may
313 // be worth revisiting this to still log events from non-incognito sessions.
314 metrics_service_
->RegisterMetricsProvider(
315 scoped_ptr
<metrics::MetricsProvider
>(new OmniboxMetricsProvider(
316 base::Bind(&chrome::IsOffTheRecordSessionActive
))));
317 metrics_service_
->RegisterMetricsProvider(
318 scoped_ptr
<metrics::MetricsProvider
>(new ChromeStabilityMetricsProvider(
319 g_browser_process
->local_state())));
320 metrics_service_
->RegisterMetricsProvider(
321 scoped_ptr
<metrics::MetricsProvider
>(new metrics::GPUMetricsProvider
));
323 drive_metrics_provider_
= new metrics::DriveMetricsProvider(
324 content::BrowserThread::GetMessageLoopProxyForThread(
325 content::BrowserThread::FILE),
326 chrome::FILE_LOCAL_STATE
);
327 metrics_service_
->RegisterMetricsProvider(
328 scoped_ptr
<metrics::MetricsProvider
>(drive_metrics_provider_
));
330 profiler_metrics_provider_
=
331 new metrics::ProfilerMetricsProvider(base::Bind(&IsCellularLogicEnabled
));
332 metrics_service_
->RegisterMetricsProvider(
333 scoped_ptr
<metrics::MetricsProvider
>(profiler_metrics_provider_
));
335 metrics_service_
->RegisterMetricsProvider(
336 scoped_ptr
<metrics::MetricsProvider
>(
337 new metrics::CallStackProfileMetricsProvider
));
339 #if defined(OS_ANDROID)
340 metrics_service_
->RegisterMetricsProvider(
341 scoped_ptr
<metrics::MetricsProvider
>(
342 new AndroidMetricsProvider(g_browser_process
->local_state())));
343 #endif // defined(OS_ANDROID)
346 google_update_metrics_provider_
= new GoogleUpdateMetricsProviderWin
;
347 metrics_service_
->RegisterMetricsProvider(
348 scoped_ptr
<metrics::MetricsProvider
>(google_update_metrics_provider_
));
350 // Report exit funnels for canary and dev only.
351 bool report_exit_funnels
= false;
352 switch (chrome::GetChannel()) {
353 case version_info::Channel::CANARY
:
354 case version_info::Channel::DEV
:
355 report_exit_funnels
= true;
357 case version_info::Channel::UNKNOWN
:
358 case version_info::Channel::BETA
:
359 case version_info::Channel::STABLE
:
360 // report_exit_funnels was initialized to the right value above.
361 DCHECK(!report_exit_funnels
);
365 metrics_service_
->RegisterMetricsProvider(
366 scoped_ptr
<metrics::MetricsProvider
>(
367 new browser_watcher::WatcherMetricsProviderWin(
368 chrome::kBrowserExitCodesRegistryPath
, report_exit_funnels
)));
369 #endif // defined(OS_WIN)
371 #if defined(ENABLE_PLUGINS)
372 plugin_metrics_provider_
=
373 new PluginMetricsProvider(g_browser_process
->local_state());
374 metrics_service_
->RegisterMetricsProvider(
375 scoped_ptr
<metrics::MetricsProvider
>(plugin_metrics_provider_
));
376 #endif // defined(ENABLE_PLUGINS)
378 #if defined(OS_CHROMEOS)
379 ChromeOSMetricsProvider
* chromeos_metrics_provider
=
380 new ChromeOSMetricsProvider
;
381 chromeos_metrics_provider_
= chromeos_metrics_provider
;
382 metrics_service_
->RegisterMetricsProvider(
383 scoped_ptr
<metrics::MetricsProvider
>(chromeos_metrics_provider
));
385 SigninStatusMetricsProviderChromeOS
* signin_metrics_provider_cros
=
386 new SigninStatusMetricsProviderChromeOS
;
387 metrics_service_
->RegisterMetricsProvider(
388 scoped_ptr
<metrics::MetricsProvider
>(signin_metrics_provider_cros
));
389 #endif // defined(OS_CHROMEOS)
391 #if !defined(OS_CHROMEOS)
392 metrics_service_
->RegisterMetricsProvider(
393 scoped_ptr
<metrics::MetricsProvider
>(
394 SigninStatusMetricsProvider::CreateInstance()));
395 #endif // !defined(OS_CHROMEOS)
397 // Clear stability metrics if it is the first time cellular upload logic
398 // should apply to avoid sudden bulk uploads. It needs to be done after all
399 // providers are registered.
400 if (ShouldClearSavedMetrics())
401 metrics_service_
->ClearSavedStabilityMetrics();
404 void ChromeMetricsServiceClient::OnInitTaskGotHardwareClass() {
405 const base::Closure got_plugin_info_callback
=
406 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotPluginInfo
,
407 weak_ptr_factory_
.GetWeakPtr());
409 #if defined(ENABLE_PLUGINS)
410 plugin_metrics_provider_
->GetPluginInformation(got_plugin_info_callback
);
412 got_plugin_info_callback
.Run();
413 #endif // defined(ENABLE_PLUGINS)
416 void ChromeMetricsServiceClient::OnInitTaskGotPluginInfo() {
417 const base::Closure got_metrics_callback
=
418 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData
,
419 weak_ptr_factory_
.GetWeakPtr());
421 #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
422 google_update_metrics_provider_
->GetGoogleUpdateData(got_metrics_callback
);
424 got_metrics_callback
.Run();
425 #endif // defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
428 void ChromeMetricsServiceClient::OnInitTaskGotGoogleUpdateData() {
429 drive_metrics_provider_
->GetDriveMetrics(
430 base::Bind(&ChromeMetricsServiceClient::OnInitTaskGotDriveMetrics
,
431 weak_ptr_factory_
.GetWeakPtr()));
434 void ChromeMetricsServiceClient::OnInitTaskGotDriveMetrics() {
435 finished_init_task_callback_
.Run();
438 bool ChromeMetricsServiceClient::ShouldIncludeProfilerDataInLog() {
439 // Upload profiler data at most once per session.
440 if (has_uploaded_profiler_data_
)
443 // For each log, flip a fair coin. Thus, profiler data is sent with the first
444 // log with probability 50%, with the second log with probability 25%, and so
445 // on. As a result, uploaded data is biased toward earlier logs.
446 // TODO(isherman): Explore other possible algorithms, and choose one that
447 // might be more appropriate. For example, it might be reasonable to include
448 // profiler data with some fixed probability, so that a given client might
449 // upload profiler data more than once; but on average, clients won't upload
451 if (base::RandDouble() < 0.5)
454 has_uploaded_profiler_data_
= true;
458 void ChromeMetricsServiceClient::ReceivedProfilerData(
459 const metrics::ProfilerDataAttributes
& attributes
,
460 const tracked_objects::ProcessDataPhaseSnapshot
& process_data_phase
,
461 const metrics::ProfilerEvents
& past_events
) {
462 profiler_metrics_provider_
->RecordProfilerData(
463 process_data_phase
, attributes
.process_id
, attributes
.process_type
,
464 attributes
.profiling_phase
, attributes
.phase_start
- start_time_
,
465 attributes
.phase_finish
- start_time_
, past_events
);
468 void ChromeMetricsServiceClient::FinishedReceivingProfilerData() {
469 CollectFinalHistograms();
472 void ChromeMetricsServiceClient::CollectFinalHistograms() {
473 DCHECK(thread_checker_
.CalledOnValidThread());
475 // Begin the multi-step process of collecting memory usage histograms:
476 // First spawn a task to collect the memory details; when that task is
477 // finished, it will call OnMemoryDetailCollectionDone. That will in turn
478 // call HistogramSynchronization to collect histograms from all renderers and
479 // then call OnHistogramSynchronizationDone to continue processing.
480 DCHECK(!waiting_for_collect_final_metrics_step_
);
481 waiting_for_collect_final_metrics_step_
= true;
483 base::Closure callback
=
484 base::Bind(&ChromeMetricsServiceClient::OnMemoryDetailCollectionDone
,
485 weak_ptr_factory_
.GetWeakPtr());
487 scoped_refptr
<MetricsMemoryDetails
> details(
488 new MetricsMemoryDetails(callback
, &memory_growth_tracker_
));
489 details
->StartFetch(MemoryDetails::FROM_CHROME_ONLY
);
492 void ChromeMetricsServiceClient::OnMemoryDetailCollectionDone() {
493 DCHECK(thread_checker_
.CalledOnValidThread());
495 // This function should only be called as the callback from an ansynchronous
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
,
531 void ChromeMetricsServiceClient::OnHistogramSynchronizationDone() {
532 DCHECK(thread_checker_
.CalledOnValidThread());
534 // This function should only be called as the callback from an ansynchronous
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)
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
)) {
553 UMA_HISTOGRAM_COUNTS_100("Chrome.CommandLineDatDirCount", 1);
556 if (command_line
->HasSwitch(switches::kApp
)) {
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());
587 omnibox_url_opened_subscription_
=
588 OmniboxEventGlobalTracker::GetInstance()->RegisterCallback(
589 base::Bind(&ChromeMetricsServiceClient::OnURLOpenedFromOmnibox
,
590 base::Unretained(this)));
593 void ChromeMetricsServiceClient::Observe(
595 const content::NotificationSource
& source
,
596 const content::NotificationDetails
& details
) {
597 DCHECK(thread_checker_
.CalledOnValidThread());
600 case chrome::NOTIFICATION_BROWSER_OPENED
:
601 case chrome::NOTIFICATION_BROWSER_CLOSED
:
602 case chrome::NOTIFICATION_TAB_PARENTED
:
603 case chrome::NOTIFICATION_TAB_CLOSING
:
604 case content::NOTIFICATION_LOAD_STOP
:
605 case content::NOTIFICATION_LOAD_START
:
606 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED
:
607 case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG
:
608 metrics_service_
->OnApplicationNotIdle();
616 void ChromeMetricsServiceClient::OnURLOpenedFromOmnibox(OmniboxLog
* log
) {
617 metrics_service_
->OnApplicationNotIdle();