Home | History | Annotate | Download | only in audio_AlsaAPI
      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