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