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