1#!/usr/bin/env python3 2# 3# Copyright (C) 2019 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 17import acts_contrib.test_utils.bt.bt_test_utils as btutils 18from acts_contrib.test_utils.bt.bt_constants import adv_succ 19from acts_contrib.test_utils.bt.A2dpBaseTest import A2dpBaseTest 20from acts_contrib.test_utils.bt.bt_constants import bt_default_timeout 21from acts_contrib.test_utils.bt.bt_constants import ble_advertise_settings_modes 22from acts_contrib.test_utils.bt.bt_constants import ble_advertise_settings_tx_powers 23from acts_contrib.test_utils.bt.bt_test_utils import BtTestUtilsError 24from queue import Empty 25from acts_contrib.test_utils.bt.bt_test_utils import generate_ble_advertise_objects 26from acts_contrib.test_utils.bt.bt_test_utils import setup_multiple_devices_for_bt_test 27 28INIT_ATTEN = 0 29 30 31class BtA2dpRangeWithBleAdvTest(A2dpBaseTest): 32 """User can generate test case with below format. 33 test_bt_a2dp_range_codec_"Codec"_adv_mode_"Adv Mode"_adv_tx_power_"Adv Tx Power" 34 35 Below are the list of test cases: 36 test_bt_a2dp_range_codec_AAC_adv_mode_low_power_adv_tx_power_ultra_low 37 test_bt_a2dp_range_codec_AAC_adv_mode_low_power_adv_tx_power_low 38 test_bt_a2dp_range_codec_AAC_adv_mode_low_power_adv_tx_power_medium 39 test_bt_a2dp_range_codec_AAC_adv_mode_low_power_adv_tx_power_high 40 test_bt_a2dp_range_codec_AAC_adv_mode_balanced_adv_tx_power_ultra_low 41 test_bt_a2dp_range_codec_AAC_adv_mode_balanced_adv_tx_power_low 42 test_bt_a2dp_range_codec_AAC_adv_mode_balanced_adv_tx_power_medium 43 test_bt_a2dp_range_codec_AAC_adv_mode_balanced_adv_tx_power_high 44 test_bt_a2dp_range_codec_AAC_adv_mode_low_latency_adv_tx_power_ultra_low 45 test_bt_a2dp_range_codec_AAC_adv_mode_low_latency_adv_tx_power_low 46 test_bt_a2dp_range_codec_AAC_adv_mode_low_latency_adv_tx_power_medium 47 test_bt_a2dp_range_codec_AAC_adv_mode_low_latency_adv_tx_power_high 48 test_bt_a2dp_range_codec_SBC_adv_mode_low_power_adv_tx_power_ultra_low 49 test_bt_a2dp_range_codec_SBC_adv_mode_low_power_adv_tx_power_low 50 test_bt_a2dp_range_codec_SBC_adv_mode_low_power_adv_tx_power_medium 51 test_bt_a2dp_range_codec_SBC_adv_mode_low_power_adv_tx_power_high 52 test_bt_a2dp_range_codec_SBC_adv_mode_balanced_adv_tx_power_ultra_low 53 test_bt_a2dp_range_codec_SBC_adv_mode_balanced_adv_tx_power_low 54 test_bt_a2dp_range_codec_SBC_adv_mode_balanced_adv_tx_power_medium 55 test_bt_a2dp_range_codec_SBC_adv_mode_balanced_adv_tx_power_high 56 test_bt_a2dp_range_codec_SBC_adv_mode_low_latency_adv_tx_power_ultra_low 57 test_bt_a2dp_range_codec_SBC_adv_mode_low_latency_adv_tx_power_low 58 test_bt_a2dp_range_codec_SBC_adv_mode_low_latency_adv_tx_power_medium 59 test_bt_a2dp_range_codec_SBC_adv_mode_low_latency_adv_tx_power_high 60 61 """ 62 def __init__(self, configs): 63 super().__init__(configs) 64 req_params = ['attenuation_vector', 'codecs'] 65 #'attenuation_vector' is a dict containing: start, stop and step of 66 #attenuation changes 67 #'codecs' is a list containing all codecs required in the tests 68 self.unpack_userparams(req_params) 69 for codec_config in self.codecs: 70 # Loop all advertise modes and power levels 71 for adv_mode in ble_advertise_settings_modes.items(): 72 for adv_power_level in ble_advertise_settings_tx_powers.items( 73 ): 74 self.generate_test_case(codec_config, adv_mode, 75 adv_power_level) 76 77 def setup_class(self): 78 super().setup_class() 79 opt_params = ['gain_mismatch', 'dual_chain'] 80 self.unpack_userparams(opt_params, dual_chain=None, gain_mismatch=None) 81 return setup_multiple_devices_for_bt_test(self.android_devices) 82 # Enable BQR on all android devices 83 btutils.enable_bqr(self.android_devices) 84 if hasattr(self, 'dual_chain') and self.dual_chain == 1: 85 self.atten_c0 = self.attenuators[0] 86 self.atten_c1 = self.attenuators[1] 87 self.atten_c0.set_atten(INIT_ATTEN) 88 self.atten_c1.set_atten(INIT_ATTEN) 89 90 def teardown_class(self): 91 super().teardown_class() 92 if hasattr(self, 'atten_c0') and hasattr(self, 'atten_c1'): 93 self.atten_c0.set_atten(INIT_ATTEN) 94 self.atten_c1.set_atten(INIT_ATTEN) 95 96 def generate_test_case(self, codec_config, adv_mode, adv_power_level): 97 def test_case_fn(): 98 adv_callback = self.start_ble_adv(adv_mode[1], adv_power_level[1]) 99 self.run_a2dp_to_max_range(codec_config) 100 self.dut.droid.bleStopBleAdvertising(adv_callback) 101 self.log.info("Advertisement stopped Successfully") 102 103 if hasattr(self, 'dual_chain') and self.dual_chain == 1: 104 test_case_name = 'test_dual_bt_a2dp_range_codec_{}_gainmimatch_{}dB'.format( 105 codec_config['codec_type'], self.gain_mismatch) 106 else: 107 test_case_name = 'test_bt_a2dp_range_codec_{}_adv_mode_{}_adv_tx_power_{}'.format( 108 codec_config['codec_type'], adv_mode[0], adv_power_level[0]) 109 setattr(self, test_case_name, test_case_fn) 110 111 def start_ble_adv(self, adv_mode, adv_power_level): 112 """Function to start an LE advertisement 113 Steps: 114 1. Create a advertise data object 115 2. Create a advertise settings object. 116 3. Create a advertise callback object. 117 4. Start an LE advertising using the objects created in steps 1-3. 118 5. Find the onSuccess advertisement event. 119 120 Expected Result: 121 Advertisement is successfully advertising. 122 123 Returns: 124 Returns advertise call back""" 125 126 self.dut.droid.bleSetAdvertiseDataIncludeDeviceName(True) 127 self.dut.droid.bleSetAdvertiseSettingsAdvertiseMode(adv_mode) 128 self.dut.droid.bleSetAdvertiseSettingsIsConnectable(True) 129 self.dut.droid.bleSetAdvertiseSettingsTxPowerLevel(adv_power_level) 130 advertise_callback, advertise_data, advertise_settings = ( 131 generate_ble_advertise_objects(self.dut.droid)) 132 self.dut.droid.bleStartBleAdvertising(advertise_callback, 133 advertise_data, 134 advertise_settings) 135 try: 136 self.dut.ed.pop_event(adv_succ.format(advertise_callback), 137 bt_default_timeout) 138 self.log.info("Advertisement started successfully") 139 except Empty as err: 140 raise BtTestUtilsError( 141 "Advertiser did not start successfully {}".format(err)) 142 return advertise_callback 143