cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / chromecast / browser / metrics / cast_metrics_service_client.cc
blobba878fc53d45ce43f9618c2d03b4398fa1bc2204
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 "chromecast/browser/metrics/cast_metrics_service_client.h"
7 #include "base/command_line.h"
8 #include "base/guid.h"
9 #include "base/i18n/rtl.h"
10 #include "base/logging.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "chromecast/base/cast_sys_info_util.h"
16 #include "chromecast/base/chromecast_switches.h"
17 #include "chromecast/base/path_utils.h"
18 #include "chromecast/base/pref_names.h"
19 #include "chromecast/base/version.h"
20 #include "chromecast/browser/cast_browser_process.h"
21 #include "chromecast/browser/cast_content_browser_client.h"
22 #include "chromecast/browser/metrics/cast_stability_metrics_provider.h"
23 #include "chromecast/public/cast_sys_info.h"
24 #include "components/metrics/client_info.h"
25 #include "components/metrics/gpu/gpu_metrics_provider.h"
26 #include "components/metrics/metrics_provider.h"
27 #include "components/metrics/metrics_service.h"
28 #include "components/metrics/metrics_state_manager.h"
29 #include "components/metrics/net/net_metrics_log_uploader.h"
30 #include "components/metrics/net/network_metrics_provider.h"
31 #include "components/metrics/profiler/profiler_metrics_provider.h"
32 #include "components/metrics/url_constants.h"
33 #include "content/public/common/content_switches.h"
35 #if defined(OS_LINUX)
36 #include "chromecast/browser/metrics/external_metrics.h"
37 #endif // defined(OS_LINUX)
39 #if defined(OS_ANDROID)
40 #include "chromecast/base/android/dumpstate_writer.h"
41 #endif
43 namespace chromecast {
44 namespace metrics {
46 namespace {
48 const int kStandardUploadIntervalMinutes = 5;
50 const char kMetricsOldClientID[] = "user_experience_metrics.client_id";
52 #if defined(OS_ANDROID)
53 const char kClientIdName[] = "Client ID";
54 #else
55 const char kExternalUmaEventsRelativePath[] = "metrics/uma-events";
56 const char kPlatformUmaEventsPath[] = "/data/share/chrome/metrics/uma-events";
58 const struct ChannelMap {
59 const char* chromecast_channel;
60 const ::metrics::SystemProfileProto::Channel chrome_channel;
61 } kMetricsChannelMap[] = {
62 { "canary-channel", ::metrics::SystemProfileProto::CHANNEL_CANARY },
63 { "dev-channel", ::metrics::SystemProfileProto::CHANNEL_DEV },
64 { "developer-channel", ::metrics::SystemProfileProto::CHANNEL_DEV },
65 { "beta-channel", ::metrics::SystemProfileProto::CHANNEL_BETA },
66 { "dogfood-channel", ::metrics::SystemProfileProto::CHANNEL_BETA },
67 { "stable-channel", ::metrics::SystemProfileProto::CHANNEL_STABLE },
70 ::metrics::SystemProfileProto::Channel
71 GetReleaseChannelFromUpdateChannelName(const std::string& channel_name) {
72 if (channel_name.empty())
73 return ::metrics::SystemProfileProto::CHANNEL_UNKNOWN;
75 for (const auto& channel_map : kMetricsChannelMap) {
76 if (channel_name.compare(channel_map.chromecast_channel) == 0)
77 return channel_map.chrome_channel;
80 // Any non-empty channel name is considered beta channel
81 return ::metrics::SystemProfileProto::CHANNEL_BETA;
83 #endif // !defined(OS_ANDROID)
85 } // namespace
87 // static
88 scoped_ptr<CastMetricsServiceClient> CastMetricsServiceClient::Create(
89 base::TaskRunner* io_task_runner,
90 PrefService* pref_service,
91 net::URLRequestContextGetter* request_context) {
92 return make_scoped_ptr(new CastMetricsServiceClient(
93 io_task_runner, pref_service, request_context));
96 void CastMetricsServiceClient::RegisterPrefs(PrefRegistrySimple* registry) {
97 registry->RegisterStringPref(kMetricsOldClientID, std::string());
100 void CastMetricsServiceClient::SetMetricsClientId(
101 const std::string& client_id) {
102 client_id_ = client_id;
103 LOG(INFO) << "Metrics client ID set: " << client_id;
104 shell::CastBrowserProcess::GetInstance()->browser_client()->
105 SetMetricsClientId(client_id);
106 #if defined(OS_ANDROID)
107 DumpstateWriter::AddDumpValue(kClientIdName, client_id);
108 #endif
111 void CastMetricsServiceClient::OnRecordingDisabled() {
114 void CastMetricsServiceClient::StoreClientInfo(
115 const ::metrics::ClientInfo& client_info) {
116 const std::string& client_id = client_info.client_id;
117 DCHECK(client_id.empty() || base::IsValidGUID(client_id));
118 // backup client_id or reset to empty.
119 SetMetricsClientId(client_id);
122 scoped_ptr< ::metrics::ClientInfo> CastMetricsServiceClient::LoadClientInfo() {
123 scoped_ptr< ::metrics::ClientInfo> client_info(new ::metrics::ClientInfo);
124 client_info_loaded_ = true;
126 // kMetricsIsNewClientID would be missing if either the device was just
127 // FDR'ed, or it is on pre-v1.2 build.
128 if (!pref_service_->GetBoolean(prefs::kMetricsIsNewClientID)) {
129 // If the old client id exists, the device must be on pre-v1.2 build,
130 // instead of just being FDR'ed.
131 if (!pref_service_->GetString(kMetricsOldClientID).empty()) {
132 // Force old client id to be regenerated. See b/9487011.
133 client_info->client_id = base::GenerateGUID();
134 pref_service_->SetBoolean(prefs::kMetricsIsNewClientID, true);
135 return client_info.Pass();
137 // else the device was just FDR'ed, pass through.
140 // Use "forced" client ID if available.
141 if (!force_client_id_.empty() && base::IsValidGUID(force_client_id_)) {
142 client_info->client_id = force_client_id_;
143 return client_info.Pass();
146 if (force_client_id_.empty()) {
147 LOG(WARNING) << "Empty client id from platform,"
148 << " assuming this is the first boot up of a new device.";
149 } else {
150 LOG(ERROR) << "Invalid client id from platform: " << force_client_id_
151 << " from platform.";
153 return scoped_ptr< ::metrics::ClientInfo>();
156 bool CastMetricsServiceClient::IsOffTheRecordSessionActive() {
157 // Chromecast behaves as "off the record" w/r/t recording browsing state,
158 // but this value is about not disabling metrics because of it.
159 return false;
162 int32_t CastMetricsServiceClient::GetProduct() {
163 // Chromecast currently uses the same product identifier as Chrome.
164 return ::metrics::ChromeUserMetricsExtension::CHROME;
167 std::string CastMetricsServiceClient::GetApplicationLocale() {
168 return base::i18n::GetConfiguredLocale();
171 bool CastMetricsServiceClient::GetBrand(std::string* brand_code) {
172 return false;
175 ::metrics::SystemProfileProto::Channel CastMetricsServiceClient::GetChannel() {
176 scoped_ptr<CastSysInfo> sys_info = CreateSysInfo();
178 #if defined(OS_ANDROID)
179 switch (sys_info->GetBuildType()) {
180 case CastSysInfo::BUILD_ENG:
181 return ::metrics::SystemProfileProto::CHANNEL_UNKNOWN;
182 case CastSysInfo::BUILD_BETA:
183 return ::metrics::SystemProfileProto::CHANNEL_BETA;
184 case CastSysInfo::BUILD_PRODUCTION:
185 return ::metrics::SystemProfileProto::CHANNEL_STABLE;
187 NOTREACHED();
188 return ::metrics::SystemProfileProto::CHANNEL_UNKNOWN;
189 #else
190 // Use the system (or signed) release channel here to avoid the noise in the
191 // metrics caused by the virtual channel which could be temporary or
192 // arbitrary.
193 return GetReleaseChannelFromUpdateChannelName(
194 sys_info->GetSystemReleaseChannel());
195 #endif // defined(OS_ANDROID)
198 std::string CastMetricsServiceClient::GetVersionString() {
199 int build_number;
200 if (!base::StringToInt(CAST_BUILD_INCREMENTAL, &build_number))
201 build_number = 0;
203 // Sample result: 31.0.1650.0-K15386-devel
204 std::string version_string(PRODUCT_VERSION);
206 version_string.append("-K");
207 version_string.append(base::IntToString(build_number));
209 int is_official_build =
210 build_number > 0 &&
211 GetChannel() != ::metrics::SystemProfileProto::CHANNEL_UNKNOWN;
212 if (!is_official_build)
213 version_string.append("-devel");
215 return version_string;
218 void CastMetricsServiceClient::OnLogUploadComplete() {
221 void CastMetricsServiceClient::InitializeSystemProfileMetrics(
222 const base::Closure& done_callback) {
223 done_callback.Run();
226 void CastMetricsServiceClient::CollectFinalMetricsForLog(
227 const base::Closure& done_callback) {
228 done_callback.Run();
231 scoped_ptr< ::metrics::MetricsLogUploader>
232 CastMetricsServiceClient::CreateUploader(
233 const base::Callback<void(int)>& on_upload_complete) {
234 std::string uma_server_url(::metrics::kDefaultMetricsServerUrl);
235 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
236 if (command_line->HasSwitch(switches::kOverrideMetricsUploadUrl)) {
237 uma_server_url.assign(
238 command_line->GetSwitchValueASCII(switches::kOverrideMetricsUploadUrl));
240 DCHECK(!uma_server_url.empty());
241 return scoped_ptr< ::metrics::MetricsLogUploader>(
242 new ::metrics::NetMetricsLogUploader(request_context_,
243 uma_server_url,
244 ::metrics::kDefaultMetricsMimeType,
245 on_upload_complete));
248 base::TimeDelta CastMetricsServiceClient::GetStandardUploadInterval() {
249 return base::TimeDelta::FromMinutes(kStandardUploadIntervalMinutes);
252 void CastMetricsServiceClient::EnableMetricsService(bool enabled) {
253 if (!task_runner_->BelongsToCurrentThread()) {
254 task_runner_->PostTask(
255 FROM_HERE, base::Bind(&CastMetricsServiceClient::EnableMetricsService,
256 base::Unretained(this), enabled));
257 return;
260 if (enabled) {
261 metrics_service_->Start();
262 } else {
263 metrics_service_->Stop();
267 CastMetricsServiceClient::CastMetricsServiceClient(
268 base::TaskRunner* io_task_runner,
269 PrefService* pref_service,
270 net::URLRequestContextGetter* request_context)
271 : io_task_runner_(io_task_runner),
272 pref_service_(pref_service),
273 cast_service_(nullptr),
274 client_info_loaded_(false),
275 #if defined(OS_LINUX)
276 external_metrics_(nullptr),
277 platform_metrics_(nullptr),
278 #endif // defined(OS_LINUX)
279 task_runner_(base::ThreadTaskRunnerHandle::Get()),
280 request_context_(request_context) {
283 CastMetricsServiceClient::~CastMetricsServiceClient() {
284 #if defined(OS_LINUX)
285 DCHECK(!external_metrics_);
286 DCHECK(!platform_metrics_);
287 #endif // defined(OS_LINUX)
290 void CastMetricsServiceClient::OnApplicationNotIdle() {
291 metrics_service_->OnApplicationNotIdle();
294 void CastMetricsServiceClient::SetForceClientId(
295 const std::string& client_id) {
296 DCHECK(force_client_id_.empty());
297 DCHECK(!client_info_loaded_)
298 << "Force client ID must be set before client info is loaded.";
299 force_client_id_ = client_id;
302 void CastMetricsServiceClient::Initialize(CastService* cast_service) {
303 DCHECK(cast_service);
304 DCHECK(!cast_service_);
305 cast_service_ = cast_service;
307 metrics_state_manager_ = ::metrics::MetricsStateManager::Create(
308 pref_service_,
309 base::Bind(&CastMetricsServiceClient::IsReportingEnabled,
310 base::Unretained(this)),
311 base::Bind(&CastMetricsServiceClient::StoreClientInfo,
312 base::Unretained(this)),
313 base::Bind(&CastMetricsServiceClient::LoadClientInfo,
314 base::Unretained(this)));
315 metrics_service_.reset(new ::metrics::MetricsService(
316 metrics_state_manager_.get(), this, pref_service_));
318 // Always create a client id as it may also be used by crash reporting,
319 // (indirectly) included in feedback, and can be queried during setup.
320 // For UMA and crash reporting, associated opt-in settings will control
321 // sending reports as directed by the user.
322 // For Setup (which also communicates the user's opt-in preferences),
323 // report the client-id and expect that setup will handle the current opt-in
324 // value.
325 metrics_state_manager_->ForceClientIdCreation();
327 CastStabilityMetricsProvider* stability_provider =
328 new CastStabilityMetricsProvider(metrics_service_.get());
329 metrics_service_->RegisterMetricsProvider(
330 scoped_ptr< ::metrics::MetricsProvider>(stability_provider));
332 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
333 if (!command_line->HasSwitch(switches::kDisableGpu)) {
334 metrics_service_->RegisterMetricsProvider(
335 scoped_ptr< ::metrics::MetricsProvider>(
336 new ::metrics::GPUMetricsProvider));
338 metrics_service_->RegisterMetricsProvider(
339 scoped_ptr< ::metrics::MetricsProvider>(
340 new ::metrics::NetworkMetricsProvider(io_task_runner_)));
341 metrics_service_->RegisterMetricsProvider(
342 scoped_ptr< ::metrics::MetricsProvider>(
343 new ::metrics::ProfilerMetricsProvider));
344 shell::CastBrowserProcess::GetInstance()->browser_client()->
345 RegisterMetricsProviders(metrics_service_.get());
347 metrics_service_->InitializeMetricsRecordingState();
348 #if !defined(OS_ANDROID)
349 // Reset clean_shutdown bit after InitializeMetricsRecordingState().
350 metrics_service_->LogNeedForCleanShutdown();
351 #endif // !defined(OS_ANDROID)
353 if (IsReportingEnabled())
354 metrics_service_->Start();
356 #if defined(OS_LINUX)
357 // Start external metrics collection, which feeds data from external
358 // processes into the main external metrics.
359 external_metrics_ = new ExternalMetrics(
360 stability_provider,
361 GetHomePathASCII(kExternalUmaEventsRelativePath).value());
362 external_metrics_->Start();
363 platform_metrics_ =
364 new ExternalMetrics(stability_provider, kPlatformUmaEventsPath);
365 platform_metrics_->Start();
366 #endif // defined(OS_LINUX)
369 void CastMetricsServiceClient::Finalize() {
370 #if !defined(OS_ANDROID)
371 // Set clean_shutdown bit.
372 metrics_service_->RecordCompletedSessionEnd();
373 #endif // !defined(OS_ANDROID)
375 #if defined(OS_LINUX)
376 // Stop metrics service cleanly before destructing CastMetricsServiceClient.
377 // The pointer will be deleted in StopAndDestroy().
378 external_metrics_->StopAndDestroy();
379 external_metrics_ = nullptr;
380 platform_metrics_->StopAndDestroy();
381 platform_metrics_ = nullptr;
382 #endif // defined(OS_LINUX)
383 metrics_service_->Stop();
386 bool CastMetricsServiceClient::IsReportingEnabled() {
387 return pref_service_->GetBoolean(prefs::kOptInStats);
390 } // namespace metrics
391 } // namespace chromecast