Home | History | Annotate | Download | only in scan
      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 This test script exercises background scan test scenarios.
     18 """
     19 
     20 from queue import Empty
     21 
     22 from acts.test_decorators import test_tracker_info
     23 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
     24 from acts.test_utils.bt.bt_test_utils import bluetooth_off
     25 from acts.test_utils.bt.bt_test_utils import bluetooth_on
     26 from acts.test_utils.bt.bt_test_utils import cleanup_scanners_and_advertisers
     27 from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
     28 from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects
     29 from acts.test_utils.bt.bt_constants import bluetooth_le_off
     30 from acts.test_utils.bt.bt_constants import bluetooth_le_on
     31 from acts.test_utils.bt.bt_constants import bt_adapter_states
     32 from acts.test_utils.bt.bt_constants import scan_result
     33 
     34 import time
     35 
     36 
     37 class BleBackgroundScanTest(BluetoothBaseTest):
     38     default_timeout = 10
     39     max_scan_instances = 28
     40     report_delay = 2000
     41     scan_callbacks = []
     42     adv_callbacks = []
     43     active_scan_callback_list = []
     44     active_adv_callback_list = []
     45 
     46     def __init__(self, controllers):
     47         BluetoothBaseTest.__init__(self, controllers)
     48         self.scn_ad = self.android_devices[0]
     49         self.adv_ad = self.android_devices[1]
     50 
     51     def setup_test(self):
     52         if (self.scn_ad.droid.bluetoothGetLeState() ==
     53                 bt_adapter_states['off']):
     54             self.scn_ad.droid.bluetoothEnableBLE()
     55             self.scn_ad.ed.pop_event(bluetooth_le_on)
     56         for a in self.android_devices:
     57             a.ed.clear_all_events()
     58         return True
     59 
     60     def teardown_test(self):
     61         cleanup_scanners_and_advertisers(
     62             self.scn_ad, self.active_adv_callback_list, self.adv_ad,
     63             self.active_adv_callback_list)
     64         self.active_adv_callback_list = []
     65         self.active_scan_callback_list = []
     66 
     67     def _setup_generic_advertisement(self):
     68         adv_callback, adv_data, adv_settings = generate_ble_advertise_objects(
     69             self.adv_ad.droid)
     70         self.adv_ad.droid.bleStartBleAdvertising(adv_callback, adv_data,
     71                                                  adv_settings)
     72         self.active_adv_callback_list.append(adv_callback)
     73 
     74     def _verify_no_events_found(self, event_name):
     75         try:
     76             self.scn_ad.ed.pop_event(event_name, self.default_timeout)
     77             self.log.error("Found an event when none was expected.")
     78             return False
     79         except Empty:
     80             self.log.info("No scan result found as expected.")
     81             return True
     82 
     83     @BluetoothBaseTest.bt_test_wrap
     84     @test_tracker_info(uuid='4d13c3a8-1805-44ef-a92a-e385540767f1')
     85     def test_background_scan(self):
     86         """Test generic background scan.
     87 
     88         Tests LE background scan. The goal is to find scan results even though
     89         Bluetooth is turned off.
     90 
     91         Steps:
     92         1. Setup an advertisement on dut1
     93         2. Enable LE on the Bluetooth Adapter on dut0
     94         3. Toggle BT off on dut1
     95         4. Start a LE scan on dut0
     96         5. Find the advertisement from dut1
     97 
     98         Expected Result:
     99         Find a advertisement from the scan instance.
    100 
    101         Returns:
    102           Pass if True
    103           Fail if False
    104 
    105         TAGS: LE, Advertising, Scanning, Background Scanning
    106         Priority: 0
    107         """
    108         import time
    109         self._setup_generic_advertisement()
    110         self.scn_ad.droid.bluetoothToggleState(False)
    111         try:
    112             self.scn_ad.ed.pop_event(bluetooth_off, self.default_timeout)
    113         except Empty:
    114             self.log.error("Bluetooth Off event not found. Expected {}".format(
    115                 bluetooth_off))
    116             return False
    117         self.scn_ad.droid.bluetoothDisableBLE()
    118         try:
    119             self.scn_ad.ed.pop_event(bluetooth_off, self.default_timeout)
    120         except Empty:
    121             self.log.error("Bluetooth Off event not found. Expected {}".format(
    122                 bluetooth_off))
    123             return False
    124         self.scn_ad.droid.bluetoothEnableBLE()
    125         try:
    126             self.scn_ad.ed.pop_event(bluetooth_off, self.default_timeout * 2)
    127         except Empty:
    128             self.log.error("Bluetooth On event not found. Expected {}".format(
    129                 bluetooth_on))
    130             return False
    131         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    132             self.scn_ad.droid)
    133         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    134                                           scan_callback)
    135         expected_event = scan_result.format(scan_callback)
    136         try:
    137             self.scn_ad.ed.pop_event(expected_event, self.default_timeout)
    138         except Empty:
    139             self.log.error("Scan Result event not found. Expected {}".format(
    140                 expected_event))
    141             return False
    142         return True
    143 
    144     @BluetoothBaseTest.bt_test_wrap
    145     @test_tracker_info(uuid='9c4577f8-5e06-4034-b977-285956734974')
    146     def test_background_scan_ble_disabled(self):
    147         """Test background LE scanning with LE disabled.
    148 
    149         Tests LE background scan. The goal is to find scan results even though
    150         Bluetooth is turned off.
    151 
    152         Steps:
    153         1. Setup an advertisement on dut1
    154         2. Enable LE on the Bluetooth Adapter on dut0
    155         3. Toggle BT off on dut1
    156         4. Start a LE scan on dut0
    157         5. Find the advertisement from dut1
    158 
    159         Expected Result:
    160         Find a advertisement from the scan instance.
    161 
    162         Returns:
    163           Pass if True
    164           Fail if False
    165 
    166         TAGS: LE, Advertising, Scanning, Background Scanning
    167         Priority: 0
    168         """
    169         self._setup_generic_advertisement()
    170         self.scn_ad.droid.bluetoothEnableBLE()
    171         self.scn_ad.droid.bluetoothToggleState(False)
    172         try:
    173             self.scn_ad.ed.pop_event(bluetooth_off, self.default_timeout)
    174         except Empty:
    175             self.log.error("Bluetooth Off event not found. Expected {}".format(
    176                 bluetooth_off))
    177             return False
    178         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    179             self.scn_ad.droid)
    180         try:
    181             self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    182                                               scan_callback)
    183             expected_event = scan_result.format(scan_callback)
    184             try:
    185                 self.scn_ad.ed.pop_event(expected_event, self.default_timeout)
    186             except Empty:
    187                 self.log.error("Scan Result event not found. Expected {}".
    188                                format(expected_event))
    189                 return False
    190             self.log.info("Was able to start background scan even though ble "
    191                           "was disabled.")
    192             return False
    193         except Exception:
    194             self.log.info(
    195                 "Was not able to start a background scan as expected.")
    196         return True
    197 
    198     @BluetoothBaseTest.bt_test_wrap
    199     @test_tracker_info(uuid='0bdd1764-3dc6-4a82-b041-76e48ed0f424')
    200     def test_airplane_mode_disables_ble(self):
    201         """Try to start LE mode in Airplane Mode.
    202 
    203         This test will enable airplane mode, then attempt to start LE scanning
    204         mode.  This should result in bluetooth still being turned off, LE
    205         not enabled.
    206 
    207         Steps:
    208         1. Start LE only mode.
    209         2. Bluetooth should be in LE ONLY mode
    210         2. Turn on airplane mode.
    211         3. Bluetooth should be OFF
    212         4. Try to start LE only mode.
    213         5. Bluetooth should stay in OFF mode (LE only start should fail)
    214         6. Turn off airplane mode.
    215         7. Bluetooth should be OFF.
    216 
    217         Expected Result:
    218         No unexpected bluetooth state changes.
    219 
    220         Returns:
    221           Pass if True
    222           Fail if False
    223 
    224         TAGS: LE, Airplane
    225         Priority: 1
    226         """
    227         ble_state_error_msg = "Bluetooth LE State not OK {}. Expected {} got {}"
    228         # Enable BLE always available (effectively enabling BT in location)
    229         self.scn_ad.adb.shell("settings put global ble_scan_always_enabled 1")
    230 
    231         self.scn_ad.droid.bluetoothToggleState(False)
    232         try:
    233             self.scn_ad.ed.pop_event(bluetooth_off, self.default_timeout)
    234         except Empty:
    235             self.log.error("Bluetooth Off event not found. Expected {}".format(
    236                 bluetooth_off))
    237             return False
    238 
    239         # Sleep because LE turns off after the bluetooth off event fires
    240         time.sleep(self.default_timeout)
    241         state = self.scn_ad.droid.bluetoothGetLeState()
    242         if state != bt_adapter_states['off']:
    243             self.log.error(
    244                 ble_state_error_msg.format("after BT Disable",
    245                                            bt_adapter_states['off'], state))
    246             return False
    247 
    248         # TODO: BleStateChangedOn got generated as we shut off bluetooth above?
    249         self.scn_ad.ed.clear_all_events()
    250         result = self.scn_ad.droid.bluetoothEnableBLE()
    251         try:
    252             self.scn_ad.ed.pop_event(bluetooth_le_on, self.default_timeout)
    253         except Empty:
    254             self.log.error("Bluetooth LE On event not found. Expected {}".
    255                            format(bluetooth_le_on))
    256             return False
    257         state = self.scn_ad.droid.bluetoothGetLeState()
    258         if state != bt_adapter_states['ble_on']:
    259             self.log.error(
    260                 ble_state_error_msg.format("before Airplane Mode OFF",
    261                                            bt_adapter_states['ble_on'], state))
    262             return False
    263 
    264         self.scn_ad.droid.bluetoothListenForBleStateChange()
    265         self.scn_ad.droid.connectivityToggleAirplaneMode(True)
    266         try:
    267             self.scn_ad.ed.pop_event(bluetooth_le_off, self.default_timeout)
    268         except Empty:
    269             self.log.error("Bluetooth LE Off event not found. Expected {}".
    270                            format(bluetooth_le_off))
    271             return False
    272         state = self.scn_ad.droid.bluetoothGetLeState()
    273         if state != bt_adapter_states['off']:
    274             self.log.error(
    275                 ble_state_error_msg.format("after Airplane Mode ON",
    276                                            bt_adapter_states['off'], state))
    277             return False
    278         result = self.scn_ad.droid.bluetoothEnableBLE()
    279         if result:
    280             self.log.error(
    281                 "Bluetooth Enable command succeded when it should have failed (in airplane mode)"
    282             )
    283             return False
    284         state = self.scn_ad.droid.bluetoothGetLeState()
    285         if state != bt_adapter_states['off']:
    286             self.log.error(
    287                 "Bluetooth LE State not OK after attempted enable. Expected {} got {}".
    288                 format(bt_adapter_states['off'], state))
    289             return False
    290         self.scn_ad.droid.connectivityToggleAirplaneMode(False)
    291         # Sleep to let Airplane Mode disable propogate through the system
    292         time.sleep(self.default_timeout)
    293         state = self.scn_ad.droid.bluetoothGetLeState()
    294         if state != bt_adapter_states['off']:
    295             self.log.error(
    296                 ble_state_error_msg.format("after Airplane Mode OFF",
    297                                            bt_adapter_states['off'], state))
    298             return False
    299         return True
    300