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