Stability improvements to BtCar tests
Check profile connected apis before
trying to look for the broadcast
receivers.
Increase pair attemps for non-pairing
attempt testcases.
Add sleep between clearing bonded devices
and pairing where necessary since the
stack needs time to reset.
Test: manual - execute automation manually
Change-Id: Icca05c1aca386da6422587b7fa67e10ed53c87b0
diff --git a/acts/framework/acts/test_utils/bt/bt_test_utils.py b/acts/framework/acts/test_utils/bt/bt_test_utils.py
index e0510b2..400b6c5 100644
--- a/acts/framework/acts/test_utils/bt/bt_test_utils.py
+++ b/acts/framework/acts/test_utils/bt/bt_test_utils.py
@@ -614,6 +614,7 @@
profile_dict['pbap_client'] = droid.bluetoothPbapClientIsReady()
return profile_dict
+
def log_energy_info(android_devices, state):
"""Logs energy info of input Android devices.
@@ -648,6 +649,7 @@
log.error("Profile {} not yet supported for priority settings".
format(profile))
+
def pair_pri_to_sec(pri_ad, sec_ad, attempts=2, auto_confirm=True):
"""Pairs pri droid to secondary droid.
@@ -661,16 +663,18 @@
Pass if True
Fail if False
"""
+ pri_ad.droid.bluetoothStartConnectionStateChangeMonitor(
+ sec_ad.droid.bluetoothGetLocalAddress())
curr_attempts = 0
while curr_attempts < attempts:
if _pair_pri_to_sec(pri_ad, sec_ad, auto_confirm):
return True
curr_attempts += 1
- time.sleep(DEFAULT_TIMEOUT)
log.error("pair_pri_to_sec failed to connect after {} attempts".format(
str(attempts)))
return False
+
def _wait_for_passkey_match(pri_ad, sec_ad):
pri_pin, sec_pin = -1, 1
pri_variant, sec_variant = -1, 1
@@ -682,18 +686,18 @@
pri_variant = pri_pairing_req["data"]["PairingVariant"]
pri_pin = pri_pairing_req["data"]["Pin"]
log.info("Primary device received Pin: {}, Variant: {}"
- .format(pri_pin, pri_variant))
+ .format(pri_pin, pri_variant))
sec_pairing_req = sec_ad.ed.pop_event(
event_name="BluetoothActionPairingRequest",
timeout=DEFAULT_TIMEOUT)
sec_variant = sec_pairing_req["data"]["PairingVariant"]
sec_pin = sec_pairing_req["data"]["Pin"]
log.info("Secondary device received Pin: {}, Variant: {}"
- .format(sec_pin, sec_variant))
+ .format(sec_pin, sec_variant))
except Empty as err:
log.error("Wait for pin error: {}".format(err))
log.error("Pairing request state, Primary: {}, Secondary: {}"
- .format(pri_pairing_req, sec_pairing_req))
+ .format(pri_pairing_req, sec_pairing_req))
return False
if pri_variant == sec_variant == PAIRING_VARIANT_PASSKEY_CONFIRMATION:
confirmation = pri_pin == sec_pin
@@ -701,10 +705,10 @@
log.info("Pairing code matched, accepting connection")
else:
log.info("Pairing code mismatched, rejecting connection")
- pri_ad.droid.eventPost(
- "BluetoothActionPairingRequestUserConfirm", str(confirmation))
- sec_ad.droid.eventPost(
- "BluetoothActionPairingRequestUserConfirm", str(confirmation))
+ pri_ad.droid.eventPost("BluetoothActionPairingRequestUserConfirm",
+ str(confirmation))
+ sec_ad.droid.eventPost("BluetoothActionPairingRequestUserConfirm",
+ str(confirmation))
if not confirmation:
return False
elif pri_variant != sec_variant:
@@ -712,6 +716,7 @@
return False
return True
+
def _pair_pri_to_sec(pri_ad, sec_ad, auto_confirm):
# Enable discovery on sec_ad so that pri_ad can find it.
# The timeout here is based on how much time it would take for two devices
@@ -748,6 +753,7 @@
log.info("Failed to bond devices.")
return False
+
def connect_pri_to_sec(pri_ad, sec_ad, profiles_set, attempts=2):
"""Connects pri droid to secondary droid.
@@ -813,12 +819,40 @@
pri_ad.droid.bluetoothConnectBonded(sec_ad.droid.bluetoothGetLocalAddress(
))
+ end_time = time.time() + 10
profile_connected = set()
+ sec_addr = sec_ad.droid.bluetoothGetLocalAddress()
log.info("Profiles to be connected {}".format(profiles_set))
+ # First use APIs to check profile connection state
+ while (time.time() < end_time and
+ not profile_connected.issuperset(profiles_set)):
+ if (BluetoothProfile.HEADSET_CLIENT.value not in profile_connected and
+ BluetoothProfile.HEADSET_CLIENT.value in profiles_set):
+ if is_hfp_client_device_connected(pri_ad, sec_addr):
+ profile_connected.add(BluetoothProfile.HEADSET_CLIENT.value)
+ if (BluetoothProfile.A2DP.value not in profile_connected and
+ BluetoothProfile.A2DP.value in profiles_set):
+ if is_a2dp_src_device_connected(pri_ad, sec_addr):
+ profile_connected.add(BluetoothProfile.A2DP.value)
+ if (BluetoothProfile.A2DP_SINK.value not in profile_connected and
+ BluetoothProfile.A2DP_SINK.value in profiles_set):
+ if is_a2dp_snk_device_connected(pri_ad, sec_addr):
+ profile_connected.add(BluetoothProfile.A2DP_SINK.value)
+ if (BluetoothProfile.MAP_MCE.value not in profile_connected and
+ BluetoothProfile.MAP_MCE.value in profiles_set):
+ if is_map_mce_device_connected(pri_ad, sec_addr):
+ profile_connected.add(BluetoothProfile.MAP_MCE.value)
+ if (BluetoothProfile.MAP.value not in profile_connected and
+ BluetoothProfile.MAP.value in profiles_set):
+ if is_map_mse_device_connected(pri_ad, sec_addr):
+ profile_connected.add(BluetoothProfile.MAP.value)
+ time.sleep(0.1)
+ # If APIs fail, try to find the connection broadcast receiver.
while not profile_connected.issuperset(profiles_set):
try:
profile_event = pri_ad.ed.pop_event(
- bluetooth_profile_connection_state_changed, DEFAULT_TIMEOUT)
+ bluetooth_profile_connection_state_changed,
+ DEFAULT_TIMEOUT + 10)
log.info("Got event {}".format(profile_event))
except Exception:
log.error("Did not get {} profiles left {}".format(
@@ -906,6 +940,7 @@
for a in android_devices:
take_btsnoop_log(a, testcase, testname)
+
def take_btsnoop_log(ad, testcase, testname):
"""Grabs the btsnoop_hci log on a device and stores it in the log directory
of the test class.
@@ -926,12 +961,13 @@
out_name = ','.join((testname, device_model, serial))
snoop_path = ad.log_path + "/BluetoothSnoopLogs"
utils.create_dir(snoop_path)
- cmd = ''.join(("adb -s ", serial, " pull ", BTSNOOP_LOG_PATH_ON_DEVICE, " ",
- snoop_path + '/' + out_name, ".btsnoop_hci.log"))
+ cmd = ''.join(("adb -s ", serial, " pull ", BTSNOOP_LOG_PATH_ON_DEVICE,
+ " ", snoop_path + '/' + out_name, ".btsnoop_hci.log"))
testcase.log.info("Test failed, grabbing the bt_snoop logs on {} {}."
.format(device_model, serial))
exe_cmd(cmd)
+
def kill_bluetooth_process(ad):
"""Kill Bluetooth process on Android device.