1 /* 2 * Copyright (C) 2019 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 com.android.car; 18 19 import static android.car.settings.CarSettings.Secure.KEY_BLUETOOTH_HFP_CLIENT_DEVICES; 20 21 import static org.mockito.Mockito.*; 22 23 import android.bluetooth.BluetoothAdapter; 24 import android.bluetooth.BluetoothDevice; 25 import android.bluetooth.BluetoothHeadsetClient; 26 import android.bluetooth.BluetoothProfile; 27 import android.bluetooth.BluetoothUuid; 28 import android.car.ICarBluetoothUserService; 29 import android.content.BroadcastReceiver; 30 import android.content.ContentResolver; 31 import android.content.Context; 32 import android.content.Intent; 33 import android.content.IntentFilter; 34 import android.os.Handler; 35 import android.os.Looper; 36 import android.os.ParcelUuid; 37 import android.os.UserHandle; 38 import android.provider.Settings; 39 import android.test.mock.MockContentResolver; 40 import android.test.suitebuilder.annotation.Suppress; 41 import android.text.TextUtils; 42 43 import androidx.test.InstrumentationRegistry; 44 import androidx.test.filters.RequiresDevice; 45 46 import com.android.internal.util.test.BroadcastInterceptingContext; 47 import com.android.internal.util.test.FakeSettingsProvider; 48 49 import org.junit.After; 50 import org.junit.Assert; 51 import org.junit.Before; 52 import org.junit.Test; 53 import org.junit.runner.RunWith; 54 import org.mockito.InOrder; 55 import org.mockito.Mock; 56 import org.mockito.invocation.InvocationOnMock; 57 import org.mockito.junit.MockitoJUnitRunner; 58 import org.mockito.stubbing.Answer; 59 60 import java.util.ArrayList; 61 import java.util.Arrays; 62 import java.util.Collections; 63 import java.util.List; 64 65 /** 66 * Unit tests for {@link BluetoothProfileDeviceManager} 67 * 68 * Run: 69 * atest BluetoothProfileDeviceManagerTest 70 */ 71 @RequiresDevice 72 @RunWith(MockitoJUnitRunner.class) 73 public class BluetoothProfileDeviceManagerTest { 74 private static final int CONNECT_LATENCY_MS = 100; 75 private static final int CONNECT_TIMEOUT_MS = 8000; 76 private static final int ADAPTER_STATE_ANY = 0; 77 private static final int ADAPTER_STATE_OFF = 1; 78 private static final int ADAPTER_STATE_OFF_NOT_PERSISTED = 2; 79 private static final int ADAPTER_STATE_ON = 3; 80 81 private static final List<String> EMPTY_DEVICE_LIST = Arrays.asList(); 82 private static final List<String> SINGLE_DEVICE_LIST = Arrays.asList("DE:AD:BE:EF:00:00"); 83 private static final List<String> SMALL_DEVICE_LIST = Arrays.asList( 84 "DE:AD:BE:EF:00:00", 85 "DE:AD:BE:EF:00:01", 86 "DE:AD:BE:EF:00:02"); 87 private static final List<String> LARGE_DEVICE_LIST = Arrays.asList( 88 "DE:AD:BE:EF:00:00", 89 "DE:AD:BE:EF:00:01", 90 "DE:AD:BE:EF:00:02", 91 "DE:AD:BE:EF:00:03", 92 "DE:AD:BE:EF:00:04", 93 "DE:AD:BE:EF:00:05", 94 "DE:AD:BE:EF:00:06", 95 "DE:AD:BE:EF:00:07"); 96 97 private static final String EMPTY_SETTINGS_STRING = ""; 98 private static final String SINGLE_SETTINGS_STRING = makeSettingsString(SINGLE_DEVICE_LIST); 99 private static final String SMALL_SETTINGS_STRING = makeSettingsString(SMALL_DEVICE_LIST); 100 private static final String LARGE_SETTINGS_STRING = makeSettingsString(LARGE_DEVICE_LIST); 101 102 BluetoothProfileDeviceManager mProfileDeviceManager; 103 104 private final int mUserId = 0; 105 private final int mProfileId = BluetoothProfile.HEADSET_CLIENT; 106 private final String mSettingsKey = KEY_BLUETOOTH_HFP_CLIENT_DEVICES; 107 private final String mConnectionAction = BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED; 108 private ParcelUuid[] mUuids = new ParcelUuid[] { 109 BluetoothUuid.HFP_AG, 110 BluetoothUuid.HSP_AG}; 111 private ParcelUuid[] mBadUuids = new ParcelUuid[] { 112 BluetoothUuid.PANU}; 113 private final int[] mProfileTriggers = new int[] { 114 BluetoothProfile.MAP_CLIENT, 115 BluetoothProfile.PBAP_CLIENT}; 116 117 @Mock private ICarBluetoothUserService mMockProxies; 118 private Handler mHandler; 119 private static final Object HANDLER_TOKEN = new Object(); 120 121 private MockContext mMockContext; 122 123 private BluetoothAdapterHelper mBluetoothAdapterHelper; 124 private BluetoothAdapter mBluetoothAdapter; 125 126 public class MockContext extends BroadcastInterceptingContext { 127 private MockContentResolver mContentResolver; 128 private FakeSettingsProvider mContentProvider; 129 MockContext(Context base)130 MockContext(Context base) { 131 super(base); 132 FakeSettingsProvider.clearSettingsProvider(); 133 mContentResolver = new MockContentResolver(this); 134 mContentProvider = new FakeSettingsProvider(); 135 mContentResolver.addProvider(Settings.AUTHORITY, mContentProvider); 136 } 137 release()138 public void release() { 139 FakeSettingsProvider.clearSettingsProvider(); 140 } 141 142 @Override getContentResolver()143 public ContentResolver getContentResolver() { 144 return mContentResolver; 145 } 146 147 @Override registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)148 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, 149 IntentFilter filter, String broadcastPermission, Handler scheduler) { 150 // We're basically ignoring the userhandle since the tests only assume one user anyway. 151 // BroadcastInterceptingContext doesn't implement this hook either so this has to do. 152 return super.registerReceiver(receiver, filter); 153 } 154 } 155 156 //--------------------------------------------------------------------------------------------// 157 // Setup/TearDown // 158 //--------------------------------------------------------------------------------------------// 159 160 @Before setUp()161 public void setUp() { 162 mMockContext = new MockContext(InstrumentationRegistry.getTargetContext()); 163 setSettingsDeviceList(""); 164 assertSettingsContains(""); 165 166 mBluetoothAdapterHelper = new BluetoothAdapterHelper(); 167 mBluetoothAdapterHelper.init(); 168 169 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 170 Assert.assertTrue(mBluetoothAdapter != null); 171 172 mHandler = new Handler(Looper.getMainLooper()); 173 174 mProfileDeviceManager = BluetoothProfileDeviceManager.create(mMockContext, mUserId, 175 mMockProxies, mProfileId); 176 Assert.assertTrue(mProfileDeviceManager != null); 177 } 178 179 @After tearDown()180 public void tearDown() { 181 if (mProfileDeviceManager != null) { 182 mProfileDeviceManager.stop(); 183 mProfileDeviceManager = null; 184 } 185 if (mHandler != null) { 186 mHandler.removeCallbacksAndMessages(HANDLER_TOKEN); 187 mHandler = null; 188 } 189 mBluetoothAdapter = null; 190 if (mBluetoothAdapterHelper != null) { 191 mBluetoothAdapterHelper.release(); 192 mBluetoothAdapterHelper = null; 193 } 194 mMockProxies = null; 195 if (mMockContext != null) { 196 mMockContext.release(); 197 mMockContext = null; 198 } 199 } 200 201 //--------------------------------------------------------------------------------------------// 202 // Utilities // 203 //--------------------------------------------------------------------------------------------// 204 setSettingsDeviceList(String devicesStr)205 private void setSettingsDeviceList(String devicesStr) { 206 Settings.Secure.putStringForUser(mMockContext.getContentResolver(), mSettingsKey, 207 devicesStr, mUserId); 208 } 209 getSettingsDeviceList()210 private String getSettingsDeviceList() { 211 String devices = Settings.Secure.getStringForUser(mMockContext.getContentResolver(), 212 mSettingsKey, mUserId); 213 if (devices == null) devices = ""; 214 return devices; 215 } 216 makeDeviceList(List<String> addresses)217 private ArrayList<BluetoothDevice> makeDeviceList(List<String> addresses) { 218 ArrayList<BluetoothDevice> devices = new ArrayList<>(); 219 for (String address : addresses) { 220 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 221 if (device == null) continue; 222 devices.add(device); 223 } 224 return devices; 225 } 226 makeSettingsString(List<String> addresses)227 private static String makeSettingsString(List<String> addresses) { 228 return TextUtils.join(",", addresses); 229 } 230 setPreconditionsAndStart(int adapterState, String settings, List<String> devices)231 private void setPreconditionsAndStart(int adapterState, String settings, 232 List<String> devices) { 233 switch (adapterState) { 234 case ADAPTER_STATE_ON: 235 mBluetoothAdapterHelper.forceAdapterOn(); 236 break; 237 case ADAPTER_STATE_OFF: 238 mBluetoothAdapterHelper.forceAdapterOff(); 239 break; 240 case ADAPTER_STATE_OFF_NOT_PERSISTED: 241 mBluetoothAdapterHelper.forceAdapterOffDoNotPersist(); 242 break; 243 case ADAPTER_STATE_ANY: 244 break; 245 default: 246 break; 247 } 248 249 setSettingsDeviceList(settings); 250 251 mProfileDeviceManager.start(); 252 253 for (BluetoothDevice device : makeDeviceList(devices)) { 254 mProfileDeviceManager.addDevice(device); 255 } 256 } 257 mockDeviceAvailability(BluetoothDevice device, boolean available)258 private void mockDeviceAvailability(BluetoothDevice device, boolean available) 259 throws Exception { 260 doAnswer(new Answer<Boolean>() { 261 @Override 262 public Boolean answer(InvocationOnMock invocation) throws Throwable { 263 Object[] arguments = invocation.getArguments(); 264 if (arguments != null && arguments.length == 2 && arguments[1] != null) { 265 BluetoothDevice device = (BluetoothDevice) arguments[1]; 266 int state = (available 267 ? BluetoothProfile.STATE_CONNECTED 268 : BluetoothProfile.STATE_DISCONNECTED); 269 mHandler.postDelayed(() -> { 270 sendConnectionStateChanged(device, state); 271 }, HANDLER_TOKEN, CONNECT_LATENCY_MS); 272 } 273 return true; 274 } 275 }).when(mMockProxies).bluetoothConnectToProfile(mProfileId, device); 276 } 277 captureDevicePriority(BluetoothDevice device)278 private void captureDevicePriority(BluetoothDevice device) throws Exception { 279 doAnswer(new Answer<Void>() { 280 @Override 281 public Void answer(InvocationOnMock invocation) throws Throwable { 282 Object[] arguments = invocation.getArguments(); 283 if (arguments != null && arguments.length == 3 && arguments[1] != null) { 284 BluetoothDevice device = (BluetoothDevice) arguments[1]; 285 int priority = (int) arguments[2]; 286 mockDevicePriority(device, priority); 287 } 288 return null; 289 } 290 }).when(mMockProxies).setProfilePriority(mProfileId, device, anyInt()); 291 } 292 mockDevicePriority(BluetoothDevice device, int priority)293 private void mockDevicePriority(BluetoothDevice device, int priority) throws Exception { 294 when(mMockProxies.getProfilePriority(mProfileId, device)).thenReturn(priority); 295 } 296 sendAdapterStateChanged(int newState)297 private void sendAdapterStateChanged(int newState) { 298 Assert.assertTrue(mMockContext != null); 299 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); 300 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState); 301 mMockContext.sendBroadcast(intent); 302 } 303 sendBondStateChanged(BluetoothDevice device, int newState)304 private void sendBondStateChanged(BluetoothDevice device, int newState) { 305 Assert.assertTrue(mMockContext != null); 306 Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED); 307 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 308 intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, newState); 309 mMockContext.sendBroadcast(intent); 310 } 311 sendDeviceUuids(BluetoothDevice device, ParcelUuid[] uuids)312 private void sendDeviceUuids(BluetoothDevice device, ParcelUuid[] uuids) { 313 Assert.assertTrue(mMockContext != null); 314 Intent intent = new Intent(BluetoothDevice.ACTION_UUID); 315 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 316 intent.putExtra(BluetoothDevice.EXTRA_UUID, uuids); 317 mMockContext.sendBroadcast(intent); 318 } 319 sendConnectionStateChanged(BluetoothDevice device, int newState)320 private void sendConnectionStateChanged(BluetoothDevice device, int newState) { 321 Assert.assertTrue(mMockContext != null); 322 Intent intent = new Intent(mConnectionAction); 323 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 324 intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); 325 mMockContext.sendBroadcast(intent); 326 } 327 assertSettingsContains(String expected)328 private synchronized void assertSettingsContains(String expected) { 329 Assert.assertTrue(expected != null); 330 String settings = getSettingsDeviceList(); 331 if (settings == null) settings = ""; 332 Assert.assertEquals(expected, settings); 333 } 334 assertDeviceList(List<String> expected)335 private void assertDeviceList(List<String> expected) { 336 ArrayList<BluetoothDevice> devices = mProfileDeviceManager.getDeviceListSnapshot(); 337 ArrayList<BluetoothDevice> expectedDevices = makeDeviceList(expected); 338 Assert.assertEquals(expectedDevices, devices); 339 } 340 341 //--------------------------------------------------------------------------------------------// 342 // Load from persistent memory tests // 343 //--------------------------------------------------------------------------------------------// 344 345 /** 346 * Preconditions: 347 * - Settings contains no devices 348 * 349 * Actions: 350 * - Initialize the device manager 351 * 352 * Outcome: 353 * - device manager should initialize 354 */ 355 @Test testEmptySettingsString_loadNoDevices()356 public void testEmptySettingsString_loadNoDevices() { 357 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 358 assertDeviceList(EMPTY_DEVICE_LIST); 359 } 360 361 /** 362 * Preconditions: 363 * - Settings contains a single device 364 * 365 * Actions: 366 * - Initialize the device manager 367 * 368 * Outcome: 369 * - The single device is now located in the device manager's device list 370 */ 371 @Test testSingleDeviceSettingsString_loadSingleDevice()372 public void testSingleDeviceSettingsString_loadSingleDevice() { 373 setPreconditionsAndStart(ADAPTER_STATE_ANY, SINGLE_SETTINGS_STRING, EMPTY_DEVICE_LIST); 374 assertDeviceList(SINGLE_DEVICE_LIST); 375 } 376 377 /** 378 * Preconditions: 379 * - Settings contains several devices 380 * 381 * Actions: 382 * - Initialize the device manager 383 * 384 * Outcome: 385 * - All devices are now in the device manager's list, all in the proper order. 386 */ 387 @Test testSeveralDevicesSettingsString_loadAllDevices()388 public void testSeveralDevicesSettingsString_loadAllDevices() { 389 setPreconditionsAndStart(ADAPTER_STATE_ANY, LARGE_SETTINGS_STRING, EMPTY_DEVICE_LIST); 390 assertDeviceList(LARGE_DEVICE_LIST); 391 } 392 393 //--------------------------------------------------------------------------------------------// 394 // Commit to persistent memory tests // 395 //--------------------------------------------------------------------------------------------// 396 397 /** 398 * Preconditions: 399 * - The device manager is initialized and the list contains no devices 400 * 401 * Actions: 402 * - An event forces the device manager to commit it's list 403 * 404 * Outcome: 405 * - The empty list should be written to Settings.Secure as an empty string, "" 406 */ 407 @Test testNoDevicesCommit_commitEmptyDeviceString()408 public void testNoDevicesCommit_commitEmptyDeviceString() { 409 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 410 sendAdapterStateChanged(BluetoothAdapter.STATE_OFF); 411 assertSettingsContains(EMPTY_SETTINGS_STRING); 412 } 413 414 /** 415 * Preconditions: 416 * - The device manager contains several devices 417 * 418 * Actions: 419 * - An event forces the device manager to commit it's list 420 * 421 * Outcome: 422 * - The ordered device list should be written to Settings.Secure as a comma separated list 423 */ 424 @Test testSeveralDevicesCommit_commitAllDeviceString()425 public void testSeveralDevicesCommit_commitAllDeviceString() { 426 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, LARGE_DEVICE_LIST); 427 sendAdapterStateChanged(BluetoothAdapter.STATE_OFF); 428 assertSettingsContains(LARGE_SETTINGS_STRING); 429 } 430 431 //--------------------------------------------------------------------------------------------// 432 // Add Device tests // 433 //--------------------------------------------------------------------------------------------// 434 435 /** 436 * Preconditions: 437 * - The device manager is initialized and contains no devices. 438 * 439 * Actions: 440 * - Add a single device 441 * 442 * Outcome: 443 * - The device manager priority list contains the single device 444 */ 445 @Test testAddSingleDevice_devicesAppearInPriorityList()446 public void testAddSingleDevice_devicesAppearInPriorityList() { 447 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SINGLE_DEVICE_LIST); 448 assertDeviceList(SINGLE_DEVICE_LIST); 449 } 450 451 /** 452 * Preconditions: 453 * - The device manager is initialized and contains no devices. 454 * 455 * Actions: 456 * - Add several devices 457 * 458 * Outcome: 459 * - The device manager priority list contains all devices, ordered properly 460 */ 461 @Test testAddMultipleDevices_devicesAppearInPriorityList()462 public void testAddMultipleDevices_devicesAppearInPriorityList() { 463 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, LARGE_DEVICE_LIST); 464 assertDeviceList(LARGE_DEVICE_LIST); 465 } 466 467 /** 468 * Preconditions: 469 * - The device manager is initialized and contains one device 470 * 471 * Actions: 472 * - Add the device that is already in the list 473 * 474 * Outcome: 475 * - The device manager's list remains unchanged with only one device in it 476 */ 477 @Test testAddDeviceAlreadyInList_priorityListUnchanged()478 public void testAddDeviceAlreadyInList_priorityListUnchanged() { 479 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SINGLE_DEVICE_LIST); 480 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 481 mProfileDeviceManager.addDevice(device); 482 assertDeviceList(SINGLE_DEVICE_LIST); 483 } 484 485 //--------------------------------------------------------------------------------------------// 486 // Remove Device tests // 487 //--------------------------------------------------------------------------------------------// 488 489 /** 490 * Preconditions: 491 * - The device manager is initialized and contains no devices. 492 * 493 * Actions: 494 * - Remove a device from the list 495 * 496 * Outcome: 497 * - The device manager does not error out and continues to have an empty list 498 */ 499 @Test testRemoveDeviceFromEmptyList_priorityListUnchanged()500 public void testRemoveDeviceFromEmptyList_priorityListUnchanged() { 501 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 502 mProfileDeviceManager.removeDevice(mBluetoothAdapter.getRemoteDevice("DE:AD:BE:EF:00:00")); 503 assertDeviceList(EMPTY_DEVICE_LIST); 504 } 505 506 /** 507 * Preconditions: 508 * - The device manager is initialized and contains several devices. 509 * 510 * Actions: 511 * - Remove the device with the highest priority (front of list) 512 * 513 * Outcome: 514 * - The device manager removes the leading device. The other devices have been shifted down. 515 */ 516 @Test testRemoveDeviceFront_deviceNoLongerInPriorityList()517 public void testRemoveDeviceFront_deviceNoLongerInPriorityList() { 518 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 519 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 520 mProfileDeviceManager.removeDevice(device); 521 ArrayList<String> expected = new ArrayList(SMALL_DEVICE_LIST); 522 expected.remove(0); 523 assertDeviceList(expected); 524 } 525 526 /** 527 * Preconditions: 528 * - The device manager is initialized and contains several devices. 529 * 530 * Actions: 531 * - Remove a device from the middle of the list 532 * 533 * Outcome: 534 * - The device manager removes the device. The other devices with larger priorities have been 535 * shifted down. 536 */ 537 @Test testRemoveDeviceMiddle_deviceNoLongerInPriorityList()538 public void testRemoveDeviceMiddle_deviceNoLongerInPriorityList() { 539 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 540 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SMALL_DEVICE_LIST.get(1)); 541 mProfileDeviceManager.removeDevice(device); 542 ArrayList<String> expected = new ArrayList(SMALL_DEVICE_LIST); 543 expected.remove(1); 544 assertDeviceList(expected); 545 } 546 547 /** 548 * Preconditions: 549 * - The device manager is initialized and contains several devices. 550 * 551 * Actions: 552 * - Remove the device from the end of the list 553 * 554 * Outcome: 555 * - The device manager removes the device. The other devices remain in their places, unchanged 556 */ 557 @Test testRemoveDeviceEnd_deviceNoLongerInPriorityList()558 public void testRemoveDeviceEnd_deviceNoLongerInPriorityList() { 559 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 560 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SMALL_DEVICE_LIST.get(2)); 561 mProfileDeviceManager.removeDevice(device); 562 ArrayList<String> expected = new ArrayList(SMALL_DEVICE_LIST); 563 expected.remove(2); // 00, 01 564 assertDeviceList(expected); 565 } 566 567 /** 568 * Preconditions: 569 * - The device manager is initialized and contains several devices. 570 * 571 * Actions: 572 * - Remove a device thats not in the list 573 * 574 * Outcome: 575 * - The device manager's list remains unchanged. 576 */ 577 @Test testRemoveDeviceNotInList_priorityListUnchanged()578 public void testRemoveDeviceNotInList_priorityListUnchanged() { 579 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 580 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice("10:20:30:40:50:60"); 581 mProfileDeviceManager.removeDevice(device); 582 assertDeviceList(SMALL_DEVICE_LIST); 583 } 584 585 //--------------------------------------------------------------------------------------------// 586 // GetDeviceConnectionPriority() tests // 587 //--------------------------------------------------------------------------------------------// 588 589 /** 590 * Preconditions: 591 * - The device manager is initialized and contains several devices. 592 * 593 * Actions: 594 * - Get the priority of each device in the list 595 * 596 * Outcome: 597 * - The device manager returns the proper priority for each device 598 */ 599 @Test testGetConnectionPriority_prioritiesReturned()600 public void testGetConnectionPriority_prioritiesReturned() { 601 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 602 ArrayList<BluetoothDevice> devices = makeDeviceList(SMALL_DEVICE_LIST); 603 for (int i = 0; i < devices.size(); i++) { 604 int priority = mProfileDeviceManager.getDeviceConnectionPriority(devices.get(i)); 605 Assert.assertEquals(i, priority); 606 } 607 } 608 609 /** 610 * Preconditions: 611 * - The device manager is initialized and contains several devices. 612 * 613 * Actions: 614 * - Get the priority of a device that is not in the list 615 * 616 * Outcome: 617 * - The device manager returns a -1 618 */ 619 @Test testGetConnectionPriorityDeviceNotInList_negativeOneReturned()620 public void testGetConnectionPriorityDeviceNotInList_negativeOneReturned() { 621 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 622 BluetoothDevice deviceNotPresent = mBluetoothAdapter.getRemoteDevice("10:20:30:40:50:60"); 623 int priority = mProfileDeviceManager.getDeviceConnectionPriority(deviceNotPresent); 624 Assert.assertEquals(-1, priority); 625 } 626 627 //--------------------------------------------------------------------------------------------// 628 // setDeviceConnectionPriority() tests // 629 //--------------------------------------------------------------------------------------------// 630 631 /** 632 * Preconditions: 633 * - The device manager is initialized and contains several devices. 634 * 635 * Actions: 636 * - Set the priority of several devices in the list, testing the following moves: 637 * Mid priority -> higher priority 638 * Mid priority -> lower priority 639 * Highest priority -> lower priority 640 * Lowest priority -> higher priority 641 * Any priority -> same priority 642 * 643 * Outcome: 644 * - Increased prioritied shuffle devices to proper lower priorities, decreased priorities 645 * shuffle devices to proper high priorities, and a request to set the same priority yields no 646 * change. 647 */ 648 @Test testSetConnectionPriority_listOrderedCorrectly()649 public void testSetConnectionPriority_listOrderedCorrectly() { 650 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 651 652 // move middle device to front 653 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SMALL_DEVICE_LIST.get(1)); 654 mProfileDeviceManager.setDeviceConnectionPriority(device, 0); 655 Assert.assertEquals(0, mProfileDeviceManager.getDeviceConnectionPriority(device)); 656 ArrayList<String> expected = new ArrayList(SMALL_DEVICE_LIST); 657 Collections.swap(expected, 1, 0); // expected: 00, [01], 02 -> [01], 00, 02 658 assertDeviceList(expected); 659 660 // move front device to the end 661 mProfileDeviceManager.setDeviceConnectionPriority(device, 2); 662 Assert.assertEquals(2, mProfileDeviceManager.getDeviceConnectionPriority(device)); 663 Collections.swap(expected, 0, 2); // expected: [01], 00, 02 -> 00, 02, [01] 664 Collections.swap(expected, 0, 1); 665 assertDeviceList(expected); 666 667 // move end device to middle 668 mProfileDeviceManager.setDeviceConnectionPriority(device, 1); 669 Assert.assertEquals(1, mProfileDeviceManager.getDeviceConnectionPriority(device)); 670 Collections.swap(expected, 2, 1); // expected: 00, 02, [01] -> 00, [01], 02 671 assertDeviceList(expected); 672 673 // move middle to end 674 mProfileDeviceManager.setDeviceConnectionPriority(device, 2); 675 Assert.assertEquals(2, mProfileDeviceManager.getDeviceConnectionPriority(device)); 676 Collections.swap(expected, 1, 2); // expected: 00, [01], 02 -> 00, 02, [01] 677 assertDeviceList(expected); 678 679 // move end to front 680 mProfileDeviceManager.setDeviceConnectionPriority(device, 0); 681 Assert.assertEquals(0, mProfileDeviceManager.getDeviceConnectionPriority(device)); 682 Collections.swap(expected, 2, 0); // expected: 00, 02, [01] -> [01], 00, 02 683 Collections.swap(expected, 1, 2); 684 assertDeviceList(expected); 685 686 // move front to middle 687 mProfileDeviceManager.setDeviceConnectionPriority(device, 1); 688 Assert.assertEquals(1, mProfileDeviceManager.getDeviceConnectionPriority(device)); 689 Collections.swap(expected, 0, 1); // expected: [01], 00, 02 -> 00, [01], 02 690 assertDeviceList(expected); 691 692 // move middle to middle (i.e same to same) 693 mProfileDeviceManager.setDeviceConnectionPriority(device, 1); 694 Assert.assertEquals(1, mProfileDeviceManager.getDeviceConnectionPriority(device)); 695 assertDeviceList(expected); // expected: 00, [01], 02 -> 00, [01], 02 696 } 697 698 /** 699 * Preconditions: 700 * - The device manager is initialized and contains several devices. 701 * 702 * Actions: 703 * - Set the priority of a device that is not currently in the list 704 * 705 * Outcome: 706 * - Device is added to the list in the requested spot. Devices with lower priorities have had 707 * their priorities adjusted accordingly. 708 */ 709 @Test testSetConnectionPriorityNewDevice_listOrderedCorrectly()710 public void testSetConnectionPriorityNewDevice_listOrderedCorrectly() { 711 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 712 713 // add new device to the middle 714 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice("10:20:30:40:50:60"); 715 mProfileDeviceManager.setDeviceConnectionPriority(device, 1); 716 Assert.assertEquals(1, mProfileDeviceManager.getDeviceConnectionPriority(device)); 717 ArrayList<String> expected = new ArrayList(SMALL_DEVICE_LIST); 718 expected.add(1, "10:20:30:40:50:60"); // 00, 60, 01, 02 719 assertDeviceList(expected); 720 721 // add new device to the front 722 device = mBluetoothAdapter.getRemoteDevice("10:20:30:40:50:61"); 723 mProfileDeviceManager.setDeviceConnectionPriority(device, 0); 724 Assert.assertEquals(0, mProfileDeviceManager.getDeviceConnectionPriority(device)); 725 expected.add(0, "10:20:30:40:50:61"); // 61, 00, 60, 01, 02 726 assertDeviceList(expected); 727 728 // add new device to the end 729 device = mBluetoothAdapter.getRemoteDevice("10:20:30:40:50:62"); 730 mProfileDeviceManager.setDeviceConnectionPriority(device, 5); 731 Assert.assertEquals(5, mProfileDeviceManager.getDeviceConnectionPriority(device)); 732 expected.add(5, "10:20:30:40:50:62"); // 61, 00, 60, 01, 02, 62 733 assertDeviceList(expected); 734 } 735 736 /** 737 * Preconditions: 738 * - The device manager is initialized and contains several devices. 739 * 740 * Actions: 741 * - Request to set a priority that exceeds the bounds of the list (upper) 742 * 743 * Outcome: 744 * - No operation is taken 745 */ 746 @Test testSetConnectionPriorityLargerThanSize_priorityListUnchanged()747 public void testSetConnectionPriorityLargerThanSize_priorityListUnchanged() { 748 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 749 750 // Attempt to move middle device to end with huge end priority 751 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SMALL_DEVICE_LIST.get(1)); 752 mProfileDeviceManager.setDeviceConnectionPriority(device, 100000); 753 Assert.assertEquals(1, mProfileDeviceManager.getDeviceConnectionPriority(device)); 754 assertDeviceList(SMALL_DEVICE_LIST); 755 } 756 757 /** 758 * Preconditions: 759 * - The device manager is initialized and contains several devices. 760 * 761 * Actions: 762 * - Request to set a priority that exceeds the bounds of the list (lower) 763 * 764 * Outcome: 765 * - No operation is taken 766 */ 767 @Test testSetConnectionPriorityNegative_priorityListUnchanged()768 public void testSetConnectionPriorityNegative_priorityListUnchanged() { 769 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 770 771 // Attempt to move middle device to negative priority 772 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SMALL_DEVICE_LIST.get(1)); 773 mProfileDeviceManager.setDeviceConnectionPriority(device, -1); 774 assertDeviceList(SMALL_DEVICE_LIST); 775 } 776 777 /** 778 * Preconditions: 779 * - The device manager is initialized and contains several devices. 780 * 781 * Actions: 782 * - Request to set a priority for a null device 783 * 784 * Outcome: 785 * - No operation is taken 786 */ 787 @Test testSetConnectionPriorityNullDevice_priorityListUnchanged()788 public void testSetConnectionPriorityNullDevice_priorityListUnchanged() { 789 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 790 mProfileDeviceManager.setDeviceConnectionPriority(null, 1); 791 assertDeviceList(SMALL_DEVICE_LIST); 792 } 793 794 //--------------------------------------------------------------------------------------------// 795 // beginAutoConnecting() tests // 796 //--------------------------------------------------------------------------------------------// 797 798 /** 799 * Preconditions: 800 * - The Bluetooth adapter is ON, the device manager is initialized and no devices are in the 801 * list. 802 * 803 * Actions: 804 * - Initiate an auto connection 805 * 806 * Outcome: 807 * - Auto connect returns immediately with no connection attempts made. 808 */ 809 @Test testAutoConnectNoDevices_returnsImmediately()810 public void testAutoConnectNoDevices_returnsImmediately() throws Exception { 811 setPreconditionsAndStart(ADAPTER_STATE_ON, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 812 mProfileDeviceManager.beginAutoConnecting(); 813 verify(mMockProxies, times(0)).bluetoothConnectToProfile(eq(mProfileId), 814 any(BluetoothDevice.class)); 815 Assert.assertFalse(mProfileDeviceManager.isAutoConnecting()); 816 } 817 818 /** 819 * Preconditions: 820 * - The Bluetooth adapter is OFF, the device manager is initialized and there are several 821 * devices are in the list. 822 * 823 * Actions: 824 * - Initiate an auto connection 825 * 826 * Outcome: 827 * - Auto connect returns immediately with no connection attempts made. 828 */ 829 @Test testAutoConnectAdapterOff_returnsImmediately()830 public void testAutoConnectAdapterOff_returnsImmediately() throws Exception { 831 setPreconditionsAndStart(ADAPTER_STATE_OFF, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 832 mProfileDeviceManager.beginAutoConnecting(); 833 verify(mMockProxies, times(0)).bluetoothConnectToProfile(eq(mProfileId), 834 any(BluetoothDevice.class)); 835 Assert.assertFalse(mProfileDeviceManager.isAutoConnecting()); 836 } 837 838 /** 839 * Preconditions: 840 * - The Bluetooth adapter is ON, the device manager is initialized and there are several 841 * devices are in the list. 842 * 843 * Actions: 844 * - Initiate an auto connection 845 * 846 * Outcome: 847 * - Auto connect attempts to connect each device in the list, in order of priority. 848 */ 849 @Test testAutoConnectSeveralDevices_attemptsToConnectEachDevice()850 public void testAutoConnectSeveralDevices_attemptsToConnectEachDevice() throws Exception { 851 setPreconditionsAndStart(ADAPTER_STATE_ON, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 852 ArrayList<BluetoothDevice> devices = makeDeviceList(SMALL_DEVICE_LIST); 853 for (BluetoothDevice device : devices) { 854 mockDeviceAvailability(device, true); 855 } 856 857 mProfileDeviceManager.beginAutoConnecting(); 858 859 InOrder ordered = inOrder(mMockProxies); 860 for (BluetoothDevice device : devices) { 861 ordered.verify(mMockProxies, timeout(CONNECT_TIMEOUT_MS).times(1)) 862 .bluetoothConnectToProfile(mProfileId, device); 863 } 864 } 865 866 //--------------------------------------------------------------------------------------------// 867 // Bluetooth stack device connection status changed event tests // 868 //--------------------------------------------------------------------------------------------// 869 870 /** 871 * Preconditions: 872 * - The device manager is initialized, there are no devices in the list. We are not auto 873 * connecting 874 * 875 * Actions: 876 * - A connection action comes in for the profile we're tracking and the device's priority is 877 * PRIORITY_AUTO_CONNECT. 878 * 879 * Outcome: 880 * - The device is added to the list. Related/configured trigger profiles are connected. 881 */ 882 @Test testReceiveDeviceConnectPriorityAutoConnect_deviceAdded()883 public void testReceiveDeviceConnectPriorityAutoConnect_deviceAdded() throws Exception { 884 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 885 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 886 mockDevicePriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT); 887 sendConnectionStateChanged(device, BluetoothProfile.STATE_CONNECTED); 888 assertDeviceList(SINGLE_DEVICE_LIST); 889 for (int profile : mProfileTriggers) { 890 verify(mMockProxies, times(1)).bluetoothConnectToProfile(profile, device); 891 } 892 } 893 894 /** 895 * Preconditions: 896 * - The device manager is initialized, there are no devices in the list. 897 * 898 * Actions: 899 * - A connection action comes in for the profile we're tracking and the device's priority is 900 * PRIORITY_ON. 901 * 902 * Outcome: 903 * - The device is added to the list. Related/configured trigger profiles are connected. 904 */ 905 @Test testReceiveDeviceConnectPriorityOn_deviceAdded()906 public void testReceiveDeviceConnectPriorityOn_deviceAdded() throws Exception { 907 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 908 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 909 mockDevicePriority(device, BluetoothProfile.PRIORITY_ON); 910 sendConnectionStateChanged(device, BluetoothProfile.STATE_CONNECTED); 911 assertDeviceList(SINGLE_DEVICE_LIST); 912 for (int profile : mProfileTriggers) { 913 verify(mMockProxies, times(1)).bluetoothConnectToProfile(profile, device); 914 } 915 } 916 917 /** 918 * Preconditions: 919 * - The device manager is initialized, there are no devices in the list. 920 * 921 * Actions: 922 * - A connection action comes in for the profile we're tracking and the device's priority is 923 * PRIORITY_OFF. 924 * 925 * Outcome: 926 * - The device is not added to the list. Related/configured trigger profiles are connected. 927 */ 928 @Test testReceiveDeviceConnectPriorityOff_deviceNotAdded()929 public void testReceiveDeviceConnectPriorityOff_deviceNotAdded() throws Exception { 930 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 931 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 932 mockDevicePriority(device, BluetoothProfile.PRIORITY_OFF); 933 sendConnectionStateChanged(device, BluetoothProfile.STATE_CONNECTED); 934 assertDeviceList(EMPTY_DEVICE_LIST); 935 for (int profile : mProfileTriggers) { 936 verify(mMockProxies, times(1)).bluetoothConnectToProfile(profile, device); 937 } 938 } 939 940 /** 941 * Preconditions: 942 * - The device manager is initialized, there are no devices in the list. 943 * 944 * Actions: 945 * - A connection action comes in for the profile we're tracking and the device's priority is 946 * PRIORITY_UNDEFINED. 947 * 948 * Outcome: 949 * - The device is not added to the list. Related/configured trigger profiles are connected. 950 */ 951 @Test testReceiveDeviceConnectPriorityUndefined_deviceNotAdded()952 public void testReceiveDeviceConnectPriorityUndefined_deviceNotAdded() throws Exception { 953 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 954 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 955 mockDevicePriority(device, BluetoothProfile.PRIORITY_UNDEFINED); 956 sendConnectionStateChanged(device, BluetoothProfile.STATE_CONNECTED); 957 assertDeviceList(EMPTY_DEVICE_LIST); 958 for (int profile : mProfileTriggers) { 959 verify(mMockProxies, times(1)).bluetoothConnectToProfile(profile, device); 960 } 961 } 962 963 /** 964 * Preconditions: 965 * - The device manager is initialized, there are is one device in the list. 966 * 967 * Actions: 968 * - A disconnection action comes in for the profile we're tracking and the device's priority is 969 * PRIORITY_AUTO_CONNECT. 970 * 971 * Outcome: 972 * - The device list is unchanged. 973 */ 974 @Test testReceiveDeviceDisconnectPriorityAutoConnect_listUnchanged()975 public void testReceiveDeviceDisconnectPriorityAutoConnect_listUnchanged() throws Exception { 976 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SINGLE_DEVICE_LIST); 977 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 978 mockDevicePriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT); 979 sendConnectionStateChanged(device, BluetoothProfile.STATE_DISCONNECTED); 980 assertDeviceList(SINGLE_DEVICE_LIST); 981 } 982 983 /** 984 * Preconditions: 985 * - The device manager is initialized, there are is one device in the list. 986 * 987 * Actions: 988 * - A disconnection action comes in for the profile we're tracking and the device's priority is 989 * PRIORITY_ON. 990 * 991 * Outcome: 992 * - The device list is unchanged. 993 */ 994 @Test testReceiveDeviceDisconnectPriorityOn_listUnchanged()995 public void testReceiveDeviceDisconnectPriorityOn_listUnchanged() throws Exception { 996 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SINGLE_DEVICE_LIST); 997 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 998 mockDevicePriority(device, BluetoothProfile.PRIORITY_ON); 999 sendConnectionStateChanged(device, BluetoothProfile.STATE_DISCONNECTED); 1000 assertDeviceList(SINGLE_DEVICE_LIST); 1001 } 1002 1003 /** 1004 * Preconditions: 1005 * - The device manager is initialized, there are is one device in the list. 1006 * 1007 * Actions: 1008 * - A disconnection action comes in for the profile we're tracking and the device's priority is 1009 * PRIORITY_OFF. 1010 * 1011 * Outcome: 1012 * - The device list is unchanged. 1013 */ 1014 @Test testReceiveDeviceDisconnectPriorityOff_deviceRemoved()1015 public void testReceiveDeviceDisconnectPriorityOff_deviceRemoved() throws Exception { 1016 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SINGLE_DEVICE_LIST); 1017 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1018 mockDevicePriority(device, BluetoothProfile.PRIORITY_OFF); 1019 sendConnectionStateChanged(device, BluetoothProfile.STATE_DISCONNECTED); 1020 assertDeviceList(SINGLE_DEVICE_LIST); 1021 } 1022 1023 /** 1024 * Preconditions: 1025 * - The device manager is initialized, there are is one device in the list. 1026 * 1027 * Actions: 1028 * - A disconnection action comes in for the profile we're tracking and the device's priority is 1029 * PRIORITY_OFF. 1030 * 1031 * Outcome: 1032 * - The device list is unchanged. 1033 */ 1034 @Test testReceiveDeviceDisconnectPriorityUndefined_listUnchanged()1035 public void testReceiveDeviceDisconnectPriorityUndefined_listUnchanged() throws Exception { 1036 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SINGLE_DEVICE_LIST); 1037 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1038 mockDevicePriority(device, BluetoothProfile.PRIORITY_UNDEFINED); 1039 sendConnectionStateChanged(device, BluetoothProfile.STATE_DISCONNECTED); 1040 assertDeviceList(SINGLE_DEVICE_LIST); 1041 } 1042 1043 //--------------------------------------------------------------------------------------------// 1044 // Bluetooth stack device bond status changed event tests // 1045 //--------------------------------------------------------------------------------------------// 1046 1047 /** 1048 * Preconditions: 1049 * - The device manager is initialized, there are is one device in the list. 1050 * 1051 * Actions: 1052 * - A device from the list has unbonded 1053 * 1054 * Outcome: 1055 * - The device is removed from the list. 1056 */ 1057 @Test testReceiveDeviceUnbonded_deviceRemoved()1058 public void testReceiveDeviceUnbonded_deviceRemoved() { 1059 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SINGLE_DEVICE_LIST); 1060 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1061 sendBondStateChanged(device, BluetoothDevice.BOND_NONE); 1062 assertDeviceList(EMPTY_DEVICE_LIST); 1063 } 1064 1065 /** 1066 * Preconditions: 1067 * - The device manager is initialized, there are no devices in the list. 1068 * 1069 * Actions: 1070 * - A device has bonded and its UUID set claims it supports this profile. 1071 * 1072 * Outcome: 1073 * - The device is added to the list. 1074 * 1075 * NOTE: Car Service version of Mockito does not support mocking final classes and 1076 * BluetoothDevice is a final class. Unsuppress this when we can support it. 1077 */ 1078 @Test 1079 @Suppress testReceiveSupportedDeviceBonded_deviceAdded()1080 public void testReceiveSupportedDeviceBonded_deviceAdded() { 1081 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 1082 BluetoothDevice device = mock(BluetoothDevice.class); 1083 doReturn(SINGLE_DEVICE_LIST.get(0)).when(device).getAddress(); 1084 doReturn(mUuids).when(device).getUuids(); 1085 sendBondStateChanged(device, BluetoothDevice.BOND_BONDED); 1086 assertDeviceList(SINGLE_DEVICE_LIST); 1087 } 1088 1089 /** 1090 * Preconditions: 1091 * - The device manager is initialized, there are no devices in the list. 1092 * 1093 * Actions: 1094 * - A device has bonded and its UUID set claims it does not support this profile. 1095 * 1096 * Outcome: 1097 * - The device is ignored. 1098 */ 1099 @Test testReceiveUnsupportedDeviceBonded_deviceNotAdded()1100 public void testReceiveUnsupportedDeviceBonded_deviceNotAdded() { 1101 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 1102 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1103 sendBondStateChanged(device, BluetoothDevice.BOND_BONDED); 1104 assertDeviceList(EMPTY_DEVICE_LIST); 1105 } 1106 1107 //--------------------------------------------------------------------------------------------// 1108 // Bluetooth stack device UUID event tests // 1109 //--------------------------------------------------------------------------------------------// 1110 1111 /** 1112 * Preconditions: 1113 * - The device manager is initialized, there are no devices in the list. 1114 * 1115 * Actions: 1116 * - A Uuid set is received for a device that has PRIORITY_AUTO_CONNECT 1117 * 1118 * Outcome: 1119 * - The device is ignored, no priority update is made. 1120 */ 1121 @Test testReceiveUuidDevicePriorityAutoConnect_doNothing()1122 public void testReceiveUuidDevicePriorityAutoConnect_doNothing() throws Exception { 1123 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 1124 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1125 mockDevicePriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT); 1126 sendDeviceUuids(device, mUuids); 1127 assertDeviceList(EMPTY_DEVICE_LIST); 1128 verify(mMockProxies, times(0)).setProfilePriority(eq(mProfileId), 1129 any(BluetoothDevice.class), anyInt()); 1130 } 1131 1132 /** 1133 * Preconditions: 1134 * - The device manager is initialized, there are no devices in the list. 1135 * 1136 * Actions: 1137 * - A Uuid set is received for a device that has PRIORITY_ON 1138 * 1139 * Outcome: 1140 * - The device is ignored, no priority update is made. 1141 */ 1142 @Test testReceiveUuidDevicePriorityOn_doNothing()1143 public void testReceiveUuidDevicePriorityOn_doNothing() throws Exception { 1144 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 1145 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1146 mockDevicePriority(device, BluetoothProfile.PRIORITY_ON); 1147 sendDeviceUuids(device, mUuids); 1148 assertDeviceList(EMPTY_DEVICE_LIST); 1149 verify(mMockProxies, times(0)).setProfilePriority(eq(mProfileId), 1150 any(BluetoothDevice.class), anyInt()); 1151 } 1152 1153 /** 1154 * Preconditions: 1155 * - The device manager is initialized, there are no devices in the list. 1156 * 1157 * Actions: 1158 * - A Uuid set is received for a device that has PRIORITY_OFF 1159 * 1160 * Outcome: 1161 * - The device is ignored, no priority update is made. 1162 */ 1163 @Test testReceiveUuidDevicePriorityOff_doNothing()1164 public void testReceiveUuidDevicePriorityOff_doNothing() throws Exception { 1165 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 1166 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1167 mockDevicePriority(device, BluetoothProfile.PRIORITY_OFF); 1168 sendDeviceUuids(device, mUuids); 1169 assertDeviceList(EMPTY_DEVICE_LIST); 1170 verify(mMockProxies, times(0)).setProfilePriority(eq(mProfileId), 1171 any(BluetoothDevice.class), anyInt()); 1172 } 1173 1174 /** 1175 * Preconditions: 1176 * - The device manager is initialized, there are no devices in the list. 1177 * 1178 * Actions: 1179 * - A Bonding state change with state == BOND_BONDING is received 1180 * - A Uuid set is received for a device that has PRIORITY_UNDEFINED 1181 * 1182 * Outcome: 1183 * - The device has its priority updated to PRIORITY_ON. 1184 */ 1185 @Test testReceiveUuidDevicePriorityUndefinedBonding_setPriorityOn()1186 public void testReceiveUuidDevicePriorityUndefinedBonding_setPriorityOn() throws Exception { 1187 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 1188 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1189 mockDevicePriority(device, BluetoothProfile.PRIORITY_UNDEFINED); 1190 sendBondStateChanged(device, BluetoothDevice.BOND_BONDING); 1191 sendDeviceUuids(device, mUuids); 1192 assertDeviceList(EMPTY_DEVICE_LIST); 1193 verify(mMockProxies, times(1)).setProfilePriority(mProfileId, device, 1194 BluetoothProfile.PRIORITY_ON); 1195 } 1196 1197 /** 1198 * Preconditions: 1199 * - The device manager is initialized, there are no devices in the list. 1200 * - The designated device is not in a bonding state. 1201 * 1202 * Actions: 1203 * - A Uuid set is received for a device that has PRIORITY_UNDEFINED 1204 * 1205 * Outcome: 1206 * - The device has its priority updated to PRIORITY_ON. 1207 */ 1208 @Test testReceiveUuidDevicePriorityUndefined_setPriorityOn()1209 public void testReceiveUuidDevicePriorityUndefined_setPriorityOn() throws Exception { 1210 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 1211 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1212 mockDevicePriority(device, BluetoothProfile.PRIORITY_UNDEFINED); 1213 sendDeviceUuids(device, mUuids); 1214 assertDeviceList(EMPTY_DEVICE_LIST); 1215 verify(mMockProxies, times(0)).setProfilePriority(mProfileId, device, 1216 BluetoothProfile.PRIORITY_ON); 1217 } 1218 1219 /** 1220 * Preconditions: 1221 * - The device manager is initialized, there are no devices in the list. 1222 * 1223 * Actions: 1224 * - A Uuid set is received for a device that is not supported for this profile 1225 * 1226 * Outcome: 1227 * - The device is ignored, no priority update is made. 1228 */ 1229 @Test testReceiveUuidsDeviceUnsupported_doNothing()1230 public void testReceiveUuidsDeviceUnsupported_doNothing() throws Exception { 1231 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, EMPTY_DEVICE_LIST); 1232 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SINGLE_DEVICE_LIST.get(0)); 1233 mockDevicePriority(device, BluetoothProfile.PRIORITY_UNDEFINED); 1234 sendDeviceUuids(device, mBadUuids); 1235 assertDeviceList(EMPTY_DEVICE_LIST); 1236 verify(mMockProxies, times(0)).getProfilePriority(eq(mProfileId), 1237 any(BluetoothDevice.class)); 1238 } 1239 1240 //--------------------------------------------------------------------------------------------// 1241 // Bluetooth stack adapter status changed event tests // 1242 //--------------------------------------------------------------------------------------------// 1243 1244 /** 1245 * Preconditions: 1246 * - The device manager is initialized, there are several devices in the list. The adapter is on 1247 * and we are currently connecting devices. 1248 * 1249 * Actions: 1250 * - The adapter is turning off 1251 * 1252 * Outcome: 1253 * - Auto-connecting is cancelled 1254 */ 1255 @Test testReceiveAdapterTurningOff_cancel()1256 public void testReceiveAdapterTurningOff_cancel() { 1257 setPreconditionsAndStart(ADAPTER_STATE_ON, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 1258 mProfileDeviceManager.beginAutoConnecting(); 1259 Assert.assertTrue(mProfileDeviceManager.isAutoConnecting()); 1260 // We have 24 seconds of auto connecting time while we force it to quit 1261 sendAdapterStateChanged(BluetoothAdapter.STATE_TURNING_OFF); 1262 Assert.assertFalse(mProfileDeviceManager.isAutoConnecting()); 1263 } 1264 1265 /** 1266 * Preconditions: 1267 * - The device manager is initialized, there are several devices in the list. The adapter is on 1268 * and we are currently connecting devices. 1269 * 1270 * Actions: 1271 * - The adapter becomes off 1272 * 1273 * Outcome: 1274 * - Auto-connecting is cancelled. The device list is committed 1275 */ 1276 @Test testReceiveAdapterOff_cancelAndCommit()1277 public void testReceiveAdapterOff_cancelAndCommit() { 1278 setPreconditionsAndStart(ADAPTER_STATE_ON, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 1279 mProfileDeviceManager.beginAutoConnecting(); 1280 Assert.assertTrue(mProfileDeviceManager.isAutoConnecting()); 1281 // We have 24 seconds of auto connecting time while we force it to quit 1282 sendAdapterStateChanged(BluetoothAdapter.STATE_OFF); 1283 Assert.assertFalse(mProfileDeviceManager.isAutoConnecting()); 1284 assertSettingsContains(SMALL_SETTINGS_STRING); 1285 } 1286 1287 /** 1288 * Preconditions: 1289 * - The device manager is initialized, there are several devices in the list. The adapter is on 1290 * and we are currently connecting devices. 1291 * 1292 * Actions: 1293 * - The adapter sends a turning on. (This can happen in weird cases in the stack where the 1294 * adapter is ON but the intent is sent away. Additionally, being ON and sending the intent is 1295 * a great way to make sure we called cancel) 1296 * 1297 * Outcome: 1298 * - Auto-connecting is cancelled 1299 */ 1300 @Test testReceiveAdapterTurningOn_cancel()1301 public void testReceiveAdapterTurningOn_cancel() { 1302 setPreconditionsAndStart(ADAPTER_STATE_ON, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 1303 mProfileDeviceManager.beginAutoConnecting(); 1304 Assert.assertTrue(mProfileDeviceManager.isAutoConnecting()); 1305 sendAdapterStateChanged(BluetoothAdapter.STATE_TURNING_ON); 1306 Assert.assertFalse(mProfileDeviceManager.isAutoConnecting()); 1307 } 1308 1309 /** 1310 * Preconditions: 1311 * - The device manager is initialized, there are several devices in the list. 1312 * 1313 * Actions: 1314 * - The adapter becomes on 1315 * 1316 * Outcome: 1317 * - No actions are taken 1318 */ 1319 @Test testReceiveAdapterOn_doNothing()1320 public void testReceiveAdapterOn_doNothing() { 1321 setPreconditionsAndStart(ADAPTER_STATE_ANY, EMPTY_SETTINGS_STRING, SMALL_DEVICE_LIST); 1322 sendAdapterStateChanged(BluetoothAdapter.STATE_ON); 1323 verifyNoMoreInteractions(mMockProxies); 1324 } 1325 } 1326