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 BluetoothTestUtils mTestUtils; 39 40 @Override 41 protected void setUp() throws Exception { 42 super.setUp(); 43 44 Context context = getInstrumentation().getTargetContext(); 45 mTestUtils = new BluetoothTestUtils(context, TAG, OUTPUT_FILE); 46 } 47 48 @Override 49 protected void tearDown() throws Exception { 50 super.tearDown(); 51 52 mTestUtils.close(); 53 } 54 55 /** 56 * Stress test for enabling and disabling Bluetooth. 57 */ 58 public void testEnable() { 59 int iterations = BluetoothTestRunner.sEnableIterations; 60 if (iterations == 0) { 61 return; 62 } 63 64 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 65 mTestUtils.disable(adapter); 66 67 for (int i = 0; i < iterations; i++) { 68 mTestUtils.writeOutput("enable iteration " + (i + 1) + " of " + iterations); 69 mTestUtils.enable(adapter); 70 mTestUtils.disable(adapter); 71 } 72 } 73 74 /** 75 * Stress test for putting the device in and taking the device out of discoverable mode. 76 */ 77 public void testDiscoverable() { 78 int iterations = BluetoothTestRunner.sDiscoverableIterations; 79 if (iterations == 0) { 80 return; 81 } 82 83 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 84 mTestUtils.disable(adapter); 85 mTestUtils.enable(adapter); 86 mTestUtils.undiscoverable(adapter); 87 88 for (int i = 0; i < iterations; i++) { 89 mTestUtils.writeOutput("discoverable iteration " + (i + 1) + " of " + iterations); 90 mTestUtils.discoverable(adapter); 91 mTestUtils.undiscoverable(adapter); 92 } 93 94 mTestUtils.disable(adapter); 95 } 96 97 /** 98 * Stress test for starting and stopping Bluetooth scans. 99 */ 100 public void testScan() { 101 int iterations = BluetoothTestRunner.sScanIterations; 102 if (iterations == 0) { 103 return; 104 } 105 106 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 107 mTestUtils.disable(adapter); 108 mTestUtils.enable(adapter); 109 mTestUtils.stopScan(adapter); 110 111 for (int i = 0; i < iterations; i++) { 112 mTestUtils.writeOutput("scan iteration " + (i + 1) + " of " + iterations); 113 mTestUtils.startScan(adapter); 114 mTestUtils.stopScan(adapter); 115 } 116 117 mTestUtils.disable(adapter); 118 } 119 120 /** 121 * Stress test for enabling and disabling the PAN NAP profile. 122 */ 123 public void testEnablePan() { 124 int iterations = BluetoothTestRunner.sEnablePanIterations; 125 if (iterations == 0) { 126 return; 127 } 128 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 129 mTestUtils.disable(adapter); 130 mTestUtils.enable(adapter); 131 mTestUtils.disablePan(adapter); 132 133 for (int i = 0; i < iterations; i++) { 134 mTestUtils.writeOutput("testEnablePan iteration " + (i + 1) + " of " 135 + iterations); 136 mTestUtils.enablePan(adapter); 137 mTestUtils.disablePan(adapter); 138 } 139 140 mTestUtils.disable(adapter); 141 } 142 143 /** 144 * Stress test for pairing and unpairing with a remote device. 145 * <p> 146 * In this test, the local device initiates pairing with a remote device, and then unpairs with 147 * the device after the pairing has successfully completed. 148 */ 149 public void testPair() { 150 int iterations = BluetoothTestRunner.sPairIterations; 151 if (iterations == 0) { 152 return; 153 } 154 155 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 156 BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 157 mTestUtils.disable(adapter); 158 mTestUtils.enable(adapter); 159 mTestUtils.unpair(adapter, device); 160 161 for (int i = 0; i < iterations; i++) { 162 mTestUtils.writeOutput("pair iteration " + (i + 1) + " of " + iterations); 163 mTestUtils.pair(adapter, device, BluetoothTestRunner.sDevicePairPasskey, 164 BluetoothTestRunner.sDevicePairPin); 165 mTestUtils.unpair(adapter, device); 166 } 167 mTestUtils.disable(adapter); 168 } 169 170 /** 171 * Stress test for accepting a pairing request and unpairing with a remote device. 172 * <p> 173 * In this test, the local device waits for a pairing request from a remote device. It accepts 174 * the request and then unpairs after the paring has successfully completed. 175 */ 176 public void testAcceptPair() { 177 int iterations = BluetoothTestRunner.sPairIterations; 178 if (iterations == 0) { 179 return; 180 } 181 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 182 BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 183 mTestUtils.disable(adapter); 184 mTestUtils.enable(adapter); 185 mTestUtils.unpair(adapter, device); 186 187 for (int i = 0; i < iterations; i++) { 188 mTestUtils.writeOutput("acceptPair iteration " + (i + 1) + " of " + iterations); 189 mTestUtils.acceptPair(adapter, device, BluetoothTestRunner.sDevicePairPasskey, 190 BluetoothTestRunner.sDevicePairPin); 191 mTestUtils.unpair(adapter, device); 192 } 193 mTestUtils.disable(adapter); 194 } 195 196 /** 197 * Stress test for connecting and disconnecting with an A2DP source. 198 * <p> 199 * In this test, the local device plays the role of an A2DP sink, and initiates connections and 200 * disconnections with an A2DP source. 201 */ 202 public void testConnectA2dp() { 203 int iterations = BluetoothTestRunner.sConnectA2dpIterations; 204 if (iterations == 0) { 205 return; 206 } 207 208 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 209 BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 210 mTestUtils.disable(adapter); 211 mTestUtils.enable(adapter); 212 mTestUtils.unpair(adapter, device); 213 mTestUtils.pair(adapter, device, BluetoothTestRunner.sDevicePairPasskey, 214 BluetoothTestRunner.sDevicePairPin); 215 mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.A2DP, null); 216 217 for (int i = 0; i < iterations; i++) { 218 mTestUtils.writeOutput("connectA2dp iteration " + (i + 1) + " of " + iterations); 219 mTestUtils.connectProfile(adapter, device, BluetoothProfile.A2DP, 220 String.format("connectA2dp(device=%s)", device)); 221 mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.A2DP, 222 String.format("disconnectA2dp(device=%s)", device)); 223 } 224 225 mTestUtils.unpair(adapter, device); 226 mTestUtils.disable(adapter); 227 } 228 229 /** 230 * Stress test for connecting and disconnecting the HFP with a hands free device. 231 * <p> 232 * In this test, the local device plays the role of an HFP audio gateway, and initiates 233 * connections and disconnections with a hands free device. 234 */ 235 public void testConnectHeadset() { 236 int iterations = BluetoothTestRunner.sConnectHeadsetIterations; 237 if (iterations == 0) { 238 return; 239 } 240 241 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 242 BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 243 mTestUtils.disable(adapter); 244 mTestUtils.enable(adapter); 245 mTestUtils.unpair(adapter, device); 246 mTestUtils.pair(adapter, device, BluetoothTestRunner.sDevicePairPasskey, 247 BluetoothTestRunner.sDevicePairPin); 248 mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.HEADSET, null); 249 250 for (int i = 0; i < iterations; i++) { 251 mTestUtils.writeOutput("connectHeadset iteration " + (i + 1) + " of " + iterations); 252 mTestUtils.connectProfile(adapter, device, BluetoothProfile.HEADSET, 253 String.format("connectHeadset(device=%s)", device)); 254 mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.HEADSET, 255 String.format("disconnectHeadset(device=%s)", device)); 256 } 257 258 mTestUtils.unpair(adapter, device); 259 mTestUtils.disable(adapter); 260 } 261 262 /** 263 * Stress test for connecting and disconnecting with a HID device. 264 * <p> 265 * In this test, the local device plays the role of a HID host, and initiates connections and 266 * disconnections with a HID device. 267 */ 268 public void testConnectInput() { 269 int iterations = BluetoothTestRunner.sConnectInputIterations; 270 if (iterations == 0) { 271 return; 272 } 273 274 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 275 BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 276 mTestUtils.disable(adapter); 277 mTestUtils.enable(adapter); 278 mTestUtils.unpair(adapter, device); 279 mTestUtils.pair(adapter, device, BluetoothTestRunner.sDevicePairPasskey, 280 BluetoothTestRunner.sDevicePairPin); 281 mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.INPUT_DEVICE, null); 282 283 for (int i = 0; i < iterations; i++) { 284 mTestUtils.writeOutput("connectInput iteration " + (i + 1) + " of " + iterations); 285 mTestUtils.connectProfile(adapter, device, BluetoothProfile.INPUT_DEVICE, 286 String.format("connectInput(device=%s)", device)); 287 mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.INPUT_DEVICE, 288 String.format("disconnectInput(device=%s)", device)); 289 } 290 291 mTestUtils.unpair(adapter, device); 292 mTestUtils.disable(adapter); 293 } 294 295 /** 296 * Stress test for connecting and disconnecting with a PAN NAP. 297 * <p> 298 * In this test, the local device plays the role of a PANU, and initiates connections and 299 * disconnections with a NAP. 300 */ 301 public void testConnectPan() { 302 int iterations = BluetoothTestRunner.sConnectPanIterations; 303 if (iterations == 0) { 304 return; 305 } 306 307 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 308 BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 309 mTestUtils.disable(adapter); 310 mTestUtils.enable(adapter); 311 mTestUtils.unpair(adapter, device); 312 mTestUtils.pair(adapter, device, BluetoothTestRunner.sDevicePairPasskey, 313 BluetoothTestRunner.sDevicePairPin); 314 315 for (int i = 0; i < iterations; i++) { 316 mTestUtils.writeOutput("connectPan iteration " + (i + 1) + " of " + iterations); 317 mTestUtils.connectPan(adapter, device); 318 mTestUtils.disconnectPan(adapter, device); 319 } 320 321 mTestUtils.unpair(adapter, device); 322 mTestUtils.disable(adapter); 323 } 324 325 /** 326 * Stress test for verifying a PANU connecting and disconnecting with the device. 327 * <p> 328 * In this test, the local device plays the role of a NAP which a remote PANU connects and 329 * disconnects from. 330 */ 331 public void testIncomingPanConnection() { 332 int iterations = BluetoothTestRunner.sConnectPanIterations; 333 if (iterations == 0) { 334 return; 335 } 336 337 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 338 BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 339 mTestUtils.disable(adapter); 340 mTestUtils.enable(adapter); 341 mTestUtils.disablePan(adapter); 342 mTestUtils.enablePan(adapter); 343 mTestUtils.unpair(adapter, device); 344 mTestUtils.acceptPair(adapter, device, BluetoothTestRunner.sDevicePairPasskey, 345 BluetoothTestRunner.sDevicePairPin); 346 347 for (int i = 0; i < iterations; i++) { 348 mTestUtils.writeOutput("incomingPanConnection iteration " + (i + 1) + " of " 349 + iterations); 350 mTestUtils.incomingPanConnection(adapter, device); 351 mTestUtils.incomingPanDisconnection(adapter, device); 352 } 353 354 mTestUtils.unpair(adapter, device); 355 mTestUtils.disablePan(adapter); 356 mTestUtils.disable(adapter); 357 } 358 359 /** 360 * Stress test for verifying that AudioManager can open and close SCO connections. 361 * <p> 362 * In this test, a HSP connection is opened with an external headset and the SCO connection is 363 * repeatibly opened and closed. 364 */ 365 public void testStartStopSco() { 366 int iterations = BluetoothTestRunner.sStartStopScoIterations; 367 if (iterations == 0) { 368 return; 369 } 370 371 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 372 BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); 373 mTestUtils.disable(adapter); 374 mTestUtils.enable(adapter); 375 mTestUtils.unpair(adapter, device); 376 mTestUtils.pair(adapter, device, BluetoothTestRunner.sDevicePairPasskey, 377 BluetoothTestRunner.sDevicePairPin); 378 mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.HEADSET, null); 379 mTestUtils.connectProfile(adapter, device, BluetoothProfile.HEADSET, null); 380 mTestUtils.stopSco(adapter, device); 381 382 for (int i = 0; i < iterations; i++) { 383 mTestUtils.writeOutput("startStopSco iteration " + (i + 1) + " of " + iterations); 384 mTestUtils.startSco(adapter, device); 385 sleep(SCO_SLEEP_TIME); 386 mTestUtils.stopSco(adapter, device); 387 sleep(SCO_SLEEP_TIME); 388 } 389 390 mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.HEADSET, null); 391 mTestUtils.unpair(adapter, device); 392 mTestUtils.disable(adapter); 393 } 394 395 private void sleep(long time) { 396 try { 397 Thread.sleep(time); 398 } catch (InterruptedException e) { 399 } 400 } 401 } 402