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 stop_playback(self): 60 """Stops playback process.""" 61 self._audio_proxy.stop_playback() 62 63 64 def set_playback_file(self, path): 65 """Copies a file to client. 66 67 @param path: A path to the file. 68 69 @returns: A new path to the file on client. 70 71 """ 72 _, ext = os.path.splitext(path) 73 _, client_file_path = tempfile.mkstemp( 74 prefix='playback_', suffix=ext) 75 self._client.send_file(path, client_file_path) 76 return client_file_path 77 78 79 def start_recording(self, data_format): 80 """Starts recording an audio file on DUT. 81 82 @param data_format: A dict containing: 83 file_type: 'raw'. 84 sample_format: 'S16_LE' for 16-bit signed integer in 85 little-endian. 86 channel: channel number. 87 rate: sampling rate. 88 89 @returns: True 90 91 """ 92 self._audio_proxy.start_recording(data_format) 93 return True 94 95 96 def stop_recording(self): 97 """Stops recording on DUT. 98 99 @returns: the path to the recorded file on DUT. 100 101 """ 102 return self._audio_proxy.stop_recording() 103 104 105 def get_recorded_file(self, remote_path, local_path): 106 """Gets a recorded file from DUT. 107 108 @param remote_path: The path to the file on DUT. 109 @param local_path: The local path for copy destination. 110 111 """ 112 self._client.get_file(remote_path, local_path) 113 114 115 def set_selected_output_volume(self, volume): 116 """Sets the selected output volume on DUT. 117 118 @param volume: the volume to be set(0-100). 119 120 """ 121 self._audio_proxy.set_selected_output_volume(volume) 122 123 124 def set_input_gain(self, gain): 125 """Sets the system capture gain. 126 127 @param gain: the capture gain in db*100 (100 = 1dB) 128 129 """ 130 self._audio_proxy.set_input_gain(gain) 131 132 133 def set_selected_node_types(self, output_node_types, input_node_types): 134 """Set selected node types. 135 136 The node types are defined in cras_utils.CRAS_NODE_TYPES. 137 138 @param output_node_types: A list of output node types. 139 None to skip setting. 140 @param input_node_types: A list of input node types. 141 None to skip setting. 142 143 """ 144 self._audio_proxy.set_selected_node_types( 145 output_node_types, input_node_types) 146 147 148 def get_selected_node_types(self): 149 """Gets the selected output and input node types on DUT. 150 151 @returns: A tuple (output_node_types, input_node_types) where each 152 field is a list of selected node types defined in 153 cras_utils.CRAS_NODE_TYPES. 154 155 """ 156 return self._audio_proxy.get_selected_node_types() 157 158 159 def get_plugged_node_types(self): 160 """Gets the plugged output and input node types on DUT. 161 162 @returns: A tuple (output_node_types, input_node_types) where each 163 field is a list of plugged node types defined in 164 cras_utils.CRAS_NODE_TYPES. 165 166 """ 167 return self._audio_proxy.get_plugged_node_types() 168 169 170 def dump_diagnostics(self, file_path): 171 """Dumps audio diagnostics results to a file. 172 173 @param file_path: The path to dump results. 174 175 @returns: True 176 177 """ 178 _, remote_path = tempfile.mkstemp( 179 prefix='audio_dump_', suffix='.txt') 180 self._audio_proxy.dump_diagnostics(remote_path) 181 self._client.get_file(remote_path, file_path) 182 return True 183 184 185 def start_counting_signal(self, signal_name): 186 """Starts counting DBus signal from Cras. 187 188 @param signal_name: Signal of interest. 189 190 """ 191 self._audio_proxy.start_counting_signal(signal_name) 192 193 194 def stop_counting_signal(self): 195 """Stops counting DBus signal from Cras. 196 197 @returns: Number of signals counted starting from last 198 start_counting_signal call. 199 200 """ 201 return self._audio_proxy.stop_counting_signal() 202 203 204 def wait_for_unexpected_nodes_changed(self, timeout_secs): 205 """Waits for unexpected nodes changed signal. 206 207 @param timeout_secs: Timeout in seconds for waiting. 208 209 """ 210 self._audio_proxy.wait_for_unexpected_nodes_changed(timeout_secs) 211 212 213 def set_chrome_active_volume(self, volume): 214 """Sets the active audio output volume using chrome.audio API. 215 216 @param volume: Volume to set (0~100). 217 218 """ 219 self._audio_proxy.set_chrome_active_volume(volume) 220 221 222 def set_chrome_mute(self, mute): 223 """Mutes the active audio output using chrome.audio API. 224 225 @param mute: True to mute. False otherwise. 226 227 """ 228 self._audio_proxy.set_chrome_mute(mute) 229 230 231 def get_chrome_active_volume_mute(self): 232 """Gets the volume state of active audio output using chrome.audio API. 233 234 @param returns: A tuple (volume, mute), where volume is 0~100, and mute 235 is True if node is muted, False otherwise. 236 237 """ 238 return self._audio_proxy.get_chrome_active_volume_mute() 239 240 241 def set_chrome_active_node_type(self, output_node_type, input_node_type): 242 """Sets active node type through chrome.audio API. 243 244 The node types are defined in cras_utils.CRAS_NODE_TYPES. 245 The current active node will be disabled first if the new active node 246 is different from the current one. 247 248 @param output_node_type: A node type defined in 249 cras_utils.CRAS_NODE_TYPES. None to skip. 250 @param input_node_type: A node type defined in 251 cras_utils.CRAS_NODE_TYPES. None to skip 252 253 """ 254 self._audio_proxy.set_chrome_active_node_type( 255 output_node_type, input_node_type) 256 257 258 def start_arc_recording(self): 259 """Starts recording using microphone app in container.""" 260 self._audio_proxy.start_arc_recording() 261 262 263 def stop_arc_recording(self): 264 """Checks the recording is stopped and gets the recorded path. 265 266 The recording duration of microphone app is fixed, so this method just 267 asks Cros device to copy the recorded result from container to a path 268 on Cros device. 269 270 @returns: Path to the recorded file on DUT. 271 272 """ 273 return self._audio_proxy.stop_arc_recording() 274 275 276 def set_arc_playback_file(self, path): 277 """Copies the file from server to Cros host and into container. 278 279 @param path: Path to the file on server. 280 281 @returns: Path to the file in container on Cros host. 282 283 """ 284 client_file_path = self.set_playback_file(path) 285 return self._audio_proxy.set_arc_playback_file(client_file_path) 286 287 288 def start_arc_playback(self, path): 289 """Starts playback through ARC on Cros host. 290 291 @param path: Path to the file in container on Cros host. 292 293 """ 294 self._audio_proxy.start_arc_playback(path) 295 296 297 def stop_arc_playback(self): 298 """Stops playback through ARC on Cros host.""" 299 self._audio_proxy.stop_arc_playback() 300