1# Lint as: python2, python3 2# Copyright 2019 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5import logging 6import re 7import time 8 9from autotest_lib.client.bin import utils 10from autotest_lib.client.common_lib.cros import chrome 11from autotest_lib.client.cros.input_playback import keyboard 12from autotest_lib.client.cros.power import power_status 13from autotest_lib.client.cros.power import power_test 14 15class power_VideoCall(power_test.power_Test): 16 """class for power_VideoCall test.""" 17 version = 1 18 19 video_url = 'https://storage.googleapis.com/chromiumos-test-assets-public/power_VideoCall/power_VideoCall.html' 20 doc_url = 'http://crospower.page.link/power_VideoCall_doc' 21 22 def initialize(self, seconds_period=20., pdash_note='', 23 force_discharge=False): 24 """initialize method.""" 25 super(power_VideoCall, self).initialize(seconds_period=seconds_period, 26 pdash_note=pdash_note, 27 force_discharge=force_discharge) 28 29 30 def run_once(self, 31 duration=7200, 32 preset='', 33 video_url='', 34 num_video=5, 35 multitask=True, 36 min_run_time_percent=100): 37 """run_once method. 38 39 @param duration: time in seconds to display url and measure power. 40 @param preset: preset of the camera record. Possible values are 41 'ultra' : 1080p30_vp9, 42 'high' : 720p30_vp9, 43 'medium' : 720p24_vp8, 44 'low' : 360p24_vp8 45 If not supplied, preset will be determined automatically. 46 @param video_url: url of video call simulator. 47 @param num_video: number of video including camera preview. 48 @param multitask: boolean indicate Google Docs multitask enablement. 49 @param min_run_time_percent: int between 0 and 100; 50 run time must be longer than 51 min_run_time_percent / 100.0 * duration. 52 """ 53 54 if not preset and not video_url: 55 preset = self._get_camera_preset() 56 if not video_url: 57 video_url = self.video_url 58 59 # Append preset to self.video_url for camera preset. 60 if preset: 61 video_url = '%s?preset=%s' % (video_url, preset) 62 63 extra_browser_args = self.get_extra_browser_args_for_camera_test() 64 with keyboard.Keyboard() as keys,\ 65 chrome.Chrome(init_network_controller=True, 66 gaia_login=False, 67 extra_browser_args=extra_browser_args, 68 autotest_ext=True) as cr: 69 70 # Move existing window to left half and open video page 71 tab_left = cr.browser.tabs[0] 72 tab_left.Activate() 73 if multitask: 74 keys.press_key('alt+[') 75 elif not tab_left.EvaluateJavaScript( 76 'document.webkitIsFullScreen'): 77 # Run in fullscreen when not multitask. 78 keys.press_key('f4') 79 80 logging.info('Navigating left window to %s', video_url) 81 tab_left.Navigate(video_url) 82 tab_left.WaitForDocumentReadyStateToBeComplete() 83 video_init_time = power_status.VideoFpsLogger.time_until_ready( 84 tab_left, num_video=num_video) 85 self.keyvals['video_init_time'] = video_init_time 86 87 tab_right = None 88 if multitask: 89 # Open Google Doc on right half 90 logging.info('Navigating right window to %s', self.doc_url) 91 cmd = 'chrome.windows.create({ url : "%s" });' % self.doc_url 92 cr.autotest_ext.EvaluateJavaScript(cmd) 93 tab_right = cr.browser.tabs[-1] 94 tab_right.Activate() 95 keys.press_key('alt+]') 96 tab_right.WaitForDocumentReadyStateToBeComplete() 97 time.sleep(5) 98 99 self._vlog = power_status.VideoFpsLogger(tab_left, 100 seconds_period=self._seconds_period, 101 checkpoint_logger=self._checkpoint_logger) 102 self._meas_logs.append(self._vlog) 103 104 # Start typing number block 105 self.start_measurements() 106 # TODO(b/226960942): Revert crrev.com/c/3556798 once root cause is 107 # found for why test fails before 2 hrs. 108 min_run_time = min_run_time_percent / 100.0 * duration 109 type_count = 0 110 while time.time() - self._start_time < duration: 111 if multitask: 112 keys.press_key('number_block') 113 type_count += 1 114 if type_count == 10: 115 keys.press_key('ctrl+a_backspace') 116 type_count = 0 117 else: 118 time.sleep(60) 119 120 if not tab_left.IsAlive(): 121 msg = 'Video tab crashed' 122 logging.error(msg) 123 if time.time() - self._start_time < min_run_time: 124 self._failure_messages.append(msg) 125 break 126 127 if tab_right and not tab_right.IsAlive(): 128 msg = 'Doc tab crashed' 129 logging.error(msg) 130 if time.time() - self._start_time < min_run_time: 131 self._failure_messages.append(msg) 132 break 133 134 self.status.refresh() 135 if self.status.is_low_battery(): 136 logging.info( 137 'Low battery, stop test early after %.0f minutes', 138 (time.time() - self._start_time) / 60) 139 break 140 141 if multitask: 142 self.collect_keypress_latency(cr) 143 144 def _get_camera_preset(self): 145 """Return camera preset appropriate to hw spec. 146 147 Preset will be determined using this logic. 148 - Newer Intel Core U/P-series CPU with fan -> 'high' 149 - Above without fan -> 'medium' 150 - AMD Ryzen CPU -> 'medium' 151 - High performance ARM -> 'medium' 152 - Other Intel Core CPU -> 'medium' 153 - AMD APU -> 'low' 154 - Intel N-series CPU -> 'low' 155 - Older ARM CPU -> 'low' 156 - Other CPU -> 'low' 157 """ 158 HIGH_IF_HAS_FAN_REGEX = r''' 159 Intel[ ]Core[ ]i[357]-[6-9][0-9]{3}U| # Intel Core i7-8650U 160 Intel[ ]Core[ ]i[357]-1[0-9]{3,4}[UPHG]| # 10510U, 1135G7, 1250P 161 Genuine[ ]Intel[ ]0000| # Unreleased Intel CPU 162 AMD[ ]Eng[ ]Sample # Unreleased AMD CPU 163 ''' 164 MEDIUM_REGEX = r''' 165 AMD[ ]Ryzen[ ][357][ ][3-9][0-9]{3}| # AMD Ryzen 7 3700 166 Intel[ ]Core[ ][im][357]-[0-9]{4,5}[UY]| # Intel Core i5-8200Y 167 Intel[ ]Core[ ][im][357]-[67]Y[0-9]{2}| # Intel Core m7-6Y75 168 Intel[ ]Pentium[ ][0-9]{4,5}[UY]| # Intel Pentium 6405U 169 Intel[ ]Celeron[ ][0-9]{4,5}[UY]| # Intel Celeron 5205U 170 qcom[ ]sc[0-9]{4}| # qcom sc7180 171 mediatek[ ]mt819[0-9] # mediatek mt8192 172 ''' 173 cpu_name = utils.get_cpu_name() 174 175 if re.search(HIGH_IF_HAS_FAN_REGEX, cpu_name, re.VERBOSE): 176 if power_status.has_fan(): 177 return 'high' 178 return 'medium' 179 180 if re.search(MEDIUM_REGEX, cpu_name, re.VERBOSE): 181 return 'medium' 182 183 return 'low' 184