OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 //------------------------------------------------------------------------------ | 5 //------------------------------------------------------------------------------ |
6 // Description of the life cycle of a instance of MetricsService. | 6 // Description of the life cycle of a instance of MetricsService. |
7 // | 7 // |
8 // OVERVIEW | 8 // OVERVIEW |
9 // | 9 // |
10 // A MetricsService instance is typically created at application startup. It is | 10 // A MetricsService instance is typically created at application startup. It is |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 #include "base/strings/string_number_conversions.h" | 177 #include "base/strings/string_number_conversions.h" |
178 #include "base/strings/utf_string_conversions.h" | 178 #include "base/strings/utf_string_conversions.h" |
179 #include "base/threading/platform_thread.h" | 179 #include "base/threading/platform_thread.h" |
180 #include "base/threading/thread.h" | 180 #include "base/threading/thread.h" |
181 #include "base/threading/thread_restrictions.h" | 181 #include "base/threading/thread_restrictions.h" |
182 #include "base/tracked_objects.h" | 182 #include "base/tracked_objects.h" |
183 #include "base/values.h" | 183 #include "base/values.h" |
184 #include "chrome/browser/browser_process.h" | 184 #include "chrome/browser/browser_process.h" |
185 #include "chrome/browser/chrome_notification_types.h" | 185 #include "chrome/browser/chrome_notification_types.h" |
186 #include "chrome/browser/io_thread.h" | 186 #include "chrome/browser/io_thread.h" |
187 #include "chrome/browser/memory_details.h" | |
188 #include "chrome/browser/metrics/compression_utils.h" | 187 #include "chrome/browser/metrics/compression_utils.h" |
189 #include "chrome/browser/metrics/metrics_log.h" | 188 #include "chrome/browser/metrics/metrics_log.h" |
190 #include "chrome/browser/metrics/metrics_state_manager.h" | 189 #include "chrome/browser/metrics/metrics_state_manager.h" |
191 #include "chrome/browser/metrics/omnibox_metrics_provider.h" | 190 #include "chrome/browser/metrics/omnibox_metrics_provider.h" |
192 #include "chrome/browser/metrics/tracking_synchronizer.h" | 191 #include "chrome/browser/metrics/tracking_synchronizer.h" |
193 #include "chrome/browser/ui/browser_otr_state.h" | 192 #include "chrome/browser/ui/browser_otr_state.h" |
194 #include "chrome/common/chrome_constants.h" | 193 #include "chrome/common/chrome_constants.h" |
195 #include "chrome/common/chrome_switches.h" | 194 #include "chrome/common/chrome_switches.h" |
196 #include "chrome/common/crash_keys.h" | 195 #include "chrome/common/crash_keys.h" |
197 #include "chrome/common/pref_names.h" | 196 #include "chrome/common/pref_names.h" |
198 #include "chrome/common/render_messages.h" | |
199 #include "chrome/common/variations/variations_util.h" | 197 #include "chrome/common/variations/variations_util.h" |
200 #include "components/metrics/metrics_log_base.h" | 198 #include "components/metrics/metrics_log_base.h" |
201 #include "components/metrics/metrics_log_manager.h" | 199 #include "components/metrics/metrics_log_manager.h" |
202 #include "components/metrics/metrics_pref_names.h" | 200 #include "components/metrics/metrics_pref_names.h" |
203 #include "components/metrics/metrics_reporting_scheduler.h" | 201 #include "components/metrics/metrics_reporting_scheduler.h" |
204 #include "components/metrics/metrics_service_client.h" | 202 #include "components/metrics/metrics_service_client.h" |
205 #include "components/variations/entropy_provider.h" | 203 #include "components/variations/entropy_provider.h" |
206 #include "components/variations/metrics_util.h" | 204 #include "components/variations/metrics_util.h" |
207 #include "content/public/browser/child_process_data.h" | 205 #include "content/public/browser/child_process_data.h" |
208 #include "content/public/browser/histogram_fetcher.h" | |
209 #include "content/public/browser/load_notification_details.h" | 206 #include "content/public/browser/load_notification_details.h" |
210 #include "content/public/browser/notification_service.h" | 207 #include "content/public/browser/notification_service.h" |
211 #include "content/public/browser/plugin_service.h" | 208 #include "content/public/browser/plugin_service.h" |
212 #include "content/public/browser/render_process_host.h" | 209 #include "content/public/browser/render_process_host.h" |
213 #include "content/public/browser/user_metrics.h" | 210 #include "content/public/browser/user_metrics.h" |
214 #include "content/public/browser/web_contents.h" | 211 #include "content/public/browser/web_contents.h" |
215 #include "content/public/common/process_type.h" | 212 #include "content/public/common/process_type.h" |
216 #include "content/public/common/webplugininfo.h" | 213 #include "content/public/common/webplugininfo.h" |
217 #include "extensions/browser/process_map.h" | 214 #include "extensions/browser/process_map.h" |
218 #include "net/base/load_flags.h" | 215 #include "net/base/load_flags.h" |
219 #include "net/url_request/url_fetcher.h" | 216 #include "net/url_request/url_fetcher.h" |
220 | 217 |
221 #if defined(OS_CHROMEOS) | 218 #if defined(OS_CHROMEOS) |
222 #include "chrome/browser/chromeos/settings/cros_settings.h" | 219 #include "chrome/browser/chromeos/settings/cros_settings.h" |
223 #include "chromeos/system/statistics_provider.h" | 220 #include "chromeos/system/statistics_provider.h" |
224 #endif | 221 #endif |
225 | 222 |
226 #if defined(OS_WIN) | 223 #if defined(OS_WIN) |
227 #include <windows.h> // Needed for STATUS_* codes | 224 #include <windows.h> // Needed for STATUS_* codes |
228 #include "base/win/registry.h" | 225 #include "base/win/registry.h" |
229 #include "chrome/browser/metrics/google_update_metrics_provider_win.h" | 226 #include "chrome/browser/metrics/google_update_metrics_provider_win.h" |
230 #endif | 227 #endif |
231 | 228 |
232 #if defined(OS_ANDROID) | 229 #if defined(OS_ANDROID) |
233 // TODO(asvitkine): Move this out of MetricsService. | 230 // TODO(asvitkine): Move this out of MetricsService. |
234 #include "chrome/browser/metrics/android_metrics_provider.h" | 231 #include "chrome/browser/metrics/android_metrics_provider.h" |
235 #else | |
236 #include "chrome/browser/service_process/service_process_control.h" | |
237 #endif | 232 #endif |
238 | 233 |
239 using base::Time; | 234 using base::Time; |
240 using content::BrowserThread; | 235 using content::BrowserThread; |
241 using content::ChildProcessData; | 236 using content::ChildProcessData; |
242 using content::LoadNotificationDetails; | 237 using content::LoadNotificationDetails; |
243 using content::PluginService; | 238 using content::PluginService; |
244 using metrics::MetricsLogManager; | 239 using metrics::MetricsLogManager; |
245 | 240 |
246 namespace { | 241 namespace { |
(...skipping 11 matching lines...) Expand all Loading... |
258 #if defined(OS_ANDROID) || defined(OS_IOS) | 253 #if defined(OS_ANDROID) || defined(OS_IOS) |
259 // On mobile devices, a significant portion of sessions last less than a minute. | 254 // On mobile devices, a significant portion of sessions last less than a minute. |
260 // Use a shorter timer on these platforms to avoid losing data. | 255 // Use a shorter timer on these platforms to avoid losing data. |
261 // TODO(dfalcantara): To avoid delaying startup, tighten up initialization so | 256 // TODO(dfalcantara): To avoid delaying startup, tighten up initialization so |
262 // that it occurs after the user gets their initial page. | 257 // that it occurs after the user gets their initial page. |
263 const int kInitializationDelaySeconds = 5; | 258 const int kInitializationDelaySeconds = 5; |
264 #else | 259 #else |
265 const int kInitializationDelaySeconds = 30; | 260 const int kInitializationDelaySeconds = 30; |
266 #endif | 261 #endif |
267 | 262 |
268 // This specifies the amount of time to wait for all renderers to send their | |
269 // data. | |
270 const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds. | |
271 | |
272 // The maximum number of events in a log uploaded to the UMA server. | 263 // The maximum number of events in a log uploaded to the UMA server. |
273 const int kEventLimit = 2400; | 264 const int kEventLimit = 2400; |
274 | 265 |
275 // If an upload fails, and the transmission was over this byte count, then we | 266 // If an upload fails, and the transmission was over this byte count, then we |
276 // will discard the log, and not try to retransmit it. We also don't persist | 267 // will discard the log, and not try to retransmit it. We also don't persist |
277 // the log to the prefs for transmission during the next chrome session if this | 268 // the log to the prefs for transmission during the next chrome session if this |
278 // limit is exceeded. | 269 // limit is exceeded. |
279 const size_t kUploadLogAvoidRetransmitSize = 50000; | 270 const size_t kUploadLogAvoidRetransmitSize = 50000; |
280 | 271 |
281 // Interval, in minutes, between state saves. | 272 // Interval, in minutes, between state saves. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 // load. | 367 // load. |
377 int instances; | 368 int instances; |
378 | 369 |
379 // The number of times there was an error loading an instance of this child | 370 // The number of times there was an error loading an instance of this child |
380 // process. | 371 // process. |
381 int loading_errors; | 372 int loading_errors; |
382 | 373 |
383 int process_type; | 374 int process_type; |
384 }; | 375 }; |
385 | 376 |
386 // Handles asynchronous fetching of memory details. | |
387 // Will run the provided task after finished. | |
388 class MetricsMemoryDetails : public MemoryDetails { | |
389 public: | |
390 explicit MetricsMemoryDetails(const base::Closure& callback) | |
391 : callback_(callback) {} | |
392 | |
393 virtual void OnDetailsAvailable() OVERRIDE { | |
394 base::MessageLoop::current()->PostTask(FROM_HERE, callback_); | |
395 } | |
396 | |
397 private: | |
398 virtual ~MetricsMemoryDetails() {} | |
399 | |
400 base::Closure callback_; | |
401 DISALLOW_COPY_AND_ASSIGN(MetricsMemoryDetails); | |
402 }; | |
403 | |
404 // static | 377 // static |
405 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) { | 378 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) { |
406 DCHECK(IsSingleThreaded()); | 379 DCHECK(IsSingleThreaded()); |
407 metrics::MetricsStateManager::RegisterPrefs(registry); | 380 metrics::MetricsStateManager::RegisterPrefs(registry); |
408 | 381 |
409 registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0); | 382 registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0); |
410 registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0); | 383 registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0); |
411 registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string()); | 384 registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string()); |
412 registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0); | 385 registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0); |
413 registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true); | 386 registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 recording_active_(false), | 438 recording_active_(false), |
466 reporting_active_(false), | 439 reporting_active_(false), |
467 test_mode_active_(false), | 440 test_mode_active_(false), |
468 state_(INITIALIZED), | 441 state_(INITIALIZED), |
469 has_initial_stability_log_(false), | 442 has_initial_stability_log_(false), |
470 idle_since_last_transmission_(false), | 443 idle_since_last_transmission_(false), |
471 session_id_(-1), | 444 session_id_(-1), |
472 next_window_id_(0), | 445 next_window_id_(0), |
473 self_ptr_factory_(this), | 446 self_ptr_factory_(this), |
474 state_saver_factory_(this), | 447 state_saver_factory_(this), |
475 waiting_for_asynchronous_reporting_step_(false), | 448 waiting_for_asynchronous_reporting_step_(false) { |
476 num_async_histogram_fetches_in_progress_(0) { | |
477 DCHECK(IsSingleThreaded()); | 449 DCHECK(IsSingleThreaded()); |
478 DCHECK(state_manager_); | 450 DCHECK(state_manager_); |
479 DCHECK(client_); | 451 DCHECK(client_); |
480 | 452 |
481 #if defined(OS_ANDROID) | 453 #if defined(OS_ANDROID) |
482 // TODO(asvitkine): Move this out of MetricsService. | 454 // TODO(asvitkine): Move this out of MetricsService. |
483 RegisterMetricsProvider( | 455 RegisterMetricsProvider( |
484 scoped_ptr<metrics::MetricsProvider>(new AndroidMetricsProvider( | 456 scoped_ptr<metrics::MetricsProvider>(new AndroidMetricsProvider( |
485 g_browser_process->local_state()))); | 457 g_browser_process->local_state()))); |
486 #endif // defined(OS_ANDROID) | 458 #endif // defined(OS_ANDROID) |
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 scheduler_->UploadFinished(true /* healthy */, false /* no unsent logs */); | 1155 scheduler_->UploadFinished(true /* healthy */, false /* no unsent logs */); |
1184 return; | 1156 return; |
1185 } | 1157 } |
1186 // If there are unsent logs, send the next one. If not, start the asynchronous | 1158 // If there are unsent logs, send the next one. If not, start the asynchronous |
1187 // process of finalizing the current log for upload. | 1159 // process of finalizing the current log for upload. |
1188 if (state_ == SENDING_OLD_LOGS) { | 1160 if (state_ == SENDING_OLD_LOGS) { |
1189 DCHECK(log_manager_.has_unsent_logs()); | 1161 DCHECK(log_manager_.has_unsent_logs()); |
1190 log_manager_.StageNextLogForUpload(); | 1162 log_manager_.StageNextLogForUpload(); |
1191 SendStagedLog(); | 1163 SendStagedLog(); |
1192 } else { | 1164 } else { |
1193 StartFinalLogInfoCollection(); | 1165 client_->CollectFinalMetrics( |
| 1166 base::Bind(&MetricsService::OnFinalLogInfoCollectionDone, |
| 1167 self_ptr_factory_.GetWeakPtr())); |
1194 } | 1168 } |
1195 } | 1169 } |
1196 | 1170 |
1197 void MetricsService::StartFinalLogInfoCollection() { | |
1198 // Begin the multi-step process of collecting memory usage histograms: | |
1199 // First spawn a task to collect the memory details; when that task is | |
1200 // finished, it will call OnMemoryDetailCollectionDone. That will in turn | |
1201 // call HistogramSynchronization to collect histograms from all renderers and | |
1202 // then call OnHistogramSynchronizationDone to continue processing. | |
1203 DCHECK(!waiting_for_asynchronous_reporting_step_); | |
1204 waiting_for_asynchronous_reporting_step_ = true; | |
1205 | |
1206 base::Closure callback = | |
1207 base::Bind(&MetricsService::OnMemoryDetailCollectionDone, | |
1208 self_ptr_factory_.GetWeakPtr()); | |
1209 | |
1210 scoped_refptr<MetricsMemoryDetails> details( | |
1211 new MetricsMemoryDetails(callback)); | |
1212 details->StartFetch(MemoryDetails::UPDATE_USER_METRICS); | |
1213 | |
1214 // Collect WebCore cache information to put into a histogram. | |
1215 for (content::RenderProcessHost::iterator i( | |
1216 content::RenderProcessHost::AllHostsIterator()); | |
1217 !i.IsAtEnd(); i.Advance()) | |
1218 i.GetCurrentValue()->Send(new ChromeViewMsg_GetCacheResourceStats()); | |
1219 } | |
1220 | |
1221 void MetricsService::OnMemoryDetailCollectionDone() { | |
1222 DCHECK(IsSingleThreaded()); | |
1223 // This function should only be called as the callback from an ansynchronous | |
1224 // step. | |
1225 DCHECK(waiting_for_asynchronous_reporting_step_); | |
1226 | |
1227 // Create a callback_task for OnHistogramSynchronizationDone. | |
1228 base::Closure callback = base::Bind( | |
1229 &MetricsService::OnHistogramSynchronizationDone, | |
1230 self_ptr_factory_.GetWeakPtr()); | |
1231 | |
1232 base::TimeDelta timeout = | |
1233 base::TimeDelta::FromMilliseconds(kMaxHistogramGatheringWaitDuration); | |
1234 | |
1235 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 0); | |
1236 | |
1237 #if defined(OS_ANDROID) | |
1238 // Android has no service process. | |
1239 num_async_histogram_fetches_in_progress_ = 1; | |
1240 #else // OS_ANDROID | |
1241 num_async_histogram_fetches_in_progress_ = 2; | |
1242 // Run requests to service and content in parallel. | |
1243 if (!ServiceProcessControl::GetInstance()->GetHistograms(callback, timeout)) { | |
1244 // Assume |num_async_histogram_fetches_in_progress_| is not changed by | |
1245 // |GetHistograms()|. | |
1246 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 2); | |
1247 // Assign |num_async_histogram_fetches_in_progress_| above and decrement it | |
1248 // here to make code work even if |GetHistograms()| fired |callback|. | |
1249 --num_async_histogram_fetches_in_progress_; | |
1250 } | |
1251 #endif // OS_ANDROID | |
1252 | |
1253 // Set up the callback to task to call after we receive histograms from all | |
1254 // child processes. Wait time specifies how long to wait before absolutely | |
1255 // calling us back on the task. | |
1256 content::FetchHistogramsAsynchronously(base::MessageLoop::current(), callback, | |
1257 timeout); | |
1258 } | |
1259 | |
1260 void MetricsService::OnHistogramSynchronizationDone() { | |
1261 DCHECK(IsSingleThreaded()); | |
1262 // This function should only be called as the callback from an ansynchronous | |
1263 // step. | |
1264 DCHECK(waiting_for_asynchronous_reporting_step_); | |
1265 DCHECK_GT(num_async_histogram_fetches_in_progress_, 0); | |
1266 | |
1267 // Check if all expected requests finished. | |
1268 if (--num_async_histogram_fetches_in_progress_ > 0) | |
1269 return; | |
1270 | |
1271 waiting_for_asynchronous_reporting_step_ = false; | |
1272 OnFinalLogInfoCollectionDone(); | |
1273 } | |
1274 | |
1275 void MetricsService::OnFinalLogInfoCollectionDone() { | 1171 void MetricsService::OnFinalLogInfoCollectionDone() { |
1276 // If somehow there is a fetch in progress, we return and hope things work | 1172 // If somehow there is a fetch in progress, we return and hope things work |
1277 // out. The scheduler isn't informed since if this happens, the scheduler | 1173 // out. The scheduler isn't informed since if this happens, the scheduler |
1278 // will get a response from the upload. | 1174 // will get a response from the upload. |
1279 DCHECK(!current_fetch_.get()); | 1175 DCHECK(!current_fetch_.get()); |
1280 if (current_fetch_.get()) | 1176 if (current_fetch_.get()) |
1281 return; | 1177 return; |
1282 | 1178 |
1283 // Abort if metrics were turned off during the final info gathering. | 1179 // Abort if metrics were turned off during the final info gathering. |
1284 if (!recording_active()) { | 1180 if (!recording_active()) { |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1907 if (metrics_service) | 1803 if (metrics_service) |
1908 metrics_service->AddObserver(observer); | 1804 metrics_service->AddObserver(observer); |
1909 } | 1805 } |
1910 | 1806 |
1911 void MetricsServiceHelper::RemoveMetricsServiceObserver( | 1807 void MetricsServiceHelper::RemoveMetricsServiceObserver( |
1912 MetricsServiceObserver* observer) { | 1808 MetricsServiceObserver* observer) { |
1913 MetricsService* metrics_service = g_browser_process->metrics_service(); | 1809 MetricsService* metrics_service = g_browser_process->metrics_service(); |
1914 if (metrics_service) | 1810 if (metrics_service) |
1915 metrics_service->RemoveObserver(observer); | 1811 metrics_service->RemoveObserver(observer); |
1916 } | 1812 } |
OLD | NEW |