| // Copyright 2019 The Chromium Authors |
| // 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/check.h" |
| #include "base/command_line.h" |
| #include "base/functional/bind.h" |
| #include "base/task/single_thread_task_runner.h" |
| #include "build/build_config.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/content/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 BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| #include "chromecast/browser/metrics/external_metrics.h" |
| #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| |
| #if BUILDFLAG(IS_ANDROID) |
| #include "chromecast/base/android/dumpstate_writer.h" |
| #endif |
| |
| namespace chromecast { |
| namespace metrics { |
| |
| const int kMetricsFetchTimeoutSeconds = 60; |
| |
| #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| const char kExternalUmaEventsRelativePath[] = "metrics/uma-events"; |
| const char kPlatformUmaEventsPath[] = "/data/share/chrome/metrics/uma-events"; |
| #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| |
| 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 BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| DCHECK(!external_metrics_); |
| DCHECK(!platform_metrics_); |
| #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| } |
| |
| 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()); |
| 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 BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| // Start external metrics collection, which feeds data from external |
| // processes into the main external metrics. |
| external_metrics_ = new ExternalMetrics( |
| GetHomePathASCII(kExternalUmaEventsRelativePath).value()); |
| external_metrics_->Start(); |
| platform_metrics_ = new ExternalMetrics(kPlatformUmaEventsPath); |
| platform_metrics_->Start(); |
| #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| } |
| |
| void CastBrowserMetrics::Finalize() { |
| #if !BUILDFLAG(IS_ANDROID) |
| // Signal that the session has exited cleanly. |
| metrics_service_client_->GetMetricsService()->LogCleanShutdown(); |
| #endif // !BUILDFLAG(IS_ANDROID) |
| |
| #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| // 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 // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| |
| metrics_service_client_->Finalize(); |
| } |
| |
| void CastBrowserMetrics::CollectFinalMetricsForLog( |
| base::OnceClosure 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::SingleThreadTaskRunner::GetCurrentDefault(), |
| std::move(done_callback), base::Seconds(kMetricsFetchTimeoutSeconds)); |
| } |
| |
| void CastBrowserMetrics::ProcessExternalEvents(base::OnceClosure cb) { |
| #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| external_metrics_->ProcessExternalEvents( |
| base::BindOnce(&ExternalMetrics::ProcessExternalEvents, |
| base::Unretained(platform_metrics_), std::move(cb))); |
| #else |
| std::move(cb).Run(); |
| #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) |
| } |
| |
| } // namespace metrics |
| } // namespace chromecast |