blob: 8377235da26d1eb63e79d819ad39a7a9a88fe717 [file] [log] [blame]
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json
import logging
from metrics import histogram_util
from metrics import Metric
from telemetry.core import util
class StartupMetric(Metric):
"""A metric for browser startup time.
User visible metrics:
process_creation_to_window_display: Time from browser process creation to
the time that the browser window initially becomes visible.
process_creation_to_foreground_tab_loaded: Time from browser process
creation to the time that the foreground tab is fully loaded.
process_creation_to_all_tabs_loaded: Time from the browser process creation
to the time that all tabs have fully loaded.
Critical code progression:
process_creation_to_main: Time from process creation to the execution of the
browser's main() entry.
main_to_messageloop_start: Time from main() entry to the start of the UI
thread's message loop.
"""
def Start(self, page, tab):
raise NotImplementedError()
def Stop(self, page, tab):
raise NotImplementedError()
def _GetBrowserMainEntryTime(self, tab):
"""Returns the main entry time (in ms) of the browser."""
high_bytes = histogram_util.GetHistogramSum(
histogram_util.BROWSER_HISTOGRAM,
'Startup.BrowserMainEntryTimeAbsoluteHighWord',
tab)
low_bytes = histogram_util.GetHistogramSum(
histogram_util.BROWSER_HISTOGRAM,
'Startup.BrowserMainEntryTimeAbsoluteLowWord',
tab)
if high_bytes == 0 and low_bytes == 0:
return None
return (int(high_bytes) << 32) | (int(low_bytes) << 1)
def _GetTabLoadTimes(self, browser):
"""Returns a tuple of (foreground_tab_load_time, all_tabs_load_time)."""
foreground_tab_load_time = 0
all_tabs_load_time = 0
for i in xrange(len(browser.tabs)):
try:
tab = browser.tabs[i]
tab_load_timing_js = 'statsCollectionController.tabLoadTiming()'
def HasLoaded():
result = json.loads(tab.EvaluateJavaScript(tab_load_timing_js))
return 'load_duration_ms' in result and result['load_duration_ms']
util.WaitFor(HasLoaded, 60)
result = json.loads(tab.EvaluateJavaScript(tab_load_timing_js))
load_time = result['load_start_ms'] + result['load_duration_ms']
all_tabs_load_time = max(all_tabs_load_time, load_time)
if tab == browser.foreground_tab:
foreground_tab_load_time = load_time
except util.TimeoutException:
# Low memory Android devices may not be able to load more than
# one tab at a time, so may timeout when the test attempts to
# access a background tab. Ignore these tabs.
logging.error('Tab timed out on JavaScript access')
return foreground_tab_load_time, all_tabs_load_time
def AddResults(self, tab, results):
absolute_browser_main_entry_ms = self._GetBrowserMainEntryTime(tab)
process_creation_to_window_display_ms = histogram_util.GetHistogramSum(
histogram_util.BROWSER_HISTOGRAM, 'Startup.BrowserWindowDisplay', tab)
absolute_foreground_tab_loaded_ms, absolute_all_tabs_loaded_ms = \
self._GetTabLoadTimes(tab.browser)
process_creation_to_messageloop_start_ms = histogram_util.GetHistogramSum(
histogram_util.BROWSER_HISTOGRAM, 'Startup.BrowserMessageLoopStartTime',
tab)
main_to_messageloop_start_ms = histogram_util.GetHistogramSum(
histogram_util.BROWSER_HISTOGRAM,
'Startup.BrowserMessageLoopStartTimeFromMainEntry',
tab)
process_creation_to_main = (process_creation_to_messageloop_start_ms -
main_to_messageloop_start_ms)
# User visible.
results.Add('process_creation_to_window_display', 'ms',
process_creation_to_window_display_ms)
results.Add('process_creation_to_foreground_tab_loaded', 'ms',
absolute_foreground_tab_loaded_ms -
absolute_browser_main_entry_ms + process_creation_to_main)
results.Add('process_creation_to_all_tabs_loaded', 'ms',
absolute_all_tabs_loaded_ms -
absolute_browser_main_entry_ms + process_creation_to_main)
# Critical code progression.
results.Add('process_creation_to_main', 'ms',
process_creation_to_main)
results.Add('main_to_messageloop_start', 'ms',
main_to_messageloop_start_ms)