Home | History | Annotate | Download | only in audio_AudioRoutingUSB
      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 
      5 import logging, time
      6 
      7 from autotest_lib.server import test
      8 from 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.
     12 SWITCH_DELAY = 7
     13 
     14 class 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 
     59 def 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