| 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/time_ticks_experiment_win.h" | 191 #include "chrome/browser/metrics/time_ticks_experiment_win.h" |
| 193 #include "chrome/browser/metrics/tracking_synchronizer.h" | 192 #include "chrome/browser/metrics/tracking_synchronizer.h" |
| 194 #include "chrome/browser/net/http_pipelining_compatibility_client.h" | 193 #include "chrome/browser/net/http_pipelining_compatibility_client.h" |
| 195 #include "chrome/browser/net/network_stats.h" | 194 #include "chrome/browser/net/network_stats.h" |
| 196 #include "chrome/browser/ui/browser_otr_state.h" | 195 #include "chrome/browser/ui/browser_otr_state.h" |
| 197 #include "chrome/common/chrome_constants.h" | 196 #include "chrome/common/chrome_constants.h" |
| 198 #include "chrome/common/chrome_switches.h" | 197 #include "chrome/common/chrome_switches.h" |
| 199 #include "chrome/common/crash_keys.h" | 198 #include "chrome/common/crash_keys.h" |
| 200 #include "chrome/common/metrics/variations/variations_util.h" | 199 #include "chrome/common/metrics/variations/variations_util.h" |
| 201 #include "chrome/common/net/test_server_locations.h" | 200 #include "chrome/common/net/test_server_locations.h" |
| 202 #include "chrome/common/pref_names.h" | 201 #include "chrome/common/pref_names.h" |
| 203 #include "chrome/common/render_messages.h" | |
| 204 #include "components/metrics/metrics_log_manager.h" | 202 #include "components/metrics/metrics_log_manager.h" |
| 205 #include "components/metrics/metrics_pref_names.h" | 203 #include "components/metrics/metrics_pref_names.h" |
| 206 #include "components/metrics/metrics_reporting_scheduler.h" | 204 #include "components/metrics/metrics_reporting_scheduler.h" |
| 205 #include "components/metrics/metrics_service_client.h" |
| 207 #include "components/variations/entropy_provider.h" | 206 #include "components/variations/entropy_provider.h" |
| 208 #include "components/variations/metrics_util.h" | 207 #include "components/variations/metrics_util.h" |
| 209 #include "content/public/browser/child_process_data.h" | 208 #include "content/public/browser/child_process_data.h" |
| 210 #include "content/public/browser/histogram_fetcher.h" | |
| 211 #include "content/public/browser/load_notification_details.h" | 209 #include "content/public/browser/load_notification_details.h" |
| 212 #include "content/public/browser/notification_service.h" | 210 #include "content/public/browser/notification_service.h" |
| 213 #include "content/public/browser/plugin_service.h" | 211 #include "content/public/browser/plugin_service.h" |
| 214 #include "content/public/browser/render_process_host.h" | 212 #include "content/public/browser/render_process_host.h" |
| 215 #include "content/public/browser/user_metrics.h" | 213 #include "content/public/browser/user_metrics.h" |
| 216 #include "content/public/browser/web_contents.h" | 214 #include "content/public/browser/web_contents.h" |
| 217 #include "content/public/common/process_type.h" | 215 #include "content/public/common/process_type.h" |
| 218 #include "content/public/common/webplugininfo.h" | 216 #include "content/public/common/webplugininfo.h" |
| 219 #include "extensions/browser/process_map.h" | 217 #include "extensions/browser/process_map.h" |
| 220 #include "net/base/load_flags.h" | 218 #include "net/base/load_flags.h" |
| 221 #include "net/url_request/url_fetcher.h" | 219 #include "net/url_request/url_fetcher.h" |
| 222 | 220 |
| 223 // TODO(port): port browser_distribution.h. | 221 // TODO(port): port browser_distribution.h. |
| 224 #if !defined(OS_POSIX) | 222 #if !defined(OS_POSIX) |
| 225 #include "chrome/installer/util/browser_distribution.h" | 223 #include "chrome/installer/util/browser_distribution.h" |
| 226 #endif | 224 #endif |
| 227 | 225 |
| 228 #if defined(OS_CHROMEOS) | 226 #if defined(OS_CHROMEOS) |
| 229 #include "chrome/browser/chromeos/settings/cros_settings.h" | 227 #include "chrome/browser/chromeos/settings/cros_settings.h" |
| 230 #include "chromeos/system/statistics_provider.h" | 228 #include "chromeos/system/statistics_provider.h" |
| 231 #endif | 229 #endif |
| 232 | 230 |
| 233 #if defined(OS_WIN) | 231 #if defined(OS_WIN) |
| 234 #include <windows.h> // Needed for STATUS_* codes | 232 #include <windows.h> // Needed for STATUS_* codes |
| 235 #include "base/win/registry.h" | 233 #include "base/win/registry.h" |
| 236 #endif | 234 #endif |
| 237 | 235 |
| 238 #if !defined(OS_ANDROID) | |
| 239 #include "chrome/browser/service_process/service_process_control.h" | |
| 240 #endif | |
| 241 | |
| 242 using base::Time; | 236 using base::Time; |
| 243 using content::BrowserThread; | 237 using content::BrowserThread; |
| 244 using content::ChildProcessData; | 238 using content::ChildProcessData; |
| 245 using content::LoadNotificationDetails; | 239 using content::LoadNotificationDetails; |
| 246 using content::PluginService; | 240 using content::PluginService; |
| 247 using metrics::MetricsLogManager; | 241 using metrics::MetricsLogManager; |
| 248 | 242 |
| 249 namespace { | 243 namespace { |
| 250 | 244 |
| 251 // Check to see that we're being called on only one thread. | 245 // Check to see that we're being called on only one thread. |
| 252 bool IsSingleThreaded() { | 246 bool IsSingleThreaded() { |
| 253 static base::PlatformThreadId thread_id = 0; | 247 static base::PlatformThreadId thread_id = 0; |
| 254 if (!thread_id) | 248 if (!thread_id) |
| 255 thread_id = base::PlatformThread::CurrentId(); | 249 thread_id = base::PlatformThread::CurrentId(); |
| 256 return base::PlatformThread::CurrentId() == thread_id; | 250 return base::PlatformThread::CurrentId() == thread_id; |
| 257 } | 251 } |
| 258 | 252 |
| 259 // The delay, in seconds, after starting recording before doing expensive | 253 // The delay, in seconds, after starting recording before doing expensive |
| 260 // initialization work. | 254 // initialization work. |
| 261 #if defined(OS_ANDROID) || defined(OS_IOS) | 255 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 262 // On mobile devices, a significant portion of sessions last less than a minute. | 256 // On mobile devices, a significant portion of sessions last less than a minute. |
| 263 // Use a shorter timer on these platforms to avoid losing data. | 257 // Use a shorter timer on these platforms to avoid losing data. |
| 264 // TODO(dfalcantara): To avoid delaying startup, tighten up initialization so | 258 // TODO(dfalcantara): To avoid delaying startup, tighten up initialization so |
| 265 // that it occurs after the user gets their initial page. | 259 // that it occurs after the user gets their initial page. |
| 266 const int kInitializationDelaySeconds = 5; | 260 const int kInitializationDelaySeconds = 5; |
| 267 #else | 261 #else |
| 268 const int kInitializationDelaySeconds = 30; | 262 const int kInitializationDelaySeconds = 30; |
| 269 #endif | 263 #endif |
| 270 | 264 |
| 271 // This specifies the amount of time to wait for all renderers to send their | |
| 272 // data. | |
| 273 const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds. | |
| 274 | |
| 275 // The maximum number of events in a log uploaded to the UMA server. | 265 // The maximum number of events in a log uploaded to the UMA server. |
| 276 const int kEventLimit = 2400; | 266 const int kEventLimit = 2400; |
| 277 | 267 |
| 278 // If an upload fails, and the transmission was over this byte count, then we | 268 // If an upload fails, and the transmission was over this byte count, then we |
| 279 // will discard the log, and not try to retransmit it. We also don't persist | 269 // will discard the log, and not try to retransmit it. We also don't persist |
| 280 // the log to the prefs for transmission during the next chrome session if this | 270 // the log to the prefs for transmission during the next chrome session if this |
| 281 // limit is exceeded. | 271 // limit is exceeded. |
| 282 const size_t kUploadLogAvoidRetransmitSize = 50000; | 272 const size_t kUploadLogAvoidRetransmitSize = 50000; |
| 283 | 273 |
| 284 // Interval, in minutes, between state saves. | 274 // Interval, in minutes, between state saves. |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 // load. | 369 // load. |
| 380 int instances; | 370 int instances; |
| 381 | 371 |
| 382 // The number of times there was an error loading an instance of this child | 372 // The number of times there was an error loading an instance of this child |
| 383 // process. | 373 // process. |
| 384 int loading_errors; | 374 int loading_errors; |
| 385 | 375 |
| 386 int process_type; | 376 int process_type; |
| 387 }; | 377 }; |
| 388 | 378 |
| 389 // Handles asynchronous fetching of memory details. | |
| 390 // Will run the provided task after finished. | |
| 391 class MetricsMemoryDetails : public MemoryDetails { | |
| 392 public: | |
| 393 explicit MetricsMemoryDetails(const base::Closure& callback) | |
| 394 : callback_(callback) {} | |
| 395 | |
| 396 virtual void OnDetailsAvailable() OVERRIDE { | |
| 397 base::MessageLoop::current()->PostTask(FROM_HERE, callback_); | |
| 398 } | |
| 399 | |
| 400 private: | |
| 401 virtual ~MetricsMemoryDetails() {} | |
| 402 | |
| 403 base::Closure callback_; | |
| 404 DISALLOW_COPY_AND_ASSIGN(MetricsMemoryDetails); | |
| 405 }; | |
| 406 | |
| 407 // static | 379 // static |
| 408 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) { | 380 void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) { |
| 409 DCHECK(IsSingleThreaded()); | 381 DCHECK(IsSingleThreaded()); |
| 410 metrics::MetricsStateManager::RegisterPrefs(registry); | 382 metrics::MetricsStateManager::RegisterPrefs(registry); |
| 411 | 383 |
| 412 registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0); | 384 registry->RegisterInt64Pref(prefs::kStabilityLaunchTimeSec, 0); |
| 413 registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0); | 385 registry->RegisterInt64Pref(prefs::kStabilityLastTimestampSec, 0); |
| 414 registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string()); | 386 registry->RegisterStringPref(prefs::kStabilityStatsVersion, std::string()); |
| 415 registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0); | 387 registry->RegisterInt64Pref(prefs::kStabilityStatsBuildTime, 0); |
| 416 registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true); | 388 registry->RegisterBooleanPref(prefs::kStabilityExitedCleanly, true); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 recording_active_(false), | 439 recording_active_(false), |
| 468 reporting_active_(false), | 440 reporting_active_(false), |
| 469 test_mode_active_(false), | 441 test_mode_active_(false), |
| 470 state_(INITIALIZED), | 442 state_(INITIALIZED), |
| 471 has_initial_stability_log_(false), | 443 has_initial_stability_log_(false), |
| 472 idle_since_last_transmission_(false), | 444 idle_since_last_transmission_(false), |
| 473 session_id_(-1), | 445 session_id_(-1), |
| 474 next_window_id_(0), | 446 next_window_id_(0), |
| 475 self_ptr_factory_(this), | 447 self_ptr_factory_(this), |
| 476 state_saver_factory_(this), | 448 state_saver_factory_(this), |
| 477 waiting_for_asynchronous_reporting_step_(false), | 449 waiting_for_asynchronous_reporting_step_(false) { |
| 478 num_async_histogram_fetches_in_progress_(0) { | |
| 479 DCHECK(IsSingleThreaded()); | 450 DCHECK(IsSingleThreaded()); |
| 480 DCHECK(state_manager_); | 451 DCHECK(state_manager_); |
| 481 DCHECK(client_); | 452 DCHECK(client_); |
| 482 | 453 |
| 483 // TODO(asvitkine): Move this out of MetricsService. | 454 // TODO(asvitkine): Move this out of MetricsService. |
| 484 RegisterMetricsProvider( | 455 RegisterMetricsProvider( |
| 485 scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider)); | 456 scoped_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider)); |
| 486 | 457 |
| 487 BrowserChildProcessObserver::Add(this); | 458 BrowserChildProcessObserver::Add(this); |
| 488 } | 459 } |
| (...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 scheduler_->UploadFinished(true /* healthy */, false /* no unsent logs */); | 1208 scheduler_->UploadFinished(true /* healthy */, false /* no unsent logs */); |
| 1238 return; | 1209 return; |
| 1239 } | 1210 } |
| 1240 // If there are unsent logs, send the next one. If not, start the asynchronous | 1211 // If there are unsent logs, send the next one. If not, start the asynchronous |
| 1241 // process of finalizing the current log for upload. | 1212 // process of finalizing the current log for upload. |
| 1242 if (state_ == SENDING_OLD_LOGS) { | 1213 if (state_ == SENDING_OLD_LOGS) { |
| 1243 DCHECK(log_manager_.has_unsent_logs()); | 1214 DCHECK(log_manager_.has_unsent_logs()); |
| 1244 log_manager_.StageNextLogForUpload(); | 1215 log_manager_.StageNextLogForUpload(); |
| 1245 SendStagedLog(); | 1216 SendStagedLog(); |
| 1246 } else { | 1217 } else { |
| 1247 StartFinalLogInfoCollection(); | 1218 client_->CollectFinalMetrics( |
| 1219 base::Bind(&MetricsService::OnFinalLogInfoCollectionDone, |
| 1220 self_ptr_factory_.GetWeakPtr())); |
| 1248 } | 1221 } |
| 1249 } | 1222 } |
| 1250 | 1223 |
| 1251 void MetricsService::StartFinalLogInfoCollection() { | |
| 1252 // Begin the multi-step process of collecting memory usage histograms: | |
| 1253 // First spawn a task to collect the memory details; when that task is | |
| 1254 // finished, it will call OnMemoryDetailCollectionDone. That will in turn | |
| 1255 // call HistogramSynchronization to collect histograms from all renderers and | |
| 1256 // then call OnHistogramSynchronizationDone to continue processing. | |
| 1257 DCHECK(!waiting_for_asynchronous_reporting_step_); | |
| 1258 waiting_for_asynchronous_reporting_step_ = true; | |
| 1259 | |
| 1260 base::Closure callback = | |
| 1261 base::Bind(&MetricsService::OnMemoryDetailCollectionDone, | |
| 1262 self_ptr_factory_.GetWeakPtr()); | |
| 1263 | |
| 1264 scoped_refptr<MetricsMemoryDetails> details( | |
| 1265 new MetricsMemoryDetails(callback)); | |
| 1266 details->StartFetch(MemoryDetails::UPDATE_USER_METRICS); | |
| 1267 | |
| 1268 // Collect WebCore cache information to put into a histogram. | |
| 1269 for (content::RenderProcessHost::iterator i( | |
| 1270 content::RenderProcessHost::AllHostsIterator()); | |
| 1271 !i.IsAtEnd(); i.Advance()) | |
| 1272 i.GetCurrentValue()->Send(new ChromeViewMsg_GetCacheResourceStats()); | |
| 1273 } | |
| 1274 | |
| 1275 void MetricsService::OnMemoryDetailCollectionDone() { | |
| 1276 DCHECK(IsSingleThreaded()); | |
| 1277 // This function should only be called as the callback from an ansynchronous | |
| 1278 // step. | |
| 1279 DCHECK(waiting_for_asynchronous_reporting_step_); | |
| 1280 | |
| 1281 // Create a callback_task for OnHistogramSynchronizationDone. | |
| 1282 base::Closure callback = base::Bind( | |
| 1283 &MetricsService::OnHistogramSynchronizationDone, | |
| 1284 self_ptr_factory_.GetWeakPtr()); | |
| 1285 | |
| 1286 base::TimeDelta timeout = | |
| 1287 base::TimeDelta::FromMilliseconds(kMaxHistogramGatheringWaitDuration); | |
| 1288 | |
| 1289 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 0); | |
| 1290 | |
| 1291 #if defined(OS_ANDROID) | |
| 1292 // Android has no service process. | |
| 1293 num_async_histogram_fetches_in_progress_ = 1; | |
| 1294 #else // OS_ANDROID | |
| 1295 num_async_histogram_fetches_in_progress_ = 2; | |
| 1296 // Run requests to service and content in parallel. | |
| 1297 if (!ServiceProcessControl::GetInstance()->GetHistograms(callback, timeout)) { | |
| 1298 // Assume |num_async_histogram_fetches_in_progress_| is not changed by | |
| 1299 // |GetHistograms()|. | |
| 1300 DCHECK_EQ(num_async_histogram_fetches_in_progress_, 2); | |
| 1301 // Assign |num_async_histogram_fetches_in_progress_| above and decrement it | |
| 1302 // here to make code work even if |GetHistograms()| fired |callback|. | |
| 1303 --num_async_histogram_fetches_in_progress_; | |
| 1304 } | |
| 1305 #endif // OS_ANDROID | |
| 1306 | |
| 1307 // Set up the callback to task to call after we receive histograms from all | |
| 1308 // child processes. Wait time specifies how long to wait before absolutely | |
| 1309 // calling us back on the task. | |
| 1310 content::FetchHistogramsAsynchronously(base::MessageLoop::current(), callback, | |
| 1311 timeout); | |
| 1312 } | |
| 1313 | |
| 1314 void MetricsService::OnHistogramSynchronizationDone() { | |
| 1315 DCHECK(IsSingleThreaded()); | |
| 1316 // This function should only be called as the callback from an ansynchronous | |
| 1317 // step. | |
| 1318 DCHECK(waiting_for_asynchronous_reporting_step_); | |
| 1319 DCHECK_GT(num_async_histogram_fetches_in_progress_, 0); | |
| 1320 | |
| 1321 // Check if all expected requests finished. | |
| 1322 if (--num_async_histogram_fetches_in_progress_ > 0) | |
| 1323 return; | |
| 1324 | |
| 1325 waiting_for_asynchronous_reporting_step_ = false; | |
| 1326 OnFinalLogInfoCollectionDone(); | |
| 1327 } | |
| 1328 | |
| 1329 void MetricsService::OnFinalLogInfoCollectionDone() { | 1224 void MetricsService::OnFinalLogInfoCollectionDone() { |
| 1330 // If somehow there is a fetch in progress, we return and hope things work | 1225 // If somehow there is a fetch in progress, we return and hope things work |
| 1331 // out. The scheduler isn't informed since if this happens, the scheduler | 1226 // out. The scheduler isn't informed since if this happens, the scheduler |
| 1332 // will get a response from the upload. | 1227 // will get a response from the upload. |
| 1333 DCHECK(!current_fetch_.get()); | 1228 DCHECK(!current_fetch_.get()); |
| 1334 if (current_fetch_.get()) | 1229 if (current_fetch_.get()) |
| 1335 return; | 1230 return; |
| 1336 | 1231 |
| 1337 // Abort if metrics were turned off during the final info gathering. | 1232 // Abort if metrics were turned off during the final info gathering. |
| 1338 if (!recording_active()) { | 1233 if (!recording_active()) { |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1972 if (metrics_service) | 1867 if (metrics_service) |
| 1973 metrics_service->AddObserver(observer); | 1868 metrics_service->AddObserver(observer); |
| 1974 } | 1869 } |
| 1975 | 1870 |
| 1976 void MetricsServiceHelper::RemoveMetricsServiceObserver( | 1871 void MetricsServiceHelper::RemoveMetricsServiceObserver( |
| 1977 MetricsServiceObserver* observer) { | 1872 MetricsServiceObserver* observer) { |
| 1978 MetricsService* metrics_service = g_browser_process->metrics_service(); | 1873 MetricsService* metrics_service = g_browser_process->metrics_service(); |
| 1979 if (metrics_service) | 1874 if (metrics_service) |
| 1980 metrics_service->RemoveObserver(observer); | 1875 metrics_service->RemoveObserver(observer); |
| 1981 } | 1876 } |
| OLD | NEW |