blob: 22b474009f33a81694b20e2874ba67b457ac8059 [file] [log] [blame]
// Copyright 2019 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_browser_metrics.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chromecast/base/chromecast_switches.h"
#include "chromecast/base/path_utils.h"
#include "chromecast/browser/metrics/cast_stability_metrics_provider.h"
#include "components/metrics/gpu/gpu_metrics_provider.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/net/network_metrics_provider.h"
#include "components/metrics/ui/screen_info_metrics_provider.h"
#include "content/public/browser/histogram_fetcher.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_switches.h"
#if defined(OS_LINUX)
#include "chromecast/browser/metrics/external_metrics.h"
#endif // defined(OS_LINUX)
#if defined(OS_ANDROID)
#include "chromecast/base/android/dumpstate_writer.h"
#endif
namespace chromecast {
namespace metrics {
const int kMetricsFetchTimeoutSeconds = 60;
#if defined(OS_LINUX)
const char kExternalUmaEventsRelativePath[] = "metrics/uma-events";
const char kPlatformUmaEventsPath[] = "/data/share/chrome/metrics/uma-events";
#endif // defined(OS_LINUX)
CastBrowserMetrics::CastBrowserMetrics(
std::unique_ptr<CastMetricsServiceClient> metrics_service_client) {
metrics_service_client_ = std::move(metrics_service_client);
metrics_service_client_->SetCallbacks(
base::BindRepeating(&CastBrowserMetrics::CollectFinalMetricsForLog,
base::Unretained(this)),
base::BindRepeating(&CastBrowserMetrics::ProcessExternalEvents,
base::Unretained(this)));
}
CastBrowserMetrics::~CastBrowserMetrics() {
#if defined(OS_LINUX)
DCHECK(!external_metrics_);
DCHECK(!platform_metrics_);
#endif // defined(OS_LINUX)
}
void CastBrowserMetrics::Initialize() {
metrics_service_client_->InitializeMetricsService();
auto* metrics_service = metrics_service_client_->GetMetricsService();
auto stability_provider_unique_ptr =
std::make_unique<CastStabilityMetricsProvider>(
metrics_service, metrics_service_client_->pref_service());
#if defined(OS_LINUX)
auto* stability_provider = stability_provider_unique_ptr.get();
#endif // defined(OS_LINUX)
metrics_service->RegisterMetricsProvider(
std::move(stability_provider_unique_ptr));
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kDisableGpu)) {
metrics_service->RegisterMetricsProvider(
std::make_unique<::metrics::GPUMetricsProvider>());
// TODO(gfhuang): Does ChromeCast actually need metrics about screen info?
// crbug.com/541577
metrics_service->RegisterMetricsProvider(
std::make_unique<::metrics::ScreenInfoMetricsProvider>());
}
metrics_service->RegisterMetricsProvider(
std::make_unique<::metrics::NetworkMetricsProvider>(
content::CreateNetworkConnectionTrackerAsyncGetter()));
metrics_service_client_->StartMetricsService();
#if defined(OS_LINUX)
// Start external metrics collection, which feeds data from external
// processes into the main external metrics.
external_metrics_ = new ExternalMetrics(
stability_provider,
GetHomePathASCII(kExternalUmaEventsRelativePath).value());
external_metrics_->Start();
platform_metrics_ =
new ExternalMetrics(stability_provider, kPlatformUmaEventsPath);
platform_metrics_->Start();
#endif // defined(OS_LINUX)
}
void CastBrowserMetrics::Finalize() {
#if !defined(OS_ANDROID)
// Set clean_shutdown bit.
metrics_service_client_->GetMetricsService()->RecordCompletedSessionEnd();
#endif // !defined(OS_ANDROID)
#if defined(OS_LINUX)
// Stop metrics service cleanly before destructing CastMetricsServiceClient.
// The pointer will be deleted in StopAndDestroy().
external_metrics_->StopAndDestroy();
external_metrics_ = nullptr;
platform_metrics_->StopAndDestroy();
platform_metrics_ = nullptr;
#endif // defined(OS_LINUX)
metrics_service_client_->Finalize();
}
void CastBrowserMetrics::CollectFinalMetricsForLog(
const base::Closure& done_callback) {
// Asynchronously fetch metrics data from child processes. Since this method
// is called on log upload, metrics that occur between log upload and child
// process termination will not be uploaded.
content::FetchHistogramsAsynchronously(
base::ThreadTaskRunnerHandle::Get(), done_callback,
base::TimeDelta::FromSeconds(kMetricsFetchTimeoutSeconds));
}
void CastBrowserMetrics::ProcessExternalEvents(const base::Closure& cb) {
#if defined(OS_LINUX)
external_metrics_->ProcessExternalEvents(
base::Bind(&ExternalMetrics::ProcessExternalEvents,
base::Unretained(platform_metrics_), cb));
#else
cb.Run();
#endif // defined(OS_LINUX)
}
} // namespace metrics
} // namespace chromecast