| Index: chromecast/metrics/cast_stability_metrics_provider.cc
|
| diff --git a/chromecast/metrics/cast_stability_metrics_provider.cc b/chromecast/metrics/cast_stability_metrics_provider.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7242cf44d272f60dd3108adab7b74a71bc3f6541
|
| --- /dev/null
|
| +++ b/chromecast/metrics/cast_stability_metrics_provider.cc
|
| @@ -0,0 +1,152 @@
|
| +// 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/metrics/cast_stability_metrics_provider.h"
|
| +
|
| +#include <vector>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/metrics/histogram.h"
|
| +#include "base/metrics/sparse_histogram.h"
|
| +#include "base/prefs/pref_registry_simple.h"
|
| +#include "base/prefs/pref_service.h"
|
| +#include "chromecast/common/chromecast_config.h"
|
| +#include "chromecast/common/pref_names.h"
|
| +#include "chromecast/metrics/cast_metrics_service_client.h"
|
| +#include "components/metrics/proto/system_profile.pb.h"
|
| +#include "content/public/browser/child_process_data.h"
|
| +#include "content/public/browser/navigation_controller.h"
|
| +#include "content/public/browser/notification_service.h"
|
| +#include "content/public/browser/notification_types.h"
|
| +#include "content/public/browser/render_process_host.h"
|
| +#include "content/public/browser/user_metrics.h"
|
| +
|
| +namespace chromecast {
|
| +namespace metrics {
|
| +
|
| +namespace {
|
| +
|
| +void IncrementPrefValue(const char* path) {
|
| + PrefService* pref = ChromecastConfig::GetInstance()->pref_service();
|
| + DCHECK(pref);
|
| + int value = pref->GetInteger(path);
|
| + pref->SetInteger(path, value + 1);
|
| +}
|
| +
|
| +// Converts an exit code into something that can be inserted into our
|
| +// histograms (which expect non-negative numbers less than MAX_INT).
|
| +int MapCrashExitCodeForHistogram(int exit_code) {
|
| + return std::abs(exit_code);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +void CastStabilityMetricsProvider::RegisterPrefs(PrefRegistrySimple* registry) {
|
| + registry->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
|
| + registry->RegisterIntegerPref(prefs::kStabilityRendererHangCount, 0);
|
| + registry->RegisterIntegerPref(prefs::kStabilityChildProcessCrashCount, 0);
|
| +}
|
| +
|
| +CastStabilityMetricsProvider::CastStabilityMetricsProvider() {
|
| + BrowserChildProcessObserver::Add(this);
|
| +}
|
| +
|
| +CastStabilityMetricsProvider::~CastStabilityMetricsProvider() {
|
| + BrowserChildProcessObserver::Remove(this);
|
| +}
|
| +
|
| +void CastStabilityMetricsProvider::OnRecordingEnabled() {
|
| + registrar_.Add(this,
|
| + content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
|
| + content::NotificationService::AllSources());
|
| + registrar_.Add(this,
|
| + content::NOTIFICATION_RENDER_WIDGET_HOST_HANG,
|
| + content::NotificationService::AllSources());
|
| +}
|
| +
|
| +void CastStabilityMetricsProvider::OnRecordingDisabled() {
|
| + registrar_.RemoveAll();
|
| +}
|
| +
|
| +void CastStabilityMetricsProvider::ProvideStabilityMetrics(
|
| + ::metrics::SystemProfileProto* system_profile_proto) {
|
| + PrefService* pref = ChromecastConfig::GetInstance()->pref_service();
|
| + ::metrics::SystemProfileProto_Stability* stability_proto =
|
| + system_profile_proto->mutable_stability();
|
| +
|
| + int count = pref->GetInteger(prefs::kStabilityChildProcessCrashCount);
|
| + if (count) {
|
| + stability_proto->set_child_process_crash_count(count);
|
| + pref->SetInteger(prefs::kStabilityChildProcessCrashCount, 0);
|
| + }
|
| +
|
| + count = pref->GetInteger(prefs::kStabilityRendererCrashCount);
|
| + if (count) {
|
| + stability_proto->set_renderer_crash_count(count);
|
| + pref->SetInteger(prefs::kStabilityRendererCrashCount, 0);
|
| + }
|
| +
|
| + count = pref->GetInteger(prefs::kStabilityRendererHangCount);
|
| + if (count) {
|
| + stability_proto->set_renderer_hang_count(count);
|
| + pref->SetInteger(prefs::kStabilityRendererHangCount, 0);
|
| + }
|
| +}
|
| +
|
| +void CastStabilityMetricsProvider::Observe(
|
| + int type,
|
| + const content::NotificationSource& source,
|
| + const content::NotificationDetails& details) {
|
| + switch (type) {
|
| + case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
|
| + content::RenderProcessHost::RendererClosedDetails* process_details =
|
| + content::Details<content::RenderProcessHost::RendererClosedDetails>(
|
| + details).ptr();
|
| + content::RenderProcessHost* host =
|
| + content::Source<content::RenderProcessHost>(source).ptr();
|
| + LogRendererCrash(
|
| + host, process_details->status, process_details->exit_code);
|
| + break;
|
| + }
|
| +
|
| + case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG:
|
| + LogRendererHang();
|
| + break;
|
| +
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void CastStabilityMetricsProvider::BrowserChildProcessCrashed(
|
| + const content::ChildProcessData& data) {
|
| + IncrementPrefValue(prefs::kStabilityChildProcessCrashCount);
|
| +}
|
| +
|
| +void CastStabilityMetricsProvider::LogRendererCrash(
|
| + content::RenderProcessHost* host,
|
| + base::TerminationStatus status,
|
| + int exit_code) {
|
| + if (status == base::TERMINATION_STATUS_PROCESS_CRASHED ||
|
| + status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION) {
|
| + IncrementPrefValue(prefs::kStabilityRendererCrashCount);
|
| +
|
| + UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Renderer",
|
| + MapCrashExitCodeForHistogram(exit_code));
|
| + UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes", 1);
|
| + } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
|
| + UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKills", 1);
|
| + } else if (status == base::TERMINATION_STATUS_STILL_RUNNING) {
|
| + UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.DisconnectedAlive", 1);
|
| + }
|
| +}
|
| +
|
| +void CastStabilityMetricsProvider::LogRendererHang() {
|
| + IncrementPrefValue(prefs::kStabilityRendererHangCount);
|
| +}
|
| +
|
| +} // namespace metrics
|
| +} // namespace chromecast
|
|
|