1# Copyright 2014 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"""An adapter to remotely access the audio facade on DUT.""" 6 7import os 8import tempfile 9 10 11class AudioFacadeRemoteAdapter(object): 12 """AudioFacadeRemoteAdapter is an adapter to remotely control DUT audio. 13 14 The Autotest host object representing the remote DUT, passed to this 15 class on initialization, can be accessed from its _client property. 16 17 """ 18 def __init__(self, host, remote_facade_proxy): 19 """Construct an AudioFacadeRemoteAdapter. 20 21 @param host: Host object representing a remote host. 22 @param remote_facade_proxy: RemoteFacadeProxy object. 23 24 """ 25 self._client = host 26 self._proxy = remote_facade_proxy 27 28 29 @property 30 def _audio_proxy(self): 31 """Gets the proxy to DUT audio facade. 32 33 @return XML RPC proxy to DUT audio facade. 34 35 """ 36 return self._proxy.audio 37 38 39 def playback(self, client_path, data_format, blocking=False): 40 """Playback an audio file on DUT. 41 42 @param client_path: The path to the file on DUT. 43 @param data_format: A dict containing data format including 44 file_type, sample_format, channel, and rate. 45 file_type: file type e.g. 'raw' or 'wav'. 46 sample_format: One of the keys in 47 audio_data.SAMPLE_FORMAT. 48 channel: number of channels. 49 rate: sampling rate. 50 @param blocking: Blocks this call until playback finishes. 51 52 @returns: True 53 54 """ 55 self._audio_proxy.playback( 56 client_path, data_format, blocking) 57 58 59 def set_playback_file(self, path): 60 """Copies a file to client. 61 62 @param path: A path to the file. 63 64 @returns: A new path to the file on client. 65 66 """ 67 _, ext = os.path.splitext(path) 68 _, client_file_path = tempfile.mkstemp( 69 prefix='playback_', suffix=ext) 70 self._client.send_file(path, client_file_path) 71 return client_file_path 72 73 74 def start_recording(self, data_format): 75 """Starts recording an audio file on DUT. 76 77 @param data_format: A dict containing: 78 file_type: 'raw'. 79 sample_format: 'S16_LE' for 16-bit signed integer in 80 little-endian. 81 channel: channel number. 82 rate: sampling rate. 83 84 @returns: True 85 86 """ 87 self._audio_proxy.start_recording(data_format) 88 return True 89 90 91 def stop_recording(self): 92 """Stops recording on DUT. 93 94 @returns: the path to the recorded file on DUT. 95 96 """ 97 return self._audio_proxy.stop_recording() 98 99 100 def get_recorded_file(self, remote_path, local_path): 101 """Gets a recorded file from DUT. 102 103 @param remote_path: The path to the file on DUT. 104 @param local_path: The local path for copy destination. 105 106 """ 107 self._client.get_file(remote_path, local_path) 108 109 110 def set_selected_output_volume(self, volume): 111 """Sets the selected output volume on DUT. 112 113 @param volume: the volume to be set(0-100). 114 115 """ 116 self._audio_proxy.set_selected_output_volume(volume) 117 118 119 def set_selected_node_types(self, output_node_types, input_node_types): 120 """Set selected node types. 121 122 The node types are defined in cras_utils.CRAS_NODE_TYPES. 123 124 @param output_node_types: A list of output node types. 125 None to skip setting. 126 @param input_node_types: A list of input node types. 127 None to skip setting. 128 129 """ 130 self._audio_proxy.set_selected_node_types( 131 output_node_types, input_node_types) 132 133 134 def get_selected_node_types(self): 135 """Gets the selected output and input node types on DUT. 136 137 @returns: A tuple (output_node_types, input_node_types) where each 138 field is a list of selected node types defined in 139 cras_utils.CRAS_NODE_TYPES. 140 141 """ 142 return self._audio_proxy.get_selected_node_types() 143 144 145 def get_plugged_node_types(self): 146 """Gets the plugged output and input node types on DUT. 147 148 @returns: A tuple (output_node_types, input_node_types) where each 149 field is a list of plugged node types defined in 150 cras_utils.CRAS_NODE_TYPES. 151 152 """ 153 return self._audio_proxy.get_plugged_node_types() 154 155 156 def dump_diagnostics(self, file_path): 157 """Dumps audio diagnostics results to a file. 158 159 @param file_path: The path to dump results. 160 161 @returns: True 162 163 """ 164 _, remote_path = tempfile.mkstemp( 165 prefix='audio_dump_', suffix='.txt') 166 self._audio_proxy.dump_diagnostics(remote_path) 167 self._client.get_file(remote_path, file_path) 168 return True 169 170 171 def start_counting_signal(self, signal_name): 172 """Starts counting DBus signal from Cras. 173 174 @param signal_name: Signal of interest. 175 176 """ 177 self._audio_proxy.start_counting_signal(signal_name) 178 179 180 def stop_counting_signal(self): 181 """Stops counting DBus signal from Cras. 182 183 @returns: Number of signals counted starting from last 184 start_counting_signal call. 185 186 """ 187 return self._audio_proxy.stop_counting_signal() 188 189 190 def wait_for_unexpected_nodes_changed(self, timeout_secs): 191 """Waits for unexpected nodes changed signal. 192 193 @param timeout_secs: Timeout in seconds for waiting. 194 195 """ 196 self._audio_proxy.wait_for_unexpected_nodes_changed(timeout_secs) 197 198 199 def set_chrome_active_volume(self, volume): 200 """Sets the active audio output volume using chrome.audio API. 201 202 @param volume: Volume to set (0~100). 203 204 """ 205 self._audio_proxy.set_chrome_active_volume(volume) 206 207 208 def set_chrome_mute(self, mute): 209 """Mutes the active audio output using chrome.audio API. 210 211 @param mute: True to mute. False otherwise. 212 213 """ 214 self._audio_proxy.set_chrome_mute(mute) 215 216 217 def get_chrome_active_volume_mute(self): 218 """Gets the volume state of active audio output using chrome.audio API. 219 220 @param returns: A tuple (volume, mute), where volume is 0~100, and mute 221 is True if node is muted, False otherwise. 222 223 """ 224 return self._audio_proxy.get_chrome_active_volume_mute() 225 226 227 def set_chrome_active_node_type(self, output_node_type, input_node_type): 228 """Sets active node type through chrome.audio API. 229 230 The node types are defined in cras_utils.CRAS_NODE_TYPES. 231 The current active node will be disabled first if the new active node 232 is different from the current one. 233 234 @param output_node_type: A node type defined in 235 cras_utils.CRAS_NODE_TYPES. None to skip. 236 @param input_node_type: A node type defined in 237 cras_utils.CRAS_NODE_TYPES. None to skip 238 239 """ 240 self._audio_proxy.set_chrome_active_node_type( 241 output_node_type, input_node_type) 242