• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, time
6
7from autotest_lib.server import test
8from autotest_lib.client.common_lib import error
9
10# After connecting/disconnecting the USB headset, we wait a while for the event
11# to be discovered, and CRAS to switch the output device.
12SWITCH_DELAY = 7
13
14class audio_AudioRoutingUSB(test.test):
15    version = 1
16
17    def get_opened_device(self, host):
18        """Returns the opened pcm device under /dev/snd."""
19        output = host.run('lsof -Fn +D /dev/snd', ignore_status=True).stdout
20        return parse_pcm_device(output);
21
22    def run_once(self, host):
23        try:
24            host.run('aplay /dev/zero </dev/null >/dev/null 2>&1 &')
25            self.run_test_while_audio_is_playing(host)
26        finally:
27            host.run('killall aplay')
28
29    def run_test_while_audio_is_playing(self, host):
30        host.servo.set('dut_usb2_prtctl', 'on')
31
32        # First disconnect the headset from DUT
33        host.servo.set('usb_mux_oe2', 'off')
34        time.sleep(SWITCH_DELAY)
35        dev1 = self.get_opened_device(host)
36
37        # Connect the headset to DUT
38        host.servo.set('usb_mux_oe2', 'on')
39        time.sleep(SWITCH_DELAY)
40        dev2 = self.get_opened_device(host)
41
42        # Disconnect the headset from DUT
43        host.servo.set('usb_mux_oe2', 'off')
44        time.sleep(SWITCH_DELAY)
45        dev3 = self.get_opened_device(host)
46
47        logging.info('dev1: %s, dev2: %s, dev3:%s', dev1, dev2, dev3)
48        if dev1 == dev2:
49            raise error.TestFail('Same audio device used when the headset is '
50                                 'connected. Make sure a USB headset is '
51                                 'plugged into DUT_USB (TYPE A/J4), and '
52                                 'DUT_IN (TYPE MICRO-B/J5) is '
53                                 'connected to a USB port on the device')
54        if dev1 != dev3:
55            raise error.TestFail('The audio device didn\'t switch back to the '
56                                 'original one after the USB headset is '
57                                 'unplugged')
58
59def parse_pcm_device(input):
60  """
61  Parses the output of lsof command. Returns the pcm device opened.
62
63  >>> input = '''
64  ... p1847
65  ... n/dev/snd/pcmC0D0p
66  ... n/dev/snd/controlC0
67  ... n/dev/snd/controlC0
68  ... n/dev/snd/controlC0
69  ... '''
70  >>> parse_pcm_device(input)
71  '/dev/snd/pcmC0D0p'
72  """
73  devices = set()
74  for line in input.split('\n'):
75    if line and line.startswith('n/dev/snd/pcmC'):
76      devices.add(line[1:])
77      logging.info('opened devices: %s', devices)
78      if len(devices) != 1:
79        raise error.TestError('Should open one and only one device')
80      return devices.pop()
81