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/BluetoothCarHfpBaseTest.py b/acts/framework/acts/test_utils/bt/BluetoothCarHfpBaseTest.py
index fd5e240..a858068 100644
--- a/acts/framework/acts/test_utils/bt/BluetoothCarHfpBaseTest.py
+++ b/acts/framework/acts/test_utils/bt/BluetoothCarHfpBaseTest.py
@@ -19,6 +19,7 @@
"""
import os
+import time
from queue import Empty
from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
@@ -75,7 +76,10 @@
self.re2_phone_number = get_phone_number(self.log, self.re2)
self.log.info("re2 tel: {}".format(self.re2_phone_number))
# Pair and connect the devices.
- if not pair_pri_to_sec(self.hf, self.ag):
+ # Grace time inbetween stack state changes
+ time.sleep(5)
+ if not pair_pri_to_sec(
+ self.hf, self.ag, attempts=4, auto_confirm=False):
self.log.error("Failed to pair")
return False
return True
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.
diff --git a/acts/tests/google/bt/car_bt/BtCarHfpConferenceTest.py b/acts/tests/google/bt/car_bt/BtCarHfpConferenceTest.py
index 40e346e..5f85289 100644
--- a/acts/tests/google/bt/car_bt/BtCarHfpConferenceTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarHfpConferenceTest.py
@@ -50,13 +50,6 @@
set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value]))
self.log.info("Connected {}".format(connected))
attempts -= 1
- # Additional profile connection check for b/
- if bt_test_utils.is_hfp_client_device_connected(
- self.hf, self.ag.droid.bluetoothGetLocalAddress()):
- connected = True
- self.log.info(
- "HFP Client connected even though connection state changed " +
- " event not found")
return connected
#@BluetoothTest(UUID=a9657693-b534-4625-bf91-69a1d1b9a943)
diff --git a/acts/tests/google/bt/car_bt/BtCarHfpConnectionTest.py b/acts/tests/google/bt/car_bt/BtCarHfpConnectionTest.py
index 4760ccb..76416a7 100644
--- a/acts/tests/google/bt/car_bt/BtCarHfpConnectionTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarHfpConnectionTest.py
@@ -103,13 +103,7 @@
self.log.error("Could not connect HF and AG {} {}".format(
self.hf.droid.getBuildSerial(), self.ag.droid.getBuildSerial(
)))
- # Additional profile connection check
- if not bt_test_utils.is_hfp_client_device_connected(
- self.hf, self.ag.droid.bluetoothGetLocalAddress()):
- self.log.info(
- "HFP Client connected even though connection state changed "
- + " event not found")
- return False
+ return False
# Check that HF is in active state
if not car_telecom_utils.wait_for_active(self.log, self.hf):
diff --git a/acts/tests/google/bt/car_bt/BtCarHfpFuzzTest.py b/acts/tests/google/bt/car_bt/BtCarHfpFuzzTest.py
index 0ffd959..f951db1 100644
--- a/acts/tests/google/bt/car_bt/BtCarHfpFuzzTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarHfpFuzzTest.py
@@ -44,13 +44,6 @@
set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value]))
self.log.info("Connected {}".format(connected))
attempts -= 1
- # Additional profile connection check for b/
- if bt_test_utils.is_hfp_client_device_connected(
- self.hf, self.ag.droid.bluetoothGetLocalAddress()):
- connected = True
- self.log.info(
- "HFP Client connected even though connection state changed " +
- " event not found")
if not connected:
self.log.error("Failed to connect")
diff --git a/acts/tests/google/bt/car_bt/BtCarHfpTest.py b/acts/tests/google/bt/car_bt/BtCarHfpTest.py
index dca44b8..ad852e0 100644
--- a/acts/tests/google/bt/car_bt/BtCarHfpTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarHfpTest.py
@@ -48,14 +48,7 @@
if not bt_test_utils.connect_pri_to_sec(self.hf, self.ag, set(
[BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
self.log.error("Failed to connect")
- # Additional profile connection check
- if bt_test_utils.is_hfp_client_device_connected(
- self.hf, self.ag.droid.bluetoothGetLocalAddress()):
- self.log.info(
- "HFP Client connected even though connection state changed "
- + " event not found")
- else:
- return False
+ return False
return True
#@BluetoothTest(UUID=4ce2195a-b70a-4584-912e-cbd20d20e19d)
diff --git a/acts/tests/google/bt/car_bt/BtCarMapMceTest.py b/acts/tests/google/bt/car_bt/BtCarMapMceTest.py
index b8c7a0a..5d143e7 100644
--- a/acts/tests/google/bt/car_bt/BtCarMapMceTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarMapMceTest.py
@@ -31,7 +31,6 @@
from acts.test_utils.tel.tel_test_utils import get_phone_number
from acts.test_utils.tel.tel_test_utils import toggle_airplane_mode
-
EVENT_MAP_MESSAGE_RECEIVED = "MapMessageReceived"
TIMEOUT = 2000
MESSAGE_TO_SEND = "Don't text and Drive!"
@@ -49,6 +48,7 @@
self.MCE = self.hf
# Phone device
self.MSE = self.ag
+ # Remote device
self.REMOTE = self.re
time.sleep(4)
return True
@@ -160,8 +160,7 @@
@BluetoothBaseTest.bt_test_wrap
def manual_test_send_message_to_contact(self):
bt_test_utils.connect_pri_to_sec(
- self.MCE, self.MSE,
- set([BtEnum.BluetoothProfile.MAP_MCE.value]))
+ self.MCE, self.MSE, set([BtEnum.BluetoothProfile.MAP_MCE.value]))
contacts = self.MCE.droid.contactsGetContactIds()
self.log.info(contacts)
selected_contact = self.MCE.droid.contactsDisplayContactPickList()
@@ -174,6 +173,5 @@
@BluetoothBaseTest.bt_test_wrap
def test_send_message_to_multiple_phones(self):
bt_test_utils.connect_pri_to_sec(
- self.MCE, self.MSE,
- set([BtEnum.BluetoothProfile.MAP_MCE.value]))
+ self.MCE, self.MSE, set([BtEnum.BluetoothProfile.MAP_MCE.value]))
return self.send_message([self.REMOTE, self.REMOTE])
diff --git a/acts/tests/google/bt/car_bt/BtCarMediaConnectionTest.py b/acts/tests/google/bt/car_bt/BtCarMediaConnectionTest.py
index d400bad..1d58aec 100644
--- a/acts/tests/google/bt/car_bt/BtCarMediaConnectionTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarMediaConnectionTest.py
@@ -41,8 +41,11 @@
self.btAddrCT = self.CT.droid.bluetoothGetLocalAddress()
self.btAddrTG = self.TG.droid.bluetoothGetLocalAddress()
+ # Additional time from the stack reset in setup.
+ time.sleep(4)
# Pair the devices.
- if not bt_test_utils.pair_pri_to_sec(self.CT, self.TG):
+ if not bt_test_utils.pair_pri_to_sec(
+ self.CT, self.TG, attempts=4, auto_confirm=False):
self.log.error("Failed to pair")
return False
@@ -97,14 +100,9 @@
if (car_media_utils.is_a2dp_connected(self.log, self.SNK, self.SRC)):
self.log.info("Already Connected")
else:
- result = bt_test_utils.connect_pri_to_sec(
- self.SRC, self.SNK, set([BtEnum.BluetoothProfile.A2DP.value]))
- if not result:
- # Additional profile connection check for b/
- if not bt_test_utils.is_a2dp_src_device_connected(
- self.SRC, self.SNK.droid.bluetoothGetLocalAddress()):
- self.log.error("Failed to connect on A2dp")
- return False
+ if (not bt_test_utils.connect_pri_to_sec(self.SRC, self.SNK, set(
+ [BtEnum.BluetoothProfile.A2DP.value]))):
+ return False
result = bt_test_utils.disconnect_pri_from_sec(
self.SRC, self.SNK, [BtEnum.BluetoothProfile.A2DP.value])
@@ -148,15 +146,9 @@
if car_media_utils.is_a2dp_connected(self.log, self.SNK, self.SRC):
self.log.info("Already Connected")
else:
- result = bt_test_utils.connect_pri_to_sec(
- self.SNK, self.SRC,
- set([BtEnum.BluetoothProfile.A2DP_SINK.value]))
- if not result:
- # Additional profile connection check for b/
- if not bt_test_utils.is_a2dp_snk_device_connected(
- self.SNK, self.SRC.droid.bluetoothGetLocalAddress()):
- self.log.error("Failed to connect on A2dp Sink")
- return False
+ if (not bt_test_utils.connect_pri_to_sec(self.SNK, self.SRC, set(
+ [BtEnum.BluetoothProfile.A2DP_SINK.value]))):
+ return False
# Disconnect
result = bt_test_utils.disconnect_pri_from_sec(
self.SNK, self.SRC, [BtEnum.BluetoothProfile.A2DP_SINK.value])
diff --git a/acts/tests/google/bt/car_bt/BtCarMediaPassthroughTest.py b/acts/tests/google/bt/car_bt/BtCarMediaPassthroughTest.py
index 96a6252..28b8b7e 100644
--- a/acts/tests/google/bt/car_bt/BtCarMediaPassthroughTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarMediaPassthroughTest.py
@@ -71,8 +71,11 @@
local_media_path + " from test config file.")
return False
+ # Additional time from the stack reset in setup.
+ time.sleep(4)
# Pair and connect the devices.
- if not bt_test_utils.pair_pri_to_sec(self.CT, self.TG):
+ if not bt_test_utils.pair_pri_to_sec(
+ self.CT, self.TG, attempts=4, auto_confirm=False):
self.log.error("Failed to pair")
return False
@@ -397,13 +400,9 @@
return False
# Now connect to Car on Bluetooth
- result = bt_test_utils.connect_pri_to_sec(
- self.SRC, self.SNK, set([BtEnum.BluetoothProfile.A2DP.value]))
- if not result:
- if not bt_test_utils.is_a2dp_src_device_connected(
- self.SRC, self.SNK.droid.bluetoothGetLocalAddress()):
- self.log.error("Failed to connect on A2dp")
- return False
+ if (not bt_test_utils.connect_pri_to_sec(
+ self.SRC, self.SNK, set([BtEnum.BluetoothProfile.A2DP.value]))):
+ return False
# Wait for a bit for the information to show up in the car side
time.sleep(2)
diff --git a/acts/tests/google/bt/car_bt/BtCarPairedConnectDisconnectTest.py b/acts/tests/google/bt/car_bt/BtCarPairedConnectDisconnectTest.py
index 95a166b..ee01607 100644
--- a/acts/tests/google/bt/car_bt/BtCarPairedConnectDisconnectTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarPairedConnectDisconnectTest.py
@@ -45,7 +45,8 @@
# Pair the devices.
# This call may block until some specified timeout in bt_test_utils.py.
- result = bt_test_utils.pair_pri_to_sec(self.car, self.ph)
+ result = bt_test_utils.pair_pri_to_sec(
+ self.car, self.ph, auto_confirm=False)
asserts.assert_true(result, "pair_pri_to_sec returned false.")
diff --git a/acts/tests/google/bt/car_bt/BtCarPairingTest.py b/acts/tests/google/bt/car_bt/BtCarPairingTest.py
index 3c71191..34958aa 100644
--- a/acts/tests/google/bt/car_bt/BtCarPairingTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarPairingTest.py
@@ -54,7 +54,8 @@
Priority: 0
"""
# Pair the devices.
- if not bt_test_utils.pair_pri_to_sec(self.car, self.ph):
+ if not bt_test_utils.pair_pri_to_sec(
+ self.car, self.ph, attempts=1, auto_confirm=False):
self.log.error("cannot pair")
return False
@@ -108,7 +109,8 @@
"""
# Pair the devices.
self.log.info("Pairing the devices ...")
- if not bt_test_utils.pair_pri_to_sec(self.car, self.ph):
+ if not bt_test_utils.pair_pri_to_sec(
+ self.car, self.ph, attempts=1, auto_confirm=False):
self.log.error("cannot pair")
return False
@@ -126,7 +128,8 @@
# Pair them again!
self.log.info("Pairing them again ...")
- if not bt_test_utils.pair_pri_to_sec(self.car, self.ph):
+ if not bt_test_utils.pair_pri_to_sec(
+ self.car, self.ph, attempts=1, auto_confirm=False):
self.log.error("cannot re-pair")
return False
diff --git a/acts/tests/google/bt/car_bt/BtCarPbapTest.py b/acts/tests/google/bt/car_bt/BtCarPbapTest.py
index 5c20939..c59d9e4 100644
--- a/acts/tests/google/bt/car_bt/BtCarPbapTest.py
+++ b/acts/tests/google/bt/car_bt/BtCarPbapTest.py
@@ -17,8 +17,7 @@
"""
import os
-from time import sleep
-from time import time
+import time
from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
from acts.base_test import BaseTestClass
@@ -49,7 +48,11 @@
# Pair the devices.
# This call may block until some specified timeout in bt_test_utils.py.
- if not bt_test_utils.pair_pri_to_sec(self.pce, self.pse):
+ # Grace time inbetween stack state changes
+
+ time.sleep(5)
+ if not bt_test_utils.pair_pri_to_sec(
+ self.pce, self.pse, attempts=4, auto_confirm=False):
self.log.error("Failed to pair.")
return False
@@ -77,7 +80,7 @@
bt_contacts_utils.erase_contacts(self.pce)):
return False
# Allow all content providers to synchronize.
- sleep(1)
+ time.sleep(1)
return True
def teardown_test(self):
@@ -323,23 +326,23 @@
bt_contacts_utils.add_call_log(
self.pse, bt_contacts_utils.INCOMMING_CALL_TYPE,
bt_contacts_utils.generate_random_phone_number().phone_number,
- int(time()) * 1000)
+ int(time.time() * 1000))
bt_contacts_utils.add_call_log(
self.pse, bt_contacts_utils.INCOMMING_CALL_TYPE,
bt_contacts_utils.generate_random_phone_number().phone_number,
- int(time()) * 1000 - 4 * CALL_LOG_TIME_OFFSET_IN_MSEC)
+ int(time.time()) * 1000 - 4 * CALL_LOG_TIME_OFFSET_IN_MSEC)
bt_contacts_utils.add_call_log(
self.pse, bt_contacts_utils.OUTGOING_CALL_TYPE,
bt_contacts_utils.generate_random_phone_number().phone_number,
- int(time()) * 1000 - CALL_LOG_TIME_OFFSET_IN_MSEC)
+ int(time.time()) * 1000 - CALL_LOG_TIME_OFFSET_IN_MSEC)
bt_contacts_utils.add_call_log(
self.pse, bt_contacts_utils.MISSED_CALL_TYPE,
bt_contacts_utils.generate_random_phone_number().phone_number,
- int(time()) * 1000 - 2 * CALL_LOG_TIME_OFFSET_IN_MSEC)
+ int(time.time()) * 1000 - 2 * CALL_LOG_TIME_OFFSET_IN_MSEC)
bt_contacts_utils.add_call_log(
self.pse, bt_contacts_utils.MISSED_CALL_TYPE,
bt_contacts_utils.generate_random_phone_number().phone_number,
- int(time()) * 1000 - 2 * CALL_LOG_TIME_OFFSET_IN_MSEC)
+ int(time.time()) * 1000 - 2 * CALL_LOG_TIME_OFFSET_IN_MSEC)
bt_test_utils.connect_pri_to_sec(
self.pce, self.pse,