Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / chromecast / browser / metrics / cast_stability_metrics_provider.cc
blob62150a3af3f217642eedac7e3d90b0d58ae592df
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_stability_metrics_provider.h"
7 #include <vector>
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/metrics/sparse_histogram.h"
12 #include "base/prefs/pref_registry_simple.h"
13 #include "base/prefs/pref_service.h"
14 #include "chromecast/browser/cast_browser_process.h"
15 #include "chromecast/browser/metrics/cast_metrics_service_client.h"
16 #include "chromecast/common/pref_names.h"
17 #include "components/metrics/metrics_service.h"
18 #include "components/metrics/proto/system_profile.pb.h"
19 #include "content/public/browser/child_process_data.h"
20 #include "content/public/browser/navigation_controller.h"
21 #include "content/public/browser/notification_service.h"
22 #include "content/public/browser/notification_types.h"
23 #include "content/public/browser/render_process_host.h"
25 namespace chromecast {
26 namespace metrics {
28 namespace {
30 void IncrementPrefValue(const char* path) {
31 PrefService* pref = shell::CastBrowserProcess::GetInstance()->pref_service();
32 DCHECK(pref);
33 int value = pref->GetInteger(path);
34 pref->SetInteger(path, value + 1);
37 // Converts an exit code into something that can be inserted into our
38 // histograms (which expect non-negative numbers less than MAX_INT).
39 int MapCrashExitCodeForHistogram(int exit_code) {
40 return std::abs(exit_code);
43 } // namespace
45 // static
46 void CastStabilityMetricsProvider::RegisterPrefs(PrefRegistrySimple* registry) {
47 registry->RegisterIntegerPref(prefs::kStabilityRendererCrashCount, 0);
48 registry->RegisterIntegerPref(prefs::kStabilityRendererHangCount, 0);
49 registry->RegisterIntegerPref(prefs::kStabilityChildProcessCrashCount, 0);
52 CastStabilityMetricsProvider::CastStabilityMetricsProvider(
53 ::metrics::MetricsService* metrics_service)
54 : metrics_service_(metrics_service) {
55 BrowserChildProcessObserver::Add(this);
58 CastStabilityMetricsProvider::~CastStabilityMetricsProvider() {
59 BrowserChildProcessObserver::Remove(this);
62 void CastStabilityMetricsProvider::OnRecordingEnabled() {
63 registrar_.Add(this,
64 content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
65 content::NotificationService::AllSources());
66 registrar_.Add(this,
67 content::NOTIFICATION_RENDER_WIDGET_HOST_HANG,
68 content::NotificationService::AllSources());
71 void CastStabilityMetricsProvider::OnRecordingDisabled() {
72 registrar_.RemoveAll();
75 void CastStabilityMetricsProvider::ProvideStabilityMetrics(
76 ::metrics::SystemProfileProto* system_profile_proto) {
77 PrefService* pref = shell::CastBrowserProcess::GetInstance()->pref_service();
78 ::metrics::SystemProfileProto_Stability* stability_proto =
79 system_profile_proto->mutable_stability();
81 int count = pref->GetInteger(prefs::kStabilityChildProcessCrashCount);
82 if (count) {
83 stability_proto->set_child_process_crash_count(count);
84 pref->SetInteger(prefs::kStabilityChildProcessCrashCount, 0);
87 count = pref->GetInteger(prefs::kStabilityRendererCrashCount);
88 if (count) {
89 stability_proto->set_renderer_crash_count(count);
90 pref->SetInteger(prefs::kStabilityRendererCrashCount, 0);
93 count = pref->GetInteger(prefs::kStabilityRendererHangCount);
94 if (count) {
95 stability_proto->set_renderer_hang_count(count);
96 pref->SetInteger(prefs::kStabilityRendererHangCount, 0);
100 void CastStabilityMetricsProvider::LogExternalCrash(
101 const std::string& crash_type) {
102 if (crash_type == "user")
103 IncrementPrefValue(prefs::kStabilityOtherUserCrashCount);
104 else if (crash_type == "kernel")
105 IncrementPrefValue(prefs::kStabilityKernelCrashCount);
106 else if (crash_type == "uncleanshutdown")
107 IncrementPrefValue(prefs::kStabilitySystemUncleanShutdownCount);
108 else
109 NOTREACHED() << "Unexpected crash type " << crash_type;
111 // Wake up metrics logs sending if necessary now that new
112 // log data is available.
113 metrics_service_->OnApplicationNotIdle();
116 void CastStabilityMetricsProvider::Observe(
117 int type,
118 const content::NotificationSource& source,
119 const content::NotificationDetails& details) {
120 switch (type) {
121 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
122 content::RenderProcessHost::RendererClosedDetails* process_details =
123 content::Details<content::RenderProcessHost::RendererClosedDetails>(
124 details).ptr();
125 content::RenderProcessHost* host =
126 content::Source<content::RenderProcessHost>(source).ptr();
127 LogRendererCrash(
128 host, process_details->status, process_details->exit_code);
129 break;
132 case content::NOTIFICATION_RENDER_WIDGET_HOST_HANG:
133 LogRendererHang();
134 break;
136 default:
137 NOTREACHED();
138 break;
142 void CastStabilityMetricsProvider::BrowserChildProcessCrashed(
143 const content::ChildProcessData& data,
144 int exit_code) {
145 IncrementPrefValue(prefs::kStabilityChildProcessCrashCount);
148 void CastStabilityMetricsProvider::LogRendererCrash(
149 content::RenderProcessHost* host,
150 base::TerminationStatus status,
151 int exit_code) {
152 if (status == base::TERMINATION_STATUS_PROCESS_CRASHED ||
153 status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION) {
154 IncrementPrefValue(prefs::kStabilityRendererCrashCount);
156 UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Renderer",
157 MapCrashExitCodeForHistogram(exit_code));
158 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes", 1);
159 } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
160 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKills", 1);
161 } else if (status == base::TERMINATION_STATUS_STILL_RUNNING) {
162 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.DisconnectedAlive", 1);
166 void CastStabilityMetricsProvider::LogRendererHang() {
167 IncrementPrefValue(prefs::kStabilityRendererHangCount);
170 } // namespace metrics
171 } // namespace chromecast