1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/metrics/content/content_stability_metrics_provider.h"
6
7 #include "base/check.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/notreached.h"
10 #include "build/build_config.h"
11 #include "components/metrics/content/extensions_helper.h"
12 #include "content/public/browser/browser_child_process_observer.h"
13 #include "content/public/browser/child_process_data.h"
14 #include "content/public/browser/child_process_termination_info.h"
15 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/notification_types.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/common/process_type.h"
19 #include "ppapi/buildflags/buildflags.h"
20
21 #if BUILDFLAG(IS_ANDROID)
22 #include "components/crash/content/browser/crash_metrics_reporter_android.h"
23 #endif
24
25 namespace metrics {
26
ContentStabilityMetricsProvider(PrefService * local_state,std::unique_ptr<ExtensionsHelper> extensions_helper)27 ContentStabilityMetricsProvider::ContentStabilityMetricsProvider(
28 PrefService* local_state,
29 std::unique_ptr<ExtensionsHelper> extensions_helper)
30 : helper_(local_state), extensions_helper_(std::move(extensions_helper)) {
31 BrowserChildProcessObserver::Add(this);
32
33 #if BUILDFLAG(IS_ANDROID)
34 auto* crash_manager = crash_reporter::CrashMetricsReporter::GetInstance();
35 DCHECK(crash_manager);
36 scoped_observation_.Observe(crash_manager);
37 #endif // BUILDFLAG(IS_ANDROID)
38 }
39
~ContentStabilityMetricsProvider()40 ContentStabilityMetricsProvider::~ContentStabilityMetricsProvider() {
41 BrowserChildProcessObserver::Remove(this);
42 }
43
OnRecordingEnabled()44 void ContentStabilityMetricsProvider::OnRecordingEnabled() {}
45
OnRecordingDisabled()46 void ContentStabilityMetricsProvider::OnRecordingDisabled() {}
47
48 #if BUILDFLAG(IS_ANDROID)
ProvideStabilityMetrics(SystemProfileProto * system_profile_proto)49 void ContentStabilityMetricsProvider::ProvideStabilityMetrics(
50 SystemProfileProto* system_profile_proto) {
51 helper_.ProvideStabilityMetrics(system_profile_proto);
52 }
53
ClearSavedStabilityMetrics()54 void ContentStabilityMetricsProvider::ClearSavedStabilityMetrics() {
55 helper_.ClearSavedStabilityMetrics();
56 }
57 #endif // BUILDFLAG(IS_ANDROID)
58
OnRenderProcessHostCreated(content::RenderProcessHost * host)59 void ContentStabilityMetricsProvider::OnRenderProcessHostCreated(
60 content::RenderProcessHost* host) {
61 bool was_extension_process =
62 extensions_helper_ && extensions_helper_->IsExtensionProcess(host);
63 helper_.LogRendererLaunched(was_extension_process);
64 if (!host_observation_.IsObservingSource(host)) {
65 host_observation_.AddObservation(host);
66 }
67 }
68
RenderProcessExited(content::RenderProcessHost * host,const content::ChildProcessTerminationInfo & info)69 void ContentStabilityMetricsProvider::RenderProcessExited(
70 content::RenderProcessHost* host,
71 const content::ChildProcessTerminationInfo& info) {
72 // On Android, the renderer crashes are recorded in
73 // `OnCrashDumpProcessed`.
74 #if !BUILDFLAG(IS_ANDROID)
75 bool was_extension_process =
76 extensions_helper_ && extensions_helper_->IsExtensionProcess(host);
77 helper_.LogRendererCrash(was_extension_process, info.status, info.exit_code);
78 #endif // !BUILDFLAG(IS_ANDROID)
79 }
80
RenderProcessHostDestroyed(content::RenderProcessHost * host)81 void ContentStabilityMetricsProvider::RenderProcessHostDestroyed(
82 content::RenderProcessHost* host) {
83 // In single-process mode, RenderProcessExited isn't called, so we ensure
84 // we remove observations here rather than there, to avoid later use-after-
85 // frees in single process mode.
86 host_observation_.RemoveObservation(host);
87 }
88
BrowserChildProcessCrashed(const content::ChildProcessData & data,const content::ChildProcessTerminationInfo & info)89 void ContentStabilityMetricsProvider::BrowserChildProcessCrashed(
90 const content::ChildProcessData& data,
91 const content::ChildProcessTerminationInfo& info) {
92 DCHECK(!data.metrics_name.empty());
93 if (data.process_type == content::PROCESS_TYPE_UTILITY)
94 helper_.BrowserUtilityProcessCrashed(data.metrics_name, info.exit_code);
95 }
96
BrowserChildProcessLaunchedAndConnected(const content::ChildProcessData & data)97 void ContentStabilityMetricsProvider::BrowserChildProcessLaunchedAndConnected(
98 const content::ChildProcessData& data) {
99 DCHECK(!data.metrics_name.empty());
100 if (data.process_type == content::PROCESS_TYPE_UTILITY)
101 helper_.BrowserUtilityProcessLaunched(data.metrics_name);
102 }
103
BrowserChildProcessLaunchFailed(const content::ChildProcessData & data,const content::ChildProcessTerminationInfo & info)104 void ContentStabilityMetricsProvider::BrowserChildProcessLaunchFailed(
105 const content::ChildProcessData& data,
106 const content::ChildProcessTerminationInfo& info) {
107 DCHECK(!data.metrics_name.empty());
108 DCHECK_EQ(info.status, base::TERMINATION_STATUS_LAUNCH_FAILED);
109 if (data.process_type == content::PROCESS_TYPE_UTILITY)
110 helper_.BrowserUtilityProcessLaunchFailed(data.metrics_name, info.exit_code
111 #if BUILDFLAG(IS_WIN)
112 ,
113 info.last_error
114 #endif
115 );
116 }
117
118 #if BUILDFLAG(IS_ANDROID)
OnCrashDumpProcessed(int rph_id,const crash_reporter::CrashMetricsReporter::ReportedCrashTypeSet & reported_counts)119 void ContentStabilityMetricsProvider::OnCrashDumpProcessed(
120 int rph_id,
121 const crash_reporter::CrashMetricsReporter::ReportedCrashTypeSet&
122 reported_counts) {
123 if (reported_counts.count(crash_reporter::CrashMetricsReporter::
124 ProcessedCrashCounts::kRendererCrashAll)) {
125 helper_.IncreaseRendererCrashCount();
126 }
127 if (reported_counts.count(crash_reporter::CrashMetricsReporter::
128 ProcessedCrashCounts::kGpuCrashAll)) {
129 helper_.IncreaseGpuCrashCount();
130 }
131 }
132 #endif // BUILDFLAG(IS_ANDROID)
133
OnPageLoadStarted()134 void ContentStabilityMetricsProvider::OnPageLoadStarted() {
135 helper_.LogLoadStarted();
136 }
137
138 } // namespace metrics
139