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 #include "chrome/browser/chromeos/boot_times_loader.h" | 5 #include "chrome/browser/chromeos/boot_times_loader.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 // Append numbers to the files. | 286 // Append numbers to the files. |
287 AppendFile(uptime_output, uptime.data(), uptime.size()); | 287 AppendFile(uptime_output, uptime.data(), uptime.size()); |
288 AppendFile(disk_output, disk.data(), disk.size()); | 288 AppendFile(disk_output, disk.data(), disk.size()); |
289 } | 289 } |
290 | 290 |
291 // static | 291 // static |
292 void BootTimesLoader::WriteTimes( | 292 void BootTimesLoader::WriteTimes( |
293 const std::string base_name, | 293 const std::string base_name, |
294 const std::string uma_name, | 294 const std::string uma_name, |
295 const std::string uma_prefix, | 295 const std::string uma_prefix, |
296 const std::vector<TimeMarker> login_times) { | 296 std::vector<TimeMarker> login_times) { |
297 const int kMinTimeMillis = 1; | 297 const int kMinTimeMillis = 1; |
298 const int kMaxTimeMillis = 30000; | 298 const int kMaxTimeMillis = 30000; |
299 const int kNumBuckets = 100; | 299 const int kNumBuckets = 100; |
300 const FilePath log_path(kLoginLogPath); | 300 const FilePath log_path(kLoginLogPath); |
301 | 301 |
302 // Need to sort by time since the entries may have been pushed onto the | |
303 // vector (on the UI thread) in a different order from which they were | |
304 // created (potentially on other threads). | |
305 std::sort(login_times.begin(), login_times.end()); | |
306 | |
302 base::Time first = login_times.front().time(); | 307 base::Time first = login_times.front().time(); |
303 base::Time last = login_times.back().time(); | 308 base::Time last = login_times.back().time(); |
304 base::TimeDelta total = last - first; | 309 base::TimeDelta total = last - first; |
305 base::Histogram* total_hist = base::Histogram::FactoryTimeGet( | 310 base::Histogram* total_hist = base::Histogram::FactoryTimeGet( |
306 uma_name, | 311 uma_name, |
307 base::TimeDelta::FromMilliseconds(kMinTimeMillis), | 312 base::TimeDelta::FromMilliseconds(kMinTimeMillis), |
308 base::TimeDelta::FromMilliseconds(kMaxTimeMillis), | 313 base::TimeDelta::FromMilliseconds(kMaxTimeMillis), |
309 kNumBuckets, | 314 kNumBuckets, |
310 base::Histogram::kUmaTargetedHistogramFlag); | 315 base::Histogram::kUmaTargetedHistogramFlag); |
311 total_hist->AddTime(total); | 316 total_hist->AddTime(total); |
(...skipping 26 matching lines...) Expand all Loading... | |
338 name.data()); | 343 name.data()); |
339 prev = tm.time(); | 344 prev = tm.time(); |
340 } | 345 } |
341 output += '\n'; | 346 output += '\n'; |
342 | 347 |
343 file_util::WriteFile( | 348 file_util::WriteFile( |
344 log_path.Append(base_name), output.data(), output.size()); | 349 log_path.Append(base_name), output.data(), output.size()); |
345 } | 350 } |
346 | 351 |
347 void BootTimesLoader::LoginDone() { | 352 void BootTimesLoader::LoginDone() { |
353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
348 AddLoginTimeMarker("LoginDone", true); | 354 AddLoginTimeMarker("LoginDone", true); |
349 RecordCurrentStats(kChromeFirstRender); | 355 RecordCurrentStats(kChromeFirstRender); |
350 registrar_.Remove(this, content::NOTIFICATION_LOAD_START, | 356 registrar_.Remove(this, content::NOTIFICATION_LOAD_START, |
351 content::NotificationService::AllSources()); | 357 content::NotificationService::AllSources()); |
352 registrar_.Remove(this, content::NOTIFICATION_LOAD_STOP, | 358 registrar_.Remove(this, content::NOTIFICATION_LOAD_STOP, |
353 content::NotificationService::AllSources()); | 359 content::NotificationService::AllSources()); |
354 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 360 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
355 content::NotificationService::AllSources()); | 361 content::NotificationService::AllSources()); |
356 registrar_.Remove(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT, | 362 registrar_.Remove(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT, |
357 content::NotificationService::AllSources()); | 363 content::NotificationService::AllSources()); |
358 // Don't swamp the FILE thread right away. | 364 // Don't swamp the FILE thread right away. |
359 BrowserThread::PostDelayedTask( | 365 BrowserThread::PostDelayedTask( |
360 BrowserThread::FILE, FROM_HERE, | 366 BrowserThread::FILE, FROM_HERE, |
361 base::Bind(&WriteTimes, kLoginTimes, kUmaLogin, kUmaLoginPrefix, | 367 base::Bind(&WriteTimes, kLoginTimes, kUmaLogin, kUmaLoginPrefix, |
362 login_time_markers_), | 368 login_time_markers_), |
363 kLoginTimeWriteDelayMs); | 369 kLoginTimeWriteDelayMs); |
364 } | 370 } |
365 | 371 |
366 void BootTimesLoader::WriteLogoutTimes() { | 372 void BootTimesLoader::WriteLogoutTimes() { |
373 // Either we're on the browser thread, or (more likely) Chrome is in the | |
374 // process of shutting down and we're on the main thread but the message loop | |
375 // has already been terminated. | |
376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | |
377 !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); | |
378 | |
367 WriteTimes(kLogoutTimes, | 379 WriteTimes(kLogoutTimes, |
368 kUmaLogout, | 380 kUmaLogout, |
369 kUmaLogoutPrefix, | 381 kUmaLogoutPrefix, |
370 logout_time_markers_); | 382 logout_time_markers_); |
371 } | 383 } |
372 | 384 |
373 void BootTimesLoader::RecordStats(const std::string& name, const Stats& stats) { | 385 void BootTimesLoader::RecordStats(const std::string& name, const Stats& stats) { |
374 BrowserThread::PostTask( | 386 BrowserThread::PostTask( |
375 BrowserThread::FILE, FROM_HERE, | 387 BrowserThread::FILE, FROM_HERE, |
376 base::Bind(&RecordStatsDelayed, name, stats.uptime, stats.disk)); | 388 base::Bind(&RecordStatsDelayed, name, stats.uptime, stats.disk)); |
(...skipping 15 matching lines...) Expand all Loading... | |
392 | 404 |
393 void BootTimesLoader::SaveChromeMainStats() { | 405 void BootTimesLoader::SaveChromeMainStats() { |
394 chrome_main_stats_ = GetCurrentStats(); | 406 chrome_main_stats_ = GetCurrentStats(); |
395 } | 407 } |
396 | 408 |
397 void BootTimesLoader::RecordChromeMainStats() { | 409 void BootTimesLoader::RecordChromeMainStats() { |
398 RecordStats(kChromeMain, chrome_main_stats_); | 410 RecordStats(kChromeMain, chrome_main_stats_); |
399 } | 411 } |
400 | 412 |
401 void BootTimesLoader::RecordLoginAttempted() { | 413 void BootTimesLoader::RecordLoginAttempted() { |
414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
402 login_time_markers_.clear(); | 415 login_time_markers_.clear(); |
403 AddLoginTimeMarker("LoginStarted", false); | 416 AddLoginTimeMarker("LoginStarted", false); |
404 if (!have_registered_) { | 417 if (!have_registered_) { |
405 have_registered_ = true; | 418 have_registered_ = true; |
406 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_AUTHENTICATION, | 419 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_AUTHENTICATION, |
407 content::NotificationService::AllSources()); | 420 content::NotificationService::AllSources()); |
408 registrar_.Add(this, content::NOTIFICATION_LOAD_START, | 421 registrar_.Add(this, content::NOTIFICATION_LOAD_START, |
409 content::NotificationService::AllSources()); | 422 content::NotificationService::AllSources()); |
410 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, | 423 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, |
411 content::NotificationService::AllSources()); | 424 content::NotificationService::AllSources()); |
412 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 425 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
413 content::NotificationService::AllSources()); | 426 content::NotificationService::AllSources()); |
414 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT, | 427 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT, |
415 content::NotificationService::AllSources()); | 428 content::NotificationService::AllSources()); |
416 } | 429 } |
417 } | 430 } |
418 | 431 |
419 void BootTimesLoader::AddLoginTimeMarker( | 432 void BootTimesLoader::AddLoginTimeMarker( |
420 const std::string& marker_name, bool send_to_uma) { | 433 const std::string& marker_name, bool send_to_uma) { |
421 login_time_markers_.push_back(TimeMarker(marker_name, send_to_uma)); | 434 AddMarker(&login_time_markers_, TimeMarker(marker_name, send_to_uma)); |
422 } | 435 } |
423 | 436 |
424 void BootTimesLoader::AddLogoutTimeMarker( | 437 void BootTimesLoader::AddLogoutTimeMarker( |
425 const std::string& marker_name, bool send_to_uma) { | 438 const std::string& marker_name, bool send_to_uma) { |
426 logout_time_markers_.push_back(TimeMarker(marker_name, send_to_uma)); | 439 AddMarker(&logout_time_markers_, TimeMarker(marker_name, send_to_uma)); |
440 } | |
441 | |
442 // static | |
443 void BootTimesLoader::AddMarker(std::vector<TimeMarker>* vector, | |
444 const TimeMarker& marker) | |
445 { | |
DaveMoore
2012/02/27 21:52:19
Why can't this all be done in AddMarker (with no A
Rick Byers
2012/02/27 21:58:23
No, AddMarkerImpl is the function that runs on the
| |
446 // The marker vectors can only be safely manipulated on the main thread. | |
447 // If we're late in the process of shutting down (eg. as can be the case at | |
448 // logout), then we have to assume we're on the main thread already. | |
449 if (BrowserThread::CurrentlyOn(BrowserThread::UI) || | |
450 !BrowserThread::IsMessageLoopValid(BrowserThread::UI)) { | |
451 AddMarkerImpl(vector, marker); | |
452 } else { | |
453 // Add the marker on the UI thread. | |
454 // Note that it's safe to use an unretained pointer to the vector because | |
455 // BootTimesLoader's lifetime exceeds that of the UI thread message loop. | |
456 BrowserThread::PostTask( | |
457 BrowserThread::UI, FROM_HERE, | |
458 base::Bind(&BootTimesLoader::AddMarkerImpl, | |
459 base::Unretained(vector), | |
460 marker)); | |
461 } | |
462 } | |
463 | |
464 // static | |
465 void BootTimesLoader::AddMarkerImpl(std::vector<TimeMarker>* vector, | |
466 TimeMarker marker) | |
467 { | |
468 vector->push_back(marker); | |
427 } | 469 } |
428 | 470 |
429 void BootTimesLoader::Observe( | 471 void BootTimesLoader::Observe( |
430 int type, | 472 int type, |
431 const content::NotificationSource& source, | 473 const content::NotificationSource& source, |
432 const content::NotificationDetails& details) { | 474 const content::NotificationDetails& details) { |
433 switch (type) { | 475 switch (type) { |
434 case chrome::NOTIFICATION_LOGIN_AUTHENTICATION: { | 476 case chrome::NOTIFICATION_LOGIN_AUTHENTICATION: { |
435 content::Details<AuthenticationNotificationDetails> auth_details(details); | 477 content::Details<AuthenticationNotificationDetails> auth_details(details); |
436 if (auth_details->success()) { | 478 if (auth_details->success()) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
475 GetRenderWidgetHost(&web_contents->GetController()); | 517 GetRenderWidgetHost(&web_contents->GetController()); |
476 render_widget_hosts_loading_.erase(render_widget_host); | 518 render_widget_hosts_loading_.erase(render_widget_host); |
477 break; | 519 break; |
478 } | 520 } |
479 default: | 521 default: |
480 break; | 522 break; |
481 } | 523 } |
482 } | 524 } |
483 | 525 |
484 } // namespace chromeos | 526 } // namespace chromeos |
OLD | NEW |