1 #/usr/bin/env python3.4 2 # 3 # Copyright (C) 2016 The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 # use this file except in compliance with the License. You may obtain a copy of 7 # the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 # License for the specific language governing permissions and limitations under 15 # the License. 16 """ 17 Test the HFP profile for advanced functionality and try to create race 18 conditions by executing actions quickly. 19 """ 20 21 import time 22 23 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest 24 from acts.test_utils.bt.BluetoothCarHfpBaseTest import BluetoothCarHfpBaseTest 25 from acts.test_utils.bt import BtEnum 26 from acts.test_utils.bt import bt_test_utils 27 from acts.test_utils.car import car_telecom_utils 28 from acts.test_utils.tel import tel_defines 29 30 STABILIZATION_DELAY_SEC = 5 31 32 33 class BtCarHfpFuzzTest(BluetoothCarHfpBaseTest): 34 def setup_class(self): 35 if not super(BtCarHfpFuzzTest, self).setup_class(): 36 return False 37 38 # Connect the devices now, try twice. 39 attempts = 2 40 connected = False 41 while attempts > 0 and not connected: 42 connected = bt_test_utils.connect_pri_to_sec( 43 self.hf, self.ag, 44 set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])) 45 self.log.info("Connected {}".format(connected)) 46 attempts -= 1 47 48 if not connected: 49 self.log.error("Failed to connect") 50 return False 51 52 # Delay set contains the delay between dial and hangup for a call. 53 # We keep very small delays to significantly large ones to stress test 54 # various kind of timing issues. 55 self.delay_set = [0.1, 56 0.2, 57 0.3, 58 0.4, 59 0.5, # Very short delays 60 1.0, 61 2.0, 62 3.0, 63 4.0, 64 5.0, # Med delays 65 10.0] # Large delays 66 67 def dial_a_hangup_b_quick(self, a, b, delay=0, ph=""): 68 """ 69 This test does a quick succession of dial and hangup. We make the test 70 case sleep for delay amount between each dial and hangup. This is 71 different from other test cases where we give enough time for devices 72 to get into a calling state before trying to tear down connection. 73 """ 74 if ph == "": ph = self.re_phone_number 75 76 # Dial from A now. 77 self.log.info("Dialing at droid {}".format(a.droid.getBuildDisplay())) 78 a.droid.telecomCallTelUri(ph) 79 80 # Wait for delay millis. 81 time.sleep(delay) 82 83 # Cancel the call at B. Use end call in this scenario so that we do not 84 # wait for looking up the call! 85 self.log.info("Hanging up at droid {}".format(b.droid.getBuildDisplay( 86 ))) 87 b.droid.telecomEndCall() 88 89 # Check/Wait that we are clear before executing the test. 90 for d in self.android_devices: 91 if not car_telecom_utils.wait_for_not_in_call(self.log, d): 92 self.log.warn( 93 "dial_a_hangup_quick wait_for_not_in_call failed {}". 94 format(d.serial)) 95 return False 96 97 return True 98 99 def stabilize_and_check_sanity(self): 100 # Since we dial and hangup very very quickly we may end up in a state 101 # where we need to wait to see the results. For instance if the delay is 102 # 0.1 sec it may take upto 2 seconds for the platform to respond to a 103 # dial() and hence even if we hangup 0.1 sec later we will not see its 104 # result immidiately (this may be a false positive on test). 105 time.sleep(STABILIZATION_DELAY_SEC) 106 107 # First check if HF is in dialing state, we can send an actual hangup if 108 # that is the case and then wait for devices to come back to normal. 109 if self.hf.droid.telecomIsInCall(): 110 self.log.info("HF still in call, send hangup") 111 self.hf.droid.telecomEndCall() 112 113 # Wait for devices to go back to normal. 114 for d in self.android_devices: 115 if not car_telecom_utils.wait_for_not_in_call(self.log, d): 116 self.log.warning( 117 "stabilize_and_check_sanity wait_for_not_in_call failed {}". 118 format(d.serial)) 119 return False 120 121 return True 122 123 #@BluetoothTest(UUID=32022c74-fdf3-44c4-9e82-e518bdcce667) 124 @BluetoothBaseTest.bt_test_wrap 125 def test_fuzz_outgoing_hf(self): 126 """ 127 Test calling and hangup from HF with varied delays as defined in 128 self.delay_set 129 130 Precondition: 131 1. Devices are paired and connected 132 133 Steps: 134 For each delay do the following: 135 a) Call HF 136 b) Wait for delay seconds 137 c) Hangup HF 138 d) Check if all devices are in stable state, if not wait for stabilizing 139 e) If (d) fails then we fail otherwise we go back to (a) 140 f) Once all delays are done we do a final check for sanity as pass 141 scenario 142 143 Returns: 144 Pass if True 145 Fail if False 146 147 Priority: 1 148 """ 149 150 for delay in self.delay_set: 151 self.log.info("test_fuzz outgoing_hf: {}".format(delay)) 152 # Make the call and hangup, we do a light check inside to see if the 153 # phones are in a clean state -- if not, we let them stabilize 154 # before continuing. 155 if not self.dial_a_hangup_b_quick(self.hf, self.hf, delay): 156 if not self.stabilize_and_check_sanity(): 157 self.log.info("Devices not able to stabilize!") 158 return False 159 160 # Final sanity check (if we never called stabilize_and_check_sanity 161 # above). 162 return self.stabilize_and_check_sanity() 163 164 #@BluetoothTest(UUID=bc6d52b2-4acc-461e-ad55-fad5a5ecb091) 165 @BluetoothBaseTest.bt_test_wrap 166 def test_fuzz_outgoing_ag(self): 167 """ 168 Test calling and hangup from AG with varied delays as defined in 169 self.delay_set 170 171 Precondition: 172 1. Devices are paired and connected 173 174 Steps: 175 For each delay do the following: 176 a) Call AG 177 b) Wait for delay seconds 178 c) Hangup AG 179 d) Check if all devices are in stable state, if not wait for stabilizing 180 e) If (d) fails then we fail otherwise we go back to (a) 181 f) Once all delays are done we do a final check for sanity as pass 182 scenario 183 184 Returns: 185 Pass if True 186 Fail if False 187 188 Priority: 1 189 """ 190 191 for delay in self.delay_set: 192 self.log.info("test_fuzz outgoing_ag: {}".format(delay)) 193 # Make the call and hangup, we do a light check inside to see if the 194 # phones are in a clean state -- if not, we let them stabilize 195 # before continuing. 196 if not self.dial_a_hangup_b_quick(self.ag, self.ag, delay): 197 if not self.stabilize_and_check_sanity(): 198 self.log.error("Devices not able to stabilize!") 199 return False 200 201 # Final sanity check (if we never called stabilize_and_check_sanity 202 # above). 203 return self.stabilize_and_check_sanity() 204 205 #@BluetoothTest(UUID=d834384a-38d5-4260-bfd5-98f8207c04f5) 206 @BluetoothBaseTest.bt_test_wrap 207 def test_fuzz_dial_hf_hangup_ag(self): 208 """ 209 Test calling and hangup from HF and AG resp. with varied delays as defined in 210 self.delay_set 211 212 Precondition: 213 1. Devices are paired and connected 214 215 Steps: 216 For each delay do the following: 217 a) Call HF 218 b) Wait for delay seconds 219 c) Hangup AG 220 d) Check if all devices are in stable state, if not wait for stabilizing 221 e) If (d) fails then we fail otherwise we go back to (a) 222 f) Once all delays are done we do a final check for sanity as pass 223 scenario 224 225 Returns: 226 Pass if True 227 Fail if False 228 229 Priority: 1 230 """ 231 232 for delay in self.delay_set: 233 self.log.info("test_fuzz dial_hf hangup_ag: {}".format(delay)) 234 # Make the call and hangup, we do a light check inside to see if the 235 # phones are in a clean state -- if not, we let them stabilize 236 # before continuing. 237 if not self.dial_a_hangup_b_quick(self.hf, self.ag, delay): 238 if not self.stabilize_and_check_sanity(): 239 self.log.info("Devices not able to stabilize!") 240 return False 241 242 # Final sanity check (if we never called stabilize_and_check_sanity 243 # above). 244 return self.stabilize_and_check_sanity() 245 246 #@BluetoothTest(UUID=6de1a8ab-3cb0-4594-a9bb-d882a3414836) 247 @BluetoothBaseTest.bt_test_wrap 248 def test_fuzz_dial_ag_hangup_hf(self): 249 """ 250 Test calling and hangup from HF and AG resp. with varied delays as defined in 251 self.delay_set 252 253 Precondition: 254 1. Devices are paired and connected 255 256 Steps: 257 For each delay do the following: 258 a) Call AG 259 b) Wait for delay seconds 260 c) Hangup HF 261 d) Check if all devices are in stable state, if not wait for stabilizing 262 e) If (d) fails then we fail otherwise we go back to (a) 263 f) Once all delays are done we do a final check for sanity as pass 264 scenario 265 266 Returns: 267 Pass if True 268 Fail if False 269 270 Priority: 1 271 """ 272 273 for delay in self.delay_set: 274 self.log.info("test_fuzz dial_ag hangup_hf: {}".format(delay)) 275 # Make the call and hangup, we do a light check inside to see if the 276 # phones are in a clean state -- if not, we let them stabilize 277 # before continuing. 278 if not self.dial_a_hangup_b_quick(self.ag, self.hf, delay): 279 if not self.stabilize_and_check_sanity(): 280 self.log.info("Devices not able to stabilize!") 281 return False 282 283 # Final sanity check (if we never called stabilize_and_check_sanity 284 # above). 285 return self.stabilize_and_check_sanity() 286