• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 logging
6import os
7import re
8
9from autotest_lib.client.bin import test
10from autotest_lib.client.bin import utils
11from autotest_lib.client.common_lib import error
12from autotest_lib.client.common_lib.cros import chrome
13from autotest_lib.client.cros.video import helper_logger
14
15EXTRA_BROWSER_ARGS = ['--use-fake-ui-for-media-stream']
16
17# Variables from the getusermedia.html page.
18IS_TEST_DONE = 'isTestDone'
19
20# Polling timeout.
21SEVERAL_MINUTES_IN_SECS = 240
22
23
24class 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