desktopui_AudioFeedback.py revision 008de183011a8d8a390852ee33b2148721179801
1# Copyright (c) 2012 The Chromium 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
6
7from autotest_lib.client.bin import test, utils
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.common_lib.cros import chrome
10from autotest_lib.client.cros.audio import audio_helper
11
12_DEFAULT_NUM_CHANNELS = 2
13_DEFAULT_RECORD_DURATION = 15
14_DEFAULT_VOLUME_LEVEL = 100
15_DEFAULT_CAPTURE_GAIN = 2500
16
17_PLAYER_READY_TIMEOUT = 45
18
19
20class desktopui_AudioFeedback(test.test):
21    """Verifies if youtube playback can be captured."""
22    version = 1
23
24    def initialize(self,
25                   num_channels=_DEFAULT_NUM_CHANNELS,
26                   record_duration=_DEFAULT_RECORD_DURATION,
27                   volume_level=_DEFAULT_VOLUME_LEVEL,
28                   capture_gain=_DEFAULT_CAPTURE_GAIN):
29        """Setup the deps for the test.
30
31        Args:
32            num_channels: The number of channels on the device to test.
33            record_duration: How long of a sample to record.
34
35        Raises:
36            error.TestError if the deps can't be run.
37        """
38        self._volume_level = volume_level
39        self._capture_gain = capture_gain
40
41        cmd_rec = 'arecord -d %f -f dat' % record_duration
42        cmd_mix = '/usr/bin/cras_test_client --show_total_rms ' \
43                  '--duration_seconds %f --num_channels 2 ' \
44                  '--rate 48000 --loopback_file' % record_duration
45        self._ah = audio_helper.AudioHelper(self,
46                                            record_command=cmd_rec,
47                                            num_channels=num_channels,
48                                            mix_command=cmd_mix)
49        self._ah.setup_deps(['audioloop', 'sox'])
50
51        super(desktopui_AudioFeedback, self).initialize()
52
53    def play_video(self, player_ready_callback, tab):
54        """Plays a Youtube video to record audio samples.
55
56           Skipping initial 60 seconds so we can ignore initial silence
57           in the video.
58
59           @param player_ready_callback: callback when yt player is ready.
60           @param tab: the tab to load page for testing.
61        """
62        tab.Navigate(self._test_url)
63        utils.poll_for_condition(
64            condition=lambda: tab.EvaluateJavaScript('getPlayerStatus()') ==
65                    'player ready',
66            exception=error.TestError('Failed to load the Youtube player'),
67            sleep_interval=1,
68            timeout=_PLAYER_READY_TIMEOUT)
69
70        tab.ExecuteJavaScript('seekAndPlay()')
71        if player_ready_callback:
72            player_ready_callback()
73
74    def run_once(self):
75        """Entry point of this test."""
76        self._ah.set_volume_levels(self._volume_level, self._capture_gain)
77        if not self._ah.check_loopback_dongle():
78            raise error.TestError('Audio loopback dongle is in bad state.')
79
80        # Record a sample of "silence" to use as a noise profile.
81        noise_file_name = self._ah.create_wav_file("noise")
82        self._ah.record_sample(noise_file_name)
83
84        with chrome.Chrome() as cr:
85            cr.browser.SetHTTPServerDirectories(self.bindir)
86            self._test_url = cr.browser.http_server.UrlOf('youtube.html')
87            logging.info('Playing back youtube media file %s.', self._test_url)
88
89            cr.wait_for_browser_to_come_up()
90            if not cr.is_logged_in():
91                raise error.TestError('Logged out unexpectedly!')
92
93            # Play the same video to test all channels.
94            self.play_video(lambda: self._ah.loopback_test_channels(
95                    noise_file_name), cr.browser.tabs[0])
96