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"""
17Test script to execute Bluetooth basic functionality test cases.
18This test was designed to be run in a shield box.
19"""
20
21import time
22
23from queue import Empty
24from acts.test_decorators import test_tracker_info
25from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
26from acts.test_utils.bt.bt_constants import bt_scan_mode_types
27from acts.test_utils.bt.bt_test_utils import check_device_supported_profiles
28from acts.test_utils.bt.bt_test_utils import reset_bluetooth
29from acts.test_utils.bt.bt_test_utils import set_device_name
30from acts.test_utils.bt.bt_test_utils import set_bt_scan_mode
31from acts.test_utils.bt.bt_test_utils import setup_multiple_devices_for_bt_test
32from acts.test_utils.bt.bt_test_utils import take_btsnoop_logs
33
34
35class BtBasicFunctionalityTest(BluetoothBaseTest):
36    default_timeout = 10
37    scan_discovery_time = 5
38
39    def setup_class(self):
40        super().setup_class()
41        self.droid_ad = self.android_devices[0]
42        self.droid1_ad = self.android_devices[1]
43
44        return setup_multiple_devices_for_bt_test(self.android_devices)
45
46    def setup_test(self):
47        for a in self.android_devices:
48            a.ed.clear_all_events()
49        return True
50
51    def teardown_test(self):
52        return True
53
54    def on_fail(self, test_name, begin_time):
55        take_btsnoop_logs(self.android_devices, self, test_name)
56        reset_bluetooth(self.android_devices)
57
58    @BluetoothBaseTest.bt_test_wrap
59    @test_tracker_info(uuid='5a5dcf94-8114-405c-a048-b80d73e80ecc')
60    def test_bluetooth_reset(self):
61        """Test resetting bluetooth.
62
63        Test the integrity of resetting bluetooth on Android.
64
65        Steps:
66        1. Toggle bluetooth off.
67        2. Toggle bluetooth on.
68
69        Expected Result:
70        Bluetooth should toggle on and off without failing.
71
72        Returns:
73          Pass if True
74          Fail if False
75
76        TAGS: Classic
77        Priority: 1
78        """
79        return reset_bluetooth([self.droid_ad])
80
81    @BluetoothBaseTest.bt_test_wrap
82    @test_tracker_info(uuid='fc205cb8-6878-4f97-b9c8-7ed532742a1b')
83    def test_make_device_discoverable(self):
84        """Test device discoverablity.
85
86        Test that verifies devices is discoverable.
87
88        Steps:
89        1. Initialize two android devices
90        2. Make device1 discoverable
91        3. Check discoverable device1 scan mode
92        4. Make device2 start discovery
93        5. Use device2 get all discovered bluetooth devices list
94        6. Verify device1 is in the list
95
96        Expected Result:
97        Device1 is in the discovered devices list.
98
99        Returns:
100          Pass if True
101          Fail if False
102
103        TAGS: Classic
104        Priority: 1
105        """
106        self.droid_ad.droid.bluetoothMakeDiscoverable()
107        scan_mode = self.droid_ad.droid.bluetoothGetScanMode()
108        if (scan_mode == bt_scan_mode_types['connectable_discoverable']):
109            self.log.debug("Android device1 scan mode is "
110                           "SCAN_MODE_CONNECTABLE_DISCOVERABLE")
111        else:
112            self.log.debug("Android device1 scan mode is not "
113                           "SCAN_MODE_CONNECTABLE_DISCOVERABLE")
114            return False
115        if self.droid1_ad.droid.bluetoothStartDiscovery():
116            self.log.debug("Android device2 start discovery process success")
117            # Give Bluetooth time to discover advertising devices
118            time.sleep(self.scan_discovery_time)
119            droid_name = self.droid_ad.droid.bluetoothGetLocalName()
120            get_all_discovered_devices = self.droid1_ad.droid.bluetoothGetDiscoveredDevices(
121            )
122            find_flag = False
123            if get_all_discovered_devices:
124                self.log.debug(
125                    "Android device2 get all the discovered devices "
126                    "list {}".format(get_all_discovered_devices))
127                for i in get_all_discovered_devices:
128                    if 'name' in i and i['name'] == droid_name:
129                        self.log.debug("Android device1 is in the discovery "
130                                       "list of device2")
131                        find_flag = True
132                        break
133            else:
134                self.log.debug(
135                    "Android device2 get all the discovered devices "
136                    "list is empty")
137                return False
138        else:
139            self.log.debug("Android device2 start discovery process error")
140            return False
141        if not find_flag:
142            return False
143        return True
144
145    @BluetoothBaseTest.bt_test_wrap
146    @test_tracker_info(uuid='c4d77bde-04ed-4805-9185-9bc46dc8af4b')
147    def test_make_device_undiscoverable(self):
148        """Test device un-discoverability.
149
150        Test that verifies device is un-discoverable.
151
152        Steps:
153        1. Initialize two android devices
154        2. Make device1 un-discoverable
155        3. Check un-discoverable device1 scan mode
156        4. Make device2 start discovery
157        5. Use device2 get all discovered bluetooth devices list
158        6. Verify device1 is not in the list
159
160        Expected Result:
161        Device1 should not be in the discovered devices list.
162
163        Returns:
164          Pass if True
165          Fail if False
166
167        TAGS: Classic
168        Priority: 1
169        """
170        self.droid_ad.droid.bluetoothMakeUndiscoverable()
171        set_bt_scan_mode(self.droid1_ad, bt_scan_mode_types['none'])
172        scan_mode = self.droid1_ad.droid.bluetoothGetScanMode()
173        if scan_mode == bt_scan_mode_types['none']:
174            self.log.debug("Android device1 scan mode is SCAN_MODE_NONE")
175        else:
176            self.log.debug("Android device1 scan mode is not SCAN_MODE_NONE")
177            return False
178        if self.droid1_ad.droid.bluetoothStartDiscovery():
179            self.log.debug("Android device2 start discovery process success")
180            # Give Bluetooth time to discover advertising devices
181            time.sleep(self.scan_discovery_time)
182            droid_name = self.droid_ad.droid.bluetoothGetLocalName()
183            get_all_discovered_devices = self.droid1_ad.droid.bluetoothGetDiscoveredDevices(
184            )
185            find_flag = False
186            if get_all_discovered_devices:
187                self.log.debug(
188                    "Android device2 get all the discovered devices "
189                    "list {}".format(get_all_discovered_devices))
190                for i in get_all_discovered_devices:
191                    if 'name' in i and i['name'] == droid_name:
192                        self.log.debug(
193                            "Android device1 is in the discovery list of "
194                            "device2")
195                        find_flag = True
196                        break
197            else:
198                self.log.debug("Android device2 found no devices.")
199                return True
200        else:
201            self.log.debug("Android device2 start discovery process error")
202            return False
203        if find_flag:
204            return False
205        return True
206
207    @BluetoothBaseTest.bt_test_wrap
208    @test_tracker_info(uuid='2bcb6288-64c3-437e-bc89-bcd416310135')
209    def test_set_device_name(self):
210        """Test bluetooth device name.
211
212        Test that a single device can be set device name.
213
214        Steps:
215        1. Initialize one android devices
216        2. Set device name
217        3. Return true is set device name success
218
219        Expected Result:
220        Bluetooth device name is set correctly.
221
222        Returns:
223          Pass if True
224          Fail if False
225
226        TAGS: Classic
227        Priority: 1
228        """
229        name = "SetDeviceName"
230        return set_device_name(self.droid_ad.droid, name)
231
232    @BluetoothBaseTest.bt_test_wrap
233    @test_tracker_info(uuid='b38fb110-a707-47cf-b1c3-981266373786')
234    def test_scan_mode_off(self):
235        """Test disabling bluetooth scanning.
236
237        Test that changes scan mode to off.
238
239        Steps:
240        1. Initialize android device.
241        2. Set scan mode STATE_OFF by disabling bluetooth.
242        3. Verify scan state.
243
244        Expected Result:
245        Verify scan state is off.
246
247        Returns:
248          Pass if True
249          Fail if False
250
251        TAGS: Classic
252        Priority: 1
253        """
254        self.log.debug("Test scan mode STATE_OFF.")
255        return set_bt_scan_mode(self.droid_ad, bt_scan_mode_types['state_off'])
256
257    #@BluetoothTest(UUID=27576aa8-d52f-45ad-986a-f44fb565167d)
258    @BluetoothBaseTest.bt_test_wrap
259    @test_tracker_info(uuid='702c3d58-94fd-47ee-9323-2421ce182ddb')
260    def test_scan_mode_none(self):
261        """Test bluetooth scan mode none.
262
263        Test that changes scan mode to none.
264
265        Steps:
266        1. Initialize android device.
267        2. Set scan mode SCAN_MODE_NONE by disabling bluetooth.
268        3. Verify scan state.
269
270        Expected Result:
271        Verify that scan mode is set to none.
272
273        Returns:
274          Pass if True
275          Fail if False
276
277        TAGS: Classic
278        Priority: 1
279        """
280        self.log.debug("Test scan mode SCAN_MODE_NONE.")
281        return set_bt_scan_mode(self.droid_ad, bt_scan_mode_types['none'])
282
283    @BluetoothBaseTest.bt_test_wrap
284    @test_tracker_info(uuid='cb998a99-31a6-46b6-9de6-a9a17081a604')
285    def test_scan_mode_connectable(self):
286        """Test bluetooth scan mode connectable.
287
288        Test that changes scan mode to connectable.
289
290        Steps:
291        1. Initialize android device.
292        2. Set scan mode SCAN_MODE_CONNECTABLE.
293        3. Verify scan state.
294
295        Expected Result:
296        Verify that scan mode is set to connectable.
297
298        Returns:
299          Pass if True
300          Fail if False
301
302        TAGS: Classic
303        Priority: 2
304        """
305        self.log.debug("Test scan mode SCAN_MODE_CONNECTABLE.")
306        return set_bt_scan_mode(self.droid_ad,
307                                bt_scan_mode_types['connectable'])
308
309    @BluetoothBaseTest.bt_test_wrap
310    @test_tracker_info(uuid='59bec55c-c64e-43e4-9a9a-e44408a801d7')
311    def test_scan_mode_connectable_discoverable(self):
312        """Test bluetooth scan mode connectable.
313
314        Test that changes scan mode to connectable.
315
316        Steps:
317        1. Initialize android device.
318        2. Set scan mode SCAN_MODE_DISCOVERABLE.
319        3. Verify scan state.
320
321        Expected Result:
322        Verify that scan mode is set to discoverable.
323
324        Returns:
325          Pass if True
326          Fail if False
327
328        TAGS: Classic
329        Priority: 2
330        """
331        self.log.debug("Test scan mode SCAN_MODE_CONNECTABLE_DISCOVERABLE.")
332        return set_bt_scan_mode(self.droid_ad,
333                                bt_scan_mode_types['connectable_discoverable'])
334
335    @BluetoothBaseTest.bt_test_wrap
336    @test_tracker_info(uuid='cd20a09d-a68d-4f55-b016-ba283b0460df')
337    def test_if_support_hid_profile(self):
338        """ Test that a single device can support HID profile.
339        Steps
340        1. Initialize one android devices
341        2. Check devices support profiles and return a dictionary
342        3. Check the value of key 'hid'
343
344        Expected Result:
345        Device1 is in the discovered devices list.
346
347        Returns:
348          Pass if True
349          Fail if False
350
351        TAGS: Classic
352        Priority: 1
353        """
354        profiles = check_device_supported_profiles(self.droid_ad.droid)
355        if not profiles['hid']:
356            self.log.debug("Android device do not support HID profile.")
357            return False
358        return True
359
360    @BluetoothBaseTest.bt_test_wrap
361    @test_tracker_info(uuid='a110d330-7090-4784-a33b-33089dc5f67f')
362    def test_if_support_hsp_profile(self):
363        """ Test that a single device can support HSP profile.
364        Steps
365        1. Initialize one android devices
366        2. Check devices support profiles and return a dictionary
367        3. Check the value of key 'hsp'
368        :return: test_result: bool
369        """
370        profiles = check_device_supported_profiles(self.droid_ad.droid)
371        if not profiles['hsp']:
372            self.log.debug("Android device do not support HSP profile.")
373            return False
374        return True
375
376    @BluetoothBaseTest.bt_test_wrap
377    @test_tracker_info(uuid='9ccefdd9-62a9-4aed-b4d9-7b0a55c338b2')
378    def test_if_support_a2dp_profile(self):
379        """ Test that a single device can support A2DP profile.
380        Steps
381        1. Initialize one android devices
382        2. Check devices support profiles and return a dictionary
383        3. Check the value of key 'a2dp'
384        :return: test_result: bool
385        """
386        profiles = check_device_supported_profiles(self.droid_ad.droid)
387        if not profiles['a2dp']:
388            self.log.debug("Android device do not support A2DP profile.")
389            return False
390        return True
391