• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 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.client.common_lib import error
14from autotest_lib.server.cros.bluetooth import bluetooth_adapter_tests
15from autotest_lib.server.cros.multimedia import remote_facade_factory
16
17
18class bluetooth_AdapterPairing(
19        bluetooth_adapter_tests.BluetoothAdapterTests):
20    """Server side bluetooth adapter pairing and connecting to bluetooth device
21
22    This test tries to verify that the adapter of the DUT could
23    pair and connect to a bluetooth HID device correctly.
24
25    In particular, the following subtests are performed. Look at the
26    docstrings of the subtests for more details.
27    -
28
29    Refer to BluetoothAdapterTests for all subtests performed in this test.
30
31    """
32
33    # TODO(josephsih): Reduce the sleep intervals to speed up the tests.
34    TEST_SLEEP_SECS = 5
35
36
37    def run_once(self, host, device_type, num_iterations=1, min_pass_count=1,
38                 pairing_twice=False, suspend_resume=False, reboot=False):
39        """Running Bluetooth adapter tests about pairing to a device.
40
41        @param host: the DUT, usually a chromebook
42        @param device_type : the bluetooth HID device type, e.g., 'MOUSE'
43        @param num_iterations: the number of rounds to execute the test
44        @param min_pass_count: the minimal pass count to pass this test
45        @param pairing_twice: True if the host tries to pair the device
46                again after the paired device is removed.
47        @param suspend_resume: True if the host suspends/resumes after
48                pairing.
49        @param reboot: True if the host reboots after pairing.
50
51        """
52        self.host = host
53        factory = remote_facade_factory.RemoteFacadeFactory(host)
54        self.bluetooth_facade = factory.create_bluetooth_hid_facade()
55        self.input_facade = factory.create_input_facade()
56        self.check_chameleon()
57
58        pass_count = 0
59        self.total_fails = {}
60        for iteration in xrange(1, num_iterations + 1):
61            self.fails = []
62
63            # Get the device object and query some important properties.
64            device = self.get_device(device_type)
65
66            # Reset the adapter to forget previously paired devices if any.
67            self.test_reset_on_adapter()
68
69            # The adapter must be set to the pairable state.
70            self.test_pairable()
71
72            # Test if the adapter could discover the target device.
73            time.sleep(self.TEST_SLEEP_SECS)
74            self.test_discover_device(device.address)
75
76            # Test if the discovery could be stopped.
77            time.sleep(self.TEST_SLEEP_SECS)
78            self.test_stop_discovery()
79
80            # Test if the discovered device class of service is correct.
81            self.test_device_class_of_service(device.address,
82                                              device.class_of_service)
83
84            # Test if the discovered device class of device is correct.
85            self.test_device_class_of_device(device.address,
86                                             device.class_of_device)
87
88            # Verify that the adapter could pair with the device.
89            # Also set the device trusted when pairing is done.
90            time.sleep(self.TEST_SLEEP_SECS)
91            self.test_pairing(device.address, device.pin, trusted=True)
92
93            # Verify that the adapter could connect to the device.
94            time.sleep(self.TEST_SLEEP_SECS)
95            self.test_connection_by_adapter(device.address)
96
97            # Test if the discovered device name is correct.
98            # Sometimes, it takes quite a long time after discovering
99            # the device (more than 60 seconds) to resolve the device name.
100            # Hence, it is safer to test the device name after pairing and
101            # connection is done.
102            time.sleep(self.TEST_SLEEP_SECS)
103            self.test_device_name(device.address, device.name)
104
105            # Test if the device is still connected after suspend/resume.
106            if suspend_resume:
107                self.suspend_resume()
108
109                time.sleep(self.TEST_SLEEP_SECS)
110                self.test_device_is_paired(device.address)
111
112                # After a suspend/resume, we need to wake the peripheral
113                # as it is not connected.
114                time.sleep(self.TEST_SLEEP_SECS)
115                self.test_connection_by_device(device)
116
117                time.sleep(self.TEST_SLEEP_SECS)
118                self.test_device_name(device.address, device.name)
119
120            # Test if the device is still connected after reboot.
121            # if reboot:
122            #     self.host.reboot()
123
124            #     time.sleep(self.TEST_SLEEP_SECS)
125            #     self.test_device_is_paired(device.address)
126
127            #     # After a reboot, we need to wake the peripheral
128            #     # as it is not connected.
129            #     time.sleep(self.TEST_SLEEP_SECS)
130            #     self.test_connection_by_adapter(device.address)
131
132            #     time.sleep(self.TEST_SLEEP_SECS)
133            #     self.test_device_is_connected(device.address)
134
135            #     time.sleep(self.TEST_SLEEP_SECS)
136            #     self.test_device_name(device.address, device.name)
137
138            # Verify that the adapter could disconnect the device.
139            self.test_disconnection_by_adapter(device.address)
140
141            time.sleep(self.TEST_SLEEP_SECS)
142            if device.can_init_connection:
143                # Verify that the device could initiate the connection.
144                self.test_connection_by_device(device)
145            else:
146                # Reconnect so that we can test disconnection from the kit
147                self.test_connection_by_adapter(device.address)
148
149            # TODO(alent): Needs a new capability, but this is a good proxy
150            if device.can_init_connection:
151                # Verify that the device could initiate the disconnection.
152                self.test_disconnection_by_device(device)
153            else:
154                # Reconnect so that we can test disconnection from the kit
155                self.test_disconnection_by_adapter(device.address)
156
157            # Verify that the adapter could remove the paired device.
158            self.test_remove_pairing(device.address)
159
160            # Check if the device could be re-paired after being forgotten.
161            if pairing_twice:
162                # Test if the adapter could discover the target device again.
163                time.sleep(self.TEST_SLEEP_SECS)
164                self.test_discover_device(device.address)
165
166                # Verify that the adapter could pair with the device again.
167                # Also set the device trusted when pairing is done.
168                time.sleep(self.TEST_SLEEP_SECS)
169                self.test_pairing(device.address, device.pin, trusted=True)
170
171                # Verify that the adapter could remove the paired device again.
172                time.sleep(self.TEST_SLEEP_SECS)
173                self.test_remove_pairing(device.address)
174
175            if bool(self.fails):
176                self.total_fails['Round %d' % iteration] = self.fails
177            else:
178                pass_count += 1
179
180            fail_count = iteration - pass_count
181            logging.info('===  (pass = %d, fail = %d) / total %d  ===\n',
182                         pass_count, fail_count, num_iterations)
183
184        if pass_count < min_pass_count:
185            raise error.TestFail(self.total_fails)
186