1#!/usr/bin/env python3 2# 3# Copyright (C) 2017 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""" 17This test script exercises different scan filters with different screen states. 18""" 19 20import concurrent 21import json 22import pprint 23import time 24 25from queue import Empty 26from acts import utils 27from acts.test_decorators import test_tracker_info 28from acts_contrib.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest 29from acts_contrib.test_utils.bt.bt_constants import adv_succ 30from acts_contrib.test_utils.bt.bt_constants import ble_advertise_settings_modes 31from acts_contrib.test_utils.bt.bt_constants import ble_scan_settings_modes 32from acts_contrib.test_utils.bt.bt_constants import bt_default_timeout 33from acts_contrib.test_utils.bt.bt_constants import scan_result 34from acts_contrib.test_utils.bt.bt_test_utils import generate_ble_advertise_objects 35from acts_contrib.test_utils.bt.bt_test_utils import generate_ble_scan_objects 36from acts_contrib.test_utils.bt.bt_test_utils import reset_bluetooth 37 38 39class BleScanScreenStateTest(BluetoothBaseTest): 40 advertise_callback = -1 41 max_concurrent_scans = 27 42 scan_callback = -1 43 shorter_scan_timeout = 4 44 45 def setup_class(self): 46 super(BluetoothBaseTest, self).setup_class() 47 self.scn_ad = self.android_devices[0] 48 self.adv_ad = self.android_devices[1] 49 50 utils.set_location_service(self.scn_ad, True) 51 utils.set_location_service(self.adv_ad, True) 52 return True 53 54 def _setup_generic_advertisement(self): 55 self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode( 56 ble_advertise_settings_modes['low_latency']) 57 self.advertise_callback, advertise_data, advertise_settings = ( 58 generate_ble_advertise_objects(self.adv_ad.droid)) 59 self.adv_ad.droid.bleStartBleAdvertising( 60 self.advertise_callback, advertise_data, advertise_settings) 61 try: 62 self.adv_ad.ed.pop_event(adv_succ.format(self.advertise_callback)) 63 except Empty: 64 self.log.error("Failed to start advertisement.") 65 return False 66 return True 67 68 def _setup_scan_with_no_filters(self): 69 filter_list, scan_settings, self.scan_callback = \ 70 generate_ble_scan_objects(self.scn_ad.droid) 71 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings, 72 self.scan_callback) 73 74 def _scan_found_results(self): 75 try: 76 self.scn_ad.ed.pop_event( 77 scan_result.format(self.scan_callback), bt_default_timeout) 78 self.log.info("Found an advertisement.") 79 except Empty: 80 self.log.info("Did not find an advertisement.") 81 return False 82 return True 83 84 @BluetoothBaseTest.bt_test_wrap 85 @test_tracker_info(uuid='9b695819-e5a8-48b3-87a0-f90422998bf9') 86 def test_scan_no_filters_screen_on(self): 87 """Test LE scanning is successful with no filters and screen on. 88 89 Test LE scanning is successful with no filters and screen on. Scan 90 results should be found. 91 92 Steps: 93 1. Setup advertisement 94 2. Turn on screen 95 3. Start scanner without filters 96 4. Verify scan results are found 97 5. Teardown advertisement and scanner 98 99 Expected Result: 100 Scan results should be found. 101 102 Returns: 103 Pass if True 104 Fail if False 105 106 TAGS: LE, Advertising, Filtering, Scanning, Screen 107 Priority: 2 108 """ 109 # Step 1 110 if not self._setup_generic_advertisement(): 111 return False 112 113 # Step 2 114 self.scn_ad.droid.wakeUpNow() 115 116 # Step 3 117 self._setup_scan_with_no_filters() 118 119 # Step 4 120 if not self._scan_found_results(): 121 return False 122 123 # Step 5 124 self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback) 125 self.scn_ad.droid.bleStopBleScan(self.scan_callback) 126 return True 127 128 @BluetoothBaseTest.bt_test_wrap 129 @test_tracker_info(uuid='38fb6959-f07b-4501-814b-81a498e3efc4') 130 def test_scan_no_filters_screen_off(self): 131 """Test LE scanning is successful with no filters and screen off. 132 133 Test LE scanning is successful with no filters and screen off. No scan 134 results should be found. 135 136 Steps: 137 1. Setup advertisement 138 2. Turn off screen 139 3. Start scanner without filters 140 4. Verify no scan results are found 141 5. Teardown advertisement and scanner 142 143 Expected Result: 144 No scan results should be found. 145 146 Returns: 147 Pass if True 148 Fail if False 149 150 TAGS: LE, Advertising, Filtering, Scanning, Screen 151 Priority: 1 152 """ 153 # Step 1 154 if not self._setup_generic_advertisement(): 155 return False 156 157 # Step 2 158 self.scn_ad.droid.goToSleepNow() 159 # Give the device time to go to sleep 160 time.sleep(2) 161 162 # Step 3 163 self._setup_scan_with_no_filters() 164 165 # Step 4 166 if self._scan_found_results(): 167 return False 168 169 # Step 5 170 self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback) 171 self.scn_ad.droid.bleStopBleScan(self.scan_callback) 172 return True 173 174 @BluetoothBaseTest.bt_test_wrap 175 @test_tracker_info(uuid='7186ef2f-096a-462e-afde-b0e3d4ecdd83') 176 def test_scan_filters_works_with_screen_off(self): 177 """Test LE scanning is successful with filters and screen off. 178 179 Test LE scanning is successful with no filters and screen off. No scan 180 results should be found. 181 182 Steps: 183 1. Setup advertisement 184 2. Turn off screen 185 3. Start scanner with filters 186 4. Verify scan results are found 187 5. Teardown advertisement and scanner 188 189 Expected Result: 190 Scan results should be found. 191 192 Returns: 193 Pass if True 194 Fail if False 195 196 TAGS: LE, Advertising, Filtering, Scanning, Screen 197 Priority: 1 198 """ 199 # Step 1 200 adv_device_name = self.adv_ad.droid.bluetoothGetLocalName() 201 print(adv_device_name) 202 self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True) 203 if not self._setup_generic_advertisement(): 204 return False 205 206 # Step 2 207 self.scn_ad.droid.goToSleepNow() 208 209 # Step 3 210 self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name) 211 filter_list, scan_settings, self.scan_callback = generate_ble_scan_objects( 212 self.scn_ad.droid) 213 self.scn_ad.droid.bleBuildScanFilter(filter_list) 214 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings, 215 self.scan_callback) 216 217 # Step 4 218 if not self._scan_found_results(): 219 return False 220 221 # Step 5 222 self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback) 223 self.scn_ad.droid.bleStopBleScan(self.scan_callback) 224 return True 225 226 @BluetoothBaseTest.bt_test_wrap 227 @test_tracker_info(uuid='02cd6dca-149e-439b-8427-a2edc7864265') 228 def test_scan_no_filters_screen_off_then_turn_on(self): 229 """Test start LE scan with no filters while screen is off then turn on. 230 231 Test that a scan without filters will not return results while the 232 screen is off but will return results when the screen turns on. 233 234 Steps: 235 1. Setup advertisement 236 2. Turn off screen 237 3. Start scanner without filters 238 4. Verify no scan results are found 239 5. Turn screen on 240 6. Verify scan results are found 241 7. Teardown advertisement and scanner 242 243 Expected Result: 244 Scan results should only come in when the screen is on. 245 246 Returns: 247 Pass if True 248 Fail if False 249 250 TAGS: LE, Advertising, Filtering, Scanning, Screen 251 Priority: 2 252 """ 253 # Step 1 254 if not self._setup_generic_advertisement(): 255 return False 256 257 # Step 2 258 self.scn_ad.droid.goToSleepNow() 259 # Give the device time to go to sleep 260 time.sleep(2) 261 262 # Step 3 263 self._setup_scan_with_no_filters() 264 265 # Step 4 266 if self._scan_found_results(): 267 return False 268 269 # Step 5 270 self.scn_ad.droid.wakeUpNow() 271 272 # Step 6 273 if not self._scan_found_results(): 274 return False 275 276 # Step 7 277 self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback) 278 self.scn_ad.droid.bleStopBleScan(self.scan_callback) 279 return True 280 281 @BluetoothBaseTest.bt_test_wrap 282 @test_tracker_info(uuid='eb9fc373-f5e8-4a55-9750-02b7a11893d1') 283 def test_scan_no_filters_screen_on_then_turn_off(self): 284 """Test start LE scan with no filters while screen is on then turn off. 285 286 Test that a scan without filters will not return results while the 287 screen is off but will return results when the screen turns on. 288 289 Steps: 290 1. Setup advertisement 291 2. Turn off screen 292 3. Start scanner without filters 293 4. Verify no scan results are found 294 5. Turn screen on 295 6. Verify scan results are found 296 7. Teardown advertisement and scanner 297 298 Expected Result: 299 Scan results should only come in when the screen is on. 300 301 Returns: 302 Pass if True 303 Fail if False 304 305 TAGS: LE, Advertising, Filtering, Scanning, Screen 306 Priority: 2 307 """ 308 # Step 1 309 if not self._setup_generic_advertisement(): 310 return False 311 312 # Step 2 313 self.scn_ad.droid.wakeUpNow() 314 315 # Step 3 316 self._setup_scan_with_no_filters() 317 318 # Step 4 319 if not self._scan_found_results(): 320 return False 321 322 # Step 5 323 self.scn_ad.droid.goToSleepNow() 324 # Give the device time to go to sleep 325 time.sleep(2) 326 self.scn_ad.ed.clear_all_events() 327 328 # Step 6 329 if self._scan_found_results(): 330 return False 331 332 # Step 7 333 self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback) 334 self.scn_ad.droid.bleStopBleScan(self.scan_callback) 335 return True 336 337 @BluetoothBaseTest.bt_test_wrap 338 @test_tracker_info(uuid='41d90e11-b0a8-4eed-bff1-c19678920762') 339 def test_scan_no_filters_screen_toggling(self): 340 """Test start LE scan with no filters and test screen toggling. 341 342 Test that a scan without filters will not return results while the 343 screen is off and return results while the screen is on. 344 345 Steps: 346 1. Setup advertisement 347 2. Turn off screen 348 3. Start scanner without filters 349 4. Verify no scan results are found 350 5. Turn screen on 351 6. Verify scan results are found 352 7. Repeat steps 1-6 10 times 353 7. Teardown advertisement and scanner 354 355 Expected Result: 356 Scan results should only come in when the screen is on. 357 358 Returns: 359 Pass if True 360 Fail if False 361 362 TAGS: LE, Advertising, Filtering, Scanning, Screen 363 Priority: 3 364 """ 365 iterations = 10 366 # Step 1 367 if not self._setup_generic_advertisement(): 368 return False 369 370 for i in range(iterations): 371 self.log.info("Starting iteration {}".format(i + 1)) 372 # Step 2 373 self.scn_ad.droid.goToSleepNow() 374 # Give the device time to go to sleep 375 time.sleep(2) 376 self.scn_ad.ed.clear_all_events() 377 378 # Step 3 379 self._setup_scan_with_no_filters() 380 381 # Step 4 382 if self._scan_found_results(): 383 return False 384 385 # Step 5 386 self.scn_ad.droid.wakeUpNow() 387 388 # Step 6 389 if not self._scan_found_results(): 390 return False 391 392 # Step 7 393 self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback) 394 self.scn_ad.droid.bleStopBleScan(self.scan_callback) 395 return True 396 397 @BluetoothBaseTest.bt_test_wrap 398 @test_tracker_info(uuid='7a2fe7ef-b15f-4e93-a2f0-40e2f7d9cbcb') 399 def test_opportunistic_scan_no_filters_screen_off_then_on(self): 400 """Test opportunistic scanning does not find results with screen off. 401 402 Test LE scanning is successful with no filters and screen off. No scan 403 results should be found. 404 405 Steps: 406 1. Setup advertisement 407 2. Turn off screen 408 3. Start opportunistic scan without filters 409 4. Start scan without filters 410 5. Verify no scan results are found on either scan instance 411 6. Wake up phone 412 7. Verify scan results on each scan instance 413 8. Teardown advertisement and scanner 414 415 Expected Result: 416 No scan results should be found. 417 418 Returns: 419 Pass if True 420 Fail if False 421 422 TAGS: LE, Advertising, Filtering, Scanning, Screen 423 Priority: 1 424 """ 425 # Step 1 426 if not self._setup_generic_advertisement(): 427 return False 428 429 # Step 2 430 self.scn_ad.droid.goToSleepNow() 431 # Give the device time to go to sleep 432 time.sleep(2) 433 434 # Step 3 435 self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[ 436 'opportunistic']) 437 filter_list, scan_settings, scan_callback = generate_ble_scan_objects( 438 self.scn_ad.droid) 439 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings, 440 scan_callback) 441 442 # Step 4 443 filter_list2, scan_settings2, scan_callback2 = generate_ble_scan_objects( 444 self.scn_ad.droid) 445 self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2, 446 scan_callback2) 447 448 # Step 5 449 try: 450 self.scn_ad.ed.pop_event( 451 scan_result.format(scan_callback), self.shorter_scan_timeout) 452 self.log.error("Found an advertisement on opportunistic scan.") 453 return False 454 except Empty: 455 self.log.info("Did not find an advertisement.") 456 try: 457 self.scn_ad.ed.pop_event( 458 scan_result.format(scan_callback2), self.shorter_scan_timeout) 459 self.log.error("Found an advertisement on scan instance.") 460 return False 461 except Empty: 462 self.log.info("Did not find an advertisement.") 463 464 # Step 6 465 self.scn_ad.droid.wakeUpNow() 466 467 # Step 7 468 try: 469 self.scn_ad.ed.pop_event( 470 scan_result.format(scan_callback), self.shorter_scan_timeout) 471 self.log.info("Found an advertisement on opportunistic scan.") 472 except Empty: 473 self.log.error( 474 "Did not find an advertisement on opportunistic scan.") 475 return False 476 try: 477 self.scn_ad.ed.pop_event( 478 scan_result.format(scan_callback2), self.shorter_scan_timeout) 479 self.log.info("Found an advertisement on scan instance.") 480 except Empty: 481 self.log.info("Did not find an advertisement.") 482 return False 483 484 # Step 8 485 self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback) 486 self.scn_ad.droid.bleStopBleScan(scan_callback) 487 self.scn_ad.droid.bleStopBleScan(scan_callback2) 488 return True 489 490 @BluetoothBaseTest.bt_test_wrap 491 @test_tracker_info(uuid='406f1a2e-160f-4fb2-8a87-6403996df36e') 492 def test_max_scan_no_filters_screen_off_then_turn_on(self): 493 """Test start max scans with no filters while screen is off then turn on 494 495 Test that max LE scan without filters will not return results while the 496 screen is off but will return results when the screen turns on. 497 498 Steps: 499 1. Setup advertisement 500 2. Turn off screen 501 3. Start scanner without filters and verify no scan results 502 4. Turn screen on 503 5. Verify scan results are found on each scan callback 504 6. Teardown advertisement and all scanner 505 506 Expected Result: 507 Scan results should only come in when the screen is on. 508 509 Returns: 510 Pass if True 511 Fail if False 512 513 TAGS: LE, Advertising, Filtering, Scanning, Screen 514 Priority: 2 515 """ 516 # Step 1 517 if not self._setup_generic_advertisement(): 518 return False 519 520 # Step 2 521 self.scn_ad.droid.goToSleepNow() 522 # Give the device time to go to sleep 523 time.sleep(2) 524 525 # Step 3 526 scan_callback_list = [] 527 for _ in range(self.max_concurrent_scans): 528 filter_list, scan_settings, scan_callback = \ 529 generate_ble_scan_objects(self.scn_ad.droid) 530 self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings, 531 scan_callback) 532 scan_callback_list.append(scan_callback) 533 try: 534 self.scn_ad.ed.pop_event( 535 scan_result.format(self.scan_callback), 536 self.shorter_scan_timeout) 537 self.log.info("Found an advertisement.") 538 return False 539 except Empty: 540 self.log.info("Did not find an advertisement.") 541 542 # Step 4 543 self.scn_ad.droid.wakeUpNow() 544 545 # Step 5 546 for callback in scan_callback_list: 547 try: 548 self.scn_ad.ed.pop_event( 549 scan_result.format(callback), self.shorter_scan_timeout) 550 self.log.info("Found an advertisement.") 551 except Empty: 552 self.log.info("Did not find an advertisement.") 553 return False 554 555 # Step 7 556 self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback) 557 for callback in scan_callback_list: 558 self.scn_ad.droid.bleStopBleScan(callback) 559 return True 560