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