1 # Copyright 2016 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 5 import os 6 import re 7 8 from autotest_lib.client.bin import test, utils 9 from autotest_lib.client.common_lib import error 10 from autotest_lib.client.cros.audio import alsa_utils 11 12 13 class audio_AlsaAPI(test.test): 14 """Checks that simple ALSA API functions correctly.""" 15 version = 2 16 _SND_DEV_DIR = '/dev/snd/' 17 _PLAYBACK_DEVICE_NAME = '^pcmC(\d+)D(\d+)p$' 18 # A dict of list of (card, device) to be skipped on some boards. 19 # Chell's HDMI device hw:0,4 can not be used without being plugged. 20 # Also, its HDMI device hw:0,5 and hw:0,6 are dummy devices. 21 _DEVICES_TO_BE_SKIPPED = {'chell': [(0, 4), (0, 5), (0, 6)]} 22 23 def run_once(self, to_test): 24 """Run alsa_api_test binary and verify its result. 25 26 Checks the source code of alsa_api_test in audiotest repo for detail. 27 28 @param to_test: support these test items: 29 move: Checks snd_pcm_forward API. 30 fill: Checks snd_pcm_mmap_begin API. 31 drop: Checks snd_pcm_drop API. 32 33 """ 34 self._devices = [] 35 self._find_sound_devices() 36 method_name = 'test_' + to_test 37 method = getattr(self, method_name) 38 for card_index, device_index in self._devices: 39 device = 'hw:%s,%s' % (card_index, device_index) 40 method(device) 41 42 43 def _skip_device(self, card_device): 44 """Skips devices on some boards. 45 46 @param card_device: A tuple of (card index, device index). 47 48 @returns: True if the device should be skipped. False otherwise. 49 50 """ 51 return card_device in self._DEVICES_TO_BE_SKIPPED.get( 52 utils.get_board().lower(), []) 53 54 55 def _find_sound_devices(self): 56 """Finds playback devices in sound device directory. 57 58 @raises: error.TestError if there is no playback device. 59 """ 60 filenames = os.listdir(self._SND_DEV_DIR) 61 for filename in filenames: 62 search = re.match(self._PLAYBACK_DEVICE_NAME, filename) 63 if search: 64 card_device = (int(search.group(1)), int(search.group(2))) 65 if not self._skip_device(card_device): 66 self._devices.append(card_device) 67 if not self._devices: 68 raise error.TestError('There is no playback device') 69 70 71 def _make_alsa_api_test_command(self, option, device): 72 """Makes command for alsa_api_test. 73 74 @param option: same as to_test in run_once. 75 @param device: device in hw:<card index>:<device index> format. 76 77 @returns: The command in a list of args. 78 79 """ 80 return ['alsa_api_test', '--device', device, '--%s' % option] 81 82 83 def test_move(self, device): 84 """Runs alsa_api_test command and checks the return code. 85 86 Test snd_pcm_forward can move appl_ptr to hw_ptr. 87 88 @param device: device in hw:<card index>:<device index> format. 89 90 @raises error.TestError if command fails. 91 92 """ 93 ret = utils.system( 94 command=self._make_alsa_api_test_command('move', device), 95 ignore_status=True) 96 if ret: 97 raise error.TestError( 98 'ALSA API failed to move appl_ptr on device %s' % device) 99 100 101 def test_fill(self, device): 102 """Runs alsa_api_test command and checks the return code. 103 104 Test snd_pcm_mmap_begin can provide the access to the buffer, and memset 105 can fill it with zeros without using snd_pcm_mmap_commit. 106 107 @param device: device in hw:<card index>:<device index> format. 108 109 @raises error.TestError if command fails. 110 111 """ 112 ret = utils.system( 113 command=self._make_alsa_api_test_command('fill', device), 114 ignore_status=True) 115 if ret: 116 raise error.TestError( 117 'ALSA API failed to fill buffer on device %s' % device) 118 119 120 def test_drop(self, device): 121 """Runs alsa_api_test command and checks the return code. 122 123 Test snd_pcm_drop can stop playback and reset hw_ptr to 0 in hardware. 124 125 @param device: device in hw:<card index>:<device index> format. 126 127 @raises error.TestError if command fails. 128 129 """ 130 ret = utils.system( 131 command=self._make_alsa_api_test_command('drop', device), 132 ignore_status=True) 133 if ret: 134 raise error.TestError( 135 'ALSA API failed to drop playback and reset hw_ptr' 136 'on device %s' % device) 137