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