• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018 The Chromium OS 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 logging, time
6
7from autotest_lib.client.bin import utils
8from autotest_lib.client.common_lib.cros import chrome
9from autotest_lib.client.common_lib import error
10from autotest_lib.client.cros import service_stopper
11from autotest_lib.client.cros.graphics import graphics_utils
12from autotest_lib.client.cros.power import power_rapl
13from autotest_lib.client.cros.power import power_status
14from autotest_lib.client.cros.power import power_utils
15
16TEST_NAME_AND_FLAGS = [
17    ['hw_overlays_hw_decode', ['']],
18    ['no_overlays_hw_decode', ['--enable-hardware-overlays=']],
19    ['hw_overlays_sw_decode', ['--disable-accelerated-video-decode']],
20    [
21        'no_overlays_sw_decode',
22        ['--disable-accelerated-video-decode', '--enable-hardware-overlays=']
23    ]
24]
25# Amount of time to wait for the URL to load and the video to start playing.
26PREAMBLE_DURATION_SECONDS = 8
27# Amount of time to let the video play while measuring power consumption.
28MEASUREMENT_DURATION_SECONDS = 12
29
30# Time in seconds to wait for cpu idle until giveup.
31IDLE_CPU_WAIT_TIMEOUT_SECONDS = 60.0
32# Maximum percent of cpu usage considered as idle.
33IDLE_CPU_LOAD_PERCENTAGE = 0.1
34
35GRAPH_NAME = 'power_consumption'
36
37
38class graphics_VideoRenderingPower(graphics_utils.GraphicsTest):
39    """This test renders on screen for a short while a video from a given
40
41    (controlled) URL while measuring the power consumption of the different SoC
42    domains.
43    """
44    version = 1
45    _backlight = None
46    _service_stopper = None
47    _power_status = None
48
49    def initialize(self):
50        super(graphics_VideoRenderingPower, self).initialize()
51
52        self._backlight = power_utils.Backlight()
53        self._backlight.set_default()
54
55        self._service_stopper = service_stopper.ServiceStopper(
56            service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
57        self._service_stopper.stop_services()
58
59        self._power_status = power_status.get_status()
60
61    def cleanup(self):
62        if self._backlight:
63            self._backlight.restore()
64        if self._service_stopper:
65            self._service_stopper.restore_services()
66        super(graphics_VideoRenderingPower, self).cleanup()
67
68    @graphics_utils.GraphicsTest.failure_report_decorator(
69        'graphics_VideoRenderingPower')
70    def run_once(self, video_url, video_short_name):
71        """Runs the graphics_VideoRenderingPower test.
72
73        @param video_url: URL with autoplay video inside. It's assumed that
74                 there's just one <video> in the HTML, and that it fits in the
75                 viewport.
76        @param video_short_name: short string describing the video; itt will be
77                 presented as part of the dashboard entry name.
78        """
79
80        # TODO(mcasas): Extend this test to non-Intel platforms.
81        if not power_utils.has_rapl_support():
82            logging.warning('This board has no RAPL power measurement support, '
83                            'skipping test.')
84            return
85
86        rapl = []
87        if power_utils.has_battery():
88            rapl.append(
89                power_status.SystemPower(self._power_status.battery_path))
90        else:
91            logging.warning('This board has no battery.')
92        rapl += power_rapl.create_rapl()
93
94        for test_name_and_flags in TEST_NAME_AND_FLAGS:
95            logging.info('Test case: %s', test_name_and_flags[0])
96            # Launch Chrome with the appropriate flag combination.
97            with chrome.Chrome(
98                    extra_browser_args=test_name_and_flags[1],
99                    init_network_controller=True) as cr:
100
101                if not utils.wait_for_idle_cpu(IDLE_CPU_WAIT_TIMEOUT_SECONDS,
102                                               IDLE_CPU_LOAD_PERCENTAGE):
103                    raise error.TestFail('Failed: Could not get idle CPU.')
104                if not utils.wait_for_cool_machine():
105                    raise error.TestFail('Failed: Could not get cold machine.')
106
107                tab = cr.browser.tabs[0]
108                tab.Navigate(video_url)
109                tab.WaitForDocumentReadyStateToBeComplete()
110                tab.EvaluateJavaScript(
111                    'document.'
112                    'getElementsByTagName(\'video\')[0].scrollIntoView(true)')
113
114                # Disabling hardware overlays is difficult because the flag is
115                # already in the browser. Instead, scroll a bit down to make the
116                # video bleed out of the viewport.
117                if '--enable-hardware-overlays=' in test_name_and_flags[1]:
118                    tab.EvaluateJavaScript('window.scrollBy(0, 1)')
119
120                power_logger = power_status.PowerLogger(rapl)
121                power_logger.start()
122                time.sleep(PREAMBLE_DURATION_SECONDS)
123
124                start_time = time.time()
125                time.sleep(MEASUREMENT_DURATION_SECONDS)
126                power_logger.checkpoint('result', start_time)
127
128                measurements = power_logger.calc()
129                logging.debug(measurements)
130
131                for category in sorted(measurements):
132                    if category.endswith('_pwr'):
133                        description = '%s_%s_%s' % (
134                            video_short_name, test_name_and_flags[0], category)
135                        self.output_perf_value(
136                            description=description,
137                            value=measurements[category],
138                            units='W',
139                            higher_is_better=False,
140                            graph=GRAPH_NAME)
141
142                    if category.endswith('_pwr_avg'):
143                        # write_perf_keyval() wants units (W) first in lowercase.
144                        description = '%s_%s_%s' % (
145                            video_short_name, test_name_and_flags[0], category)
146                        self.write_perf_keyval({
147                            'w_' + description: measurements[category]
148                        })
149