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.
8 from telemetry
.core
import exceptions
9 from telemetry
.value
import histogram_util
10 from telemetry
.value
import scalar
12 from metrics
import Metric
15 class StartupMetric(Metric
):
16 "A metric for browser startup time."
18 # Seconds to wait for page loading complete.
19 DEFAULT_LOADING_TIMEOUT
= 90
21 HISTOGRAMS_TO_RECORD
= {
22 'messageloop_start_time' :
23 'Startup.BrowserMessageLoopStartTimeFromMainEntry',
24 'window_display_time' : 'Startup.BrowserWindowDisplay',
25 'open_tabs_time' : 'Startup.BrowserOpenTabs',
26 'first_non_empty_paint_time' : 'Startup.FirstWebContents.NonEmptyPaint',
27 'first_main_frame_load_time' : 'Startup.FirstWebContents.MainFrameLoad'}
29 def Start(self
, page
, tab
):
30 raise NotImplementedError()
32 def Stop(self
, page
, tab
):
33 raise NotImplementedError()
35 def _GetBrowserMainEntryTime(self
, tab
):
36 """Returns the main entry time (in ms) of the browser."""
37 histogram_type
= histogram_util
.BROWSER_HISTOGRAM
38 high_bytes
= histogram_util
.GetHistogramSum(
40 'Startup.BrowserMainEntryTimeAbsoluteHighWord',
42 low_bytes
= histogram_util
.GetHistogramSum(
44 'Startup.BrowserMainEntryTimeAbsoluteLowWord',
46 if high_bytes
== 0 and low_bytes
== 0:
48 return (int(high_bytes
) << 32) |
(int(low_bytes
) << 1)
50 def _RecordTabLoadTimes(self
, tab
, browser_main_entry_time_ms
, results
):
51 """Records the tab load times for the browser. """
52 TabLoadTime
= collections
.namedtuple(
54 ['request_start_ms', 'load_end_ms'])
58 val
= t
.EvaluateJavaScript(exp
)
60 logging
.warn('%s undefined' % exp
)
65 t
.WaitForJavaScriptExpression(
66 'window.performance.timing["loadEventEnd"] > 0',
67 self
.DEFAULT_LOADING_TIMEOUT
)
69 # EvaluateJavaScript(window.performance.timing) doesn't guarantee to
70 # return the desired javascript object (crbug/472603). It may return an
71 # empty object. However getting individual field works.
72 # The behavior depends on Webkit implementation on different platforms.
73 load_event_end
= EvaluateInt(
74 'window.performance.timing["loadEventEnd"]')
75 request_start
= EvaluateInt(
76 'window.performance.timing["requestStart"]')
78 return TabLoadTime(request_start
, load_event_end
)
80 except exceptions
.TimeoutException
:
81 # Low memory Android devices may not be able to load more than
82 # one tab at a time, so may timeout when the test attempts to
83 # access a background tab. Ignore these tabs.
84 logging
.error("Tab timed out on JavaScript access")
86 # Only measure the foreground tab. We can't measure all tabs on Android
87 # because on Android the data of the background tabs is loaded on demand,
88 # when the user switches to them, rather than during startup. In view of
89 # this, to get the same measures on all platform, we only measure the
90 # foreground tab on all platforms.
91 foreground_tab_stats
= RecordOneTab(tab
.browser
.foreground_tab
)
93 if foreground_tab_stats
:
94 foreground_tab_load_complete
= (
95 foreground_tab_stats
.load_end_ms
- browser_main_entry_time_ms
)
96 results
.AddValue(scalar
.ScalarValue(
97 results
.current_page
, 'foreground_tab_load_complete', 'ms',
98 foreground_tab_load_complete
))
99 if foreground_tab_stats
.request_start_ms
> 0:
100 results
.AddValue(scalar
.ScalarValue(
101 results
.current_page
, 'foreground_tab_request_start', 'ms',
102 foreground_tab_stats
.request_start_ms
- browser_main_entry_time_ms
))
104 def AddResults(self
, tab
, results
):
105 get_histogram_js
= 'statsCollectionController.getBrowserHistogram("%s")'
107 for display_name
, histogram_name
in self
.HISTOGRAMS_TO_RECORD
.iteritems():
108 result
= tab
.EvaluateJavaScript(get_histogram_js
% histogram_name
)
109 result
= json
.loads(result
)
113 # For all the histograms logged here, there's a single entry so sum
114 # is the exact value for that entry.
115 measured_time
= result
['sum']
116 elif 'buckets' in result
:
118 (result
['buckets'][0]['high'] + result
['buckets'][0]['low']) / 2
120 results
.AddValue(scalar
.ScalarValue(
121 results
.current_page
, display_name
, 'ms', measured_time
))
123 # Get tab load times.
124 browser_main_entry_time_ms
= self
._GetBrowserMainEntryTime
(tab
)
125 if browser_main_entry_time_ms
is None:
126 print "Outdated Chrome version, browser main entry time not supported."
128 self
._RecordTabLoadTimes
(tab
, browser_main_entry_time_ms
, results
)