1# Copyright 2015 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"""This is a server side audio nodes s test using the Chameleon board."""
6
7import os
8import time
9
10from autotest_lib.client.common_lib import error
11from autotest_lib.client.cros.chameleon import audio_test_utils
12from autotest_lib.client.cros.chameleon import chameleon_audio_ids
13from autotest_lib.client.cros.chameleon import chameleon_audio_helper
14from autotest_lib.client.cros.chameleon import chameleon_port_finder
15
16from autotest_lib.client.cros.chameleon import edid as edid_lib
17from autotest_lib.server.cros.audio import audio_test
18
19
20
21class audio_AudioNodeSwitch(audio_test.AudioTest):
22    """Server side audio test.
23
24    This test talks to a Chameleon board and a Cros device to verify
25    audio nodes switch correctly.
26
27    """
28    version = 1
29    _APPLY_EDID_DELAY = 5
30    _PLUG_DELAY = 5
31    _VOLUMES = {'INTERNAL_SPEAKER': 100,
32                'HEADPHONE': 80,
33                'HDMI': 60,
34                'USB': 40,}
35
36    def check_default_nodes(self):
37        """Checks default audio nodes for devices with onboard audio support."""
38        if audio_test_utils.has_internal_microphone(self.host):
39            audio_test_utils.check_audio_nodes(self.audio_facade,
40                                               (None, ['INTERNAL_MIC']))
41        if audio_test_utils.has_internal_speaker(self.host):
42            audio_test_utils.check_audio_nodes(self.audio_facade,
43                                               (['INTERNAL_SPEAKER'], None))
44
45
46    def set_active_volume_to_node_volume(self, node):
47        """Sets Chrome volume to the specified volume of node.
48
49        @param node: One of node type in self._VOLUMES.
50
51        """
52        self.audio_facade.set_chrome_active_volume(self._VOLUMES[node])
53
54
55    def check_active_node_volume(self, node):
56        """Checks the active node type and checks if its volume is as expected.
57
58        @param node: The expected node.
59
60        @raises: TestFail if node volume is not as expected.
61
62        """
63        # Checks the node type is the active node type.
64        audio_test_utils.check_audio_nodes(self.audio_facade, ([node], None))
65        # Checks if active volume is the node volume.
66        volume, mute = self.audio_facade.get_chrome_active_volume_mute()
67        expected_volume = self._VOLUMES[node]
68        if volume != expected_volume:
69            raise error.TestFail(
70                    'Node %s volume %d != %d' % (node, volume, expected_volume))
71
72
73    def switch_nodes_and_check_volume(self, nodes):
74        """Switches between nodes and check the node volumes.
75
76        @param nodes: A list of node types to check.
77
78        """
79        if len(nodes) == 1:
80            self.check_active_node_volume(nodes[0])
81        for node in nodes:
82            # Switch nodes and check their volume.
83            self.audio_facade.set_chrome_active_node_type(node, None)
84            self.check_active_node_volume(node)
85
86
87    def run_once(self, host, jack_node=False, hdmi_node=False, usb_node=False):
88        self.host = host
89        chameleon_board = host.chameleon
90        audio_board = chameleon_board.get_audio_board()
91        factory = self.create_remote_facade_factory(host)
92
93        chameleon_board.reset()
94        self.audio_facade = factory.create_audio_facade()
95        self.display_facade = factory.create_display_facade()
96
97        self.check_default_nodes()
98        nodes = []
99        if audio_test_utils.has_internal_speaker(self.host):
100            self.set_active_volume_to_node_volume('INTERNAL_SPEAKER')
101            nodes.append('INTERNAL_SPEAKER')
102            self.switch_nodes_and_check_volume(nodes)
103
104
105        if hdmi_node:
106            edid_path = os.path.join(self.bindir,
107                                     'test_data/edids/HDMI_DELL_U2410.txt')
108            finder = chameleon_port_finder.ChameleonVideoInputFinder(
109                chameleon_board, self.display_facade)
110            hdmi_port = finder.find_port('HDMI')
111            hdmi_port.apply_edid(edid_lib.Edid.from_file(edid_path))
112            time.sleep(self._APPLY_EDID_DELAY)
113            hdmi_port.set_plug(True)
114            time.sleep(self._PLUG_DELAY)
115
116            audio_test_utils.check_audio_nodes(self.audio_facade,
117                                               (['HDMI'], None))
118
119            self.set_active_volume_to_node_volume('HDMI')
120            nodes.append('HDMI')
121            self.switch_nodes_and_check_volume(nodes)
122
123        if jack_node:
124            jack_plugger = audio_board.get_jack_plugger()
125            jack_plugger.plug()
126            time.sleep(self._PLUG_DELAY)
127            audio_test_utils.dump_cros_audio_logs(host, self.audio_facade,
128                                                  self.resultsdir)
129            audio_test_utils.check_audio_nodes(self.audio_facade,
130                                               (['HEADPHONE'], ['MIC']))
131
132            self.set_active_volume_to_node_volume('HEADPHONE')
133            nodes.append('HEADPHONE')
134            self.switch_nodes_and_check_volume(nodes)
135
136        if usb_node:
137            widget_factory = chameleon_audio_helper.AudioWidgetFactory(
138                factory, host)
139
140            source = widget_factory.create_widget(
141                chameleon_audio_ids.CrosIds.USBOUT)
142            recorder = widget_factory.create_widget(
143                chameleon_audio_ids.ChameleonIds.USBIN)
144            binder = widget_factory.create_binder(source, recorder)
145
146            with chameleon_audio_helper.bind_widgets(binder):
147                time.sleep(self._PLUG_DELAY)
148                audio_test_utils.check_audio_nodes(self.audio_facade,
149                                                   (['USB'], ['USB']))
150                self.set_active_volume_to_node_volume('USB')
151                nodes.append('USB')
152                self.switch_nodes_and_check_volume(nodes)
153            time.sleep(self._PLUG_DELAY)
154            nodes.remove('USB')
155            self.switch_nodes_and_check_volume(nodes)
156
157        if jack_node:
158            if usb_node:
159                audio_test_utils.check_audio_nodes(self.audio_facade,
160                                                   (['HEADPHONE'], ['MIC']))
161            jack_plugger.unplug()
162            time.sleep(self._PLUG_DELAY)
163            nodes.remove('HEADPHONE')
164            self.switch_nodes_and_check_volume(nodes)
165
166        if hdmi_node:
167            if usb_node or jack_node :
168                audio_test_utils.check_audio_nodes(self.audio_facade,
169                                                   (['HDMI'], None))
170            hdmi_port.set_plug(False)
171            time.sleep(self._PLUG_DELAY)
172            nodes.remove('HDMI')
173            self.switch_nodes_and_check_volume(nodes)
174
175        self.check_default_nodes()
176
177