1 /* 2 * Copyright (C) 2021 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.settings.qc; 18 19 import static android.os.UserManager.DISALLOW_BLUETOOTH; 20 21 import static com.android.car.qc.QCItem.QC_ACTION_TOGGLE_STATE; 22 import static com.android.car.settings.qc.PairedBluetoothDevices.BLUETOOTH_BUTTON; 23 import static com.android.car.settings.qc.PairedBluetoothDevices.EXTRA_BUTTON_TYPE; 24 import static com.android.car.settings.qc.PairedBluetoothDevices.EXTRA_DEVICE_KEY; 25 import static com.android.car.settings.qc.PairedBluetoothDevices.MEDIA_BUTTON; 26 import static com.android.car.settings.qc.PairedBluetoothDevices.PHONE_BUTTON; 27 28 import static com.google.common.truth.Truth.assertThat; 29 30 import static org.mockito.ArgumentMatchers.any; 31 import static org.mockito.ArgumentMatchers.anyBoolean; 32 import static org.mockito.ArgumentMatchers.eq; 33 import static org.mockito.Mockito.mock; 34 import static org.mockito.Mockito.verify; 35 import static org.mockito.Mockito.when; 36 37 import android.bluetooth.BluetoothAdapter; 38 import android.bluetooth.BluetoothClass; 39 import android.bluetooth.BluetoothDevice; 40 import android.bluetooth.BluetoothProfile; 41 import android.content.Intent; 42 import android.os.UserManager; 43 44 import androidx.test.ext.junit.runners.AndroidJUnit4; 45 46 import com.android.car.qc.QCActionItem; 47 import com.android.car.qc.QCItem; 48 import com.android.car.qc.QCList; 49 import com.android.car.qc.QCRow; 50 import com.android.car.settings.R; 51 import com.android.dx.mockito.inline.extended.ExtendedMockito; 52 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 53 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; 54 import com.android.settingslib.bluetooth.LocalBluetoothAdapter; 55 import com.android.settingslib.bluetooth.LocalBluetoothManager; 56 import com.android.settingslib.bluetooth.LocalBluetoothProfile; 57 58 import org.junit.After; 59 import org.junit.Before; 60 import org.junit.Test; 61 import org.junit.runner.RunWith; 62 import org.mockito.Mock; 63 import org.mockito.MockitoAnnotations; 64 import org.mockito.MockitoSession; 65 import org.mockito.quality.Strictness; 66 67 import java.util.ArrayList; 68 import java.util.Arrays; 69 import java.util.HashSet; 70 import java.util.Set; 71 72 @RunWith(AndroidJUnit4.class) 73 public class PairedBluetoothDevicesTest extends BaseSettingsQCItemTestCase { 74 private static final String DEFAULT_NAME = "DEFAULT_NAME"; 75 private static final String DEFAULT_SUMMARY = "DEFAULT_SUMMARY"; 76 private static final String DEFAULT_ADDRESS = "F6:8F:AC:E8:32:50"; 77 78 private PairedBluetoothDevices mPairedBluetoothDevices; 79 private MockitoSession mSession; 80 private ArrayList<CachedBluetoothDevice> mCachedDevices = new ArrayList<>(); 81 private Set<BluetoothDevice> mBondedDevices = new HashSet<>(); 82 83 @Mock 84 private BluetoothAdapter mBluetoothAdapter; 85 @Mock 86 private LocalBluetoothAdapter mLocalBluetoothAdapter; 87 @Mock 88 private LocalBluetoothManager mBluetoothManager; 89 90 @Before setUp()91 public void setUp() { 92 MockitoAnnotations.initMocks(this); 93 mSession = ExtendedMockito.mockitoSession() 94 .strictness(Strictness.LENIENT) 95 .mockStatic(BluetoothAdapter.class) 96 .mockStatic(LocalBluetoothManager.class) 97 .startMocking(); 98 when(BluetoothAdapter.getDefaultAdapter()).thenReturn(mBluetoothAdapter); 99 when(mBluetoothAdapter.isEnabled()).thenReturn(true); 100 when(LocalBluetoothManager.getInstance(any(), any())).thenReturn(mBluetoothManager); 101 when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mLocalBluetoothAdapter); 102 when(mLocalBluetoothAdapter.getBondedDevices()).thenReturn(mBondedDevices); 103 104 CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class); 105 when(mBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager); 106 when(deviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices); 107 108 mPairedBluetoothDevices = new PairedBluetoothDevices(mContext); 109 } 110 111 @After tearDown()112 public void tearDown() { 113 if (mSession != null) { 114 mSession.finishMocking(); 115 } 116 } 117 118 @Test getQCItem_bluetoothDisallowed_returnsNull()119 public void getQCItem_bluetoothDisallowed_returnsNull() { 120 setUserRestriction(DISALLOW_BLUETOOTH, true); 121 QCItem item = mPairedBluetoothDevices.getQCItem(); 122 assertThat(item).isNull(); 123 } 124 125 @Test getQCItem_bluetoothDisabled_returnsBluetoothDisabledMessage()126 public void getQCItem_bluetoothDisabled_returnsBluetoothDisabledMessage() { 127 when(mBluetoothAdapter.isEnabled()).thenReturn(false); 128 QCItem item = mPairedBluetoothDevices.getQCItem(); 129 assertThat(item).isNotNull(); 130 QCList list = (QCList) item; 131 assertThat(list.getRows().size()).isEqualTo(1); 132 QCRow row = list.getRows().get(0); 133 assertThat(row.getTitle()).isEqualTo( 134 mContext.getString(R.string.qc_bluetooth_off_devices_info)); 135 assertThat(row.getStartIcon()).isNotNull(); 136 } 137 138 @Test getQCItem_noDevices_returnsPairMessage()139 public void getQCItem_noDevices_returnsPairMessage() { 140 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 141 assertThat(list.getRows().size()).isEqualTo(1); 142 QCRow row = list.getRows().get(0); 143 assertThat(row.getTitle()).isEqualTo( 144 mContext.getString(R.string.qc_bluetooth_on_no_devices_info)); 145 assertThat(row.getStartIcon()).isNotNull(); 146 } 147 148 @Test getQCItem_hasDevices_hasRows()149 public void getQCItem_hasDevices_hasRows() { 150 addBluetoothDevice("Device1", /* connected= */ true, /* busy= */ false, 151 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 152 /* hasHumanReadableName= */ true); 153 addBluetoothDevice("Device2", /* connected= */ true, /* busy= */ false, 154 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 155 /* hasHumanReadableName= */ true); 156 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 157 assertThat(list.getRows().size()).isEqualTo(2); 158 } 159 160 @Test getQCItem_hasDevices_onlyDisplaysHumanReadableNames()161 public void getQCItem_hasDevices_onlyDisplaysHumanReadableNames() { 162 addBluetoothDevice("Device1", /* connected= */ true, /* busy= */ false, 163 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 164 /* hasHumanReadableName= */ true); 165 addBluetoothDevice("Device2", /* connected= */ true, /* busy= */ false, 166 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 167 /* hasHumanReadableName= */ false); 168 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 169 assertThat(list.getRows().size()).isEqualTo(1); 170 } 171 172 @Test getQCItem_limitsDeviceCount()173 public void getQCItem_limitsDeviceCount() { 174 addBluetoothDevice("Device1", /* connected= */ true, /* busy= */ false, 175 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 176 /* hasHumanReadableName= */ true); 177 addBluetoothDevice("Device2", /* connected= */ false, /* busy= */ false, 178 /* phoneEnabled= */ false, /* mediaEnabled= */ false, 179 /* hasHumanReadableName= */ true); 180 addBluetoothDevice("Device3", /* connected= */ false, /* busy= */ false, 181 /* phoneEnabled= */ false, /* mediaEnabled= */ false, 182 /* hasHumanReadableName= */ true); 183 addBluetoothDevice("Device4", /* connected= */ false, /* busy= */ false, 184 /* phoneEnabled= */ false, /* mediaEnabled= */ false, 185 /* hasHumanReadableName= */ true); 186 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 187 assertThat(list.getRows().size()).isEqualTo(3); 188 } 189 190 @Test getQCItem_setsTitle()191 public void getQCItem_setsTitle() { 192 addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false, 193 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 194 /* hasHumanReadableName= */ true); 195 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 196 QCRow row = list.getRows().get(0); 197 assertThat(row.getTitle()).isEqualTo(DEFAULT_NAME); 198 } 199 200 @Test getQCItem_bluetoothDisabled_togglesUpdated()201 public void getQCItem_bluetoothDisabled_togglesUpdated() { 202 addBluetoothDevice(DEFAULT_NAME, /* connected= */ false, /* busy= */ false, 203 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 204 /* hasHumanReadableName= */ true); 205 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 206 QCRow row = list.getRows().get(0); 207 QCActionItem btToggle = row.getEndItems().get(0); 208 QCActionItem phoneToggle = row.getEndItems().get(1); 209 QCActionItem mediaToggle = row.getEndItems().get(2); 210 assertThat(btToggle.isChecked()).isFalse(); 211 assertThat(btToggle.isEnabled()).isTrue(); 212 assertThat(phoneToggle.isAvailable()).isFalse(); 213 assertThat(mediaToggle.isAvailable()).isFalse(); 214 } 215 216 @Test getQCItem_bluetoothEnabled_togglesUpdated()217 public void getQCItem_bluetoothEnabled_togglesUpdated() { 218 addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false, 219 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 220 /* hasHumanReadableName= */ true); 221 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 222 QCRow row = list.getRows().get(0); 223 QCActionItem btToggle = row.getEndItems().get(0); 224 QCActionItem phoneToggle = row.getEndItems().get(1); 225 QCActionItem mediaToggle = row.getEndItems().get(2); 226 assertThat(btToggle.isChecked()).isTrue(); 227 assertThat(btToggle.isEnabled()).isTrue(); 228 assertThat(phoneToggle.isChecked()).isTrue(); 229 assertThat(phoneToggle.isEnabled()).isTrue(); 230 assertThat(phoneToggle.isAvailable()).isTrue(); 231 assertThat(mediaToggle.isChecked()).isTrue(); 232 assertThat(mediaToggle.isEnabled()).isTrue(); 233 assertThat(mediaToggle.isAvailable()).isTrue(); 234 } 235 236 @Test getQCItem_isBusy_togglesDisabled()237 public void getQCItem_isBusy_togglesDisabled() { 238 addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ true, 239 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 240 /* hasHumanReadableName= */ true); 241 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 242 QCRow row = list.getRows().get(0); 243 QCActionItem btToggle = row.getEndItems().get(0); 244 QCActionItem phoneToggle = row.getEndItems().get(1); 245 QCActionItem mediaToggle = row.getEndItems().get(2); 246 assertThat(btToggle.isEnabled()).isFalse(); 247 assertThat(phoneToggle.isEnabled()).isFalse(); 248 assertThat(mediaToggle.isEnabled()).isFalse(); 249 } 250 251 @Test getQCItem_hasBaseUmRestriction_togglesDisabled()252 public void getQCItem_hasBaseUmRestriction_togglesDisabled() { 253 addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false, 254 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 255 /* hasHumanReadableName= */ true); 256 setBaseUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, /* restricted= */ true); 257 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 258 QCRow row = list.getRows().get(0); 259 QCActionItem btToggle = row.getEndItems().get(0); 260 QCActionItem phoneToggle = row.getEndItems().get(1); 261 QCActionItem mediaToggle = row.getEndItems().get(2); 262 assertThat(btToggle.isEnabled()).isTrue(); 263 assertThat(phoneToggle.isEnabled()).isFalse(); 264 assertThat(phoneToggle.isClickableWhileDisabled()).isFalse(); 265 assertThat(mediaToggle.isEnabled()).isFalse(); 266 assertThat(mediaToggle.isClickableWhileDisabled()).isFalse(); 267 } 268 269 @Test getQCItem_hasUmRestriction_togglesClickableWhileDisabled()270 public void getQCItem_hasUmRestriction_togglesClickableWhileDisabled() { 271 addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false, 272 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 273 /* hasHumanReadableName= */ true); 274 setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, /* restricted= */ true); 275 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 276 QCRow row = list.getRows().get(0); 277 QCActionItem btToggle = row.getEndItems().get(0); 278 QCActionItem phoneToggle = row.getEndItems().get(1); 279 QCActionItem mediaToggle = row.getEndItems().get(2); 280 assertThat(btToggle.isEnabled()).isTrue(); 281 assertThat(phoneToggle.isEnabled()).isFalse(); 282 assertThat(phoneToggle.isClickableWhileDisabled()).isTrue(); 283 assertThat(mediaToggle.isEnabled()).isFalse(); 284 assertThat(mediaToggle.isClickableWhileDisabled()).isTrue(); 285 } 286 287 @Test onNotifyChange_toggleBluetooth()288 public void onNotifyChange_toggleBluetooth() { 289 addBluetoothDevice(DEFAULT_NAME, /* connected= */ false, /* busy= */ true, 290 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 291 /* hasHumanReadableName= */ true); 292 Intent intent = new Intent(); 293 intent.putExtra(EXTRA_DEVICE_KEY, DEFAULT_ADDRESS); 294 intent.putExtra(EXTRA_BUTTON_TYPE, BLUETOOTH_BUTTON); 295 intent.putExtra(QC_ACTION_TOGGLE_STATE, true); 296 mPairedBluetoothDevices.onNotifyChange(intent); 297 CachedBluetoothDevice device = mCachedDevices.get(0); 298 verify(device).connect(); 299 } 300 301 @Test onNotifyChange_togglePhone()302 public void onNotifyChange_togglePhone() { 303 addBluetoothDevice(DEFAULT_NAME, /* connected= */ false, /* busy= */ true, 304 /* phoneEnabled= */ false, /* mediaEnabled= */ true, 305 /* hasHumanReadableName= */ true); 306 Intent intent = new Intent(); 307 intent.putExtra(EXTRA_DEVICE_KEY, DEFAULT_ADDRESS); 308 intent.putExtra(EXTRA_BUTTON_TYPE, PHONE_BUTTON); 309 intent.putExtra(QC_ACTION_TOGGLE_STATE, true); 310 mPairedBluetoothDevices.onNotifyChange(intent); 311 CachedBluetoothDevice device = mCachedDevices.get(0); 312 LocalBluetoothProfile profile = getProfile(device, BluetoothProfile.HEADSET_CLIENT); 313 verify(profile).setEnabled(any(), eq(true)); 314 } 315 316 @Test onNotifyChange_toggleMedia()317 public void onNotifyChange_toggleMedia() { 318 addBluetoothDevice(DEFAULT_NAME, /* connected= */ false, /* busy= */ true, 319 /* phoneEnabled= */ true, /* mediaEnabled= */ false, 320 /* hasHumanReadableName= */ true); 321 Intent intent = new Intent(); 322 intent.putExtra(EXTRA_DEVICE_KEY, DEFAULT_ADDRESS); 323 intent.putExtra(EXTRA_BUTTON_TYPE, MEDIA_BUTTON); 324 intent.putExtra(QC_ACTION_TOGGLE_STATE, true); 325 mPairedBluetoothDevices.onNotifyChange(intent); 326 CachedBluetoothDevice device = mCachedDevices.get(0); 327 LocalBluetoothProfile profile = getProfile(device, BluetoothProfile.A2DP_SINK); 328 verify(profile).setEnabled(any(), eq(true)); 329 } 330 331 @Test getQCItem_createsItem_bluetoothDisabled_zoneWrite()332 public void getQCItem_createsItem_bluetoothDisabled_zoneWrite() { 333 when(mBluetoothAdapter.isEnabled()).thenReturn(false); 334 mPairedBluetoothDevices.setAvailabilityStatusForZone("write"); 335 QCItem item = mPairedBluetoothDevices.getQCItem(); 336 assertThat(item).isNotNull(); 337 } 338 339 @Test getQCItem_createsItem_bluetoothDisabled_zoneRead()340 public void getQCItem_createsItem_bluetoothDisabled_zoneRead() { 341 when(mBluetoothAdapter.isEnabled()).thenReturn(false); 342 mPairedBluetoothDevices.setAvailabilityStatusForZone("read"); 343 QCItem item = mPairedBluetoothDevices.getQCItem(); 344 assertThat(item).isNotNull(); 345 } 346 347 @Test getQCItem_createsItem_bluetoothDisabled_zoneHidden()348 public void getQCItem_createsItem_bluetoothDisabled_zoneHidden() { 349 when(mBluetoothAdapter.isEnabled()).thenReturn(false); 350 mPairedBluetoothDevices.setAvailabilityStatusForZone("hidden"); 351 QCItem item = mPairedBluetoothDevices.getQCItem(); 352 assertThat(item).isNull(); 353 } 354 355 @Test getQCItem_createsItem_noDevices_zoneWrite()356 public void getQCItem_createsItem_noDevices_zoneWrite() { 357 mPairedBluetoothDevices.setAvailabilityStatusForZone("write"); 358 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 359 assertThat(list.getRows().size()).isEqualTo(1); 360 QCRow row = list.getRows().get(0); 361 assertThat(row.getStartIcon()).isNotNull(); 362 } 363 364 @Test getQCItem_createsItem_noDevices_zoneRead()365 public void getQCItem_createsItem_noDevices_zoneRead() { 366 mPairedBluetoothDevices.setAvailabilityStatusForZone("read"); 367 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 368 assertThat(list.getRows().size()).isEqualTo(1); 369 QCRow row = list.getRows().get(0); 370 assertThat(row.getStartIcon()).isNotNull(); 371 } 372 373 @Test getQCItem_createsItem_noDevices_zoneHidden()374 public void getQCItem_createsItem_noDevices_zoneHidden() { 375 mPairedBluetoothDevices.setAvailabilityStatusForZone("hidden"); 376 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 377 assertThat(list).isNull(); 378 } 379 380 @Test getQCItem_createsToggles_bluetoothEnabled_zoneWrite()381 public void getQCItem_createsToggles_bluetoothEnabled_zoneWrite() { 382 mPairedBluetoothDevices.setAvailabilityStatusForZone("write"); 383 addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false, 384 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 385 /* hasHumanReadableName= */ true); 386 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 387 QCRow row = list.getRows().get(0); 388 QCActionItem btToggle = row.getEndItems().get(0); 389 QCActionItem phoneToggle = row.getEndItems().get(1); 390 QCActionItem mediaToggle = row.getEndItems().get(2); 391 assertThat(btToggle.isEnabled()).isTrue(); 392 assertThat(phoneToggle.isEnabled()).isTrue(); 393 assertThat(mediaToggle.isEnabled()).isTrue(); 394 } 395 396 @Test getQCItem_createsToggles_bluetoothEnabled_zoneRead()397 public void getQCItem_createsToggles_bluetoothEnabled_zoneRead() { 398 mPairedBluetoothDevices.setAvailabilityStatusForZone("read"); 399 addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false, 400 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 401 /* hasHumanReadableName= */ true); 402 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 403 QCRow row = list.getRows().get(0); 404 QCActionItem btToggle = row.getEndItems().get(0); 405 QCActionItem phoneToggle = row.getEndItems().get(1); 406 QCActionItem mediaToggle = row.getEndItems().get(2); 407 assertThat(btToggle.isEnabled()).isFalse(); 408 assertThat(phoneToggle.isEnabled()).isFalse(); 409 assertThat(mediaToggle.isEnabled()).isFalse(); 410 assertThat(btToggle.isClickableWhileDisabled()).isTrue(); 411 assertThat(phoneToggle.isClickableWhileDisabled()).isTrue(); 412 assertThat(mediaToggle.isClickableWhileDisabled()).isTrue(); 413 } 414 415 @Test getQCItem_createsToggles_bluetoothEnabled_zoneHidden()416 public void getQCItem_createsToggles_bluetoothEnabled_zoneHidden() { 417 mPairedBluetoothDevices.setAvailabilityStatusForZone("hidden"); 418 addBluetoothDevice(DEFAULT_NAME, /* connected= */ true, /* busy= */ false, 419 /* phoneEnabled= */ true, /* mediaEnabled= */ true, 420 /* hasHumanReadableName= */ true); 421 QCList list = (QCList) mPairedBluetoothDevices.getQCItem(); 422 assertThat(list).isNull(); 423 } 424 addBluetoothDevice(String name, boolean connected, boolean busy, boolean phoneEnabled, boolean mediaEnabled, boolean hasHumanReadableName)425 private void addBluetoothDevice(String name, boolean connected, boolean busy, 426 boolean phoneEnabled, boolean mediaEnabled, boolean hasHumanReadableName) { 427 CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class); 428 BluetoothDevice device = mock(BluetoothDevice.class); 429 when(cachedDevice.getDevice()).thenReturn(device); 430 when(device.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); 431 when(cachedDevice.getName()).thenReturn(name); 432 when(cachedDevice.getAddress()).thenReturn(DEFAULT_ADDRESS); 433 when(cachedDevice.isConnected()).thenReturn(connected); 434 when(cachedDevice.isBusy()).thenReturn(busy); 435 when(cachedDevice.getCarConnectionSummary(anyBoolean())).thenReturn(DEFAULT_SUMMARY); 436 when(cachedDevice.hasHumanReadableName()).thenReturn(hasHumanReadableName); 437 BluetoothClass btClass = mock(BluetoothClass.class); 438 when(cachedDevice.getBtClass()).thenReturn(btClass); 439 when(btClass.getMajorDeviceClass()).thenReturn(BluetoothClass.Device.Major.PHONE); 440 LocalBluetoothProfile phoneProfile = mock(LocalBluetoothProfile.class); 441 LocalBluetoothProfile mediaProfile = mock(LocalBluetoothProfile.class); 442 when(phoneProfile.getProfileId()).thenReturn(BluetoothProfile.HEADSET_CLIENT); 443 when(mediaProfile.getProfileId()).thenReturn(BluetoothProfile.A2DP_SINK); 444 when(phoneProfile.isEnabled(any())).thenReturn(phoneEnabled); 445 when(mediaProfile.isEnabled(any())).thenReturn(mediaEnabled); 446 when(cachedDevice.getProfiles()).thenReturn(Arrays.asList(phoneProfile, mediaProfile)); 447 mCachedDevices.add(cachedDevice); 448 mBondedDevices.add(device); 449 } 450 getProfile(CachedBluetoothDevice device, int profileId)451 private LocalBluetoothProfile getProfile(CachedBluetoothDevice device, int profileId) { 452 for (LocalBluetoothProfile profile : device.getProfiles()) { 453 if (profile.getProfileId() == profileId) { 454 return profile; 455 } 456 } 457 return null; 458 } 459 } 460