CachedBluetoothDeviceTest.java revision f050932e2a7a35f9d64a77fcdaff475bdab8f749
1/* 2 * Copyright (C) 2017 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 */ 16package com.android.settingslib.bluetooth; 17 18import static com.google.common.truth.Truth.assertThat; 19import static org.mockito.Matchers.any; 20import static org.mockito.Matchers.anyString; 21import static org.mockito.Mockito.doAnswer; 22import static org.mockito.Mockito.never; 23import static org.mockito.Mockito.spy; 24import static org.mockito.Mockito.verify; 25import static org.mockito.Mockito.when; 26import static org.robolectric.Shadows.shadowOf; 27 28import android.bluetooth.BluetoothAdapter; 29import android.bluetooth.BluetoothDevice; 30import android.bluetooth.BluetoothProfile; 31import android.content.Context; 32import android.media.AudioManager; 33 34import com.android.settingslib.SettingsLibRobolectricTestRunner; 35 36import org.junit.Before; 37import org.junit.Test; 38import org.junit.runner.RunWith; 39import org.mockito.Mock; 40import org.mockito.MockitoAnnotations; 41import org.robolectric.RuntimeEnvironment; 42import org.robolectric.shadows.ShadowAudioManager; 43 44@RunWith(SettingsLibRobolectricTestRunner.class) 45public class CachedBluetoothDeviceTest { 46 private final static String DEVICE_NAME = "TestName"; 47 private final static String DEVICE_ALIAS = "TestAlias"; 48 private final static String DEVICE_ADDRESS = "AA:BB:CC:DD:EE:FF"; 49 private final static String DEVICE_ALIAS_NEW = "TestAliasNew"; 50 @Mock 51 private LocalBluetoothAdapter mAdapter; 52 @Mock 53 private LocalBluetoothProfileManager mProfileManager; 54 @Mock 55 private HeadsetProfile mHfpProfile; 56 @Mock 57 private A2dpProfile mA2dpProfile; 58 @Mock 59 private PanProfile mPanProfile; 60 @Mock 61 private HearingAidProfile mHearingAidProfile; 62 @Mock 63 private BluetoothDevice mDevice; 64 private CachedBluetoothDevice mCachedDevice; 65 private ShadowAudioManager mShadowAudioManager; 66 private Context mContext; 67 private int mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 68 69 @Before 70 public void setUp() { 71 MockitoAnnotations.initMocks(this); 72 mContext = RuntimeEnvironment.application; 73 mShadowAudioManager = shadowOf(mContext.getSystemService(AudioManager.class)); 74 when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS); 75 when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON); 76 when(mHfpProfile.isProfileReady()).thenReturn(true); 77 when(mA2dpProfile.isProfileReady()).thenReturn(true); 78 when(mPanProfile.isProfileReady()).thenReturn(true); 79 when(mHearingAidProfile.isProfileReady()).thenReturn(true); 80 mCachedDevice = spy( 81 new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice)); 82 doAnswer((invocation) -> mBatteryLevel).when(mCachedDevice).getBatteryLevel(); 83 } 84 85 @Test 86 public void testGetConnectionSummary_testSingleProfileConnectDisconnect() { 87 // Test without battery level 88 // Set PAN profile to be connected and test connection state summary 89 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED); 90 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 91 92 // Set PAN profile to be disconnected and test connection state summary 93 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); 94 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 95 96 // Test with battery level 97 mBatteryLevel = 10; 98 // Set PAN profile to be connected and test connection state summary 99 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED); 100 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery"); 101 102 // Set PAN profile to be disconnected and test connection state summary 103 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); 104 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 105 106 // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level 107 mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 108 109 // Set PAN profile to be connected and test connection state summary 110 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED); 111 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 112 113 // Set PAN profile to be disconnected and test connection state summary 114 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); 115 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 116 } 117 118 @Test 119 public void testGetConnectionSummary_testMultipleProfileConnectDisconnect() { 120 mBatteryLevel = 10; 121 122 // Set HFP, A2DP and PAN profile to be connected and test connection state summary 123 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); 124 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); 125 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED); 126 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery"); 127 128 // Disconnect HFP only and test connection state summary 129 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); 130 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( 131 "10% battery"); 132 133 // Disconnect A2DP only and test connection state summary 134 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); 135 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); 136 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( 137 "10% battery"); 138 139 // Disconnect both HFP and A2DP and test connection state summary 140 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); 141 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( 142 "10% battery"); 143 144 // Disconnect all profiles and test connection state summary 145 mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED); 146 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 147 } 148 149 @Test 150 public void testGetConnectionSummary_testSingleProfileActiveDeviceA2dp() { 151 // Test without battery level 152 // Set A2DP profile to be connected and test connection state summary 153 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); 154 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 155 156 // Set device as Active for A2DP and test connection state summary 157 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); 158 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); 159 160 // Test with battery level 161 mBatteryLevel = 10; 162 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( 163 "Active, 10% battery"); 164 165 // Set A2DP profile to be disconnected and test connection state summary 166 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); 167 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 168 169 // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level 170 mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 171 // Set A2DP profile to be connected, Active and test connection state summary 172 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); 173 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); 174 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); 175 176 // Set A2DP profile to be disconnected and test connection state summary 177 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); 178 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 179 } 180 181 @Test 182 public void testGetConnectionSummary_testSingleProfileActiveDeviceHfp() { 183 // Test without battery level 184 // Set HFP profile to be connected and test connection state summary 185 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); 186 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 187 188 // Set device as Active for HFP and test connection state summary 189 mCachedDevice.onAudioModeChanged(); 190 mShadowAudioManager.setMode(AudioManager.MODE_IN_CALL); 191 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); 192 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); 193 194 // Test with battery level 195 mBatteryLevel = 10; 196 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( 197 "Active, 10% battery"); 198 199 // Set HFP profile to be disconnected and test connection state summary 200 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); 201 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 202 203 // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level 204 mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 205 // Set HFP profile to be connected, Active and test connection state summary 206 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); 207 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); 208 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); 209 210 // Set HFP profile to be disconnected and test connection state summary 211 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); 212 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 213 } 214 215 @Test 216 public void testGetConnectionSummary_testSingleProfileActiveDeviceHearingAid() { 217 // Test without battery level 218 // Set Hearing Aid profile to be connected and test connection state summary 219 mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); 220 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 221 222 // Set device as Active for Hearing Aid and test connection state summary 223 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID); 224 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); 225 226 // Set Hearing Aid profile to be disconnected and test connection state summary 227 mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEARING_AID); 228 mCachedDevice. 229 onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED); 230 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 231 } 232 233 @Test 234 public void testGetConnectionSummary_testMultipleProfilesActiveDevice() { 235 // Test without battery level 236 // Set A2DP and HFP profiles to be connected and test connection state summary 237 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); 238 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); 239 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 240 241 // Set device as Active for A2DP and HFP and test connection state summary 242 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); 243 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); 244 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); 245 246 // Test with battery level 247 mBatteryLevel = 10; 248 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( 249 "Active, 10% battery"); 250 251 // Disconnect A2DP only and test connection state summary 252 mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP); 253 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); 254 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( 255 "10% battery"); 256 257 // Disconnect HFP only and test connection state summary 258 mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET); 259 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); 260 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); 261 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); 262 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( 263 "Active, 10% battery"); 264 265 // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level 266 mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 267 // Set A2DP and HFP profiles to be connected, Active and test connection state summary 268 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); 269 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); 270 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP); 271 mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET); 272 assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active"); 273 274 // Set A2DP and HFP profiles to be disconnected and test connection state summary 275 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); 276 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); 277 assertThat(mCachedDevice.getConnectionSummary()).isNull(); 278 } 279 280 @Test 281 public void testDeviceName_testAliasNameAvailable() { 282 when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS); 283 when(mDevice.getName()).thenReturn(DEVICE_NAME); 284 CachedBluetoothDevice cachedBluetoothDevice = 285 new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice); 286 // Verify alias is returned on getName 287 assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ALIAS); 288 // Verify device is visible 289 assertThat(cachedBluetoothDevice.hasHumanReadableName()).isTrue(); 290 } 291 292 @Test 293 public void testDeviceName_testNameNotAvailable() { 294 CachedBluetoothDevice cachedBluetoothDevice = 295 new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice); 296 // Verify device address is returned on getName 297 assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ADDRESS); 298 // Verify device is not visible 299 assertThat(cachedBluetoothDevice.hasHumanReadableName()).isFalse(); 300 } 301 302 @Test 303 public void testDeviceName_testRenameDevice() { 304 final String[] alias = {DEVICE_ALIAS}; 305 doAnswer(invocation -> alias[0]).when(mDevice).getAliasName(); 306 doAnswer(invocation -> { 307 alias[0] = (String) invocation.getArguments()[0]; 308 return true; 309 }).when(mDevice).setAlias(anyString()); 310 when(mDevice.getName()).thenReturn(DEVICE_NAME); 311 CachedBluetoothDevice cachedBluetoothDevice = 312 new CachedBluetoothDevice(mContext, mAdapter, mProfileManager, mDevice); 313 // Verify alias is returned on getName 314 assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ALIAS); 315 // Verify null name does not get set 316 cachedBluetoothDevice.setName(null); 317 verify(mDevice, never()).setAlias(any()); 318 // Verify new name is set properly 319 cachedBluetoothDevice.setName(DEVICE_ALIAS_NEW); 320 verify(mDevice).setAlias(DEVICE_ALIAS_NEW); 321 // Verify new alias is returned on getName 322 assertThat(cachedBluetoothDevice.getName()).isEqualTo(DEVICE_ALIAS_NEW); 323 } 324 325 @Test 326 public void testSetActive() { 327 when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); 328 when(mProfileManager.getHeadsetProfile()).thenReturn(mHfpProfile); 329 when(mA2dpProfile.setActiveDevice(any(BluetoothDevice.class))).thenReturn(true); 330 when(mHfpProfile.setActiveDevice(any(BluetoothDevice.class))).thenReturn(true); 331 332 assertThat(mCachedDevice.setActive()).isFalse(); 333 334 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED); 335 assertThat(mCachedDevice.setActive()).isTrue(); 336 337 mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED); 338 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED); 339 assertThat(mCachedDevice.setActive()).isTrue(); 340 341 mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED); 342 assertThat(mCachedDevice.setActive()).isFalse(); 343 } 344 345 @Test 346 public void testIsA2dpDevice_isA2dpDevice() { 347 when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); 348 when(mA2dpProfile.getConnectionStatus(mDevice)). 349 thenReturn(BluetoothProfile.STATE_CONNECTED); 350 351 assertThat(mCachedDevice.isA2dpDevice()).isTrue(); 352 } 353 354 @Test 355 public void testIsA2dpDevice_isNotA2dpDevice() { 356 when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); 357 when(mA2dpProfile.getConnectionStatus(mDevice)). 358 thenReturn(BluetoothProfile.STATE_DISCONNECTING); 359 360 assertThat(mCachedDevice.isA2dpDevice()).isFalse(); 361 } 362 363 @Test 364 public void testIsHfpDevice_isHfpDevice() { 365 when(mProfileManager.getHeadsetProfile()).thenReturn(mHfpProfile); 366 when(mHfpProfile.getConnectionStatus(mDevice)). 367 thenReturn(BluetoothProfile.STATE_CONNECTED); 368 369 assertThat(mCachedDevice.isHfpDevice()).isTrue(); 370 } 371 372 @Test 373 public void testIsHfpDevice_isNotHfpDevice() { 374 when(mProfileManager.getHeadsetProfile()).thenReturn(mHfpProfile); 375 when(mHfpProfile.getConnectionStatus(mDevice)). 376 thenReturn(BluetoothProfile.STATE_DISCONNECTING); 377 378 assertThat(mCachedDevice.isHfpDevice()).isFalse(); 379 } 380} 381