Home | History | Annotate | Download | only in video_WebRtcCamera
      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 
      5 import logging
      6 import os
      7 import re
      8 
      9 from autotest_lib.client.bin import test
     10 from autotest_lib.client.bin import utils
     11 from autotest_lib.client.common_lib import error
     12 from autotest_lib.client.common_lib.cros import chrome
     13 from autotest_lib.client.cros.video import helper_logger
     14 
     15 EXTRA_BROWSER_ARGS = ['--use-fake-ui-for-media-stream']
     16 
     17 # Variables from the getusermedia.html page.
     18 IS_TEST_DONE = 'isTestDone'
     19 
     20 # Polling timeout.
     21 SEVERAL_MINUTES_IN_SECS = 240
     22 
     23 
     24 class video_WebRtcCamera(test.test):
     25     """Local getUserMedia test with webcam at VGA (and 720p, if supported)."""
     26     version = 1
     27 
     28     def start_getusermedia(self, cr):
     29         """Opens the test page.
     30 
     31         @param cr: Autotest Chrome instance.
     32         """
     33         cr.browser.platform.SetHTTPServerDirectories(self.bindir)
     34 
     35         self.tab = cr.browser.tabs[0]
     36         self.tab.Navigate(cr.browser.platform.http_server.UrlOf(
     37                 os.path.join(self.bindir, 'getusermedia.html')))
     38         self.tab.WaitForDocumentReadyStateToBeComplete()
     39 
     40 
     41     def webcam_supports_720p(self):
     42         """Checks if 720p capture supported.
     43 
     44         @returns: True if 720p supported, false if VGA is supported.
     45         @raises: TestError if neither 720p nor VGA are supported.
     46         """
     47         cmd = 'lsusb -v'
     48         # Get usb devices and make output a string with no newline marker.
     49         usb_devices = utils.system_output(cmd, ignore_status=True).splitlines()
     50         usb_devices = ''.join(usb_devices)
     51 
     52         # Check if 720p resolution supported.
     53         if re.search(r'\s+wWidth\s+1280\s+wHeight\s+720', usb_devices):
     54             return True
     55         # The device should support at least VGA.
     56         # Otherwise the cam must be broken.
     57         if re.search(r'\s+wWidth\s+640\s+wHeight\s+480', usb_devices):
     58             return False
     59         # This should not happen.
     60         raise error.TestFail(
     61                 'Could not find any cameras reporting '
     62                 'either VGA or 720p in lsusb output: %s' % usb_devices)
     63 
     64 
     65     def wait_test_completed(self, timeout_secs):
     66         """Waits until the test is done.
     67 
     68         @param timeout_secs Max time to wait in seconds.
     69 
     70         @raises TestError on timeout, or javascript eval fails.
     71         """
     72         def _test_done():
     73             is_test_done = self.tab.EvaluateJavaScript(IS_TEST_DONE)
     74             return is_test_done == 1
     75 
     76         utils.poll_for_condition(
     77             _test_done, timeout=timeout_secs, sleep_interval=1,
     78             desc=('getusermedia.html:reportTestDone did not run. Test did not '
     79                   'complete successfully.'))
     80 
     81     @helper_logger.video_log_wrapper
     82     def run_once(self):
     83         """Runs the test."""
     84         self.board = utils.get_current_board()
     85         with chrome.Chrome(extra_browser_args=EXTRA_BROWSER_ARGS +\
     86                            [helper_logger.chrome_vmodule_flag()],
     87                            init_network_controller=True) as cr:
     88             self.start_getusermedia(cr)
     89             self.print_perf_results()
     90 
     91 
     92     def print_perf_results(self):
     93         """Prints the perf results unless there was an error.
     94 
     95         @returns the empty string if perf results were printed, otherwise
     96                  a description of the error that occured.
     97         """
     98         self.wait_test_completed(SEVERAL_MINUTES_IN_SECS)
     99         try:
    100             results = self.tab.EvaluateJavaScript('getResults()')
    101         except Exception as e:
    102             raise error.TestFail('Failed to get getusermedia.html results', e)
    103         logging.info('Results: %s', results)
    104 
    105         errors = []
    106         for width_height, data in results.iteritems():
    107             resolution = re.sub(',', 'x', width_height)
    108             if data['cameraErrors']:
    109                 if (resolution == '1280x720' and
    110                         not self.webcam_supports_720p()):
    111                     logging.info('Accepting 720p failure since device webcam '
    112                                  'does not support 720p')
    113                     continue
    114 
    115                 # Else we had a VGA failure or a legit 720p failure.
    116                 errors.append('Camera error: %s for resolution '
    117                             '%s.' % (data['cameraErrors'], resolution))
    118                 continue
    119             if not data['frameStats']:
    120                 errors.append('Frame Stats is empty '
    121                               'for resolution: %s' % resolution)
    122                 continue
    123             self.output_perf_value(
    124                     description='black_frames_%s' % resolution,
    125                     value=data['frameStats']['numBlackFrames'],
    126                     units='frames', higher_is_better=False)
    127             self.output_perf_value(
    128                     description='frozen_frames_%s' % resolution,
    129                     value=data['frameStats']['numFrozenFrames'],
    130                     units='frames', higher_is_better=False)
    131             self.output_perf_value(
    132                     description='total_num_frames_%s' % resolution,
    133                     value=data['frameStats']['numFrames'],
    134                     units='frames', higher_is_better=True)
    135         if errors:
    136             raise error.TestFail('Found errors: %s' % ', '.join(errors))
    137