• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""
6Server side bluetooth tests on adapter pairing and connecting to a bluetooth
7HID device.
8"""
9
10import logging
11import time
12
13from autotest_lib.server.cros.bluetooth import bluetooth_adapter_tests
14
15
16class BluetoothAdapterPairingTests(
17        bluetooth_adapter_tests.BluetoothAdapterTests):
18    """Server side bluetooth adapter pairing and connecting to bluetooth device
19
20    This test tries to verify that the adapter of the DUT could
21    pair and connect to a bluetooth HID device correctly.
22
23    In particular, the following subtests are performed. Look at the
24    docstrings of the subtests for more details.
25    -
26
27    Refer to BluetoothAdapterTests for all subtests performed in this test.
28
29    """
30
31    # TODO(josephsih): Reduce the sleep intervals to speed up the tests.
32    PAIR_TEST_SLEEP_SECS = 5
33
34    def pairing_test(self, device, check_connected_method=lambda device: True,
35                     pairing_twice=False, suspend_resume=False, reboot=False):
36        """Running Bluetooth adapter tests about pairing to a device."""
37
38        # Reset the adapter to forget previously paired devices if any.
39        self.test_reset_on_adapter()
40
41        # The adapter must be set to the pairable state.
42        self.test_pairable()
43
44        # Test if the adapter could discover the target device.
45        time.sleep(self.PAIR_TEST_SLEEP_SECS)
46        self.test_discover_device(device.address)
47
48        # Test if the discovery could be stopped.
49        time.sleep(self.PAIR_TEST_SLEEP_SECS)
50        self.test_stop_discovery()
51
52        # Test if the discovered device class of service is correct.
53        self.test_device_class_of_service(device.address,
54                                          device.class_of_service)
55
56        # Test if the discovered device class of device is correct.
57        self.test_device_class_of_device(device.address,
58                                         device.class_of_device)
59
60        # Verify that the adapter could pair with the device.
61        # Also set the device trusted when pairing is done.
62        time.sleep(self.PAIR_TEST_SLEEP_SECS)
63        self.test_pairing(device.address, device.pin, trusted=True)
64
65        # Verify that the adapter could connect to the device.
66        time.sleep(self.PAIR_TEST_SLEEP_SECS)
67        self.test_connection_by_adapter(device.address)
68
69        # Test if the discovered device name is correct.
70        # Sometimes, it takes quite a long time after discovering
71        # the device (more than 60 seconds) to resolve the device name.
72        # Hence, it is safer to test the device name after pairing and
73        # connection is done.
74        time.sleep(self.PAIR_TEST_SLEEP_SECS)
75        self.test_device_name(device.address, device.name)
76
77        # Test if the device is still connected after suspend/resume.
78        if suspend_resume:
79            self.suspend_resume()
80
81            time.sleep(self.PAIR_TEST_SLEEP_SECS)
82            self.test_device_is_paired(device.address)
83
84
85            # check if peripheral is connected after suspend resume
86            if not self.ignore_failure(check_connected_method, device):
87                logging.info("device not connected after suspend_resume")
88                self.test_connection_by_device(device)
89            else:
90                logging.info("device remains connected after suspend_resume")
91
92            time.sleep(self.PAIR_TEST_SLEEP_SECS)
93            check_connected_method(device)
94
95            time.sleep(self.PAIR_TEST_SLEEP_SECS)
96            self.test_device_name(device.address, device.name)
97
98        # Test if the device is still connected after reboot.
99        # if reboot:
100        #     self.host.reboot()
101
102        #     time.sleep(self.PAIR_TEST_SLEEP_SECS)
103        #     self.test_device_is_paired(device.address)
104
105        #     # After a reboot, we need to wake the peripheral
106        #     # as it is not connected.
107        #     time.sleep(self.PAIR_TEST_SLEEP_SECS)
108        #     self.test_connection_by_adapter(device.address)
109
110        #     time.sleep(self.PAIR_TEST_SLEEP_SECS)
111        #     self.test_device_is_connected(device.address)
112
113        #     time.sleep(self.PAIR_TEST_SLEEP_SECS)
114        #     self.test_device_name(device.address, device.name)
115
116        # Verify that the adapter could disconnect the device.
117        self.test_disconnection_by_adapter(device.address)
118
119        time.sleep(self.PAIR_TEST_SLEEP_SECS)
120        if device.can_init_connection:
121            # Verify that the device could initiate the connection.
122            self.test_connection_by_device(device)
123            check_connected_method(device)
124        else:
125            # Reconnect so that we can test disconnection from the kit
126            self.test_connection_by_adapter(device.address)
127
128        # TODO(alent): Needs a new capability, but this is a good proxy
129        if device.can_init_connection:
130            # Verify that the device could initiate the disconnection.
131            self.test_disconnection_by_device(device)
132        else:
133            # Reconnect so that we can test disconnection from the kit
134            self.test_disconnection_by_adapter(device.address)
135
136        # Verify that the adapter could remove the paired device.
137        self.test_remove_pairing(device.address)
138
139        # Check if the device could be re-paired after being forgotten.
140        if pairing_twice:
141            # Test if the adapter could discover the target device again.
142            time.sleep(self.PAIR_TEST_SLEEP_SECS)
143            self.test_discover_device(device.address)
144
145            # Verify that the adapter could pair with the device again.
146            # Also set the device trusted when pairing is done.
147            time.sleep(self.PAIR_TEST_SLEEP_SECS)
148            self.test_pairing(device.address, device.pin, trusted=True)
149
150            # Verify that the adapter could remove the paired device again.
151            time.sleep(self.PAIR_TEST_SLEEP_SECS)
152            self.test_remove_pairing(device.address)
153
154
155    def connect_disconnect_loop(self, device, loops):
156        """Perform a connect disconnect loop test"""
157
158        # First pair and disconnect, to emulate real life scenario
159        self.test_discover_device(device.address)
160        # self.bluetooth_facade.is_discovering() doesn't work as expected:
161        # crbug:905374
162        # self.test_stop_discovery()
163        self.bluetooth_facade.stop_discovery()
164        time.sleep(self.PAIR_TEST_SLEEP_SECS)
165        self.test_pairing(device.address, device.pin, trusted=True)
166        time.sleep(self.PAIR_TEST_SLEEP_SECS)
167        # Disconnect the device
168        self.test_disconnection_by_adapter(device.address)
169        total_duration_by_adapter = 0
170        loop_cnt = 0
171        for i in xrange(0, loops):
172
173            # Verify device didn't connect automatically
174            time.sleep(2)
175            self.test_device_is_not_connected(device.address)
176
177            start_time = time.time()
178            self.test_connection_by_adapter(device.address)
179            end_time = time.time()
180            time_diff = end_time - start_time
181
182            # Verify device is now connected
183            self.test_device_is_connected(device.address)
184            self.test_disconnection_by_adapter(device.address)
185
186            if not bool(self.fails):
187                loop_cnt += 1
188                total_duration_by_adapter += time_diff
189                logging.info('%d: Connection establishment duration %f sec',
190                             i, time_diff)
191            else:
192               break
193
194        if not bool(self.fails):
195            logging.info('Average duration (by adapter) %f sec',
196                         total_duration_by_adapter/loop_cnt)
197
198
199    def auto_reconnect_loop(self, device, loops,
200                            check_connected_method=lambda device: True):
201        """Running a loop to verify the paired peer can auto reconnect"""
202
203        # Let the adapter pair, and connect to the target device first
204        self.test_discover_device(device.address)
205        # self.bluetooth_facade.is_discovering() doesn't work as expected:
206        # crbug:905374
207        # self.test_stop_discovery()
208        self.bluetooth_facade.stop_discovery()
209        time.sleep(self.PAIR_TEST_SLEEP_SECS)
210        self.test_pairing(device.address, device.pin, trusted=True)
211        time.sleep(self.PAIR_TEST_SLEEP_SECS)
212        self.test_connection_by_adapter(device.address)
213
214        total_reconnection_duration = 0
215        loop_cnt = 0
216        for i in xrange(loops):
217            # Restart and clear peer HID device
218            self.restart_peers()
219            start_time = time.time()
220
221            # Verify that the device is reconnecting
222            self.test_device_is_connected(device.address)
223            check_connected_method(device)
224            end_time = time.time()
225            time_diff = end_time - start_time
226
227            if not bool(self.fails):
228                total_reconnection_duration += time_diff
229                loop_cnt += 1
230                logging.info('%d: Reconnection duration %f sec', i, time_diff)
231            else:
232               break
233
234        if not bool(self.fails):
235            logging.info('Average Reconnection duration %f sec',
236                         total_reconnection_duration/loop_cnt)
237