[autotest] audio_AlsaAPI: use hw:X,Y to access playback devices

The ALSA API behavior when accessing device using sysdefault is different
from the behavior when accessing device using hw:X,Y directly.
Use hw:X,Y to access and test all playback devices on the board instead
of testing only sysdefault device.

BUG=chromium:617516
TEST=run audio_AlsAPI test on auron_paine.

Change-Id: Ic43edf5b06ae398c0fd34bd83326de5948340262
Reviewed-on: https://chromium-review.googlesource.com/355893
Commit-Ready: Cheng-Yi Chiang <cychiang@chromium.org>
Tested-by: Cheng-Yi Chiang <cychiang@chromium.org>
Reviewed-by: Hsinyu Chao <hychao@chromium.org>
diff --git a/client/site_tests/audio_AlsaAPI/audio_AlsaAPI.py b/client/site_tests/audio_AlsaAPI/audio_AlsaAPI.py
index 6fb35f8..7ed4cdf 100644
--- a/client/site_tests/audio_AlsaAPI/audio_AlsaAPI.py
+++ b/client/site_tests/audio_AlsaAPI/audio_AlsaAPI.py
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import os
+import re
 
 from autotest_lib.client.bin import test, utils
 from autotest_lib.client.common_lib import error
@@ -10,8 +12,9 @@
 
 class audio_AlsaAPI(test.test):
     """Checks that simple ALSA API functions correctly."""
-    version = 1
-
+    version = 2
+    _SND_DEV_DIR = '/dev/snd/'
+    _PLAYBACK_DEVICE_NAME = '^pcmC(\d+)D(\d+)p$'
 
     def run_once(self, to_test):
         """Run alsa_api_test binary and verify its result.
@@ -22,62 +25,94 @@
                         move: Checks snd_pcm_forward API.
                         fill: Checks snd_pcm_mmap_begin API.
                         drop: Checks snd_pcm_drop API.
+
         """
-        self._device = alsa_utils.get_sysdefault_playback_device()
+        self._devices = []
+        self._find_sound_devices()
         method_name = 'test_' + to_test
         method = getattr(self, method_name)
-        method()
+        for card_index, device_index in self._devices:
+            device = 'hw:%s,%s' % (card_index, device_index)
+            method(device)
 
 
-    def _make_alsa_api_test_command(self, option):
+    def _find_sound_devices(self):
+        """Finds playback devices in sound device directory.
+
+        @raises: error.TestError if there is no playback device.
+        """
+        filenames = os.listdir(self._SND_DEV_DIR)
+        for filename in filenames:
+            search = re.match(self._PLAYBACK_DEVICE_NAME, filename)
+            if search:
+                self._devices.append((search.group(1), search.group(2)))
+        if not self._devices:
+            raise error.TestError('There is no playback device')
+
+
+    def _make_alsa_api_test_command(self, option, device):
         """Makes command for alsa_api_test.
 
         @param option: same as to_test in run_once.
+        @param device: device in hw:<card index>:<device index> format.
 
         @returns: The command in a list of args.
+
         """
-        return ['alsa_api_test', '--device', self._device, '--%s' % option]
+        return ['alsa_api_test', '--device', device, '--%s' % option]
 
 
-    def test_move(self):
+    def test_move(self, device):
         """Runs alsa_api_test command and checks the return code.
 
         Test snd_pcm_forward can move appl_ptr to hw_ptr.
 
+        @param device: device in hw:<card index>:<device index> format.
+
         @raises error.TestError if command fails.
+
         """
         ret = utils.system(
-                command=self._make_alsa_api_test_command('move'),
+                command=self._make_alsa_api_test_command('move', device),
                 ignore_status=True)
         if ret:
-            raise error.TestError('ALSA API failed to move appl_ptr')
+            raise error.TestError(
+                    'ALSA API failed to move appl_ptr on device %s' % device)
 
 
-    def test_fill(self):
+    def test_fill(self, device):
         """Runs alsa_api_test command and checks the return code.
 
         Test snd_pcm_mmap_begin can provide the access to the buffer, and memset
         can fill it with zeros without using snd_pcm_mmap_commit.
 
+        @param device: device in hw:<card index>:<device index> format.
+
         @raises error.TestError if command fails.
+
         """
         ret = utils.system(
-                command=self._make_alsa_api_test_command('fill'),
+                command=self._make_alsa_api_test_command('fill', device),
                 ignore_status=True)
         if ret:
-            raise error.TestError('ALSA API failed to fill buffer')
+            raise error.TestError(
+                    'ALSA API failed to fill buffer on device %s' % device)
 
 
-    def test_drop(self):
+    def test_drop(self, device):
         """Runs alsa_api_test command and checks the return code.
 
         Test snd_pcm_drop can stop playback and reset hw_ptr to 0 in hardware.
 
+        @param device: device in hw:<card index>:<device index> format.
+
         @raises error.TestError if command fails.
+
         """
         ret = utils.system(
-                command=self._make_alsa_api_test_command('drop'),
+                command=self._make_alsa_api_test_command('drop', device),
                 ignore_status=True)
         if ret:
             raise error.TestError(
-                    'ALSA API failed to drop playback and reset hw_ptr')
+                    'ALSA API failed to drop playback and reset hw_ptr'
+                    'on device %s' % device)