1 package com.android.bluetooth.hfpclient; 2 3 import android.bluetooth.BluetoothAdapter; 4 import android.bluetooth.BluetoothDevice; 5 import android.bluetooth.BluetoothProfile; 6 import android.content.Context; 7 import android.content.Intent; 8 import android.media.AudioManager; 9 import android.os.Bundle; 10 import android.test.AndroidTestCase; 11 import android.util.Log; 12 13 import java.nio.ByteBuffer; 14 import java.util.List; 15 import java.util.Arrays; 16 import java.util.ArrayList; 17 18 import com.android.bluetooth.btservice.AdapterService; 19 20 import static org.mockito.Mockito.*; 21 22 import org.mockito.ArgumentCaptor; 23 24 public class HeadsetClientStateMachineTest extends AndroidTestCase { 25 private BluetoothAdapter mAdapter = null; 26 27 @Override setUp()28 protected void setUp() throws Exception { 29 AdapterService inst = mock(AdapterService.class); 30 assertTrue(inst != null); 31 mAdapter = BluetoothAdapter.getDefaultAdapter(); 32 } 33 34 // Test that default state is disconnected testDefaultDisconnectedState()35 public void testDefaultDisconnectedState() { 36 HeadsetClientService mockService = mock(HeadsetClientService.class); 37 AudioManager mockAudioManager = mock(AudioManager.class); 38 39 when(mockService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager); 40 41 HeadsetClientStateMachine mockSM = new HeadsetClientStateMachine( 42 mockService, getContext().getMainLooper()); 43 assertEquals( 44 mockSM.getConnectionState((BluetoothDevice) null), BluetoothProfile.STATE_DISCONNECTED); 45 } 46 47 // Test that an incoming connection with low priority is rejected testIncomingPriorityReject()48 public void testIncomingPriorityReject() { 49 HeadsetClientService mockService = mock(HeadsetClientService.class); 50 AudioManager mockAudioManager = mock(AudioManager.class); 51 BluetoothDevice device = mAdapter.getRemoteDevice("00:01:02:03:04:05"); 52 53 when(mockService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager); 54 55 HeadsetClientStateMachine mockSM = new HeadsetClientStateMachine( 56 mockService, getContext().getMainLooper()); 57 mockSM.start(); 58 59 // Return false for priority. 60 when(mockService.getPriority(any(BluetoothDevice.class))).thenReturn( 61 BluetoothProfile.PRIORITY_OFF); 62 63 // Inject an event for when incoming connection is requested 64 StackEvent connStCh = 65 new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); 66 connStCh.valueInt = HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED; 67 connStCh.valueInt2 = 0; 68 connStCh.valueInt3 = 0; 69 connStCh.device = device; 70 mockSM.sendMessage(StackEvent.STACK_EVENT, connStCh); 71 72 // Verify that no connection state broadcast is executed 73 verify(mockService, never()).sendBroadcast(any(Intent.class), anyString()); 74 // Check we are in disconnected state still. 75 assertTrue(mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Disconnected); 76 } 77 78 // Test that an incoming connection with high priority is accepted testIncomingPriorityAccept()79 public void testIncomingPriorityAccept() { 80 HeadsetClientService mockService = mock(HeadsetClientService.class); 81 AudioManager mockAudioManager = mock(AudioManager.class); 82 BluetoothDevice device = mAdapter.getRemoteDevice("00:01:02:03:04:05"); 83 84 when(mockService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager); 85 // Set a valid volume 86 when(mockAudioManager.getStreamVolume(anyInt())).thenReturn(2); 87 when(mockAudioManager.getStreamMaxVolume(anyInt())).thenReturn(10); 88 when(mockAudioManager.getStreamMinVolume(anyInt())).thenReturn(1); 89 90 91 HeadsetClientStateMachine mockSM = new HeadsetClientStateMachine( 92 mockService, getContext().getMainLooper()); 93 mockSM.start(); 94 95 // Return false for priority. 96 when(mockService.getPriority(any(BluetoothDevice.class))).thenReturn( 97 BluetoothProfile.PRIORITY_ON); 98 99 // Inject an event for when incoming connection is requested 100 StackEvent connStCh = 101 new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); 102 connStCh.valueInt = HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED; 103 connStCh.valueInt2 = 0; 104 connStCh.valueInt3 = 0; 105 connStCh.device = device; 106 mockSM.sendMessage(StackEvent.STACK_EVENT, connStCh); 107 108 // Verify that one connection state broadcast is executed 109 ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class); 110 verify(mockService, 111 timeout(1000)).sendBroadcast(intentArgument1.capture(), anyString()); 112 assertEquals(BluetoothProfile.STATE_CONNECTING, 113 intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); 114 115 // Check we are in connecting state now. 116 assertTrue(mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Connecting); 117 118 // Send a message to trigger SLC connection 119 StackEvent slcEvent = 120 new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); 121 slcEvent.valueInt = HeadsetClientHalConstants.CONNECTION_STATE_SLC_CONNECTED; 122 slcEvent.valueInt2 = HeadsetClientHalConstants.PEER_FEAT_ECS; 123 slcEvent.valueInt3 = 0; 124 slcEvent.device = device; 125 mockSM.sendMessage(StackEvent.STACK_EVENT, slcEvent); 126 127 // Verify that one connection state broadcast is executed 128 ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class); 129 verify(mockService, 130 timeout(1000).times(2)).sendBroadcast(intentArgument2.capture(), anyString()); 131 assertEquals(BluetoothProfile.STATE_CONNECTED, 132 intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); 133 // Check we are in connecting state now. 134 assertTrue(mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Connected); 135 } 136 137 // Test that an incoming connection that times out testIncomingTimeout()138 public void testIncomingTimeout() { 139 HeadsetClientService mockService = mock(HeadsetClientService.class); 140 AudioManager mockAudioManager = mock(AudioManager.class); 141 BluetoothDevice device = mAdapter.getRemoteDevice("00:01:02:03:04:05"); 142 143 when(mockService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mockAudioManager); 144 // Set a valid volume 145 when(mockAudioManager.getStreamVolume(anyInt())).thenReturn(2); 146 when(mockAudioManager.getStreamMaxVolume(anyInt())).thenReturn(10); 147 when(mockAudioManager.getStreamMinVolume(anyInt())).thenReturn(1); 148 149 150 HeadsetClientStateMachine mockSM = new HeadsetClientStateMachine( 151 mockService, getContext().getMainLooper()); 152 mockSM.start(); 153 154 // Return false for priority. 155 when(mockService.getPriority(any(BluetoothDevice.class))).thenReturn( 156 BluetoothProfile.PRIORITY_ON); 157 158 // Inject an event for when incoming connection is requested 159 StackEvent connStCh = 160 new StackEvent(StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); 161 connStCh.valueInt = HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED; 162 connStCh.valueInt2 = 0; 163 connStCh.valueInt3 = 0; 164 connStCh.device = device; 165 mockSM.sendMessage(StackEvent.STACK_EVENT, connStCh); 166 167 // Verify that one connection state broadcast is executed 168 ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class); 169 verify(mockService, timeout(1000)).sendBroadcast(intentArgument1.capture(), anyString()); 170 assertEquals(BluetoothProfile.STATE_CONNECTING, 171 intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); 172 173 // Check we are in connecting state now. 174 assertTrue(mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Connecting); 175 176 // Verify that one connection state broadcast is executed 177 ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class); 178 verify(mockService, 179 timeout(HeadsetClientStateMachine.CONNECTING_TIMEOUT_MS * 2).times(2)).sendBroadcast( 180 intentArgument2.capture(), anyString()); 181 assertEquals(BluetoothProfile.STATE_DISCONNECTED, 182 intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); 183 184 // Check we are in connecting state now. 185 assertTrue(mockSM.getCurrentState() instanceof HeadsetClientStateMachine.Disconnected); 186 } 187 } 188