1# Copyright 2015 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 hashlib, logging, os, time 6 7 8from autotest_lib.client.bin import test 9from autotest_lib.client.common_lib import error, file_utils 10from autotest_lib.client.common_lib.cros import chrome 11from autotest_lib.client.cros import service_stopper 12from autotest_lib.client.cros.power import power_status, power_utils 13 14_DOWNLOAD_BASE = ('http://commondatastorage.googleapis.com/' 15 'chromiumos-test-assets-public/audio_power/') 16 17# Minimum battery charge percentage to run the test 18BATTERY_INITIAL_CHARGED_MIN = 10 19 20# Measurement duration in seconds. 21MEASUREMENT_DURATION = 150 22 23POWER_DESCRIPTION = 'avg_energy_rate_' 24 25# Time to exclude from calculation after playing audio [seconds]. 26STABILIZATION_DURATION = 10 27 28 29class audio_PlaybackPower(test.test): 30 """Captures power usage for audio playback.""" 31 32 version = 1 33 34 35 def initialize(self): 36 self._service_stopper = None 37 self._backlight = None 38 39 def run_power_test(self, audio_type): 40 """ 41 Captures power usage and reports it to the perf dashboard. 42 43 @param audio_type: audio format label to attach with perf keyval. 44 """ 45 46 self._backlight = power_utils.Backlight() 47 self._backlight.set_default() 48 49 self._service_stopper = service_stopper.ServiceStopper( 50 service_stopper.ServiceStopper.POWER_DRAW_SERVICES) 51 self._service_stopper.stop_services() 52 53 self._power_status = power_status.get_status() 54 # Verify that we are running on battery and the battery is sufficiently 55 # charged. 56 self._power_status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN) 57 58 measurements = [power_status.SystemPower( 59 self._power_status.battery_path)] 60 61 def get_power(): 62 power_logger = power_status.PowerLogger(measurements) 63 power_logger.start() 64 time.sleep(STABILIZATION_DURATION) 65 start_time = time.time() 66 time.sleep(MEASUREMENT_DURATION) 67 power_logger.checkpoint('result', start_time) 68 keyval = power_logger.calc() 69 logging.info('Power output %s', keyval) 70 return keyval['result_' + measurements[0].domain + '_pwr_avg'] 71 72 energy_rate = get_power() 73 perf_keyval = {} 74 perf_keyval[POWER_DESCRIPTION + audio_type] = energy_rate 75 self.output_perf_value(description=POWER_DESCRIPTION + audio_type, 76 value=energy_rate, units='W', 77 higher_is_better=False) 78 self.write_perf_keyval(perf_keyval) 79 80 81 def run_once(self, test_file, checksum): 82 local_path = os.path.join(self.bindir, '%s' % test_file) 83 file_utils.download_file(_DOWNLOAD_BASE + test_file, local_path) 84 logging.info('Downloaded file: %s. Expected checksum: %s', 85 local_path, checksum) 86 with open(local_path, 'r') as r: 87 md5sum = hashlib.md5(r.read()).hexdigest() 88 if md5sum != checksum: 89 raise error.TestError('unmatched md5 sum: %s' % md5sum) 90 with chrome.Chrome(init_network_controller=True) as cr: 91 cr.browser.platform.SetHTTPServerDirectories(self.bindir) 92 url = cr.browser.platform.http_server.UrlOf(local_path) 93 self.play_audio(cr.browser.tabs[0], url) 94 self.run_power_test(url.split('.')[-1]) 95 96 97 def play_audio(self, tab, url): 98 """Navigates to an audio file over http and plays it in loop. 99 100 @param tab: tab to open an audio stream. 101 @param url: audio/video test url. 102 """ 103 tab.Navigate(url) 104 tab.ExecuteJavaScript( 105 "document.getElementsByTagName('video')[0].loop=true") 106 tab.ExecuteJavaScript( 107 "document.getElementsByTagName('video')[0].volume=1") 108 109 110 def cleanup(self): 111 # cleanup() is run by common_lib/test.py. 112 if self._backlight: 113 self._backlight.restore() 114 if self._service_stopper: 115 self._service_stopper.restore_services() 116 117 super(audio_PlaybackPower, self).cleanup() 118