resolve merge conflicts of 9bce15d9087a80c2bf565717e9b61c1a2fcd02e3 to stage-aosp-master
BUG: None
Test: I solemnly swear I tested this conflict resolution.
Change-Id: I41cfea9d74d5f044866ade338d187b469acb4c4d
diff --git a/acts/framework/acts/test_utils/bt/BluetoothBaseTest.py b/acts/framework/acts/test_utils/bt/BluetoothBaseTest.py
index a311857..197da27 100644
--- a/acts/framework/acts/test_utils/bt/BluetoothBaseTest.py
+++ b/acts/framework/acts/test_utils/bt/BluetoothBaseTest.py
@@ -31,6 +31,7 @@
from acts.libs.proto.proto_utils import compile_import_proto
from acts.libs.proto.proto_utils import parse_proto_to_ascii
from acts.test_utils.bt.bt_metrics_utils import get_bluetooth_metrics
+from acts.test_utils.bt.bt_test_utils import get_device_selector_dictionary
from acts.test_utils.bt.bt_test_utils import reset_bluetooth
from acts.test_utils.bt.bt_test_utils import setup_multiple_devices_for_bt_test
from acts.test_utils.bt.bt_test_utils import take_btsnoop_logs
@@ -52,6 +53,13 @@
BaseTestClass.__init__(self, controllers)
for ad in self.android_devices:
self._setup_bt_libs(ad)
+ if 'preferred_device_order' in self.user_params:
+ prefered_device_order = self.user_params['preferred_device_order']
+ for i, ad in enumerate(self.android_devices):
+ if ad.serial in prefered_device_order:
+ index = prefered_device_order.index(ad.serial)
+ self.android_devices[i], self.android_devices[index] = \
+ self.android_devices[index], self.android_devices[i]
def collect_bluetooth_manager_metrics_logs(self, ads, test_name):
"""
@@ -123,6 +131,8 @@
return _safe_wrap_test_case
def setup_class(self):
+ self.device_selector = get_device_selector_dictionary(
+ self.android_devices)
if "reboot_between_test_class" in self.user_params:
threads = []
for a in self.android_devices:
@@ -235,3 +245,6 @@
# Shell command library
setattr(android_device, "shell",
ShellCommands(log=self.log, dut=android_device))
+ # Setup Android Device feature list
+ setattr(android_device, "features",
+ android_device.adb.shell("pm list features").split("\n"))
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 534adf1..e35e2f1 100644
--- a/acts/framework/acts/test_utils/bt/bt_test_utils.py
+++ b/acts/framework/acts/test_utils/bt/bt_test_utils.py
@@ -223,7 +223,8 @@
threads = []
try:
for a in android_devices:
- thread = threading.Thread(target=factory_reset_bluetooth, args=([[a]]))
+ thread = threading.Thread(
+ target=factory_reset_bluetooth, args=([[a]]))
threads.append(thread)
thread.start()
for t in threads:
@@ -282,7 +283,11 @@
return False
return True
-def wait_for_bluetooth_manager_state(droid, state=None, timeout=10, threshold=5):
+
+def wait_for_bluetooth_manager_state(droid,
+ state=None,
+ timeout=10,
+ threshold=5):
""" Waits for BlueTooth normalized state or normalized explicit state
args:
droid: droid device object
@@ -301,7 +306,8 @@
# for any normalized state
if state is None:
if len(set(all_states[-threshold:])) == 1:
- log.info("State normalized {}".format(set(all_states[-threshold:])))
+ log.info("State normalized {}".format(
+ set(all_states[-threshold:])))
return True
else:
# explicit check against normalized state
@@ -310,9 +316,11 @@
time.sleep(0.5)
log.error(
"Bluetooth state fails to normalize" if state is None else
- "Failed to match bluetooth state, current state {} expected state {}".format(get_state(), state))
+ "Failed to match bluetooth state, current state {} expected state {}".
+ format(get_state(), state))
return False
+
def factory_reset_bluetooth(android_devices):
"""Clears Bluetooth stack of input Android device list.
@@ -340,6 +348,7 @@
return False
return True
+
def reset_bluetooth(android_devices):
"""Resets Bluetooth state of input Android device list.
@@ -576,6 +585,7 @@
mac_address = event['data']['Result']['deviceInfo']['address']
return mac_address, advertise_callback, scan_callback
+
def enable_bluetooth(droid, ed):
if droid.bluetoothCheckState() is True:
return True
@@ -594,6 +604,7 @@
return True
+
def disable_bluetooth(droid):
"""Disable Bluetooth on input Droid object.
@@ -1000,7 +1011,8 @@
bluetooth_profile_connection_state_changed, bt_default_timeout)
pri_ad.log.info("Got event {}".format(profile_event))
except Exception as e:
- pri_ad.log.error("Did not disconnect from Profiles. Reason {}".format(e))
+ pri_ad.log.error(
+ "Did not disconnect from Profiles. Reason {}".format(e))
return False
profile = profile_event['data']['profile']
@@ -1398,3 +1410,78 @@
if (device["address"] == source.droid.bluetoothGetLocalAddress()):
return True
return False
+
+
+def get_device_selector_dictionary(android_device_list):
+ """Create a dictionary of Bluetooth features vs Android devices.
+
+ Args:
+ android_device_list: The list of Android devices.
+ Returns:
+ A dictionary of profiles/features to Android devices.
+ """
+ selector_dict = {}
+ for ad in android_device_list:
+ uuids = ad.droid.bluetoothGetLocalUuids()
+
+ for profile, uuid_const in sig_uuid_constants.items():
+ uuid_check = sig_uuid_constants['BASE_UUID'].format(
+ uuid_const).lower()
+ if uuid_check in uuids:
+ if profile in selector_dict:
+ selector_dict[profile].append(ad)
+ else:
+ selector_dict[profile] = [ad]
+
+ # Various services may not be active during BT startup.
+ # If the device can be identified through adb shell pm list features
+ # then try to add them to the appropriate profiles / features.
+
+ # Android TV.
+ if "feature:com.google.android.tv.installed" in ad.features:
+ ad.log.info("Android TV device found.")
+ supported_profiles = ['AudioSink']
+ _add_android_device_to_dictionary(ad, supported_profiles,
+ selector_dict)
+
+ # Android Auto
+ elif "feature:android.hardware.type.automotive" in ad.features:
+ ad.log.info("Android Auto device found.")
+ # Add: AudioSink , A/V_RemoteControl,
+ supported_profiles = [
+ 'AudioSink', 'A/V_RemoteControl', 'Message Notification Server'
+ ]
+ _add_android_device_to_dictionary(ad, supported_profiles,
+ selector_dict)
+ # Android Wear
+ elif "feature:android.hardware.type.watch" in ad.features:
+ ad.log.info("Android Wear device found.")
+ supported_profiles = []
+ _add_android_device_to_dictionary(ad, supported_profiles,
+ selector_dict)
+ # Android Phone
+ elif "feature:android.hardware.telephony" in ad.features:
+ ad.log.info("Android Phone device found.")
+ # Add: AudioSink
+ supported_profiles = [
+ 'AudioSource', 'A/V_RemoteControlTarget',
+ 'Message Access Server'
+ ]
+ _add_android_device_to_dictionary(ad, supported_profiles,
+ selector_dict)
+ return selector_dict
+
+
+def _add_android_device_to_dictionary(android_device, profile_list,
+ selector_dict):
+ """Adds the AndroidDevice and supported features to the selector dictionary
+
+ Args:
+ android_device: The Android device.
+ profile_list: The list of profiles the Android device supports.
+ """
+ for profile in profile_list:
+ if profile in selector_dict and android_device not in selector_dict[profile]:
+ selector_dict[profile].append(android_device)
+ else:
+ selector_dict[profile] = [android_device]