OLD | NEW |
| (Empty) |
1 // Copyright 2015 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. | |
4 | |
5 #include "ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h" | |
6 | |
7 #include <stdint.h> | |
8 | |
9 #include <utility> | |
10 #include <vector> | |
11 | |
12 #include "base/bind.h" | |
13 #include "base/callback.h" | |
14 #include "base/command_line.h" | |
15 #include "base/files/file_path.h" | |
16 #include "base/logging.h" | |
17 #include "base/memory/ptr_util.h" | |
18 #include "base/metrics/histogram.h" | |
19 #include "base/process/process_metrics.h" | |
20 #include "base/rand_util.h" | |
21 #include "base/strings/string16.h" | |
22 #include "base/threading/platform_thread.h" | |
23 #include "components/crash/core/common/crash_keys.h" | |
24 #include "components/metrics/call_stack_profile_metrics_provider.h" | |
25 #include "components/metrics/drive_metrics_provider.h" | |
26 #include "components/metrics/metrics_pref_names.h" | |
27 #include "components/metrics/metrics_reporting_default_state.h" | |
28 #include "components/metrics/metrics_service.h" | |
29 #include "components/metrics/net/cellular_logic_helper.h" | |
30 #include "components/metrics/net/net_metrics_log_uploader.h" | |
31 #include "components/metrics/net/network_metrics_provider.h" | |
32 #include "components/metrics/net/version_utils.h" | |
33 #include "components/metrics/profiler/profiler_metrics_provider.h" | |
34 #include "components/metrics/profiler/tracking_synchronizer.h" | |
35 #include "components/metrics/stability_metrics_helper.h" | |
36 #include "components/metrics/ui/screen_info_metrics_provider.h" | |
37 #include "components/metrics/url_constants.h" | |
38 #include "components/omnibox/browser/omnibox_metrics_provider.h" | |
39 #include "components/prefs/pref_registry_simple.h" | |
40 #include "components/prefs/pref_service.h" | |
41 #include "components/signin/core/browser/signin_status_metrics_provider.h" | |
42 #include "components/sync/device_info/device_count_metrics_provider.h" | |
43 #include "components/translate/core/browser/translate_ranker_metrics_provider.h" | |
44 #include "components/variations/variations_associated_data.h" | |
45 #include "components/version_info/version_info.h" | |
46 #include "ios/chrome/browser/application_context.h" | |
47 #include "ios/chrome/browser/chrome_paths.h" | |
48 #include "ios/chrome/browser/google/google_brand.h" | |
49 #include "ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h" | |
50 #include "ios/chrome/browser/metrics/mobile_session_shutdown_metrics_provider.h" | |
51 #include "ios/chrome/browser/signin/ios_chrome_signin_status_metrics_provider_de
legate.h" | |
52 #include "ios/chrome/browser/sync/ios_chrome_sync_client.h" | |
53 #include "ios/chrome/browser/tab_parenting_global_observer.h" | |
54 #include "ios/chrome/browser/ui/browser_otr_state.h" | |
55 #include "ios/chrome/common/channel_info.h" | |
56 #include "ios/web/public/web_thread.h" | |
57 | |
58 IOSChromeMetricsServiceClient::IOSChromeMetricsServiceClient( | |
59 metrics::MetricsStateManager* state_manager) | |
60 : metrics_state_manager_(state_manager), | |
61 stability_metrics_provider_(nullptr), | |
62 profiler_metrics_provider_(nullptr), | |
63 drive_metrics_provider_(nullptr), | |
64 start_time_(base::TimeTicks::Now()), | |
65 has_uploaded_profiler_data_(false), | |
66 weak_ptr_factory_(this) { | |
67 DCHECK(thread_checker_.CalledOnValidThread()); | |
68 RegisterForNotifications(); | |
69 } | |
70 | |
71 IOSChromeMetricsServiceClient::~IOSChromeMetricsServiceClient() { | |
72 DCHECK(thread_checker_.CalledOnValidThread()); | |
73 } | |
74 | |
75 // static | |
76 std::unique_ptr<IOSChromeMetricsServiceClient> | |
77 IOSChromeMetricsServiceClient::Create( | |
78 metrics::MetricsStateManager* state_manager) { | |
79 // Perform two-phase initialization so that |client->metrics_service_| only | |
80 // receives pointers to fully constructed objects. | |
81 std::unique_ptr<IOSChromeMetricsServiceClient> client( | |
82 new IOSChromeMetricsServiceClient(state_manager)); | |
83 client->Initialize(); | |
84 | |
85 return client; | |
86 } | |
87 | |
88 // static | |
89 void IOSChromeMetricsServiceClient::RegisterPrefs( | |
90 PrefRegistrySimple* registry) { | |
91 metrics::MetricsService::RegisterPrefs(registry); | |
92 metrics::StabilityMetricsHelper::RegisterPrefs(registry); | |
93 metrics::RegisterMetricsReportingStatePrefs(registry); | |
94 } | |
95 | |
96 metrics::MetricsService* IOSChromeMetricsServiceClient::GetMetricsService() { | |
97 return metrics_service_.get(); | |
98 } | |
99 | |
100 void IOSChromeMetricsServiceClient::SetMetricsClientId( | |
101 const std::string& client_id) { | |
102 crash_keys::SetMetricsClientIdFromGUID(client_id); | |
103 } | |
104 | |
105 int32_t IOSChromeMetricsServiceClient::GetProduct() { | |
106 return metrics::ChromeUserMetricsExtension::CHROME; | |
107 } | |
108 | |
109 std::string IOSChromeMetricsServiceClient::GetApplicationLocale() { | |
110 return GetApplicationContext()->GetApplicationLocale(); | |
111 } | |
112 | |
113 bool IOSChromeMetricsServiceClient::GetBrand(std::string* brand_code) { | |
114 return ios::google_brand::GetBrand(brand_code); | |
115 } | |
116 | |
117 metrics::SystemProfileProto::Channel | |
118 IOSChromeMetricsServiceClient::GetChannel() { | |
119 return metrics::AsProtobufChannel(::GetChannel()); | |
120 } | |
121 | |
122 std::string IOSChromeMetricsServiceClient::GetVersionString() { | |
123 return metrics::GetVersionString(); | |
124 } | |
125 | |
126 void IOSChromeMetricsServiceClient::OnLogUploadComplete() {} | |
127 | |
128 void IOSChromeMetricsServiceClient::InitializeSystemProfileMetrics( | |
129 const base::Closure& done_callback) { | |
130 finished_init_task_callback_ = done_callback; | |
131 drive_metrics_provider_->GetDriveMetrics( | |
132 base::Bind(&IOSChromeMetricsServiceClient::OnInitTaskGotDriveMetrics, | |
133 weak_ptr_factory_.GetWeakPtr())); | |
134 } | |
135 | |
136 void IOSChromeMetricsServiceClient::CollectFinalMetricsForLog( | |
137 const base::Closure& done_callback) { | |
138 DCHECK(thread_checker_.CalledOnValidThread()); | |
139 | |
140 collect_final_metrics_done_callback_ = done_callback; | |
141 | |
142 if (ShouldIncludeProfilerDataInLog()) { | |
143 // Fetch profiler data. This will call into | |
144 // |FinishedReceivingProfilerData()| when the task completes. | |
145 metrics::TrackingSynchronizer::FetchProfilerDataAsynchronously( | |
146 weak_ptr_factory_.GetWeakPtr()); | |
147 } else { | |
148 CollectFinalHistograms(); | |
149 } | |
150 } | |
151 | |
152 std::unique_ptr<metrics::MetricsLogUploader> | |
153 IOSChromeMetricsServiceClient::CreateUploader( | |
154 const base::Callback<void(int)>& on_upload_complete) { | |
155 return std::unique_ptr<metrics::MetricsLogUploader>( | |
156 new metrics::NetMetricsLogUploader( | |
157 GetApplicationContext()->GetSystemURLRequestContext(), | |
158 metrics::kDefaultMetricsServerUrl, metrics::kDefaultMetricsMimeType, | |
159 on_upload_complete)); | |
160 } | |
161 | |
162 base::TimeDelta IOSChromeMetricsServiceClient::GetStandardUploadInterval() { | |
163 return metrics::GetUploadInterval(); | |
164 } | |
165 | |
166 base::string16 IOSChromeMetricsServiceClient::GetRegistryBackupKey() { | |
167 return base::string16(); | |
168 } | |
169 | |
170 void IOSChromeMetricsServiceClient::OnRendererProcessCrash() { | |
171 stability_metrics_provider_->LogRendererCrash(); | |
172 } | |
173 | |
174 void IOSChromeMetricsServiceClient::WebStateDidStartLoading( | |
175 web::WebState* web_state) { | |
176 metrics_service_->OnApplicationNotIdle(); | |
177 } | |
178 | |
179 void IOSChromeMetricsServiceClient::WebStateDidStopLoading( | |
180 web::WebState* web_state) { | |
181 metrics_service_->OnApplicationNotIdle(); | |
182 } | |
183 | |
184 void IOSChromeMetricsServiceClient::Initialize() { | |
185 metrics_service_.reset(new metrics::MetricsService( | |
186 metrics_state_manager_, this, GetApplicationContext()->GetLocalState())); | |
187 | |
188 // Register metrics providers. | |
189 metrics_service_->RegisterMetricsProvider( | |
190 std::unique_ptr<metrics::MetricsProvider>( | |
191 new metrics::NetworkMetricsProvider( | |
192 web::WebThread::GetBlockingPool()))); | |
193 | |
194 // Currently, we configure OmniboxMetricsProvider to not log events to UMA | |
195 // if there is a single incognito session visible. In the future, it may | |
196 // be worth revisiting this to still log events from non-incognito sessions. | |
197 metrics_service_->RegisterMetricsProvider( | |
198 std::unique_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider( | |
199 base::Bind(&::IsOffTheRecordSessionActive)))); | |
200 | |
201 stability_metrics_provider_ = new IOSChromeStabilityMetricsProvider( | |
202 GetApplicationContext()->GetLocalState()); | |
203 metrics_service_->RegisterMetricsProvider( | |
204 std::unique_ptr<metrics::MetricsProvider>(stability_metrics_provider_)); | |
205 | |
206 metrics_service_->RegisterMetricsProvider( | |
207 std::unique_ptr<metrics::MetricsProvider>( | |
208 new metrics::ScreenInfoMetricsProvider)); | |
209 | |
210 drive_metrics_provider_ = new metrics::DriveMetricsProvider( | |
211 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE), | |
212 ios::FILE_LOCAL_STATE); | |
213 metrics_service_->RegisterMetricsProvider( | |
214 std::unique_ptr<metrics::MetricsProvider>(drive_metrics_provider_)); | |
215 | |
216 profiler_metrics_provider_ = new metrics::ProfilerMetricsProvider( | |
217 base::Bind(&metrics::IsCellularLogicEnabled)); | |
218 metrics_service_->RegisterMetricsProvider( | |
219 std::unique_ptr<metrics::MetricsProvider>(profiler_metrics_provider_)); | |
220 | |
221 metrics_service_->RegisterMetricsProvider( | |
222 std::unique_ptr<metrics::MetricsProvider>( | |
223 new metrics::CallStackProfileMetricsProvider)); | |
224 | |
225 metrics_service_->RegisterMetricsProvider( | |
226 std::unique_ptr<metrics::MetricsProvider>( | |
227 SigninStatusMetricsProvider::CreateInstance(base::WrapUnique( | |
228 new IOSChromeSigninStatusMetricsProviderDelegate)))); | |
229 | |
230 metrics_service_->RegisterMetricsProvider( | |
231 std::unique_ptr<metrics::MetricsProvider>( | |
232 new MobileSessionShutdownMetricsProvider(metrics_service_.get()))); | |
233 | |
234 metrics_service_->RegisterMetricsProvider( | |
235 std::unique_ptr<metrics::MetricsProvider>( | |
236 new syncer::DeviceCountMetricsProvider( | |
237 base::Bind(&IOSChromeSyncClient::GetDeviceInfoTrackers)))); | |
238 | |
239 metrics_service_->RegisterMetricsProvider( | |
240 std::unique_ptr<metrics::MetricsProvider>( | |
241 new translate::TranslateRankerMetricsProvider())); | |
242 } | |
243 | |
244 void IOSChromeMetricsServiceClient::OnInitTaskGotDriveMetrics() { | |
245 finished_init_task_callback_.Run(); | |
246 } | |
247 | |
248 bool IOSChromeMetricsServiceClient::ShouldIncludeProfilerDataInLog() { | |
249 // Upload profiler data at most once per session. | |
250 if (has_uploaded_profiler_data_) | |
251 return false; | |
252 | |
253 // For each log, flip a fair coin. Thus, profiler data is sent with the first | |
254 // log with probability 50%, with the second log with probability 25%, and so | |
255 // on. As a result, uploaded data is biased toward earlier logs. | |
256 // TODO(isherman): Explore other possible algorithms, and choose one that | |
257 // might be more appropriate. For example, it might be reasonable to include | |
258 // profiler data with some fixed probability, so that a given client might | |
259 // upload profiler data more than once; but on average, clients won't upload | |
260 // too much data. | |
261 if (base::RandDouble() < 0.5) | |
262 return false; | |
263 | |
264 has_uploaded_profiler_data_ = true; | |
265 return true; | |
266 } | |
267 | |
268 void IOSChromeMetricsServiceClient::ReceivedProfilerData( | |
269 const metrics::ProfilerDataAttributes& attributes, | |
270 const tracked_objects::ProcessDataPhaseSnapshot& process_data_phase, | |
271 const metrics::ProfilerEvents& past_events) { | |
272 profiler_metrics_provider_->RecordProfilerData( | |
273 process_data_phase, attributes.process_id, attributes.process_type, | |
274 attributes.profiling_phase, attributes.phase_start - start_time_, | |
275 attributes.phase_finish - start_time_, past_events); | |
276 } | |
277 | |
278 void IOSChromeMetricsServiceClient::FinishedReceivingProfilerData() { | |
279 CollectFinalHistograms(); | |
280 } | |
281 | |
282 void IOSChromeMetricsServiceClient::CollectFinalHistograms() { | |
283 DCHECK(thread_checker_.CalledOnValidThread()); | |
284 | |
285 // TODO(ios): Try to extract the flow below into a utility function that is | |
286 // shared between the iOS port's usage and | |
287 // ChromeMetricsServiceClient::CollectFinalHistograms()'s usage of | |
288 // MetricsMemoryDetails. | |
289 std::unique_ptr<base::ProcessMetrics> process_metrics( | |
290 base::ProcessMetrics::CreateProcessMetrics( | |
291 base::GetCurrentProcessHandle())); | |
292 UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", | |
293 process_metrics->GetWorkingSetSize() / 1024); | |
294 collect_final_metrics_done_callback_.Run(); | |
295 } | |
296 | |
297 void IOSChromeMetricsServiceClient::RegisterForNotifications() { | |
298 tab_parented_subscription_ = | |
299 TabParentingGlobalObserver::GetInstance()->RegisterCallback( | |
300 base::Bind(&IOSChromeMetricsServiceClient::OnTabParented, | |
301 base::Unretained(this))); | |
302 omnibox_url_opened_subscription_ = | |
303 OmniboxEventGlobalTracker::GetInstance()->RegisterCallback( | |
304 base::Bind(&IOSChromeMetricsServiceClient::OnURLOpenedFromOmnibox, | |
305 base::Unretained(this))); | |
306 } | |
307 | |
308 void IOSChromeMetricsServiceClient::OnTabParented(web::WebState* web_state) { | |
309 metrics_service_->OnApplicationNotIdle(); | |
310 } | |
311 | |
312 void IOSChromeMetricsServiceClient::OnURLOpenedFromOmnibox(OmniboxLog* log) { | |
313 metrics_service_->OnApplicationNotIdle(); | |
314 } | |
315 | |
316 metrics::EnableMetricsDefault | |
317 IOSChromeMetricsServiceClient::GetMetricsReportingDefaultState() { | |
318 return metrics::GetMetricsReportingDefaultState( | |
319 GetApplicationContext()->GetLocalState()); | |
320 } | |
OLD | NEW |