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
5"""The tab switching measurement.
6
7This measurement opens pages in different tabs. After all the tabs have opened,
8it cycles through each tab in sequence, and records a histogram of the time
9between when a tab was first requested to be shown, and when it was painted.
10Power usage is also measured.
11"""
12
13import time
14
15from metrics import histogram_util
16from metrics import power
17from telemetry.core import util
18from telemetry.page import page_measurement
19from telemetry.value import histogram
20
21# TODO: Revisit this test once multitab support is finalized.
22
23class TabSwitching(page_measurement.PageMeasurement):
24  def __init__(self):
25    super(TabSwitching, self).__init__()
26    self._first_page_in_pageset = True
27    self._power_metric = power.PowerMetric()
28
29  def CustomizeBrowserOptions(self, options):
30    options.AppendExtraBrowserArgs([
31        '--enable-stats-collection-bindings'
32    ])
33    power.PowerMetric.CustomizeBrowserOptions(options)
34
35  def DidStartBrowser(self, browser):
36    self._first_page_in_pageset = True
37
38  def TabForPage(self, page, browser):
39    if self._first_page_in_pageset:
40      # The initial browser window contains a single tab, navigate that tab
41      # rather than creating a new one.
42      self._first_page_in_pageset = False
43      return browser.tabs[0]
44
45    return browser.tabs.New()
46
47  def StopBrowserAfterPage(self, browser, page):
48    # Restart the browser after the last page in the pageset.
49    return len(browser.tabs) >= len(page.page_set.pages)
50
51  def MeasurePage(self, page, tab, results):
52    """On the last tab, cycle through each tab that was opened and then record
53    a single histogram for the tab switching metric."""
54    if len(tab.browser.tabs) != len(page.page_set.pages):
55      return
56
57    # Measure power usage of tabs after quiescence.
58    util.WaitFor(tab.HasReachedQuiescence, 60)
59
60    self._power_metric.Start(page, tab)
61    time.sleep(60)
62    self._power_metric.Stop(page, tab)
63    self._power_metric.AddResults(tab, results,)
64
65    histogram_name = 'MPArch.RWH_TabSwitchPaintDuration'
66    histogram_type = histogram_util.BROWSER_HISTOGRAM
67    display_name = 'MPArch_RWH_TabSwitchPaintDuration'
68    first_histogram = histogram_util.GetHistogram(
69        histogram_type, histogram_name, tab)
70    prev_histogram = first_histogram
71
72    for i in xrange(len(tab.browser.tabs)):
73      t = tab.browser.tabs[i]
74      t.Activate()
75      def _IsDone():
76        cur_histogram = histogram_util.GetHistogram(
77            histogram_type, histogram_name, tab)
78        diff_histogram = histogram_util.SubtractHistogram(
79            cur_histogram, prev_histogram)
80        return diff_histogram
81      util.WaitFor(_IsDone, 30)
82      prev_histogram = histogram_util.GetHistogram(
83          histogram_type, histogram_name, tab)
84
85    last_histogram = histogram_util.GetHistogram(
86        histogram_type, histogram_name, tab)
87    diff_histogram = histogram_util.SubtractHistogram(last_histogram,
88        first_histogram)
89
90    results.AddSummaryValue(
91        histogram.HistogramValue(None, display_name, '',
92                                 raw_value_json=diff_histogram,
93                                 important=False))
94