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