blob: 3e97217bea0c348aef93cb71cce49ad69296cd1d [file]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/browser/metrics/cast_metrics_service_client.h"
#include "base/command_line.h"
#include "base/guid.h"
#include "base/i18n/rtl.h"
#include "base/prefs/pref_service.h"
#include "chromecast/browser/metrics/cast_stability_metrics_provider.h"
#include "chromecast/browser/metrics/platform_metrics_providers.h"
#include "chromecast/common/chromecast_switches.h"
#include "chromecast/common/pref_names.h"
#include "components/metrics/client_info.h"
#include "components/metrics/gpu/gpu_metrics_provider.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_provider.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/metrics_state_manager.h"
#include "components/metrics/net/net_metrics_log_uploader.h"
#include "components/metrics/net/network_metrics_provider.h"
#include "components/metrics/profiler/profiler_metrics_provider.h"
#include "components/metrics/url_constants.h"
#include "content/public/common/content_switches.h"
#if defined(OS_LINUX)
#include "chromecast/browser/metrics/external_metrics.h"
#endif // defined(OS_LINUX)
namespace chromecast {
namespace metrics {
// static
scoped_ptr<CastMetricsServiceClient> CastMetricsServiceClient::Create(
base::TaskRunner* io_task_runner,
PrefService* pref_service,
net::URLRequestContextGetter* request_context) {
return make_scoped_ptr(new CastMetricsServiceClient(io_task_runner,
pref_service,
request_context));
}
void CastMetricsServiceClient::SetMetricsClientId(
const std::string& client_id) {
client_id_ = client_id;
LOG(INFO) << "Metrics client ID set: " << client_id;
PlatformSetClientID(cast_service_, client_id);
}
void CastMetricsServiceClient::StoreClientInfo(
const ::metrics::ClientInfo& client_info) {
const std::string& client_id = client_info.client_id;
DCHECK(client_id.empty() || base::IsValidGUID(client_id));
// backup client_id or reset to empty.
SetMetricsClientId(client_id);
}
scoped_ptr< ::metrics::ClientInfo> CastMetricsServiceClient::LoadClientInfo() {
scoped_ptr< ::metrics::ClientInfo> client_info(new ::metrics::ClientInfo);
// kMetricsIsNewClientID would be missing if either the device was just
// FDR'ed, or it is on pre-v1.2 build.
if (!pref_service_->GetBoolean(prefs::kMetricsIsNewClientID)) {
// If the old client id exists, the device must be on pre-v1.2 build,
// instead of just being FDR'ed.
if (!pref_service_->GetString(::metrics::prefs::kMetricsOldClientID)
.empty()) {
// Force old client id to be regenerated. See b/9487011.
client_info->client_id = base::GenerateGUID();
pref_service_->SetBoolean(prefs::kMetricsIsNewClientID, true);
return client_info.Pass();
}
// else the device was just FDR'ed, pass through.
}
const std::string client_id(GetPlatformClientID(cast_service_));
if (!client_id.empty() && base::IsValidGUID(client_id)) {
client_info->client_id = client_id;
return client_info.Pass();
} else {
if (client_id.empty()) {
LOG(WARNING) << "Empty client id from platform,"
<< " assuming this is the first boot up of a new device.";
} else {
LOG(ERROR) << "Invalid client id " << client_id << " from platform.";
}
return scoped_ptr< ::metrics::ClientInfo>();
}
}
bool CastMetricsServiceClient::IsOffTheRecordSessionActive() {
// Chromecast behaves as "off the record" w/r/t recording browsing state,
// but this value is about not disabling metrics because of it.
return false;
}
int32_t CastMetricsServiceClient::GetProduct() {
// Chromecast currently uses the same product identifier as Chrome.
return ::metrics::ChromeUserMetricsExtension::CHROME;
}
std::string CastMetricsServiceClient::GetApplicationLocale() {
return base::i18n::GetConfiguredLocale();
}
bool CastMetricsServiceClient::GetBrand(std::string* brand_code) {
return false;
}
::metrics::SystemProfileProto::Channel CastMetricsServiceClient::GetChannel() {
return GetPlatformReleaseChannel(cast_service_);
}
std::string CastMetricsServiceClient::GetVersionString() {
return GetPlatformVersionString(cast_service_);
}
void CastMetricsServiceClient::OnLogUploadComplete() {
PlatformOnLogUploadComplete(cast_service_);
}
void CastMetricsServiceClient::StartGatheringMetrics(
const base::Closure& done_callback) {
done_callback.Run();
}
void CastMetricsServiceClient::CollectFinalMetrics(
const base::Closure& done_callback) {
done_callback.Run();
}
scoped_ptr< ::metrics::MetricsLogUploader>
CastMetricsServiceClient::CreateUploader(
const base::Callback<void(int)>& on_upload_complete) {
std::string uma_server_url(::metrics::kDefaultMetricsServerUrl);
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kOverrideMetricsUploadUrl)) {
uma_server_url.assign(
command_line->GetSwitchValueASCII(switches::kOverrideMetricsUploadUrl));
}
DCHECK(!uma_server_url.empty());
return scoped_ptr< ::metrics::MetricsLogUploader>(
new ::metrics::NetMetricsLogUploader(
request_context_,
uma_server_url,
::metrics::kDefaultMetricsMimeType,
on_upload_complete));
}
void CastMetricsServiceClient::EnableMetricsService(bool enabled) {
if (!metrics_service_loop_->BelongsToCurrentThread()) {
metrics_service_loop_->PostTask(
FROM_HERE,
base::Bind(&CastMetricsServiceClient::EnableMetricsService,
base::Unretained(this),
enabled));
return;
}
if (enabled) {
metrics_service_->Start();
} else {
metrics_service_->Stop();
}
}
CastMetricsServiceClient::CastMetricsServiceClient(
base::TaskRunner* io_task_runner,
PrefService* pref_service,
net::URLRequestContextGetter* request_context)
: io_task_runner_(io_task_runner),
pref_service_(pref_service),
cast_service_(NULL),
#if !defined(OS_ANDROID)
external_metrics_(NULL),
#endif // !defined(OS_ANDROID)
metrics_service_loop_(base::MessageLoopProxy::current()),
request_context_(request_context) {
}
CastMetricsServiceClient::~CastMetricsServiceClient() {
#if !defined(OS_ANDROID)
DCHECK(!external_metrics_);
#endif // !defined(OS_ANDROID)
}
void CastMetricsServiceClient::Initialize(CastService* cast_service) {
DCHECK(cast_service);
DCHECK(!cast_service_);
cast_service_ = cast_service;
metrics_state_manager_ = ::metrics::MetricsStateManager::Create(
pref_service_,
base::Bind(&CastMetricsServiceClient::IsReportingEnabled,
base::Unretained(this)),
base::Bind(&CastMetricsServiceClient::StoreClientInfo,
base::Unretained(this)),
base::Bind(&CastMetricsServiceClient::LoadClientInfo,
base::Unretained(this)));
metrics_service_.reset(new ::metrics::MetricsService(
metrics_state_manager_.get(),
this,
pref_service_));
// Always create a client id as it may also be used by crash reporting,
// (indirectly) included in feedback, and can be queried during setup.
// For UMA and crash reporting, associated opt-in settings will control
// sending reports as directed by the user.
// For Setup (which also communicates the user's opt-in preferences),
// report the client-id and expect that setup will handle the current opt-in
// value.
metrics_state_manager_->ForceClientIdCreation();
CastStabilityMetricsProvider* stability_provider =
new CastStabilityMetricsProvider(metrics_service_.get());
metrics_service_->RegisterMetricsProvider(
scoped_ptr< ::metrics::MetricsProvider>(stability_provider));
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kDisableGpu)) {
metrics_service_->RegisterMetricsProvider(
scoped_ptr< ::metrics::MetricsProvider>(
new ::metrics::GPUMetricsProvider));
}
metrics_service_->RegisterMetricsProvider(
scoped_ptr< ::metrics::MetricsProvider>(
new ::metrics::NetworkMetricsProvider(io_task_runner_)));
metrics_service_->RegisterMetricsProvider(
scoped_ptr< ::metrics::MetricsProvider>(
new ::metrics::ProfilerMetricsProvider));
RegisterPlatformMetricsProviders(metrics_service_.get(), cast_service_);
metrics_service_->InitializeMetricsRecordingState();
#if !defined(OS_ANDROID)
// Reset clean_shutdown bit after InitializeMetricsRecordingState().
metrics_service_->LogNeedForCleanShutdown();
#endif // !defined(OS_ANDROID)
if (IsReportingEnabled())
metrics_service_->Start();
// Start external metrics collection, which feeds data from external
// processes into the main external metrics.
#if defined(OS_LINUX)
external_metrics_ = new ExternalMetrics(stability_provider);
external_metrics_->Start();
#endif // defined(OS_LINUX)
}
void CastMetricsServiceClient::Finalize() {
#if !defined(OS_ANDROID)
// Set clean_shutdown bit.
metrics_service_->RecordCompletedSessionEnd();
#endif // !defined(OS_ANDROID)
// Stop metrics service cleanly before destructing CastMetricsServiceClient.
#if defined(OS_LINUX)
external_metrics_->StopAndDestroy();
external_metrics_ = NULL;
#endif // defined(OS_LINUX)
metrics_service_->Stop();
}
bool CastMetricsServiceClient::IsReportingEnabled() {
return PlatformIsReportingEnabled(cast_service_);
}
} // namespace metrics
} // namespace chromecast