| 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 TimeMarker marker) |
| 445 { |
| 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 vector->push_back(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::AddMarker, |
| 459 base::Unretained(vector), |
| 460 marker)); |
| 461 } |
| 427 } | 462 } |
| 428 | 463 |
| 429 void BootTimesLoader::Observe( | 464 void BootTimesLoader::Observe( |
| 430 int type, | 465 int type, |
| 431 const content::NotificationSource& source, | 466 const content::NotificationSource& source, |
| 432 const content::NotificationDetails& details) { | 467 const content::NotificationDetails& details) { |
| 433 switch (type) { | 468 switch (type) { |
| 434 case chrome::NOTIFICATION_LOGIN_AUTHENTICATION: { | 469 case chrome::NOTIFICATION_LOGIN_AUTHENTICATION: { |
| 435 content::Details<AuthenticationNotificationDetails> auth_details(details); | 470 content::Details<AuthenticationNotificationDetails> auth_details(details); |
| 436 if (auth_details->success()) { | 471 if (auth_details->success()) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 GetRenderWidgetHost(&web_contents->GetController()); | 510 GetRenderWidgetHost(&web_contents->GetController()); |
| 476 render_widget_hosts_loading_.erase(render_widget_host); | 511 render_widget_hosts_loading_.erase(render_widget_host); |
| 477 break; | 512 break; |
| 478 } | 513 } |
| 479 default: | 514 default: |
| 480 break; | 515 break; |
| 481 } | 516 } |
| 482 } | 517 } |
| 483 | 518 |
| 484 } // namespace chromeos | 519 } // namespace chromeos |
| OLD | NEW |