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
7
8from autotest_lib.client.bin import test
9from autotest_lib.client.bin import utils
10from autotest_lib.client.common_lib import error
11from autotest_lib.client.common_lib.cros import chrome
12
13EXTRA_BROWSER_ARGS = ['--use-fake-ui-for-media-stream']
14
15# Polling timeout.
16TIMEOUT = 90
17
18
19class video_WebRtcPeerConnectionWithCamera(test.test):
20    """Tests a full WebRTC call with a real webcam."""
21    version = 1
22
23    def start_loopback(self, cr, video_codec):
24        """Opens WebRTC loopback page.
25
26        @param cr: Autotest Chrome instance.
27        @param video_codec: video codec to use.
28        """
29        cr.browser.platform.SetHTTPServerDirectories(self.bindir)
30
31        self.tab = cr.browser.tabs[0]
32        self.tab.Navigate(cr.browser.platform.http_server.UrlOf(
33                os.path.join(self.bindir, 'loopback.html')))
34        self.tab.WaitForDocumentReadyStateToBeComplete()
35        self.tab.EvaluateJavaScript(
36                "testWebRtcLoopbackCall('%s')" % video_codec)
37
38    def wait_test_completed(self, timeout_secs):
39        """Waits until the test is done.
40
41        @param timeout_secs Max time to wait in seconds.
42
43        @raises TestError on timeout, or javascript eval fails.
44        """
45        def _test_done():
46            status = self.tab.EvaluateJavaScript('getStatus()')
47            logging.debug(status);
48            return status != 'running'
49
50        utils.poll_for_condition(
51            _test_done, timeout=timeout_secs, sleep_interval=1,
52            desc='loopback.html reports itself as finished')
53
54    def run_once(self, video_codec):
55        """Runs the video_WebRtcPeerConnectionWithCamera test.
56
57        @param video_codec: video codec to use.
58        """
59        with chrome.Chrome(extra_browser_args=EXTRA_BROWSER_ARGS,
60                           init_network_controller=True) as cr:
61            self.start_loopback(cr, video_codec)
62            self.wait_test_completed(TIMEOUT)
63            self.print_loopback_result(video_codec)
64
65    def print_loopback_result(self, video_codec):
66        """Prints loopback results (unless we failed to retrieve them).
67
68        @param video_codec: video codec to use.
69        @raises TestError if the test failed outright.
70        """
71        status = self.tab.EvaluateJavaScript('getStatus()')
72        if status != 'ok-done':
73            raise error.TestFail('Failed: %s' % status)
74
75        results = self.tab.EvaluateJavaScript('getResults()')
76        logging.info('Camera Type: %s', results['cameraType'])
77        logging.info('PeerConnectionstats: %s', results['peerConnectionStats'])
78        logging.info('FrameStats: %s', results['frameStats'])
79
80        pc_stats = results.get('peerConnectionStats')
81        if not pc_stats:
82            raise error.TestFail('Peer Connection Stats is empty')
83        self.output_perf_value(
84                description='max_input_fps_%s' % video_codec,
85                value=pc_stats[1], units='fps', higher_is_better=True)
86        self.output_perf_value(
87                description='max_sent_fps_%s' % video_codec,
88                value=pc_stats[4], units='fps', higher_is_better=True)
89
90        frame_stats = results.get('frameStats')
91        if not frame_stats:
92            raise error.TestFail('Frame Stats is empty')
93
94        self.output_perf_value(
95                description='black_frames_%s' % video_codec,
96                value=frame_stats['numBlackFrames'],
97                units='frames', higher_is_better=False)
98        self.output_perf_value(
99                description='frozen_frames_%s' % video_codec,
100                value=frame_stats['numFrozenFrames'],
101                units='frames', higher_is_better=False)
102        self.output_perf_value(
103                description='total_num_frames_%s' % video_codec,
104                value=frame_stats['numFrames'],
105                units='frames', higher_is_better=True)
106