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 |