1 package com.android.bluetooth.btservice; 2 3 import static android.Manifest.permission.BLUETOOTH_CONNECT; 4 import static org.mockito.Mockito.*; 5 6 import android.bluetooth.BluetoothAdapter; 7 import android.bluetooth.BluetoothAssignedNumbers; 8 import android.bluetooth.BluetoothDevice; 9 import android.bluetooth.BluetoothHeadset; 10 import android.bluetooth.BluetoothProfile; 11 import android.content.Intent; 12 import android.os.Bundle; 13 import android.os.HandlerThread; 14 import android.os.Message; 15 import android.os.TestLooperManager; 16 17 import androidx.test.InstrumentationRegistry; 18 import androidx.test.filters.MediumTest; 19 import androidx.test.runner.AndroidJUnit4; 20 21 import com.android.bluetooth.Utils; 22 import com.android.bluetooth.hfp.HeadsetHalConstants; 23 24 import org.junit.After; 25 import org.junit.Assert; 26 import org.junit.Before; 27 import org.junit.Test; 28 import org.junit.runner.RunWith; 29 import org.mockito.ArgumentCaptor; 30 import org.mockito.Mock; 31 import org.mockito.MockitoAnnotations; 32 33 import java.util.ArrayList; 34 35 @MediumTest 36 @RunWith(AndroidJUnit4.class) 37 public class RemoteDevicesTest { 38 private static final String TEST_BT_ADDR_1 = "00:11:22:33:44:55"; 39 40 private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class); 41 private ArgumentCaptor<String> mStringArgument = ArgumentCaptor.forClass(String.class); 42 private BluetoothDevice mDevice1; 43 private RemoteDevices mRemoteDevices; 44 private HandlerThread mHandlerThread; 45 private TestLooperManager mTestLooperManager; 46 47 @Mock private AdapterService mAdapterService; 48 49 @Before setUp()50 public void setUp() { 51 MockitoAnnotations.initMocks(this); 52 mDevice1 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR_1); 53 mHandlerThread = new HandlerThread("RemoteDevicesTestHandlerThread"); 54 mHandlerThread.start(); 55 mTestLooperManager = InstrumentationRegistry.getInstrumentation() 56 .acquireLooperManager(mHandlerThread.getLooper()); 57 mRemoteDevices = new RemoteDevices(mAdapterService, mHandlerThread.getLooper()); 58 } 59 60 @After tearDown()61 public void tearDown() { 62 mTestLooperManager.release(); 63 mHandlerThread.quit(); 64 } 65 66 @Test testSendUuidIntent()67 public void testSendUuidIntent() { 68 // Verify that a handler message is sent by the method call 69 mRemoteDevices.updateUuids(mDevice1); 70 Message msg = mTestLooperManager.next(); 71 Assert.assertNotNull(msg); 72 73 // Verify that executing that message results in a broadcast intent 74 mTestLooperManager.execute(msg); 75 verify(mAdapterService).sendBroadcast(any(), anyString(), any()); 76 verifyNoMoreInteractions(mAdapterService); 77 } 78 79 @Test testUpdateBatteryLevel_normalSequence()80 public void testUpdateBatteryLevel_normalSequence() { 81 int batteryLevel = 10; 82 83 // Verify that device property is null initially 84 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 85 86 // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent 87 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 88 verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), 89 any(Bundle.class)); 90 verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); 91 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 92 93 // Verify that user can get battery level after the update 94 Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); 95 Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), 96 batteryLevel); 97 98 // Verify that update same battery level for the same device does not trigger intent 99 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 100 verify(mAdapterService).sendBroadcast(any(), anyString(), any()); 101 102 // Verify that updating battery level to different value triggers the intent again 103 batteryLevel = 15; 104 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 105 verify(mAdapterService, times(2)).sendBroadcast(mIntentArgument.capture(), 106 mStringArgument.capture(), any(Bundle.class)); 107 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 108 verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); 109 110 // Verify that user can get battery level after the update 111 Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), 112 batteryLevel); 113 114 verifyNoMoreInteractions(mAdapterService); 115 } 116 117 @Test testUpdateBatteryLevel_errorNegativeValue()118 public void testUpdateBatteryLevel_errorNegativeValue() { 119 int batteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 120 121 // Verify that device property is null initially 122 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 123 124 // Verify that updating with invalid battery level does not trigger the intent 125 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 126 verify(mAdapterService, never()).sendBroadcast(any(), anyString(), any()); 127 128 // Verify that device property stays null after invalid update 129 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 130 131 verifyNoMoreInteractions(mAdapterService); 132 } 133 134 @Test testUpdateBatteryLevel_errorTooLargeValue()135 public void testUpdateBatteryLevel_errorTooLargeValue() { 136 int batteryLevel = 101; 137 138 // Verify that device property is null initially 139 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 140 141 // Verify that updating invalid battery level does not trigger the intent 142 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 143 verify(mAdapterService, never()).sendBroadcast(any(), anyString(), any()); 144 145 // Verify that device property stays null after invalid update 146 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 147 148 verifyNoMoreInteractions(mAdapterService); 149 } 150 151 @Test testResetBatteryLevel_testResetBeforeUpdate()152 public void testResetBatteryLevel_testResetBeforeUpdate() { 153 // Verify that device property is null initially 154 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 155 156 // Verify that resetting battery level keeps device property null 157 mRemoteDevices.resetBatteryLevel(mDevice1); 158 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 159 160 verifyNoMoreInteractions(mAdapterService); 161 } 162 163 @Test testResetBatteryLevel_testResetAfterUpdate()164 public void testResetBatteryLevel_testResetAfterUpdate() { 165 int batteryLevel = 10; 166 167 // Verify that device property is null initially 168 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 169 170 // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent 171 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 172 verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), 173 any(Bundle.class)); 174 verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); 175 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 176 177 // Verify that user can get battery level after the update 178 Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); 179 Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), 180 batteryLevel); 181 182 // Verify that resetting battery level changes it back to BluetoothDevice 183 // .BATTERY_LEVEL_UNKNOWN 184 mRemoteDevices.resetBatteryLevel(mDevice1); 185 // Verify BATTERY_LEVEL_CHANGED intent is sent after first reset 186 verify(mAdapterService, times(2)).sendBroadcast(mIntentArgument.capture(), 187 mStringArgument.capture(), any(Bundle.class)); 188 verifyBatteryLevelChangedIntent(mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 189 mIntentArgument); 190 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 191 // Verify value is reset in properties 192 Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); 193 Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), 194 BluetoothDevice.BATTERY_LEVEL_UNKNOWN); 195 196 // Verify no intent is sent after second reset 197 mRemoteDevices.resetBatteryLevel(mDevice1); 198 verify(mAdapterService, times(2)).sendBroadcast(any(), anyString(), 199 any()); 200 201 // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent again 202 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 203 verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(), 204 mStringArgument.capture(), any(Bundle.class)); 205 verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); 206 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 207 208 verifyNoMoreInteractions(mAdapterService); 209 } 210 211 @Test testResetBatteryLevelOnHeadsetStateChange()212 public void testResetBatteryLevelOnHeadsetStateChange() { 213 int batteryLevel = 10; 214 215 // Verify that device property is null initially 216 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 217 218 // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent 219 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 220 verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), 221 any(Bundle.class)); 222 verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); 223 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 224 225 // Verify that user can get battery level after the update 226 Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); 227 Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), 228 batteryLevel); 229 230 // Verify that resetting battery level changes it back to BluetoothDevice 231 // .BATTERY_LEVEL_UNKNOWN 232 mRemoteDevices.onHeadsetConnectionStateChanged( 233 getHeadsetConnectionStateChangedIntent(mDevice1, 234 BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_DISCONNECTED)); 235 // Verify BATTERY_LEVEL_CHANGED intent is sent after first reset 236 verify(mAdapterService, times(2)).sendBroadcast(mIntentArgument.capture(), 237 mStringArgument.capture(), any(Bundle.class)); 238 verifyBatteryLevelChangedIntent(mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 239 mIntentArgument); 240 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 241 // Verify value is reset in properties 242 Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); 243 Assert.assertEquals(mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel(), 244 BluetoothDevice.BATTERY_LEVEL_UNKNOWN); 245 246 // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent again 247 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 248 verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(), 249 mStringArgument.capture(), any(Bundle.class)); 250 verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); 251 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 252 253 verifyNoMoreInteractions(mAdapterService); 254 } 255 256 @Test testResetBatteryLevel_testAclStateChangeCallback()257 public void testResetBatteryLevel_testAclStateChangeCallback() { 258 int batteryLevel = 10; 259 260 // Verify that device property is null initially 261 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 262 263 // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent 264 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 265 verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), 266 any(Bundle.class)); 267 verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); 268 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 269 270 // Verify that user can get battery level after the update 271 Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); 272 Assert.assertEquals(batteryLevel, 273 mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); 274 275 // Verify that when device is completely disconnected, RemoteDevices reset battery level to 276 // BluetoothDevice.BATTERY_LEVEL_UNKNOWN 277 when(mAdapterService.getState()).thenReturn(BluetoothAdapter.STATE_ON); 278 mRemoteDevices.aclStateChangeCallback(0, Utils.getByteAddress(mDevice1), 279 AbstractionLayer.BT_ACL_STATE_DISCONNECTED, 19); // HCI code 19 remote terminated 280 // Verify ACTION_ACL_DISCONNECTED and BATTERY_LEVEL_CHANGED intent are sent 281 verify(mAdapterService, times(3)).sendBroadcast(mIntentArgument.capture(), 282 mStringArgument.capture(), any(Bundle.class)); 283 verify(mAdapterService, times(2)).obfuscateAddress(mDevice1); 284 verifyBatteryLevelChangedIntent(mDevice1, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 285 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); 286 Assert.assertEquals(BLUETOOTH_CONNECT, 287 mStringArgument.getAllValues().get(mStringArgument.getAllValues().size() - 2)); 288 Assert.assertEquals(BluetoothDevice.ACTION_ACL_DISCONNECTED, 289 mIntentArgument.getValue().getAction()); 290 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 291 // Verify value is reset in properties 292 Assert.assertNotNull(mRemoteDevices.getDeviceProperties(mDevice1)); 293 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 294 mRemoteDevices.getDeviceProperties(mDevice1).getBatteryLevel()); 295 296 // Verify that updating battery level triggers ACTION_BATTERY_LEVEL_CHANGED intent again 297 mRemoteDevices.updateBatteryLevel(mDevice1, batteryLevel); 298 verify(mAdapterService, times(4)).sendBroadcast(mIntentArgument.capture(), 299 mStringArgument.capture(), any(Bundle.class)); 300 verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); 301 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 302 } 303 304 @Test testHfIndicatorParser_testCorrectValue()305 public void testHfIndicatorParser_testCorrectValue() { 306 int batteryLevel = 10; 307 308 // Verify that device property is null initially 309 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 310 311 // Verify that ACTION_HF_INDICATORS_VALUE_CHANGED intent updates battery level 312 mRemoteDevices.onHfIndicatorValueChanged(getHfIndicatorIntent(mDevice1, batteryLevel, 313 HeadsetHalConstants.HF_INDICATOR_BATTERY_LEVEL_STATUS)); 314 verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), 315 any(Bundle.class)); 316 verifyBatteryLevelChangedIntent(mDevice1, batteryLevel, mIntentArgument); 317 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 318 } 319 320 @Test testHfIndicatorParser_testWrongIndicatorId()321 public void testHfIndicatorParser_testWrongIndicatorId() { 322 int batteryLevel = 10; 323 324 // Verify that device property is null initially 325 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 326 327 // Verify that ACTION_HF_INDICATORS_VALUE_CHANGED intent updates battery level 328 mRemoteDevices.onHfIndicatorValueChanged(getHfIndicatorIntent(mDevice1, batteryLevel, 3)); 329 verify(mAdapterService, never()).sendBroadcast(any(), anyString()); 330 // Verify that device property is still null after invalid update 331 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 332 } 333 334 @Test testOnVendorSpecificHeadsetEvent_testCorrectPlantronicsXEvent()335 public void testOnVendorSpecificHeadsetEvent_testCorrectPlantronicsXEvent() { 336 // Verify that device property is null initially 337 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 338 339 // Verify that correct ACTION_VENDOR_SPECIFIC_HEADSET_EVENT updates battery level 340 mRemoteDevices.onVendorSpecificHeadsetEvent(getVendorSpecificHeadsetEventIntent( 341 BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT, 342 BluetoothAssignedNumbers.PLANTRONICS, BluetoothHeadset.AT_CMD_TYPE_SET, 343 getXEventArray(3, 8), mDevice1)); 344 verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), 345 any(Bundle.class)); 346 verifyBatteryLevelChangedIntent(mDevice1, 42, mIntentArgument); 347 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 348 } 349 350 @Test testOnVendorSpecificHeadsetEvent_testCorrectAppleBatteryVsc()351 public void testOnVendorSpecificHeadsetEvent_testCorrectAppleBatteryVsc() { 352 // Verify that device property is null initially 353 Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1)); 354 355 // Verify that correct ACTION_VENDOR_SPECIFIC_HEADSET_EVENT updates battery level 356 mRemoteDevices.onVendorSpecificHeadsetEvent(getVendorSpecificHeadsetEventIntent( 357 BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV, 358 BluetoothAssignedNumbers.APPLE, BluetoothHeadset.AT_CMD_TYPE_SET, new Object[]{ 359 3, 360 BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 361 5, 362 2, 363 1, 364 3, 365 10 366 }, mDevice1)); 367 verify(mAdapterService).sendBroadcast(mIntentArgument.capture(), mStringArgument.capture(), 368 any(Bundle.class)); 369 verifyBatteryLevelChangedIntent(mDevice1, 60, mIntentArgument); 370 Assert.assertEquals(BLUETOOTH_CONNECT, mStringArgument.getValue()); 371 } 372 373 @Test testGetBatteryLevelFromXEventVsc()374 public void testGetBatteryLevelFromXEventVsc() { 375 Assert.assertEquals(42, RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(3, 8))); 376 Assert.assertEquals(100, 377 RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(10, 11))); 378 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 379 RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(1, 1))); 380 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 381 RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(3, 1))); 382 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 383 RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(-1, 1))); 384 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 385 RemoteDevices.getBatteryLevelFromXEventVsc(getXEventArray(-1, -1))); 386 } 387 388 @Test testGetBatteryLevelFromAppleBatteryVsc()389 public void testGetBatteryLevelFromAppleBatteryVsc() { 390 Assert.assertEquals(10, RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ 391 1, BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 0 392 })); 393 Assert.assertEquals(100, RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ 394 1, BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 9 395 })); 396 Assert.assertEquals(60, RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ 397 3, 398 BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 399 5, 400 2, 401 1, 402 3, 403 10 404 })); 405 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 406 RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ 407 3, 408 BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 409 5, 410 2, 411 1, 412 3 413 })); 414 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 415 RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ 416 1, 417 BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 418 10 419 })); 420 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 421 RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ 422 1, 423 BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 424 -1 425 })); 426 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 427 RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{ 428 1, 429 BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL, 430 "5" 431 })); 432 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 433 RemoteDevices.getBatteryLevelFromAppleBatteryVsc(new Object[]{1, 35, 37})); 434 Assert.assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 435 RemoteDevices.getBatteryLevelFromAppleBatteryVsc( 436 new Object[]{1, "WRONG", "WRONG"})); 437 } 438 verifyBatteryLevelChangedIntent(BluetoothDevice device, int batteryLevel, ArgumentCaptor<Intent> intentArgument)439 private static void verifyBatteryLevelChangedIntent(BluetoothDevice device, int batteryLevel, 440 ArgumentCaptor<Intent> intentArgument) { 441 verifyBatteryLevelChangedIntent(device, batteryLevel, intentArgument.getValue()); 442 } 443 verifyBatteryLevelChangedIntent(BluetoothDevice device, int batteryLevel, Intent intent)444 private static void verifyBatteryLevelChangedIntent(BluetoothDevice device, int batteryLevel, 445 Intent intent) { 446 Assert.assertEquals(BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED, intent.getAction()); 447 Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); 448 Assert.assertEquals(batteryLevel, 449 intent.getIntExtra(BluetoothDevice.EXTRA_BATTERY_LEVEL, -15)); 450 Assert.assertEquals(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 451 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, intent.getFlags()); 452 } 453 getHeadsetConnectionStateChangedIntent(BluetoothDevice device, int oldState, int newState)454 private static Intent getHeadsetConnectionStateChangedIntent(BluetoothDevice device, 455 int oldState, int newState) { 456 Intent intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); 457 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 458 intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, oldState); 459 intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); 460 return intent; 461 } 462 getHfIndicatorIntent(BluetoothDevice device, int batteryLevel, int indicatorId)463 private static Intent getHfIndicatorIntent(BluetoothDevice device, int batteryLevel, 464 int indicatorId) { 465 Intent intent = new Intent(BluetoothHeadset.ACTION_HF_INDICATORS_VALUE_CHANGED); 466 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 467 intent.putExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, indicatorId); 468 intent.putExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, batteryLevel); 469 return intent; 470 } 471 getVendorSpecificHeadsetEventIntent(String command, int companyId, int commandType, Object[] arguments, BluetoothDevice device)472 private static Intent getVendorSpecificHeadsetEventIntent(String command, int companyId, 473 int commandType, Object[] arguments, BluetoothDevice device) { 474 Intent intent = new Intent(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT); 475 intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD, command); 476 intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE, commandType); 477 // assert: all elements of args are Serializable 478 intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS, arguments); 479 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 480 intent.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "." 481 + Integer.toString(companyId)); 482 return intent; 483 } 484 getXEventArray(int batteryLevel, int numLevels)485 private static Object[] getXEventArray(int batteryLevel, int numLevels) { 486 ArrayList<Object> list = new ArrayList<>(); 487 list.add(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL); 488 list.add(batteryLevel); 489 list.add(numLevels); 490 list.add(0); 491 list.add(0); 492 return list.toArray(); 493 } 494 } 495