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_->OnFinalLogCollection( |
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()); | |
Ilya Sherman
2014/05/21 13:37:07
Hmm, why did you drop this DCHECK?
Alexei Svitkine (slow)
2014/05/21 14:20:15
I didn't drop it in so much as I didn't re-create
| |
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 |