OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/startup_metric_utils/browser/startup_metric_utils.h" | 5 #include "components/startup_metric_utils/browser/startup_metric_utils.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <string> | 10 #include <string> |
(...skipping 21 matching lines...) Expand all Loading... | |
32 #include <winternl.h> | 32 #include <winternl.h> |
33 #include "base/win/win_util.h" | 33 #include "base/win/win_util.h" |
34 #endif | 34 #endif |
35 | 35 |
36 namespace startup_metric_utils { | 36 namespace startup_metric_utils { |
37 | 37 |
38 namespace { | 38 namespace { |
39 | 39 |
40 // Mark as volatile to defensively make sure usage is thread-safe. | 40 // Mark as volatile to defensively make sure usage is thread-safe. |
41 // Note that at the time of this writing, access is only on the UI thread. | 41 // Note that at the time of this writing, access is only on the UI thread. |
42 volatile bool g_non_browser_ui_displayed = false; | 42 volatile bool g_main_window_startup_interrupted = false; |
43 | 43 |
44 base::LazyInstance<base::TimeTicks>::Leaky g_process_creation_ticks = | 44 base::LazyInstance<base::TimeTicks>::Leaky g_process_creation_ticks = |
45 LAZY_INSTANCE_INITIALIZER; | 45 LAZY_INSTANCE_INITIALIZER; |
46 | 46 |
47 base::LazyInstance<base::TimeTicks>::Leaky g_browser_main_entry_point_ticks = | 47 base::LazyInstance<base::TimeTicks>::Leaky g_browser_main_entry_point_ticks = |
48 LAZY_INSTANCE_INITIALIZER; | 48 LAZY_INSTANCE_INITIALIZER; |
49 | 49 |
50 base::LazyInstance<base::TimeTicks>::Leaky g_renderer_main_entry_point_ticks = | 50 base::LazyInstance<base::TimeTicks>::Leaky g_renderer_main_entry_point_ticks = |
51 LAZY_INSTANCE_INITIALIZER; | 51 LAZY_INSTANCE_INITIALIZER; |
52 | 52 |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
550 | 550 |
551 } // namespace | 551 } // namespace |
552 | 552 |
553 void RegisterPrefs(PrefRegistrySimple* registry) { | 553 void RegisterPrefs(PrefRegistrySimple* registry) { |
554 DCHECK(registry); | 554 DCHECK(registry); |
555 registry->RegisterInt64Pref(prefs::kLastStartupTimestamp, 0); | 555 registry->RegisterInt64Pref(prefs::kLastStartupTimestamp, 0); |
556 registry->RegisterStringPref(prefs::kLastStartupVersion, std::string()); | 556 registry->RegisterStringPref(prefs::kLastStartupVersion, std::string()); |
557 registry->RegisterIntegerPref(prefs::kSameVersionStartupCount, 0); | 557 registry->RegisterIntegerPref(prefs::kSameVersionStartupCount, 0); |
558 } | 558 } |
559 | 559 |
560 bool WasNonBrowserUIDisplayed() { | 560 bool WasMainWindowStartupInterrupted() { |
561 return g_non_browser_ui_displayed; | 561 return g_main_window_startup_interrupted; |
562 } | 562 } |
563 | 563 |
564 void SetNonBrowserUIDisplayed() { | 564 void SetNonBrowserUIDisplayed() { |
565 g_non_browser_ui_displayed = true; | 565 g_main_window_startup_interrupted = true; |
566 } | |
567 | |
568 void SetBackgroundModeEnabled() { | |
569 g_main_window_startup_interrupted = true; | |
566 } | 570 } |
567 | 571 |
568 void RecordStartupProcessCreationTime(const base::Time& time) { | 572 void RecordStartupProcessCreationTime(const base::Time& time) { |
569 DCHECK(g_process_creation_ticks.Get().is_null()); | 573 DCHECK(g_process_creation_ticks.Get().is_null()); |
570 g_process_creation_ticks.Get() = StartupTimeToTimeTicks(time); | 574 g_process_creation_ticks.Get() = StartupTimeToTimeTicks(time); |
571 DCHECK(!g_process_creation_ticks.Get().is_null()); | 575 DCHECK(!g_process_creation_ticks.Get().is_null()); |
572 } | 576 } |
573 | 577 |
574 void RecordMainEntryPointTime(const base::Time& time) { | 578 void RecordMainEntryPointTime(const base::Time& time) { |
575 DCHECK(g_browser_main_entry_point_ticks.Get().is_null()); | 579 DCHECK(g_browser_main_entry_point_ticks.Get().is_null()); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
655 UMA_HISTOGRAM_LONG_TIMES, "Startup.LoadTime.ProcessCreateToDllMain2", | 659 UMA_HISTOGRAM_LONG_TIMES, "Startup.LoadTime.ProcessCreateToDllMain2", |
656 main_entry_ticks - process_creation_ticks); | 660 main_entry_ticks - process_creation_ticks); |
657 } | 661 } |
658 } | 662 } |
659 | 663 |
660 void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) { | 664 void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) { |
661 static bool is_first_call = true; | 665 static bool is_first_call = true; |
662 if (!is_first_call || ticks.is_null()) | 666 if (!is_first_call || ticks.is_null()) |
663 return; | 667 return; |
664 is_first_call = false; | 668 is_first_call = false; |
665 if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null()) | 669 if (WasMainWindowStartupInterrupted() || |
670 g_process_creation_ticks.Get().is_null()) | |
Alexei Svitkine (slow)
2017/04/18 16:01:32
Nit: Instead of checking for both conditions in a
themblsha
2017/04/19 15:06:09
Good idea, thanks!
| |
666 return; | 671 return; |
667 | 672 |
668 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( | 673 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( |
669 UMA_HISTOGRAM_LONG_TIMES, "Startup.BrowserWindowDisplay", | 674 UMA_HISTOGRAM_LONG_TIMES, "Startup.BrowserWindowDisplay", |
670 g_process_creation_ticks.Get(), ticks); | 675 g_process_creation_ticks.Get(), ticks); |
671 } | 676 } |
672 | 677 |
673 void RecordBrowserOpenTabsDelta(const base::TimeDelta& delta) { | 678 void RecordBrowserOpenTabsDelta(const base::TimeDelta& delta) { |
674 static bool is_first_call = true; | 679 static bool is_first_call = true; |
675 if (!is_first_call) | 680 if (!is_first_call) |
676 return; | 681 return; |
677 is_first_call = false; | 682 is_first_call = false; |
678 | 683 |
679 UMA_HISTOGRAM_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( | 684 UMA_HISTOGRAM_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( |
680 UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserOpenTabs", delta); | 685 UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserOpenTabs", delta); |
681 } | 686 } |
682 | 687 |
683 void RecordRendererMainEntryTime(const base::TimeTicks& ticks) { | 688 void RecordRendererMainEntryTime(const base::TimeTicks& ticks) { |
684 // Record the renderer main entry time, but don't log the UMA metric | 689 // Record the renderer main entry time, but don't log the UMA metric |
685 // immediately because the startup temperature is not known yet. | 690 // immediately because the startup temperature is not known yet. |
686 if (g_renderer_main_entry_point_ticks.Get().is_null()) | 691 if (g_renderer_main_entry_point_ticks.Get().is_null()) |
687 g_renderer_main_entry_point_ticks.Get() = ticks; | 692 g_renderer_main_entry_point_ticks.Get() = ticks; |
688 } | 693 } |
689 | 694 |
690 void RecordFirstWebContentsMainFrameLoad(const base::TimeTicks& ticks) { | 695 void RecordFirstWebContentsMainFrameLoad(const base::TimeTicks& ticks) { |
691 static bool is_first_call = true; | 696 static bool is_first_call = true; |
692 if (!is_first_call || ticks.is_null()) | 697 if (!is_first_call || ticks.is_null()) |
693 return; | 698 return; |
694 is_first_call = false; | 699 is_first_call = false; |
695 if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null()) | 700 if (WasMainWindowStartupInterrupted() || |
701 g_process_creation_ticks.Get().is_null()) | |
696 return; | 702 return; |
697 | 703 |
698 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( | 704 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( |
699 UMA_HISTOGRAM_LONG_TIMES_100, "Startup.FirstWebContents.MainFrameLoad2", | 705 UMA_HISTOGRAM_LONG_TIMES_100, "Startup.FirstWebContents.MainFrameLoad2", |
700 g_process_creation_ticks.Get(), ticks); | 706 g_process_creation_ticks.Get(), ticks); |
701 } | 707 } |
702 | 708 |
703 void RecordFirstWebContentsNonEmptyPaint(const base::TimeTicks& ticks) { | 709 void RecordFirstWebContentsNonEmptyPaint(const base::TimeTicks& ticks) { |
704 static bool is_first_call = true; | 710 static bool is_first_call = true; |
705 if (!is_first_call || ticks.is_null()) | 711 if (!is_first_call || ticks.is_null()) |
706 return; | 712 return; |
707 is_first_call = false; | 713 is_first_call = false; |
708 | 714 |
709 // Log Startup.BrowserMainToRendererMain now that the first renderer main | 715 // Log Startup.BrowserMainToRendererMain now that the first renderer main |
710 // entry time and the startup temperature are known. | 716 // entry time and the startup temperature are known. |
711 RecordRendererMainEntryHistogram(); | 717 RecordRendererMainEntryHistogram(); |
712 | 718 |
713 if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null()) | 719 if (WasMainWindowStartupInterrupted() || |
720 g_process_creation_ticks.Get().is_null()) | |
714 return; | 721 return; |
715 | 722 |
716 base::StackSamplingProfiler::SetProcessMilestone( | 723 base::StackSamplingProfiler::SetProcessMilestone( |
717 metrics::CallStackProfileMetricsProvider::FIRST_NONEMPTY_PAINT); | 724 metrics::CallStackProfileMetricsProvider::FIRST_NONEMPTY_PAINT); |
718 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( | 725 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( |
719 UMA_HISTOGRAM_LONG_TIMES_100, "Startup.FirstWebContents.NonEmptyPaint2", | 726 UMA_HISTOGRAM_LONG_TIMES_100, "Startup.FirstWebContents.NonEmptyPaint2", |
720 g_process_creation_ticks.Get(), ticks); | 727 g_process_creation_ticks.Get(), ticks); |
721 } | 728 } |
722 | 729 |
723 void RecordFirstWebContentsMainNavigationStart(const base::TimeTicks& ticks, | 730 void RecordFirstWebContentsMainNavigationStart(const base::TimeTicks& ticks, |
724 WebContentsWorkload workload) { | 731 WebContentsWorkload workload) { |
725 static bool is_first_call = true; | 732 static bool is_first_call = true; |
726 if (!is_first_call || ticks.is_null()) | 733 if (!is_first_call || ticks.is_null()) |
727 return; | 734 return; |
728 is_first_call = false; | 735 is_first_call = false; |
729 if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null()) | 736 if (WasMainWindowStartupInterrupted() || |
737 g_process_creation_ticks.Get().is_null()) | |
730 return; | 738 return; |
731 | 739 |
732 base::StackSamplingProfiler::SetProcessMilestone( | 740 base::StackSamplingProfiler::SetProcessMilestone( |
733 metrics::CallStackProfileMetricsProvider::MAIN_NAVIGATION_START); | 741 metrics::CallStackProfileMetricsProvider::MAIN_NAVIGATION_START); |
734 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( | 742 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( |
735 UMA_HISTOGRAM_LONG_TIMES_100, | 743 UMA_HISTOGRAM_LONG_TIMES_100, |
736 "Startup.FirstWebContents.MainNavigationStart", | 744 "Startup.FirstWebContents.MainNavigationStart", |
737 g_process_creation_ticks.Get(), ticks); | 745 g_process_creation_ticks.Get(), ticks); |
738 | 746 |
739 // Log extra information about this startup's workload. Only added to this | 747 // Log extra information about this startup's workload. Only added to this |
(...skipping 11 matching lines...) Expand all Loading... | |
751 ticks - g_process_creation_ticks.Get()); | 759 ticks - g_process_creation_ticks.Get()); |
752 } | 760 } |
753 } | 761 } |
754 | 762 |
755 void RecordFirstWebContentsMainNavigationFinished( | 763 void RecordFirstWebContentsMainNavigationFinished( |
756 const base::TimeTicks& ticks) { | 764 const base::TimeTicks& ticks) { |
757 static bool is_first_call = true; | 765 static bool is_first_call = true; |
758 if (!is_first_call || ticks.is_null()) | 766 if (!is_first_call || ticks.is_null()) |
759 return; | 767 return; |
760 is_first_call = false; | 768 is_first_call = false; |
761 if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null()) | 769 if (WasMainWindowStartupInterrupted() || |
770 g_process_creation_ticks.Get().is_null()) | |
762 return; | 771 return; |
gab
2017/04/18 13:52:15
Add {} per conditional becoming multi-lines (here
themblsha
2017/04/19 15:06:09
Alexei had a better idea :-)
| |
763 | 772 |
764 base::StackSamplingProfiler::SetProcessMilestone( | 773 base::StackSamplingProfiler::SetProcessMilestone( |
765 metrics::CallStackProfileMetricsProvider::MAIN_NAVIGATION_FINISHED); | 774 metrics::CallStackProfileMetricsProvider::MAIN_NAVIGATION_FINISHED); |
766 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( | 775 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE_AND_SAME_VERSION_COUNT( |
767 UMA_HISTOGRAM_LONG_TIMES_100, | 776 UMA_HISTOGRAM_LONG_TIMES_100, |
768 "Startup.FirstWebContents.MainNavigationFinished", | 777 "Startup.FirstWebContents.MainNavigationFinished", |
769 g_process_creation_ticks.Get(), ticks); | 778 g_process_creation_ticks.Get(), ticks); |
770 } | 779 } |
771 | 780 |
781 void RecordBrowserWindowFirstPaint(const base::TimeTicks& ticks) { | |
Alexei Svitkine (slow)
2017/04/18 16:01:32
Nit: TimeTicks should be passed by value (see head
themblsha
2017/04/19 15:06:09
Do you mean this? https://codereview.chromium.org/
Alexei Svitkine (slow)
2017/04/19 15:26:19
From base/time/time.h:
// All time classes are co
themblsha
2017/04/19 15:47:33
Ahhar! Removed references from the whole file.
| |
782 static bool is_first_call = true; | |
783 if (!is_first_call || ticks.is_null()) | |
784 return; | |
785 is_first_call = false; | |
786 if (WasMainWindowStartupInterrupted() || | |
787 g_process_creation_ticks.Get().is_null()) | |
788 return; | |
789 | |
790 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE( | |
791 UMA_HISTOGRAM_LONG_TIMES_100, "Startup.BrowserWindow.FirstPaint", | |
792 g_process_creation_ticks.Get(), ticks); | |
793 } | |
794 | |
795 void RecordBrowserWindowFirstPaintCompositingEnded( | |
796 const base::TimeTicks& ticks) { | |
797 static bool is_first_call = true; | |
798 if (!is_first_call || ticks.is_null()) | |
799 return; | |
800 is_first_call = false; | |
801 if (WasMainWindowStartupInterrupted() || | |
802 g_process_creation_ticks.Get().is_null()) | |
803 return; | |
804 | |
805 UMA_HISTOGRAM_AND_TRACE_WITH_TEMPERATURE( | |
806 UMA_HISTOGRAM_LONG_TIMES_100, | |
807 "Startup.BrowserWindow.FirstPaint.CompositingEnded", | |
808 g_process_creation_ticks.Get(), ticks); | |
809 } | |
810 | |
772 base::TimeTicks MainEntryPointTicks() { | 811 base::TimeTicks MainEntryPointTicks() { |
773 return g_browser_main_entry_point_ticks.Get(); | 812 return g_browser_main_entry_point_ticks.Get(); |
774 } | 813 } |
775 | 814 |
776 } // namespace startup_metric_utils | 815 } // namespace startup_metric_utils |
OLD | NEW |