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/metrics_services_manager.h"
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "base/prefs/pref_service.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
14 #include "chrome/browser/metrics/chrome_metrics_service_client.h"
15 #include "chrome/browser/metrics/metrics_reporting_state.h"
16 #include "chrome/browser/metrics/variations/variations_service.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/ui/browser_otr_state.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/pref_names.h"
22 #include "chrome/installer/util/google_update_settings.h"
23 #include "components/metrics/metrics_service.h"
24 #include "components/metrics/metrics_state_manager.h"
25 #include "components/rappor/rappor_pref_names.h"
26 #include "components/rappor/rappor_service.h"
27 #include "content/public/browser/browser_thread.h"
29 #if defined(OS_CHROMEOS)
30 #include "chrome/browser/chromeos/settings/cros_settings.h"
35 // Check if the safe browsing setting is enabled for all existing profiles.
36 bool CheckSafeBrowsingSettings() {
37 bool all_enabled
= true;
38 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
39 if (profile_manager
) {
40 std::vector
<Profile
*> profiles
= profile_manager
->GetLoadedProfiles();
41 for (Profile
* profile
: profiles
) {
42 if (profile
->IsOffTheRecord())
44 all_enabled
= all_enabled
&& profile
->GetPrefs()->GetBoolean(
45 prefs::kSafeBrowsingEnabled
);
51 // Posts |GoogleUpdateSettings::StoreMetricsClientInfo| on blocking pool thread
52 // because it needs access to IO and cannot work from UI thread.
53 void PostStoreMetricsClientInfo(const metrics::ClientInfo
& client_info
) {
54 content::BrowserThread::GetBlockingPool()->PostTask(FROM_HERE
,
55 base::Bind(&GoogleUpdateSettings::StoreMetricsClientInfo
, client_info
));
60 MetricsServicesManager::MetricsServicesManager(PrefService
* local_state
)
61 : local_state_(local_state
),
65 pref_change_registrar_
.Init(local_state
);
68 MetricsServicesManager::~MetricsServicesManager() {
71 metrics::MetricsService
* MetricsServicesManager::GetMetricsService() {
72 DCHECK(thread_checker_
.CalledOnValidThread());
73 return GetChromeMetricsServiceClient()->metrics_service();
76 rappor::RapporService
* MetricsServicesManager::GetRapporService() {
77 DCHECK(thread_checker_
.CalledOnValidThread());
78 if (!rappor_service_
) {
79 rappor_service_
.reset(new rappor::RapporService(
80 local_state_
, base::Bind(&chrome::IsOffTheRecordSessionActive
)));
81 rappor_service_
->Initialize(g_browser_process
->system_request_context());
83 return rappor_service_
.get();
86 chrome_variations::VariationsService
*
87 MetricsServicesManager::GetVariationsService() {
88 DCHECK(thread_checker_
.CalledOnValidThread());
89 if (!variations_service_
) {
91 chrome_variations::VariationsService::Create(local_state_
,
92 GetMetricsStateManager());
94 return variations_service_
.get();
97 void MetricsServicesManager::OnPluginLoadingError(
98 const base::FilePath
& plugin_path
) {
99 GetChromeMetricsServiceClient()->LogPluginLoadingError(plugin_path
);
102 ChromeMetricsServiceClient
*
103 MetricsServicesManager::GetChromeMetricsServiceClient() {
104 DCHECK(thread_checker_
.CalledOnValidThread());
105 if (!metrics_service_client_
) {
106 metrics_service_client_
= ChromeMetricsServiceClient::Create(
107 GetMetricsStateManager(), local_state_
);
109 return metrics_service_client_
.get();
112 metrics::MetricsStateManager
* MetricsServicesManager::GetMetricsStateManager() {
113 DCHECK(thread_checker_
.CalledOnValidThread());
114 if (!metrics_state_manager_
) {
115 metrics_state_manager_
= metrics::MetricsStateManager::Create(
117 base::Bind(&ChromeMetricsServiceAccessor::IsMetricsReportingEnabled
),
118 base::Bind(&PostStoreMetricsClientInfo
),
119 base::Bind(&GoogleUpdateSettings::LoadMetricsClientInfo
));
121 return metrics_state_manager_
.get();
124 bool MetricsServicesManager::IsRapporEnabled(bool metrics_enabled
) const {
125 if (!local_state_
->HasPrefPath(rappor::prefs::kRapporEnabled
)) {
126 // For upgrading users, derive an initial setting from UMA / safe browsing.
127 bool should_enable
= metrics_enabled
|| CheckSafeBrowsingSettings();
128 local_state_
->SetBoolean(rappor::prefs::kRapporEnabled
, should_enable
);
130 return local_state_
->GetBoolean(rappor::prefs::kRapporEnabled
);
133 rappor::RecordingLevel
MetricsServicesManager::GetRapporRecordingLevel(
134 bool metrics_enabled
) const {
135 rappor::RecordingLevel recording_level
= rappor::RECORDING_DISABLED
;
136 #if defined(GOOGLE_CHROME_BUILD)
137 if (HasRapporOption()) {
138 if (IsRapporEnabled(metrics_enabled
)) {
139 recording_level
= metrics_enabled
?
141 rappor::COARSE_LEVEL
;
143 } else if (metrics_enabled
) {
144 recording_level
= rappor::FINE_LEVEL
;
146 #endif // defined(GOOGLE_CHROME_BUILD)
147 return recording_level
;
150 void MetricsServicesManager::UpdateRapporService() {
151 GetRapporService()->Update(GetRapporRecordingLevel(may_record_
), may_upload_
);
152 // The first time this function is called, we can start listening for
153 // changes to RAPPOR option. This avoids starting the RapporService in
154 // tests which do not intend to start services.
155 if (pref_change_registrar_
.IsEmpty() && HasRapporOption()) {
156 pref_change_registrar_
.Add(rappor::prefs::kRapporEnabled
,
157 base::Bind(&MetricsServicesManager::UpdateRapporService
,
158 base::Unretained(this)));
162 void MetricsServicesManager::UpdatePermissions(bool may_record
,
164 // Stash the current permissions so that we can update the RapporService
165 // correctly when the Rappor preference changes. The metrics recording
166 // preference partially determines the initial rappor setting, and also
167 // controls whether FINE metrics are sent.
168 may_record_
= may_record
;
169 may_upload_
= may_upload
;
171 metrics::MetricsService
* metrics
= GetMetricsService();
173 const base::CommandLine
* cmdline
= base::CommandLine::ForCurrentProcess();
175 const bool only_do_metrics_recording
=
176 cmdline
->HasSwitch(switches::kMetricsRecordingOnly
) ||
177 cmdline
->HasSwitch(switches::kEnableBenchmarking
);
179 if (only_do_metrics_recording
) {
180 metrics
->StartRecordingForTests();
181 GetRapporService()->Update(rappor::FINE_LEVEL
, false);
186 if (!metrics
->recording_active())
190 metrics
->EnableReporting();
192 metrics
->DisableReporting();
193 } else if (metrics
->recording_active() || metrics
->reporting_active()) {
197 UpdateRapporService();
200 void MetricsServicesManager::UpdateUploadPermissions(bool may_upload
) {
201 return UpdatePermissions(
202 ChromeMetricsServiceAccessor::IsMetricsReportingEnabled(), may_upload
);