• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3# found in the LICENSE file.
4
5import json
6import logging
7
8from metrics import histogram_util
9from metrics import Metric
10from telemetry.core import util
11
12
13class StartupMetric(Metric):
14  """A metric for browser startup time.
15
16  User visible metrics:
17    process_creation_to_window_display: Time from browser process creation to
18        the time that the browser window initially becomes visible.
19    process_creation_to_foreground_tab_loaded: Time from browser process
20        creation to the time that the foreground tab is fully loaded.
21    process_creation_to_all_tabs_loaded: Time from the browser process creation
22        to the time that all tabs have fully loaded.
23
24  Critical code progression:
25    process_creation_to_main: Time from process creation to the execution of the
26        browser's main() entry.
27    main_to_messageloop_start: Time from main() entry to the start of the UI
28        thread's message loop.
29  """
30
31  def Start(self, page, tab):
32    raise NotImplementedError()
33
34  def Stop(self, page, tab):
35    raise NotImplementedError()
36
37  def _GetBrowserMainEntryTime(self, tab):
38    """Returns the main entry time (in ms) of the browser."""
39    high_bytes = histogram_util.GetHistogramSum(
40        histogram_util.BROWSER_HISTOGRAM,
41        'Startup.BrowserMainEntryTimeAbsoluteHighWord',
42        tab)
43    low_bytes = histogram_util.GetHistogramSum(
44        histogram_util.BROWSER_HISTOGRAM,
45        'Startup.BrowserMainEntryTimeAbsoluteLowWord',
46        tab)
47    if high_bytes == 0 and low_bytes == 0:
48      return None
49    return (int(high_bytes) << 32) | (int(low_bytes) << 1)
50
51  def _GetTabLoadTimes(self, browser):
52    """Returns a tuple of (foreground_tab_load_time, all_tabs_load_time)."""
53    foreground_tab_load_time = 0
54    all_tabs_load_time = 0
55    for i in xrange(len(browser.tabs)):
56      try:
57        tab = browser.tabs[i]
58        tab_load_timing_js = 'statsCollectionController.tabLoadTiming()'
59        def HasLoaded():
60          result = json.loads(tab.EvaluateJavaScript(tab_load_timing_js))
61          return 'load_duration_ms' in result and result['load_duration_ms']
62        util.WaitFor(HasLoaded, 60)
63        result = json.loads(tab.EvaluateJavaScript(tab_load_timing_js))
64        load_time = result['load_start_ms'] + result['load_duration_ms']
65        all_tabs_load_time = max(all_tabs_load_time, load_time)
66        if tab == browser.foreground_tab:
67          foreground_tab_load_time = load_time
68      except util.TimeoutException:
69        # Low memory Android devices may not be able to load more than
70        # one tab at a time, so may timeout when the test attempts to
71        # access a background tab. Ignore these tabs.
72        logging.error('Tab timed out on JavaScript access')
73    return foreground_tab_load_time, all_tabs_load_time
74
75  def AddResults(self, tab, results):
76    absolute_browser_main_entry_ms = self._GetBrowserMainEntryTime(tab)
77
78    process_creation_to_window_display_ms = histogram_util.GetHistogramSum(
79        histogram_util.BROWSER_HISTOGRAM, 'Startup.BrowserWindowDisplay', tab)
80    absolute_foreground_tab_loaded_ms, absolute_all_tabs_loaded_ms = \
81        self._GetTabLoadTimes(tab.browser)
82    process_creation_to_messageloop_start_ms = histogram_util.GetHistogramSum(
83        histogram_util.BROWSER_HISTOGRAM, 'Startup.BrowserMessageLoopStartTime',
84        tab)
85    main_to_messageloop_start_ms = histogram_util.GetHistogramSum(
86        histogram_util.BROWSER_HISTOGRAM,
87        'Startup.BrowserMessageLoopStartTimeFromMainEntry',
88        tab)
89    process_creation_to_main = (process_creation_to_messageloop_start_ms -
90                                main_to_messageloop_start_ms)
91
92    # User visible.
93    results.Add('process_creation_to_window_display', 'ms',
94                process_creation_to_window_display_ms)
95    results.Add('process_creation_to_foreground_tab_loaded', 'ms',
96                absolute_foreground_tab_loaded_ms -
97                absolute_browser_main_entry_ms + process_creation_to_main)
98    results.Add('process_creation_to_all_tabs_loaded', 'ms',
99                absolute_all_tabs_loaded_ms -
100                absolute_browser_main_entry_ms + process_creation_to_main)
101
102    # Critical code progression.
103    results.Add('process_creation_to_main', 'ms',
104                process_creation_to_main)
105    results.Add('main_to_messageloop_start', 'ms',
106                main_to_messageloop_start_ms)
107