1#!/usr/bin/env python3
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"""
17This test script exercises different opportunistic scan scenarios.
18It is expected that the second AndroidDevice is able to advertise.
19
20This test script was designed with this setup in mind:
21Shield box one: Android Device, Android Device
22"""
23
24from queue import Empty
25
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 ble_scan_settings_modes
30from acts.test_utils.bt.bt_constants import ble_scan_settings_modes
31from acts.test_utils.bt.bt_constants import batch_scan_result
32from acts.test_utils.bt.bt_test_utils import cleanup_scanners_and_advertisers
33from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
34from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects
35from acts.test_utils.bt.bt_test_utils import reset_bluetooth
36from acts.test_utils.bt.bt_constants import scan_result
37
38
39class BleOpportunisticScanTest(BluetoothBaseTest):
40    default_timeout = 10
41    max_scan_instances = 25
42    report_delay = 2000
43    scan_callbacks = []
44    adv_callbacks = []
45    active_scan_callback_list = []
46    active_adv_callback_list = []
47
48    def setup_class(self):
49        super(BluetoothBaseTest, self).setup_class()
50        self.scn_ad = self.android_devices[0]
51        self.adv_ad = self.android_devices[1]
52
53        utils.set_location_service(self.scn_ad, True)
54        utils.set_location_service(self.adv_ad, True)
55        return True
56
57    def teardown_test(self):
58        cleanup_scanners_and_advertisers(
59            self.scn_ad, self.active_scan_callback_list, self.adv_ad,
60            self.active_adv_callback_list)
61        self.active_adv_callback_list = []
62        self.active_scan_callback_list = []
63
64    def on_exception(self, test_name, begin_time):
65        reset_bluetooth(self.android_devices)
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            event = self.scn_ad.ed.pop_event(event_name, self.default_timeout)
77            self.log.error("Found an event when none was expected: {}".format(
78                event))
79            return False
80        except Empty:
81            self.log.info("No scan result found as expected.")
82            return True
83
84    @BluetoothBaseTest.bt_test_wrap
85    @test_tracker_info(uuid='6bccfbea-3734-4504-8ea9-3511ad17a3e0')
86    def test_scan_result_no_advertisement(self):
87        """Test opportunistic scan with no advertisement.
88
89        Tests opportunistic scan where there are no advertisements. This should
90        not find any onScanResults.
91
92        Steps:
93        1. Initialize scanner with scan mode set to opportunistic mode.
94        2. Start scanning on dut 0
95        3. Pop onScanResults event on the scanner
96
97        Expected Result:
98        Find no advertisements with the opportunistic scan instance.
99
100        Returns:
101          Pass if True
102          Fail if False
103
104        TAGS: LE, Advertising, Scanning, Opportunistic Scan
105        Priority: 1
106        """
107        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
108            'opportunistic'])
109        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
110            self.scn_ad.droid)
111        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
112                                          scan_callback)
113        self.active_scan_callback_list.append(scan_callback)
114        if not self._verify_no_events_found(scan_result.format(scan_callback)):
115            return False
116        self.scn_ad.droid.bleStopBleScan(scan_callback)
117        return True
118
119    @BluetoothBaseTest.bt_test_wrap
120    @test_tracker_info(uuid='8430bc57-925c-4b70-a62e-cd34df264ca1')
121    def test_batch_scan_result_no_advertisement(self):
122        """Test batch opportunistic scan without an advertisement.
123
124        Tests opportunistic scan where there are no advertisements. This should
125        not find any onBatchScanResult.
126
127        Steps:
128        1. Initialize scanner with scan mode set to opportunistic mode.
129        2. Set report delay seconds such that onBatchScanResult events are
130        expected
131        2. Start scanning on dut 0
132        3. Pop onBatchScanResult event on the scanner
133
134        Expected Result:
135        Find no advertisements with the opportunistic scan instance.
136
137        Returns:
138          Pass if True
139          Fail if False
140
141        TAGS: LE, Advertising, Scanning, Opportunistic Scan, Batch Scanning
142        Priority: 1
143        """
144        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
145            'opportunistic'])
146        self.scn_ad.droid.bleSetScanSettingsReportDelayMillis(
147            self.report_delay)
148        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
149            self.scn_ad.droid)
150        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
151                                          scan_callback)
152        self.active_scan_callback_list.append(scan_callback)
153        if not self._verify_no_events_found(
154                batch_scan_result.format(scan_callback)):
155            return False
156        self.scn_ad.droid.bleStopBleScan(scan_callback)
157        return True
158
159    @BluetoothBaseTest.bt_test_wrap
160    @test_tracker_info(uuid='4613cb67-0f54-494e-8a56-2e8ce56fad41')
161    def test_scan_result(self):
162        """Test opportunistic scan with an advertisement.
163
164        Tests opportunistic scan where it will only report scan results when
165        other registered scanners find results.
166
167        Steps:
168        1. Initialize advertiser and start advertisement on dut1
169        2. Initialize scanner with scan mode set to opportunistic mode on dut0
170        and start scanning
171        3. Try to find an event, expect none.
172        4. Start a second scanner on dut0, with any other mode set
173        5. Pop onScanResults event on the second scanner
174        6. Pop onScanResults event on the first scanner
175
176        Expected Result:
177        Scan result is found on the opportunistic scan instance.
178
179        Returns:
180          Pass if True
181          Fail if False
182
183        TAGS: LE, Advertising, Scanning, Opportunistic Scan
184        Priority: 1
185        """
186        self._setup_generic_advertisement()
187        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
188            'opportunistic'])
189        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
190            self.scn_ad.droid)
191
192        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
193                                          scan_callback)
194        self.active_scan_callback_list.append(scan_callback)
195        if not self._verify_no_events_found(scan_result.format(scan_callback)):
196            return False
197        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
198            'low_latency'])
199        filter_list2, scan_settings2, scan_callback2 = (
200            generate_ble_scan_objects(self.scn_ad.droid))
201        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
202                                          scan_callback2)
203        self.active_scan_callback_list.append(scan_callback2)
204        try:
205            self.scn_ad.ed.pop_event(
206                scan_result.format(scan_callback2), self.default_timeout)
207        except Empty:
208            self.log.error("Non-Opportunistic scan found no scan results.")
209            return False
210        try:
211            self.scn_ad.ed.pop_event(
212                scan_result.format(scan_callback), self.default_timeout)
213        except Empty:
214            self.log.error("Opportunistic scan found no scan results.")
215            return False
216        return True
217
218    @BluetoothBaseTest.bt_test_wrap
219    @test_tracker_info(uuid='5b46fefc-70ef-48a0-acf4-35077cd72202')
220    def test_batch_scan_result(self):
221        """Test batch opportunistic scan with advertisement.
222
223        Tests opportunistic scan where it will only report scan results when
224        other registered scanners find results. Set the report delay millis such
225        that an onBatchScanResult is expected.
226
227        Steps:
228        1. Initialize advertiser and start advertisement on dut1
229        2. Initialize scanner with scan mode set to opportunistic mode and
230        set scan settings report delay seconds such that a batch scan is
231        expected
232        3. Start scanning on dut 0
233        4. Try to find an event, expect none.
234        5. Start a second scanner on dut0, with any other mode set and set scan
235        settings report delay millis such that an onBatchScanResult is expected
236        6. Pop onBatchScanResult event on the second scanner
237        7. Pop onBatchScanResult event on the first scanner
238
239        Expected Result:
240        Find a batch scan result on both opportunistic scan instances.
241
242        Returns:
243          Pass if True
244          Fail if False
245
246        TAGS: LE, Advertising, Scanning, Opportunistic Scan, Batch Scanning
247        Priority: 1
248        """
249        self._setup_generic_advertisement()
250        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
251            'opportunistic'])
252        self.scn_ad.droid.bleSetScanSettingsReportDelayMillis(
253            self.report_delay)
254        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
255            self.scn_ad.droid)
256        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
257                                          scan_callback)
258        self.active_scan_callback_list.append(scan_callback)
259        if not self._verify_no_events_found(
260                batch_scan_result.format(scan_callback)):
261            return False
262        self.scn_ad.droid.bleSetScanSettingsReportDelayMillis(
263            self.report_delay)
264        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
265            'low_latency'])
266        filter_list2, scan_settings2, scan_callback2 = generate_ble_scan_objects(
267            self.scn_ad.droid)
268        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
269                                          scan_callback2)
270        self.active_scan_callback_list.append(scan_callback2)
271        try:
272            self.scn_ad.ed.pop_event(
273                batch_scan_result.format(scan_callback2), self.default_timeout)
274        except Empty:
275            self.log.error("Non-Opportunistic scan found no scan results.")
276            return False
277        try:
278            self.scn_ad.ed.pop_event(
279                batch_scan_result.format(scan_callback), self.default_timeout)
280        except Empty:
281            self.log.error("Opportunistic scan found no scan results.")
282            return False
283        return True
284
285    @BluetoothBaseTest.bt_test_wrap
286    @test_tracker_info(uuid='fd85d95e-dc8c-48c1-8d8a-83c3475755ff')
287    def test_batch_scan_result_not_expected(self):
288        """Test opportunistic batch scan without expecting an event.
289
290        Tests opportunistic scan where it will only report scan results when
291        other registered scanners find results. Set the report delay millis such
292        that a batch scan is not expected.
293
294        Steps:
295        1. Initialize advertiser and start advertisement on dut1
296        2. Initialize scanner with scan mode set to opportunistic mode and
297        set scan settings report delay seconds such that a batch scan is
298        expected.
299        3. Start scanning on dut 0
300        4. Try to find an event, expect none.
301        5. Start a second scanner on dut0, with any other mode set and set scan
302        settings report delay millis to 0 such that an onBatchScanResult is not
303        expected.
304        6. Pop onScanResults event on the second scanner
305        7. Pop onBatchScanResult event on the first scanner
306
307        Expected Result:
308        Batch scan result is not expected on opportunistic scan instance.
309
310        Returns:
311          Pass if True
312          Fail if False
313
314        TAGS: LE, Advertising, Scanning, Opportunistic Scan, Batch Scanning
315        Priority: 1
316        """
317        self._setup_generic_advertisement()
318        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
319            'opportunistic'])
320        self.scn_ad.droid.bleSetScanSettingsReportDelayMillis(
321            self.report_delay)
322        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
323            self.scn_ad.droid)
324        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
325                                          scan_callback)
326        self.active_scan_callback_list.append(scan_callback)
327        if not self._verify_no_events_found(
328                batch_scan_result.format(scan_callback)):
329
330            return False
331        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
332            'low_latency'])
333        filter_list2, scan_settings2, scan_callback2 = (
334            generate_ble_scan_objects(self.scn_ad.droid))
335        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
336                                          scan_callback2)
337        self.active_scan_callback_list.append(scan_callback2)
338        try:
339            self.scn_ad.ed.pop_event(
340                scan_result.format(scan_callback2), self.default_timeout)
341        except Empty:
342            self.log.error("Non-Opportunistic scan found no scan results.")
343            return False
344        return self._verify_no_events_found(
345            batch_scan_result.format(scan_callback))
346
347    @BluetoothBaseTest.bt_test_wrap
348    @test_tracker_info(uuid='6138592e-8fd5-444f-9a7c-25cd9695644a')
349    def test_scan_result_not_expected(self):
350        """Test opportunistic scan without expecting an event.
351
352        Tests opportunistic scan where it will only report batch scan results
353        when other registered scanners find results.
354
355        Steps:
356        1. Initialize advertiser and start advertisement on dut1
357        2. Initialize scanner with scan mode set to opportunistic mode.
358        3. Start scanning on dut 0
359        4. Try to find an event, expect none.
360        5. Start a second scanner on dut0, with any other mode set and set scan
361        settings
362        report delay millis such that an onBatchScanResult is expected
363        6. Pop onBatchScanResult event on the second scanner
364        7. Pop onScanResults event on the first scanner
365
366        Expected Result:
367        Scan result is not expected on opportunistic scan instance.
368
369        Returns:
370          Pass if True
371          Fail if False
372
373        TAGS: LE, Advertising, Scanning, Opportunistic Scan
374        Priority: 1
375        """
376        self._setup_generic_advertisement()
377        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
378            'opportunistic'])
379        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
380            self.scn_ad.droid)
381        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
382                                          scan_callback)
383        self.active_scan_callback_list.append(scan_callback)
384        if not self._verify_no_events_found(scan_result.format(scan_callback)):
385            return False
386        self.scn_ad.droid.bleSetScanSettingsReportDelayMillis(
387            self.report_delay)
388        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
389            'low_latency'])
390        filter_list2, scan_settings2, scan_callback2 = (
391            generate_ble_scan_objects(self.scn_ad.droid))
392        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
393                                          scan_callback2)
394        self.active_scan_callback_list.append(scan_callback2)
395        try:
396            self.scn_ad.ed.pop_event(
397                batch_scan_result.format(scan_callback2), self.default_timeout)
398        except Empty:
399            self.log.error("Non-Opportunistic scan found no scan results.")
400            return False
401        return self._verify_no_events_found(scan_result.format(scan_callback))
402
403    @BluetoothBaseTest.bt_test_wrap
404    @test_tracker_info(uuid='f7aba3d9-d3f7-4b2f-976e-441772705613')
405    def test_max_opportunistic_scan_instances(self):
406        """Test max number of opportunistic scan instances.
407
408        Tests max instances of opportunistic scans. Each instances should
409        find an onScanResults event.
410
411        Steps:
412        1. Initialize advertiser and start advertisement on dut1
413        2. Set scan settings to opportunistic scan on dut0 scan instance
414        3. Start scan scan from step 2
415        4. Repeat step two and three until there are max_scan_instances-1 scan
416        instances
417        5. Start a regular ble scan on dut0 with the last available scan
418        instance
419        6. Pop onScanResults event on all scan instances
420
421        Expected Result:
422        Each opportunistic scan instance finds a advertisement.
423
424        Returns:
425          Pass if True
426          Fail if False
427
428        TAGS: LE, Advertising, Scanning, Opportunistic Scan
429        Priority: 1
430        """
431        self._setup_generic_advertisement()
432        for _ in range(self.max_scan_instances - 1):
433            self.scn_ad.droid.bleSetScanSettingsScanMode(
434                ble_scan_settings_modes['opportunistic'])
435            filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
436                self.scn_ad.droid)
437            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
438                                              scan_callback)
439            self.active_scan_callback_list.append(scan_callback)
440
441        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
442            'low_latency'])
443        filter_list2, scan_settings2, scan_callback2 = (
444            generate_ble_scan_objects(self.scn_ad.droid))
445        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
446                                          scan_callback2)
447        self.active_scan_callback_list.append(scan_callback2)
448
449        for callback in self.active_scan_callback_list:
450            try:
451                self.scn_ad.ed.pop_event(
452                    scan_result.format(callback), self.default_timeout)
453            except Empty:
454                self.log.error("No scan results found for callback {}".format(
455                    callback))
456                return False
457        return True
458
459    @BluetoothBaseTest.bt_test_wrap
460    @test_tracker_info(uuid='cf971f08-4d92-4046-bba6-b86a75aa773c')
461    def test_max_opportunistic_batch_scan_instances(self):
462        """Test max opportunistic batch scan instances.
463
464        Tests max instances of opportunistic batch scans. Each instances should
465        find an onBatchScanResult event.
466
467        Steps:
468        1. Initialize advertiser and start advertisement on dut1
469        2. Set scan settings to opportunistic scan on dut0 scan instance and
470        set report delay seconds such that an onBatchScanResult is expected
471        3. Start scan scan from step 2
472        4. Repeat step two and three until there are max_scan_instances-1 scan
473        instances
474        5. Start a regular ble scan on dut0 with the last available scan
475        instance
476        6. Pop onBatchScanResult event on all scan instances
477
478        Expected Result:
479        Each opportunistic scan instance finds an advertisement.
480
481        Returns:
482          Pass if True
483          Fail if False
484
485        TAGS: LE, Advertising, Scanning, Opportunistic Scan, Batch Scanning
486        Priority: 1
487        """
488        self._setup_generic_advertisement()
489        for _ in range(self.max_scan_instances - 1):
490            self.scn_ad.droid.bleSetScanSettingsScanMode(
491                ble_scan_settings_modes['opportunistic'])
492            self.scn_ad.droid.bleSetScanSettingsReportDelayMillis(
493                self.report_delay)
494            filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
495                self.scn_ad.droid)
496            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
497                                              scan_callback)
498            self.active_scan_callback_list.append(scan_callback)
499
500        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
501            'low_latency'])
502        self.scn_ad.droid.bleSetScanSettingsReportDelayMillis(
503            self.report_delay)
504        filter_list2, scan_settings2, scan_callback2 = (
505            generate_ble_scan_objects(self.scn_ad.droid))
506        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
507                                          scan_callback2)
508        self.active_scan_callback_list.append(scan_callback2)
509
510        for callback in self.active_scan_callback_list:
511            try:
512                self.scn_ad.ed.pop_event(
513                    batch_scan_result.format(callback), self.default_timeout)
514            except Empty:
515                self.log.error("No scan results found for callback {}".format(
516                    callback))
517        return True
518
519    @BluetoothBaseTest.bt_test_wrap
520    @test_tracker_info(uuid='965d84ef-11a7-418a-97e9-2a441c6de776')
521    def test_discover_opportunistic_scan_result_off_secondary_scan_filter(
522            self):
523        """Test opportunistic scan result from secondary scan filter.
524
525        Tests opportunistic scan where the filtered scan instance does not find
526        an advertisement and the scan instance with scan mode set to
527        opportunistic scan will also not find an advertisement.
528
529        Steps:
530        1. Initialize advertiser and start advertisement on dut1 (make sure the
531        advertisement is not advertising the device name)
532        2. Set scan settings to opportunistic scan on dut0 scan instance
533        3. Start scan scan from step 2
534        4. Try to find an event, expect none
535        5. Start a second scanner on dut0, with any other mode set and set the
536        scan filter device name to "opp_test"
537        6. Pop onScanResults from the second scanner
538        7. Expect no events
539        8. Pop onScanResults from the first scanner
540        9. Expect no events
541
542        Expected Result:
543        Opportunistic scan instance finds an advertisement.
544
545        Returns:
546          Pass if True
547          Fail if False
548
549        TAGS: LE, Advertising, Scanning, Opportunistic Scan
550        Priority: 1
551        """
552        self._setup_generic_advertisement()
553        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
554            'opportunistic'])
555        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
556            self.scn_ad.droid)
557
558        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
559                                          scan_callback)
560        self.active_scan_callback_list.append(scan_callback)
561        if not self._verify_no_events_found(scan_result.format(scan_callback)):
562            return False
563        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
564            'low_latency'])
565        self.scn_ad.droid.bleSetScanFilterDeviceName("opp_test")
566        filter_list2, scan_settings2, scan_callback2 = (
567            generate_ble_scan_objects(self.scn_ad.droid))
568        self.scn_ad.droid.bleBuildScanFilter(filter_list2)
569        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
570                                          scan_callback2)
571        self.active_scan_callback_list.append(scan_callback2)
572        if not self._verify_no_events_found(
573                scan_result.format(scan_callback2)):
574            return False
575        if not self._verify_no_events_found(scan_result.format(scan_callback)):
576            return False
577        return True
578
579    @BluetoothBaseTest.bt_test_wrap
580    @test_tracker_info(uuid='13b0a83f-e96e-4d64-84ef-66351ec5054c')
581    def test_negative_opportunistic_scan_filter_result_off_secondary_scan_result(
582            self):
583        """Test opportunistic scan not found scenario.
584
585        Tests opportunistic scan where the secondary scan instance does find an
586        advertisement but the scan instance with scan mode set to opportunistic
587        scan does not find an advertisement due to mismatched scan filters.
588
589        Steps:
590        1. Initialize advertiser and start advertisement on dut1 (make sure the
591        advertisement is not advertising the device name)
592        2. Set scan settings to opportunistic scan on dut0 scan instance and set
593        the scan filter device name to "opp_test"
594        3. Start scan scan from step 2
595        4. Try to find an event, expect none
596        5. Start a second scanner on dut0, with any other mode set
597        6. Pop onScanResults from the second scanner
598        7. Pop onScanResults from the first scanner
599        8. Expect no events
600
601        Expected Result:
602        Opportunistic scan instance doesn't find any advertisements.
603
604        Returns:
605          Pass if True
606          Fail if False
607
608        TAGS: LE, Advertising, Scanning, Opportunistic Scan
609        Priority: 1
610        """
611        self._setup_generic_advertisement()
612        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
613            'opportunistic'])
614        self.scn_ad.droid.bleSetScanFilterDeviceName("opp_test")
615        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
616            self.scn_ad.droid)
617        self.scn_ad.droid.bleBuildScanFilter(filter_list)
618        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
619                                          scan_callback)
620        self.active_scan_callback_list.append(scan_callback)
621        if not self._verify_no_events_found(scan_result.format(scan_callback)):
622            return False
623        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
624            'low_latency'])
625        filter_list2, scan_settings2, scan_callback2 = (
626            generate_ble_scan_objects(self.scn_ad.droid))
627        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
628                                          scan_callback2)
629        self.active_scan_callback_list.append(scan_callback2)
630        try:
631            self.scn_ad.ed.pop_event(
632                scan_result.format(scan_callback2), self.default_timeout)
633        except Empty:
634            self.log.error("Non-Opportunistic scan found no scan results.")
635            return False
636        return self._verify_no_events_found(scan_result.format(scan_callback))
637
638    @BluetoothBaseTest.bt_test_wrap
639    @test_tracker_info(uuid='087f60b2-f6a1-4919-b4c5-cdf3debcfeff')
640    def test_opportunistic_scan_filter_result_off_secondary_scan_result(self):
641        """Test opportunistic scan from a secondary scan result.
642
643        Tests opportunistic scan where the scan filters are the same between the
644        first scan instance with opportunistic scan set and the second instance
645        with any other mode set.
646
647        Steps:
648        1. Initialize advertiser and start advertisement on dut1
649        2. On dut0, set the scan settings mode to opportunistic scan and set
650        the scan filter device name to the advertiser's device name
651        3. Start scan scan from step 2
652        4. Try to find an event, expect none
653        5. Start a second scanner on dut0, with any other mode set and set the
654        scan filter device name to the advertiser's device name
655        6. Pop onScanResults from the second scanner
656        7. Pop onScanResults from the first scanner
657
658        Expected Result:
659        Opportunistic scan instance finds a advertisement.
660
661        Returns:
662          Pass if True
663          Fail if False
664
665        TAGS: LE, Advertising, Scanning, Opportunistic Scan
666        Priority: 1
667        """
668        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
669        self._setup_generic_advertisement()
670        adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
671        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
672            'opportunistic'])
673        self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
674        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
675            self.scn_ad.droid)
676        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
677                                          scan_callback)
678        self.active_scan_callback_list.append(scan_callback)
679        if not self._verify_no_events_found(scan_result.format(scan_callback)):
680            return False
681        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
682            'low_latency'])
683        filter_list2, scan_settings2, scan_callback2 = (
684            generate_ble_scan_objects(self.scn_ad.droid))
685        self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
686        self.scn_ad.droid.bleBuildScanFilter(filter_list2)
687        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
688                                          scan_callback2)
689        self.active_scan_callback_list.append(scan_callback2)
690        try:
691            self.scn_ad.ed.pop_event(
692                scan_result.format(scan_callback2), self.default_timeout)
693        except Empty:
694            self.log.error("Opportunistic scan found no scan results.")
695            return False
696        try:
697            self.scn_ad.ed.pop_event(
698                scan_result.format(scan_callback), self.default_timeout)
699        except Empty:
700            self.log.error("Non-Opportunistic scan found no scan results.")
701            return False
702        return True
703