1"""Bluetooth stub class. 2 3This controller offers no direct control to any device. It simply prompts the 4user to perform a certain action on the device it is standing in for. For use 5in test scripts where no controller for the DUT exists. 6""" 7 8from __future__ import absolute_import 9from __future__ import division 10from __future__ import print_function 11 12from typing import Any, List 13 14import six 15 16 17class BtStub(object): 18 """Stub for when controller class does not exist for a Bluetooth device. 19 20 This class will simulate semi-automation by prompting user to manually 21 perform actions on the Bluetooth device. 22 """ 23 24 # Connection Commands 25 def power_off(self) -> None: 26 """Prompt the user to power off the Bluetooth device.""" 27 six.moves.input('Power Off Bluetooth device, then press enter.') 28 29 def power_on(self) -> None: 30 """Prompt the user to power on the Bluetooth device.""" 31 six.moves.input('Power ON Bluetooth device, then press enter.') 32 33 def activate_pairing_mode(self) -> None: 34 """Prompt the user to put the Bluetooth device into pairing mode.""" 35 six.moves.input('Put Bluetooth device into pairing mode, then press enter.') 36 37 def get_bluetooth_mac_address(self) -> str: 38 """Prompt the user to input the Bluetooth MAC address for this device. 39 40 Returns: 41 mac_address (str): the string received from user input. 42 """ 43 mac_address = six.moves.input('Enter BT MAC address, then press enter.') 44 return mac_address 45 46 def set_device_name(self, device_name: str) -> None: 47 """Prompt the user to set the device name (Carkit Only). 48 49 Args: 50 device_name: String of device name to be set. 51 52 Returns: None 53 """ 54 six.moves.input(f'Device name is: {device_name}') 55 56 def factory_reset_bluetooth(self) -> None: 57 """Prompt the user to factory reset Bluetooth on the device.""" 58 six.moves.input('Factory reset Bluetooth on the Bluetooth device, ' 59 'then press enter.') 60 61 # A2DP: Bluetooth stereo streaming protocol methods. 62 def is_audio_playing(self) -> bool: 63 """Prompt the user to indicate if the audio is playing. 64 65 Returns: 66 A Bool, true is audio is playing, false if not. 67 """ 68 audio_playing = six.moves.input('Indicate if audio is playing: ' 69 'true/false.') 70 return bool(audio_playing) 71 72 # AVRCP Commands 73 def volume_up(self) -> None: 74 """Prompt the user to raise the volume on the Bluetooth device.""" 75 six.moves.input('Press the Volume Up Button on the Bluetooth device, ' 76 'then press enter.') 77 78 def volume_down(self) -> None: 79 """Prompt the user to lower the volume on the Bluetooth device.""" 80 six.moves.input('Press the Volume Down Button on the Bluetooth device, ' 81 'then press enter.') 82 83 def track_next(self) -> None: 84 """Prompt the user to skip the track on the Bluetooth device.""" 85 six.moves.input('Press the Skip Track Button on the Bluetooth device, ' 86 'then press enter.') 87 88 def track_previous(self) -> None: 89 """Prompt the user to rewind the track on the Bluetooth device.""" 90 six.moves.input('Press the Rewind Track Button on the Bluetooth device, ' 91 'then press enter.') 92 93 def play(self) -> None: 94 """Prompt the user to press play on the Bluetooth device.""" 95 six.moves.input('Press the Play Button on the Bluetooth device, ' 96 'then press enter.') 97 98 def pause(self) -> None: 99 """Prompt the user to press pause on the Bluetooth device.""" 100 six.moves.input('Press the Pause Button on the Bluetooth device, ' 101 'then press enter.') 102 103 def repeat(self) -> None: 104 """Prompt the user to set the repeat option on the device.""" 105 six.moves.input('Press the Repeat Button on the Bluetooth device, ' 106 'then press enter.') 107 108 def fast_forward(self) -> None: 109 """Prompt the user to press the fast forward option/button on the device. 110 111 Returns: None 112 """ 113 six.moves.input('Press the Fast Forward Button on the Bluetooth device, ' 114 'then press enter.') 115 116 def rewind(self) -> None: 117 """Prompt the user to press Rewind option on the device. 118 119 Returns: None 120 """ 121 six.moves.input('Press the Rewind option on the Bluetooth device, ' 122 'then press enter.') 123 124 # TODO(user): browse_media_content may need more work in terms of input 125 # params and value(s) returned 126 def browse_media_content(self, directory: str = '') -> List[Any]: 127 """Prompt the user to enter to the paired device media folders. 128 129 Args: 130 directory: A path to the directory to browse to. 131 132 Returns: 133 List - empty 134 """ 135 six.moves.input(f'Navigate to directory: {directory}') 136 return [] 137 138 def delete_song(self, file_path: str = '') -> None: 139 """Prompt the user to delete a song. 140 141 Args: 142 file_path (optional): A file path to the song to be deleted. 143 144 Returns: None 145 """ 146 six.moves.input(f'Delete a song {file_path}') 147 148 def shuffle_song(self) -> None: 149 """Prompt the user to shuffle a playlist. 150 151 Returns: None 152 """ 153 six.moves.input('Shuffle a playlist') 154 155 # HFP (Hands Free Phone protocol) Commands 156 def call_volume_up(self) -> None: 157 """Prompt the user to press the volume up button on an active call. 158 159 Returns: None 160 """ 161 six.moves.input('Press the volume up button for an active call.') 162 163 def call_volume_down(self) -> None: 164 """Prompt the user to press the volume down button on an active call. 165 166 Returns: None 167 """ 168 six.moves.input('Press the volume down button for an active call.') 169 170 def answer_phone_call(self) -> None: 171 """Prompt the user to press the button to answer a phone call.. 172 173 Returns: None 174 """ 175 six.moves.input('Press the button to answer the phone call.') 176 177 def hangup_phone_call(self) -> None: 178 """Prompt the user to press the button to hang up on an active phone call. 179 180 Returns: None 181 """ 182 six.moves.input('Press the button to hang up on the phone call.') 183 184 def call_contact(self, name: str) -> None: 185 """Prompt the user to select a contact from the phonebook and call. 186 187 Args: 188 name: string name of contact to call 189 190 Returns: None 191 """ 192 six.moves.input(f'Select contact, {name}, to call.') 193 194 def call_number(self, phone_number: str) -> None: 195 """Prompt the user to dial a phone number and call. 196 197 Args: 198 phone_number: string of phone number to dial and call 199 200 Returns: None 201 """ 202 six.moves.input(f'Dial phone number and initiate a call. {phone_number}') 203 204 def swap_call(self) -> None: 205 """Prompt the user to push the button to swap. 206 207 Function swaps between the primary and secondary calls. One call will 208 be active and the other will be on hold. 209 210 Returns: None 211 """ 212 six.moves.input('Press the button to swap calls.') 213 214 def merge_call(self) -> None: 215 """Prompt the user to push the button to merge calls. 216 217 Merges calls between the primary and secondary calls into a conference 218 call. 219 220 Returns: None 221 """ 222 six.moves.input('Press the button to merge calls into a conference call.') 223 224 def hold_call(self) -> None: 225 """Prompt the user to put the primary call on hold. 226 227 Primary call will be on hold, while the secondary call becomes active. 228 229 Returns: None 230 """ 231 six.moves.input('Press the hold button to put primary call on hold.') 232 233 def mute_call(self) -> None: 234 """Prompt the user to mute the ongoing active call. 235 236 Returns: None 237 """ 238 six.moves.input('Press Mute button on active call.') 239 240 def unmute_call(self) -> None: 241 """Prompt the user to unmute the ongoing active call. 242 243 Returns: None 244 """ 245 six.moves.input('Press the Unmute button on an active call.') 246 247 def reject_phone_call(self) -> None: 248 """Prompt the user to reject an incoming call. 249 250 Returns: None 251 """ 252 six.moves.input('Press the Reject button to reject an incoming call.') 253 254 def answer_voip_call(self) -> None: 255 """Prompt the user to press the button to answer a VOIP call. 256 257 Returns: None 258 """ 259 six.moves.input('Press the Answer button on an incoming VOIP phone call.') 260 261 def hangup_voip_call(self) -> None: 262 """Prompt the user to press the button to hangup on the active VOIP call. 263 264 Returns: None 265 """ 266 six.moves.input('Press the hangup button on the active VOIP call.') 267 268 def reject_voip_call(self) -> None: 269 """Prompt the user to press the Reject button on the incoming VOIP call. 270 271 Returns: None 272 """ 273 six.moves.input('Press the Reject button on the incoming VOIP call.') 274 275 def voice_dial(self) -> None: 276 """Prompt user to initiate a voice dial from the phone. 277 278 Returns: None 279 """ 280 six.moves.input('Initiate a voice dial.') 281 282 def last_number_dial(self) -> None: 283 """Prompt user to iniate a call to the last number dialed. 284 285 Returns: None 286 """ 287 six.moves.input('Initiate a call to the last number dialed.') 288 289 # TODO(user): does this method need a input parameter? 290 def route_call_audio(self) -> None: 291 """Prompt user to route a call from AG to HF, and vice versa. 292 293 Returns: None 294 """ 295 six.moves.input('Reroute call audio.') 296