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