Fire an error if a pref used in the UI is missing once all prefs are fetched.
[chromium-blink-merge.git] / chrome / browser / metrics / metrics_services_manager.cc
blob9f55dae47a9cddee6687198d45d5a7f84093db35
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"
7 #include <string>
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"
31 #endif
33 namespace {
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())
43 continue;
44 all_enabled = all_enabled && profile->GetPrefs()->GetBoolean(
45 prefs::kSafeBrowsingEnabled);
48 return all_enabled;
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));
58 } // namespace
60 MetricsServicesManager::MetricsServicesManager(PrefService* local_state)
61 : local_state_(local_state),
62 may_upload_(false),
63 may_record_(false) {
64 DCHECK(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_) {
90 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(
116 local_state_,
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 ?
140 rappor::FINE_LEVEL :
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,
163 bool may_upload) {
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);
182 return;
185 if (may_record) {
186 if (!metrics->recording_active())
187 metrics->Start();
189 if (may_upload)
190 metrics->EnableReporting();
191 else
192 metrics->DisableReporting();
193 } else if (metrics->recording_active() || metrics->reporting_active()) {
194 metrics->Stop();
197 UpdateRapporService();
200 void MetricsServicesManager::UpdateUploadPermissions(bool may_upload) {
201 return UpdatePermissions(
202 ChromeMetricsServiceAccessor::IsMetricsReportingEnabled(), may_upload);