1# Copyright 2020 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
5import logging
6import time
7
8from autotest_lib.client.bin import test
9from autotest_lib.client.bin import utils
10from autotest_lib.client.common_lib import error
11from autotest_lib.client.common_lib.cros import chrome
12from autotest_lib.client.cros import constants as cros_constants
13from autotest_lib.client.cros.audio import cras_utils
14from autotest_lib.client.cros.multimedia import audio_facade_native
15
16class audio_CrasGetNodes(test.test):
17    """Verifies dbus GetNodes API of CRAS."""
18    version = 1
19
20    ALOOP_CRAS_NODE_TYPE = 'ALSA_LOOPBACK'
21    ALOOP_MODULE_NAME = 'snd-aloop'
22
23    def run_once(self):
24        """Entry point of this test."""
25        # Check CRAS server is alive. If not, restart it and wait a second to
26        # get server ready.
27        if utils.get_service_pid('cras') == 0:
28            logging.debug('CRAS server is down. Restart it.')
29            utils.start_service('cras', ignore_status=True)
30            time.sleep(1)
31
32        utils.load_module(self.ALOOP_MODULE_NAME)
33
34        try:
35            with chrome.Chrome(
36                    extension_paths=[cros_constants.AUDIO_TEST_EXTENSION],
37                    autotest_ext=True) as cr:
38                audio_facade = audio_facade_native.AudioFacadeNative(cr)
39                audio_facade.set_chrome_active_node_type(
40                        self.ALOOP_CRAS_NODE_TYPE, self.ALOOP_CRAS_NODE_TYPE)
41
42            # Checks active output and input node types are correct.
43            active_output_types, active_input_types = (
44                cras_utils.get_selected_node_types())
45            if len(active_output_types) != 1:
46                raise error.TestFail(
47                    'Length of active output types is not 1, got: %d',
48                    len(active_output_types))
49            if active_output_types[0] != self.ALOOP_CRAS_NODE_TYPE:
50                raise error.TestFail(
51                    'Active output device is not %s, got: %d',
52                    self.ALOOP_CRAS_NODE_TYPE, active_output_types[0])
53            if len(active_input_types) != 1:
54                raise error.TestFail(
55                    'Length of active input types is not 1, got: %d',
56                    len(active_input_types))
57            if active_input_types[0] != self.ALOOP_CRAS_NODE_TYPE:
58                raise error.TestFail(
59                    'Active input device is not %s, got: %d',
60                    self.ALOOP_CRAS_NODE_TYPE, active_input_types[0])
61
62            # Checks active node volume is correct.
63            for target_volume in [25, 75]:
64                cras_utils.set_selected_output_node_volume(target_volume)
65                volume = cras_utils.get_active_node_volume()
66                if volume != target_volume:
67                    raise error.TestFail('Volume is as expected: %d, got: %d',
68                                         target_volume, volume)
69
70        finally:
71            utils.stop_service('cras', ignore_status=True)
72            utils.unload_module(self.ALOOP_MODULE_NAME)
73            utils.start_service('cras', ignore_status=True)
74