1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.bluetooth; 18 19 import android.content.Context; 20 import android.test.InstrumentationTestCase; 21 22 /** 23 * Stress test suite for Bluetooth related functions. 24 * 25 * Includes tests for enabling/disabling bluetooth, enabling/disabling discoverable mode, 26 * starting/stopping scans, connecting/disconnecting to HFP, A2DP, HID, PAN profiles, and verifying 27 * that remote connections/disconnections occur for the PAN profile. 28 * <p> 29 * This test suite uses {@link android.bluetooth.BluetoothTestRunner} to for parameters such as the 30 * number of iterations and the addresses of remote Bluetooth devices. 31 */ 32 public class BluetoothStressTest extends InstrumentationTestCase { 33 private static final String TAG = "BluetoothStressTest"; 34 private static final String OUTPUT_FILE = "BluetoothStressTestOutput.txt"; 35 /** The amount of time to sleep between issuing start/stop SCO in ms. */ 36 private static final long SCO_SLEEP_TIME = 2 * 1000; 37 38 private BluetoothAdapter mAdapter; 39 private BluetoothTestUtils mTestUtils; 40 41 @Override setUp()42 protected void setUp() throws Exception { 43 super.setUp(); 44 45 Context context = getInstrumentation().getTargetContext(); 46 mAdapter = BluetoothAdapter.getDefaultAdapter(); 47 mTestUtils = new BluetoothTestUtils(context, TAG, OUTPUT_FILE); 48 49 // Start all tests in a disabled state. 50 if (mAdapter.isEnabled()) { 51 mTestUtils.disable(mAdapter); 52 } 53 } 54 55 @Override tearDown()56 protected void tearDown() throws Exception { 57 super.tearDown(); 58 mTestUtils.close(); 59 } 60 61 /** 62 * Stress test for enabling and disabling Bluetooth. 63 */ testEnable()64 public void testEnable() { 65 int iterations = BluetoothTestRunner.sEnableIterations; 66 if (iterations == 0) { 67 return; 68 } 69 70 for (int i = 0; i < iterations; i++) { 71 mTestUtils.writeOutput("enable iteration " + (i + 1) + " of " + iterations); 72 mTestUtils.enable(mAdapter); 73 mTestUtils.disable(mAdapter); 74 } 75 } 76 77 /** 78 * Stress test for putting the device in and taking the device out of discoverable mode. 79 */ testDiscoverable()80 public void testDiscoverable() { 81 int iterations = BluetoothTestRunner.sDiscoverableIterations; 82 if (iterations == 0) { 83 return; 84 } 85 86 mTestUtils.enable(mAdapter); 87 mTestUtils.undiscoverable(mAdapter); 88 89 for (int i = 0; i < iterations; i++) { 90 mTestUtils.writeOutput("discoverable iteration " + (i + 1) + " of " + iterations); 91 mTestUtils.discoverable(mAdapter); 92 mTestUtils.undiscoverable(mAdapter); 93 } 94 } 95 96 /** 97 * Stress test for starting and stopping Bluetooth scans. 98 */ testScan()99 public void testScan() { 100 int iterations = BluetoothTestRunner.sScanIterations; 101 if (iterations == 0) { 102 return; 103 } 104 105 mTestUtils.enable(mAdapter); 106 mTestUtils.stopScan(mAdapter); 107 108 for (int i = 0; i < iterations; i++) { 109 mTestUtils.writeOutput("scan iteration " + (i + 1) + " of " + iterations); 110 mTestUtils.startScan(mAdapter); 111 mTestUtils.stopScan(mAdapter); 112 } 113 } 114 115 /** 116 * Stress test for enabling and disabling the PAN NAP profile. 117 */ testEnablePan()118 public void testEnablePan() { 119 int iterations = BluetoothTestRunner.sEnablePanIterations; 120 if (iterations == 0) { 121 return; 122 } 123 124 mTestUtils.enable(mAdapter); 125 mTestUtils.disablePan(mAdapter); 126 127 for (int i = 0; i < iterations; i++) { 128 mTestUtils.writeOutput("testEnablePan iteration " + (i + 1) + " of " 129 + iterations); 130 mTestUtils.enablePan(mAdapter); 131 mTestUtils.disablePan(mAdapter); 132 } 133 } 134 135 /** 136 * Stress test for pairing and unpairing with a remote device. 137 * <p> 138 * In this test, the local device initiates pairing with a remote device, and then unpairs with 139 * the device after the pairing has successfully completed. 140 */ testPair()141 public void testPair() { 142 int iterations = BluetoothTestRunner.sPairIterations; 143 if (iterations == 0) { 144 return; 145 } 146 147 BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 148 mTestUtils.enable(mAdapter); 149 mTestUtils.unpair(mAdapter, device); 150 151 for (int i = 0; i < iterations; i++) { 152 mTestUtils.writeOutput("pair iteration " + (i + 1) + " of " + iterations); 153 mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey, 154 BluetoothTestRunner.sDevicePairPin); 155 mTestUtils.unpair(mAdapter, device); 156 } 157 } 158 159 /** 160 * Stress test for accepting a pairing request and unpairing with a remote device. 161 * <p> 162 * In this test, the local device waits for a pairing request from a remote device. It accepts 163 * the request and then unpairs after the paring has successfully completed. 164 */ testAcceptPair()165 public void testAcceptPair() { 166 int iterations = BluetoothTestRunner.sPairIterations; 167 if (iterations == 0) { 168 return; 169 } 170 BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 171 mTestUtils.enable(mAdapter); 172 mTestUtils.unpair(mAdapter, device); 173 174 for (int i = 0; i < iterations; i++) { 175 mTestUtils.writeOutput("acceptPair iteration " + (i + 1) + " of " + iterations); 176 mTestUtils.acceptPair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey, 177 BluetoothTestRunner.sDevicePairPin); 178 mTestUtils.unpair(mAdapter, device); 179 } 180 } 181 182 /** 183 * Stress test for connecting and disconnecting with an A2DP source. 184 * <p> 185 * In this test, the local device plays the role of an A2DP sink, and initiates connections and 186 * disconnections with an A2DP source. 187 */ testConnectA2dp()188 public void testConnectA2dp() { 189 int iterations = BluetoothTestRunner.sConnectA2dpIterations; 190 if (iterations == 0) { 191 return; 192 } 193 194 BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 195 mTestUtils.enable(mAdapter); 196 mTestUtils.unpair(mAdapter, device); 197 mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey, 198 BluetoothTestRunner.sDevicePairPin); 199 mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.A2DP, null); 200 201 for (int i = 0; i < iterations; i++) { 202 mTestUtils.writeOutput("connectA2dp iteration " + (i + 1) + " of " + iterations); 203 mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.A2DP, 204 String.format("connectA2dp(device=%s)", device)); 205 mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.A2DP, 206 String.format("disconnectA2dp(device=%s)", device)); 207 } 208 209 mTestUtils.unpair(mAdapter, device); 210 } 211 212 /** 213 * Stress test for connecting and disconnecting the HFP with a hands free device. 214 * <p> 215 * In this test, the local device plays the role of an HFP audio gateway, and initiates 216 * connections and disconnections with a hands free device. 217 */ testConnectHeadset()218 public void testConnectHeadset() { 219 int iterations = BluetoothTestRunner.sConnectHeadsetIterations; 220 if (iterations == 0) { 221 return; 222 } 223 224 BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 225 mTestUtils.enable(mAdapter); 226 mTestUtils.unpair(mAdapter, device); 227 mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey, 228 BluetoothTestRunner.sDevicePairPin); 229 mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HEADSET, null); 230 231 for (int i = 0; i < iterations; i++) { 232 mTestUtils.writeOutput("connectHeadset iteration " + (i + 1) + " of " + iterations); 233 mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.HEADSET, 234 String.format("connectHeadset(device=%s)", device)); 235 mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HEADSET, 236 String.format("disconnectHeadset(device=%s)", device)); 237 } 238 239 mTestUtils.unpair(mAdapter, device); 240 } 241 242 /** 243 * Stress test for connecting and disconnecting with a HID device. 244 * <p> 245 * In this test, the local device plays the role of a HID host, and initiates connections and 246 * disconnections with a HID device. 247 */ testConnectInput()248 public void testConnectInput() { 249 int iterations = BluetoothTestRunner.sConnectInputIterations; 250 if (iterations == 0) { 251 return; 252 } 253 254 BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 255 mTestUtils.enable(mAdapter); 256 mTestUtils.unpair(mAdapter, device); 257 mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey, 258 BluetoothTestRunner.sDevicePairPin); 259 mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HID_HOST, null); 260 261 for (int i = 0; i < iterations; i++) { 262 mTestUtils.writeOutput("connectInput iteration " + (i + 1) + " of " + iterations); 263 mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.HID_HOST, 264 String.format("connectInput(device=%s)", device)); 265 mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HID_HOST, 266 String.format("disconnectInput(device=%s)", device)); 267 } 268 269 mTestUtils.unpair(mAdapter, device); 270 } 271 272 /** 273 * Stress test for connecting and disconnecting with a PAN NAP. 274 * <p> 275 * In this test, the local device plays the role of a PANU, and initiates connections and 276 * disconnections with a NAP. 277 */ testConnectPan()278 public void testConnectPan() { 279 int iterations = BluetoothTestRunner.sConnectPanIterations; 280 if (iterations == 0) { 281 return; 282 } 283 284 BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 285 mTestUtils.enable(mAdapter); 286 mTestUtils.unpair(mAdapter, device); 287 mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey, 288 BluetoothTestRunner.sDevicePairPin); 289 290 for (int i = 0; i < iterations; i++) { 291 mTestUtils.writeOutput("connectPan iteration " + (i + 1) + " of " + iterations); 292 mTestUtils.connectPan(mAdapter, device); 293 mTestUtils.disconnectPan(mAdapter, device); 294 } 295 296 mTestUtils.unpair(mAdapter, device); 297 } 298 299 /** 300 * Stress test for verifying a PANU connecting and disconnecting with the device. 301 * <p> 302 * In this test, the local device plays the role of a NAP which a remote PANU connects and 303 * disconnects from. 304 */ testIncomingPanConnection()305 public void testIncomingPanConnection() { 306 int iterations = BluetoothTestRunner.sConnectPanIterations; 307 if (iterations == 0) { 308 return; 309 } 310 311 BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 312 mTestUtils.enable(mAdapter); 313 mTestUtils.disablePan(mAdapter); 314 mTestUtils.enablePan(mAdapter); 315 mTestUtils.unpair(mAdapter, device); 316 mTestUtils.acceptPair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey, 317 BluetoothTestRunner.sDevicePairPin); 318 319 for (int i = 0; i < iterations; i++) { 320 mTestUtils.writeOutput("incomingPanConnection iteration " + (i + 1) + " of " 321 + iterations); 322 mTestUtils.incomingPanConnection(mAdapter, device); 323 mTestUtils.incomingPanDisconnection(mAdapter, device); 324 } 325 326 mTestUtils.unpair(mAdapter, device); 327 mTestUtils.disablePan(mAdapter); 328 } 329 330 /** 331 * Stress test for verifying that AudioManager can open and close SCO connections. 332 * <p> 333 * In this test, a HSP connection is opened with an external headset and the SCO connection is 334 * repeatibly opened and closed. 335 */ testStartStopSco()336 public void testStartStopSco() { 337 int iterations = BluetoothTestRunner.sStartStopScoIterations; 338 if (iterations == 0) { 339 return; 340 } 341 342 BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 343 mTestUtils.enable(mAdapter); 344 mTestUtils.unpair(mAdapter, device); 345 mTestUtils.pair(mAdapter, device, BluetoothTestRunner.sDevicePairPasskey, 346 BluetoothTestRunner.sDevicePairPin); 347 mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HEADSET, null); 348 mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.HEADSET, null); 349 mTestUtils.stopSco(mAdapter, device); 350 351 for (int i = 0; i < iterations; i++) { 352 mTestUtils.writeOutput("startStopSco iteration " + (i + 1) + " of " + iterations); 353 mTestUtils.startSco(mAdapter, device); 354 sleep(SCO_SLEEP_TIME); 355 mTestUtils.stopSco(mAdapter, device); 356 sleep(SCO_SLEEP_TIME); 357 } 358 359 mTestUtils.disconnectProfile(mAdapter, device, BluetoothProfile.HEADSET, null); 360 mTestUtils.unpair(mAdapter, device); 361 } 362 sleep(long time)363 private void sleep(long time) { 364 try { 365 Thread.sleep(time); 366 } catch (InterruptedException e) { 367 } 368 } 369 } 370