1 /* 2 * Copyright 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 */ 16 17 package com.android.bluetooth.hfp; 18 19 import static android.Manifest.permission.BLUETOOTH_CONNECT; 20 import static org.mockito.Mockito.*; 21 22 import android.bluetooth.BluetoothAdapter; 23 import android.bluetooth.BluetoothDevice; 24 import android.bluetooth.BluetoothHeadset; 25 import android.bluetooth.BluetoothProfile; 26 import android.content.ContentResolver; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.ServiceConnection; 30 import android.database.Cursor; 31 import android.media.AudioManager; 32 import android.net.Uri; 33 import android.os.Bundle; 34 import android.os.CancellationSignal; 35 import android.os.HandlerThread; 36 import android.os.UserHandle; 37 import android.provider.CallLog; 38 import android.provider.CallLog.Calls; 39 import android.telephony.PhoneStateListener; 40 import android.test.mock.MockContentProvider; 41 import android.test.mock.MockContentResolver; 42 43 import androidx.test.InstrumentationRegistry; 44 import androidx.test.filters.MediumTest; 45 import androidx.test.runner.AndroidJUnit4; 46 47 import com.android.bluetooth.R; 48 import com.android.bluetooth.TestUtils; 49 import com.android.bluetooth.btservice.AdapterService; 50 51 import org.hamcrest.core.IsInstanceOf; 52 import org.junit.After; 53 import org.junit.Assert; 54 import org.junit.Assume; 55 import org.junit.Before; 56 import org.junit.Test; 57 import org.junit.runner.RunWith; 58 import org.mockito.ArgumentCaptor; 59 import org.mockito.Mock; 60 import org.mockito.MockitoAnnotations; 61 62 /** 63 * Tests for {@link HeadsetStateMachine} 64 */ 65 @MediumTest 66 @RunWith(AndroidJUnit4.class) 67 public class HeadsetStateMachineTest { 68 private static final int CONNECT_TIMEOUT_TEST_MILLIS = 1000; 69 private static final int CONNECT_TIMEOUT_TEST_WAIT_MILLIS = CONNECT_TIMEOUT_TEST_MILLIS * 3 / 2; 70 private static final int ASYNC_CALL_TIMEOUT_MILLIS = 250; 71 private static final String TEST_PHONE_NUMBER = "1234567890"; 72 private Context mTargetContext; 73 private BluetoothAdapter mAdapter; 74 private HandlerThread mHandlerThread; 75 private HeadsetStateMachine mHeadsetStateMachine; 76 private BluetoothDevice mTestDevice; 77 private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class); 78 79 @Mock private AdapterService mAdapterService; 80 @Mock private HeadsetService mHeadsetService; 81 @Mock private HeadsetSystemInterface mSystemInterface; 82 @Mock private AudioManager mAudioManager; 83 @Mock private HeadsetPhoneState mPhoneState; 84 private MockContentResolver mMockContentResolver; 85 private HeadsetNativeInterface mNativeInterface; 86 87 @Before setUp()88 public void setUp() throws Exception { 89 mTargetContext = InstrumentationRegistry.getTargetContext(); 90 Assume.assumeTrue("Ignore test when HeadsetService is not enabled", 91 mTargetContext.getResources().getBoolean(R.bool.profile_supported_hs_hfp)); 92 // Setup mocks and test assets 93 MockitoAnnotations.initMocks(this); 94 TestUtils.setAdapterService(mAdapterService); 95 // Stub system interface 96 when(mSystemInterface.getHeadsetPhoneState()).thenReturn(mPhoneState); 97 when(mSystemInterface.getAudioManager()).thenReturn(mAudioManager); 98 // This line must be called to make sure relevant objects are initialized properly 99 mAdapter = BluetoothAdapter.getDefaultAdapter(); 100 // Get a device for testing 101 mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); 102 // Spy on native interface 103 mNativeInterface = spy(HeadsetNativeInterface.getInstance()); 104 doNothing().when(mNativeInterface).init(anyInt(), anyBoolean()); 105 doReturn(true).when(mNativeInterface).connectHfp(mTestDevice); 106 doReturn(true).when(mNativeInterface).disconnectHfp(mTestDevice); 107 doReturn(true).when(mNativeInterface).connectAudio(mTestDevice); 108 doReturn(true).when(mNativeInterface).disconnectAudio(mTestDevice); 109 // Stub headset service 110 mMockContentResolver = new MockContentResolver(); 111 when(mHeadsetService.getContentResolver()).thenReturn(mMockContentResolver); 112 doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService) 113 .getBondState(any(BluetoothDevice.class)); 114 when(mHeadsetService.bindService(any(Intent.class), any(ServiceConnection.class), anyInt())) 115 .thenReturn(true); 116 when(mHeadsetService.getResources()).thenReturn( 117 InstrumentationRegistry.getTargetContext().getResources()); 118 when(mHeadsetService.getPackageManager()).thenReturn( 119 InstrumentationRegistry.getContext().getPackageManager()); 120 when(mHeadsetService.getConnectionPolicy(any(BluetoothDevice.class))).thenReturn( 121 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 122 when(mHeadsetService.getForceScoAudio()).thenReturn(true); 123 when(mHeadsetService.okToAcceptConnection(any(BluetoothDevice.class))).thenReturn(true); 124 when(mHeadsetService.isScoAcceptable(any(BluetoothDevice.class))).thenReturn(true); 125 // Setup thread and looper 126 mHandlerThread = new HandlerThread("HeadsetStateMachineTestHandlerThread"); 127 mHandlerThread.start(); 128 // Modify CONNECT timeout to a smaller value for test only 129 HeadsetStateMachine.sConnectTimeoutMs = CONNECT_TIMEOUT_TEST_MILLIS; 130 mHeadsetStateMachine = HeadsetObjectsFactory.getInstance() 131 .makeStateMachine(mTestDevice, mHandlerThread.getLooper(), mHeadsetService, 132 mAdapterService, mNativeInterface, mSystemInterface); 133 } 134 135 @After tearDown()136 public void tearDown() throws Exception { 137 if (!mTargetContext.getResources().getBoolean(R.bool.profile_supported_hs_hfp)) { 138 return; 139 } 140 HeadsetObjectsFactory.getInstance().destroyStateMachine(mHeadsetStateMachine); 141 mHandlerThread.quit(); 142 TestUtils.clearAdapterService(mAdapterService); 143 } 144 145 /** 146 * Test that default state is Disconnected 147 */ 148 @Test testDefaultDisconnectedState()149 public void testDefaultDisconnectedState() { 150 Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, 151 mHeadsetStateMachine.getConnectionState()); 152 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 153 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); 154 } 155 156 /** 157 * Test that state is Connected after calling setUpConnectedState() 158 */ 159 @Test testSetupConnectedState()160 public void testSetupConnectedState() { 161 setUpConnectedState(); 162 Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, 163 mHeadsetStateMachine.getConnectionState()); 164 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 165 IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); 166 } 167 168 /** 169 * Test state transition from Disconnected to Connecting state via CONNECT message 170 */ 171 @Test testStateTransition_DisconnectedToConnecting_Connect()172 public void testStateTransition_DisconnectedToConnecting_Connect() { 173 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT, mTestDevice); 174 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( 175 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 176 any(Bundle.class)); 177 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 178 BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, 179 mIntentArgument.getValue()); 180 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 181 IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); 182 } 183 184 /** 185 * Test state transition from Disconnected to Connecting state via StackEvent.CONNECTED message 186 */ 187 @Test testStateTransition_DisconnectedToConnecting_StackConnected()188 public void testStateTransition_DisconnectedToConnecting_StackConnected() { 189 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 190 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 191 HeadsetHalConstants.CONNECTION_STATE_CONNECTED, mTestDevice)); 192 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( 193 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 194 any(Bundle.class)); 195 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 196 BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, 197 mIntentArgument.getValue()); 198 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 199 IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); 200 } 201 202 /** 203 * Test state transition from Disconnected to Connecting state via StackEvent.CONNECTING message 204 */ 205 @Test testStateTransition_DisconnectedToConnecting_StackConnecting()206 public void testStateTransition_DisconnectedToConnecting_StackConnecting() { 207 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 208 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 209 HeadsetHalConstants.CONNECTION_STATE_CONNECTING, mTestDevice)); 210 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( 211 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 212 any(Bundle.class)); 213 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 214 BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, 215 mIntentArgument.getValue()); 216 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 217 IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); 218 } 219 220 /** 221 * Test state transition from Connecting to Disconnected state via StackEvent.DISCONNECTED 222 * message 223 */ 224 @Test testStateTransition_ConnectingToDisconnected_StackDisconnected()225 public void testStateTransition_ConnectingToDisconnected_StackDisconnected() { 226 int numBroadcastsSent = setUpConnectingState(); 227 // Indicate disconnecting to test state machine, which should do nothing 228 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 229 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 230 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); 231 // Should do nothing new 232 verify(mHeadsetService, 233 after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 234 any(Intent.class), any(UserHandle.class), anyString(), any(Bundle.class)); 235 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 236 IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); 237 238 // Indicate connection failed to test state machine 239 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 240 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 241 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); 242 243 numBroadcastsSent++; 244 verify(mHeadsetService, 245 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 246 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 247 any(Bundle.class)); 248 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 249 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING, 250 mIntentArgument.getValue()); 251 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 252 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); 253 } 254 255 /** 256 * Test state transition from Connecting to Disconnected state via CONNECT_TIMEOUT message 257 */ 258 @Test testStateTransition_ConnectingToDisconnected_Timeout()259 public void testStateTransition_ConnectingToDisconnected_Timeout() { 260 int numBroadcastsSent = setUpConnectingState(); 261 // Let the connection timeout 262 numBroadcastsSent++; 263 verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times( 264 numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(), 265 eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 266 any(Bundle.class)); 267 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 268 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING, 269 mIntentArgument.getValue()); 270 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 271 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); 272 } 273 274 /** 275 * Test state transition from Connecting to Connected state via StackEvent.SLC_CONNECTED message 276 */ 277 @Test testStateTransition_ConnectingToConnected_StackSlcConnected()278 public void testStateTransition_ConnectingToConnected_StackSlcConnected() { 279 int numBroadcastsSent = setUpConnectingState(); 280 // Indicate connecting to test state machine 281 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 282 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 283 HeadsetHalConstants.CONNECTION_STATE_CONNECTING, mTestDevice)); 284 // Should do nothing 285 verify(mHeadsetService, 286 after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 287 any(Intent.class), any(UserHandle.class), anyString(), any(Bundle.class)); 288 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 289 IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); 290 291 // Indicate RFCOMM connection is successful to test state machine 292 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 293 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 294 HeadsetHalConstants.CONNECTION_STATE_CONNECTED, mTestDevice)); 295 // Should do nothing 296 verify(mHeadsetService, 297 after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 298 any(Intent.class), any(UserHandle.class), anyString(), any(Bundle.class)); 299 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 300 IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); 301 302 // Indicate SLC connection is successful to test state machine 303 numBroadcastsSent++; 304 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 305 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 306 HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, mTestDevice)); 307 verify(mHeadsetService, 308 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 309 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 310 any(Bundle.class)); 311 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 312 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, 313 mIntentArgument.getValue()); 314 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 315 IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); 316 } 317 318 /** 319 * Test state transition from Disconnecting to Disconnected state via StackEvent.DISCONNECTED 320 * message 321 */ 322 @Test testStateTransition_DisconnectingToDisconnected_StackDisconnected()323 public void testStateTransition_DisconnectingToDisconnected_StackDisconnected() { 324 int numBroadcastsSent = setUpDisconnectingState(); 325 // Send StackEvent.DISCONNECTED message 326 numBroadcastsSent++; 327 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 328 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 329 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); 330 verify(mHeadsetService, 331 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 332 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 333 any(Bundle.class)); 334 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 335 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING, 336 mIntentArgument.getValue()); 337 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 338 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); 339 } 340 341 /** 342 * Test state transition from Disconnecting to Disconnected state via CONNECT_TIMEOUT 343 * message 344 */ 345 @Test testStateTransition_DisconnectingToDisconnected_Timeout()346 public void testStateTransition_DisconnectingToDisconnected_Timeout() { 347 int numBroadcastsSent = setUpDisconnectingState(); 348 // Let the connection timeout 349 numBroadcastsSent++; 350 verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times( 351 numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(), 352 eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 353 any(Bundle.class)); 354 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 355 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING, 356 mIntentArgument.getValue()); 357 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 358 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); 359 } 360 361 /** 362 * Test state transition from Disconnecting to Connected state via StackEvent.SLC_CONNECTED 363 * message 364 */ 365 @Test testStateTransition_DisconnectingToConnected_StackSlcCconnected()366 public void testStateTransition_DisconnectingToConnected_StackSlcCconnected() { 367 int numBroadcastsSent = setUpDisconnectingState(); 368 // Send StackEvent.SLC_CONNECTED message 369 numBroadcastsSent++; 370 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 371 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 372 HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, mTestDevice)); 373 verify(mHeadsetService, 374 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 375 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 376 any(Bundle.class)); 377 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 378 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTING, 379 mIntentArgument.getValue()); 380 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 381 IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); 382 } 383 384 /** 385 * Test state transition from Connected to Disconnecting state via DISCONNECT message 386 */ 387 @Test testStateTransition_ConnectedToDisconnecting_Disconnect()388 public void testStateTransition_ConnectedToDisconnecting_Disconnect() { 389 int numBroadcastsSent = setUpConnectedState(); 390 // Send DISCONNECT message 391 numBroadcastsSent++; 392 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT, mTestDevice); 393 verify(mHeadsetService, 394 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 395 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 396 any(Bundle.class)); 397 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 398 BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, 399 mIntentArgument.getValue()); 400 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 401 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); 402 } 403 404 /** 405 * Test state transition from Connected to Disconnecting state via StackEvent.DISCONNECTING 406 * message 407 */ 408 @Test testStateTransition_ConnectedToDisconnecting_StackDisconnecting()409 public void testStateTransition_ConnectedToDisconnecting_StackDisconnecting() { 410 int numBroadcastsSent = setUpConnectedState(); 411 // Send StackEvent.DISCONNECTING message 412 numBroadcastsSent++; 413 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 414 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 415 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); 416 verify(mHeadsetService, 417 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 418 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 419 any(Bundle.class)); 420 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 421 BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, 422 mIntentArgument.getValue()); 423 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 424 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); 425 } 426 427 /** 428 * Test state transition from Connected to Disconnected state via StackEvent.DISCONNECTED 429 * message 430 */ 431 @Test testStateTransition_ConnectedToDisconnected_StackDisconnected()432 public void testStateTransition_ConnectedToDisconnected_StackDisconnected() { 433 int numBroadcastsSent = setUpConnectedState(); 434 // Send StackEvent.DISCONNECTED message 435 numBroadcastsSent++; 436 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 437 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 438 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); 439 verify(mHeadsetService, 440 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 441 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 442 any(Bundle.class)); 443 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 444 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED, 445 mIntentArgument.getValue()); 446 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 447 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); 448 } 449 450 /** 451 * Test state transition from Connected to AudioConnecting state via CONNECT_AUDIO message 452 */ 453 @Test testStateTransition_ConnectedToAudioConnecting_ConnectAudio()454 public void testStateTransition_ConnectedToAudioConnecting_ConnectAudio() { 455 int numBroadcastsSent = setUpConnectedState(); 456 // Send CONNECT_AUDIO message 457 numBroadcastsSent++; 458 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO, mTestDevice); 459 verify(mHeadsetService, 460 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 461 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 462 any(Bundle.class)); 463 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 464 BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 465 mIntentArgument.getValue()); 466 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 467 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioConnecting.class)); 468 } 469 470 /** 471 * Test state transition from Connected to AudioConnecting state via 472 * StackEvent.AUDIO_CONNECTING message 473 */ 474 @Test testStateTransition_ConnectedToAudioConnecting_StackAudioConnecting()475 public void testStateTransition_ConnectedToAudioConnecting_StackAudioConnecting() { 476 int numBroadcastsSent = setUpConnectedState(); 477 // Send StackEvent.AUDIO_CONNECTING message 478 numBroadcastsSent++; 479 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 480 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, 481 HeadsetHalConstants.AUDIO_STATE_CONNECTING, mTestDevice)); 482 verify(mHeadsetService, 483 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 484 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 485 any(Bundle.class)); 486 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 487 BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 488 mIntentArgument.getValue()); 489 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 490 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioConnecting.class)); 491 } 492 493 /** 494 * Test state transition from Connected to AudioOn state via StackEvent.AUDIO_CONNECTED message 495 */ 496 @Test testStateTransition_ConnectedToAudioOn_StackAudioConnected()497 public void testStateTransition_ConnectedToAudioOn_StackAudioConnected() { 498 int numBroadcastsSent = setUpConnectedState(); 499 // Send StackEvent.AUDIO_CONNECTED message 500 numBroadcastsSent++; 501 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 502 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, 503 HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice)); 504 verify(mHeadsetService, 505 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 506 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 507 any(Bundle.class)); 508 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 509 BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 510 mIntentArgument.getValue()); 511 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 512 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class)); 513 } 514 515 /** 516 * Test state transition from AudioConnecting to Connected state via CONNECT_TIMEOUT message 517 */ 518 @Test testStateTransition_AudioConnectingToConnected_Timeout()519 public void testStateTransition_AudioConnectingToConnected_Timeout() { 520 int numBroadcastsSent = setUpAudioConnectingState(); 521 // Wait for connection to timeout 522 numBroadcastsSent++; 523 verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times( 524 numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(), 525 eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 526 any(Bundle.class)); 527 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 528 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, 529 mIntentArgument.getValue()); 530 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 531 IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); 532 } 533 534 /** 535 * Test state transition from AudioConnecting to Connected state via 536 * StackEvent.AUDIO_DISCONNECTED message 537 */ 538 @Test testStateTransition_AudioConnectingToConnected_StackAudioDisconnected()539 public void testStateTransition_AudioConnectingToConnected_StackAudioDisconnected() { 540 int numBroadcastsSent = setUpAudioConnectingState(); 541 // Send StackEvent.AUDIO_DISCONNECTED message 542 numBroadcastsSent++; 543 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 544 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, 545 HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, mTestDevice)); 546 verify(mHeadsetService, 547 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 548 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 549 any(Bundle.class)); 550 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 551 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, 552 mIntentArgument.getValue()); 553 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 554 IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); 555 } 556 557 /** 558 * Test state transition from AudioConnecting to Disconnected state via 559 * StackEvent.DISCONNECTED message 560 */ 561 @Test testStateTransition_AudioConnectingToDisconnected_StackDisconnected()562 public void testStateTransition_AudioConnectingToDisconnected_StackDisconnected() { 563 int numBroadcastsSent = setUpAudioConnectingState(); 564 // Send StackEvent.DISCONNECTED message 565 numBroadcastsSent += 2; 566 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 567 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 568 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); 569 verify(mHeadsetService, 570 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 571 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 572 any(Bundle.class)); 573 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 574 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, 575 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); 576 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 577 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED, 578 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); 579 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 580 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); 581 } 582 583 /** 584 * Test state transition from AudioConnecting to Disconnecting state via 585 * StackEvent.DISCONNECTING message 586 */ 587 @Test testStateTransition_AudioConnectingToDisconnecting_StackDisconnecting()588 public void testStateTransition_AudioConnectingToDisconnecting_StackDisconnecting() { 589 int numBroadcastsSent = setUpAudioConnectingState(); 590 // Send StackEvent.DISCONNECTED message 591 numBroadcastsSent += 2; 592 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 593 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 594 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); 595 verify(mHeadsetService, 596 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 597 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 598 any(Bundle.class)); 599 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 600 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, 601 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); 602 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 603 BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, 604 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); 605 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 606 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); 607 } 608 609 /** 610 * Test state transition from AudioConnecting to AudioOn state via 611 * StackEvent.AUDIO_CONNECTED message 612 */ 613 @Test testStateTransition_AudioConnectingToAudioOn_StackAudioConnected()614 public void testStateTransition_AudioConnectingToAudioOn_StackAudioConnected() { 615 int numBroadcastsSent = setUpAudioConnectingState(); 616 // Send StackEvent.AUDIO_DISCONNECTED message 617 numBroadcastsSent++; 618 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 619 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, 620 HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice)); 621 verify(mHeadsetService, 622 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 623 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 624 any(Bundle.class)); 625 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 626 BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, 627 mIntentArgument.getValue()); 628 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 629 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class)); 630 } 631 632 /** 633 * Test state transition from AudioOn to AudioDisconnecting state via 634 * StackEvent.AUDIO_DISCONNECTING message 635 */ 636 @Test testStateTransition_AudioOnToAudioDisconnecting_StackAudioDisconnecting()637 public void testStateTransition_AudioOnToAudioDisconnecting_StackAudioDisconnecting() { 638 int numBroadcastsSent = setUpAudioOnState(); 639 // Send StackEvent.AUDIO_DISCONNECTING message 640 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 641 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, 642 HeadsetHalConstants.AUDIO_STATE_DISCONNECTING, mTestDevice)); 643 verify(mHeadsetService, 644 after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 645 any(Intent.class), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 646 any(Bundle.class)); 647 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 648 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class)); 649 } 650 651 /** 652 * Test state transition from AudioOn to AudioDisconnecting state via 653 * DISCONNECT_AUDIO message 654 */ 655 @Test testStateTransition_AudioOnToAudioDisconnecting_DisconnectAudio()656 public void testStateTransition_AudioOnToAudioDisconnecting_DisconnectAudio() { 657 int numBroadcastsSent = setUpAudioOnState(); 658 // Send DISCONNECT_AUDIO message 659 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO, mTestDevice); 660 // Should not sent any broadcast due to lack of AUDIO_DISCONNECTING intent value 661 verify(mHeadsetService, 662 after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 663 any(Intent.class), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 664 any(Bundle.class)); 665 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 666 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class)); 667 } 668 669 /** 670 * Test state transition from AudioOn to AudioDisconnecting state via 671 * Stack.AUDIO_DISCONNECTED message 672 */ 673 @Test testStateTransition_AudioOnToConnected_StackAudioDisconnected()674 public void testStateTransition_AudioOnToConnected_StackAudioDisconnected() { 675 int numBroadcastsSent = setUpAudioOnState(); 676 // Send DISCONNECT_AUDIO message 677 numBroadcastsSent++; 678 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 679 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, 680 HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, mTestDevice)); 681 verify(mHeadsetService, 682 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 683 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 684 any(Bundle.class)); 685 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 686 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, 687 mIntentArgument.getValue()); 688 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 689 IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); 690 } 691 692 /** 693 * Test state transition from AudioOn to Disconnected state via 694 * Stack.DISCONNECTED message 695 */ 696 @Test testStateTransition_AudioOnToDisconnected_StackDisconnected()697 public void testStateTransition_AudioOnToDisconnected_StackDisconnected() { 698 int numBroadcastsSent = setUpAudioOnState(); 699 // Send StackEvent.DISCONNECTED message 700 numBroadcastsSent += 2; 701 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 702 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 703 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); 704 verify(mHeadsetService, 705 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 706 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 707 any(Bundle.class)); 708 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 709 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, 710 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); 711 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 712 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED, 713 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); 714 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 715 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); 716 } 717 718 /** 719 * Test state transition from AudioOn to Disconnecting state via 720 * Stack.DISCONNECTING message 721 */ 722 @Test testStateTransition_AudioOnToDisconnecting_StackDisconnecting()723 public void testStateTransition_AudioOnToDisconnecting_StackDisconnecting() { 724 int numBroadcastsSent = setUpAudioOnState(); 725 // Send StackEvent.DISCONNECTING message 726 numBroadcastsSent += 2; 727 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 728 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 729 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); 730 verify(mHeadsetService, 731 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 732 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 733 any(Bundle.class)); 734 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 735 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, 736 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); 737 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 738 BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, 739 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); 740 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 741 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); 742 } 743 744 /** 745 * Test state transition from AudioDisconnecting to Connected state via 746 * CONNECT_TIMEOUT message 747 */ 748 @Test testStateTransition_AudioDisconnectingToConnected_Timeout()749 public void testStateTransition_AudioDisconnectingToConnected_Timeout() { 750 int numBroadcastsSent = setUpAudioDisconnectingState(); 751 // Wait for connection to timeout 752 numBroadcastsSent++; 753 verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times( 754 numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(), 755 eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 756 any(Bundle.class)); 757 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 758 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, 759 mIntentArgument.getValue()); 760 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 761 IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); 762 } 763 764 /** 765 * Test state transition from AudioDisconnecting to Connected state via 766 * Stack.AUDIO_DISCONNECTED message 767 */ 768 @Test testStateTransition_AudioDisconnectingToConnected_StackAudioDisconnected()769 public void testStateTransition_AudioDisconnectingToConnected_StackAudioDisconnected() { 770 int numBroadcastsSent = setUpAudioDisconnectingState(); 771 // Send Stack.AUDIO_DISCONNECTED message 772 numBroadcastsSent++; 773 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 774 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, 775 HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, mTestDevice)); 776 verify(mHeadsetService, 777 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 778 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 779 any(Bundle.class)); 780 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 781 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, 782 mIntentArgument.getValue()); 783 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 784 IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); 785 } 786 787 /** 788 * Test state transition from AudioDisconnecting to AudioOn state via 789 * Stack.AUDIO_CONNECTED message 790 */ 791 @Test testStateTransition_AudioDisconnectingToAudioOn_StackAudioConnected()792 public void testStateTransition_AudioDisconnectingToAudioOn_StackAudioConnected() { 793 int numBroadcastsSent = setUpAudioDisconnectingState(); 794 // Send Stack.AUDIO_CONNECTED message 795 numBroadcastsSent++; 796 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 797 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, 798 HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice)); 799 verify(mHeadsetService, 800 after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 801 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 802 any(Bundle.class)); 803 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 804 BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, 805 mIntentArgument.getValue()); 806 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 807 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class)); 808 } 809 810 /** 811 * Test state transition from AudioDisconnecting to Disconnecting state via 812 * Stack.DISCONNECTING message 813 */ 814 @Test testStateTransition_AudioDisconnectingToDisconnecting_StackDisconnecting()815 public void testStateTransition_AudioDisconnectingToDisconnecting_StackDisconnecting() { 816 int numBroadcastsSent = setUpAudioDisconnectingState(); 817 // Send StackEvent.DISCONNECTING message 818 numBroadcastsSent += 2; 819 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 820 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 821 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice)); 822 verify(mHeadsetService, 823 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 824 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 825 any(Bundle.class)); 826 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 827 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, 828 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); 829 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 830 BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, 831 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); 832 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 833 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); 834 } 835 836 /** 837 * Test state transition from AudioDisconnecting to Disconnecting state via 838 * Stack.DISCONNECTED message 839 */ 840 @Test testStateTransition_AudioDisconnectingToDisconnected_StackDisconnected()841 public void testStateTransition_AudioDisconnectingToDisconnected_StackDisconnected() { 842 int numBroadcastsSent = setUpAudioDisconnectingState(); 843 // Send StackEvent.DISCONNECTED message 844 numBroadcastsSent += 2; 845 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 846 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 847 HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice)); 848 verify(mHeadsetService, 849 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 850 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 851 any(Bundle.class)); 852 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 853 BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED, 854 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2)); 855 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 856 BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED, 857 mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1)); 858 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 859 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class)); 860 } 861 862 /** 863 * A test to verify that we correctly subscribe to phone state updates for service and signal 864 * strength information and further updates via AT+BIA command results in update 865 */ 866 @Test testAtBiaEvent_initialSubscriptionWithUpdates()867 public void testAtBiaEvent_initialSubscriptionWithUpdates() { 868 setUpConnectedState(); 869 verify(mPhoneState).listenForPhoneState(mTestDevice, PhoneStateListener.LISTEN_SERVICE_STATE 870 | PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH); 871 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 872 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA, 873 new HeadsetAgIndicatorEnableState(true, true, false, false), mTestDevice)); 874 verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice, 875 PhoneStateListener.LISTEN_SERVICE_STATE); 876 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 877 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA, 878 new HeadsetAgIndicatorEnableState(false, true, true, false), mTestDevice)); 879 verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice, 880 PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH); 881 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 882 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA, 883 new HeadsetAgIndicatorEnableState(false, true, false, false), mTestDevice)); 884 verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice, 885 PhoneStateListener.LISTEN_NONE); 886 } 887 888 /** 889 * A test to verify that we correctly handles key pressed event from a HSP headset 890 */ 891 @Test testKeyPressedEventWhenIdleAndAudioOff_dialCall()892 public void testKeyPressedEventWhenIdleAndAudioOff_dialCall() { 893 setUpConnectedState(); 894 Cursor cursor = mock(Cursor.class); 895 when(cursor.getCount()).thenReturn(1); 896 when(cursor.moveToNext()).thenReturn(true); 897 int magicNumber = 42; 898 when(cursor.getColumnIndexOrThrow(CallLog.Calls.NUMBER)).thenReturn(magicNumber); 899 when(cursor.getString(magicNumber)).thenReturn(TEST_PHONE_NUMBER); 900 MockContentProvider mockContentProvider = new MockContentProvider() { 901 @Override 902 public Cursor query(Uri uri, String[] projection, Bundle queryArgs, 903 CancellationSignal cancellationSignal) { 904 if (uri == null || !uri.equals(CallLog.Calls.CONTENT_URI)) { 905 return null; 906 } 907 if (projection == null || (projection.length == 0) || !projection[0].equals( 908 CallLog.Calls.NUMBER)) { 909 return null; 910 } 911 if (queryArgs == null 912 || !queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SELECTION).equals( 913 Calls.TYPE + "=" + Calls.OUTGOING_TYPE) 914 || !queryArgs.getString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER).equals( 915 Calls.DEFAULT_SORT_ORDER) 916 || queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT) != 1) { 917 return null; 918 } 919 if (cancellationSignal != null) { 920 return null; 921 } 922 return cursor; 923 } 924 }; 925 mMockContentResolver.addProvider(CallLog.AUTHORITY, mockContentProvider); 926 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 927 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); 928 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).dialOutgoingCall(mTestDevice, 929 TEST_PHONE_NUMBER); 930 } 931 932 /** 933 * A test to verify that we correctly handles key pressed event from a HSP headset 934 */ 935 @Test testKeyPressedEventDuringRinging_answerCall()936 public void testKeyPressedEventDuringRinging_answerCall() { 937 setUpConnectedState(); 938 when(mSystemInterface.isRinging()).thenReturn(true); 939 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 940 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); 941 verify(mSystemInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).answerCall(mTestDevice); 942 } 943 944 /** 945 * A test to verify that we correctly handles key pressed event from a HSP headset 946 */ 947 @Test testKeyPressedEventInCallButAudioOff_setActiveDevice()948 public void testKeyPressedEventInCallButAudioOff_setActiveDevice() { 949 setUpConnectedState(); 950 when(mSystemInterface.isInCall()).thenReturn(true); 951 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 952 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); 953 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setActiveDevice(mTestDevice); 954 } 955 956 /** 957 * A test to verify that we correctly handles key pressed event from a HSP headset 958 */ 959 @Test testKeyPressedEventInCallAndAudioOn_hangupCall()960 public void testKeyPressedEventInCallAndAudioOn_hangupCall() { 961 setUpAudioOnState(); 962 when(mSystemInterface.isInCall()).thenReturn(true); 963 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 964 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); 965 verify(mSystemInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).hangupCall(mTestDevice); 966 } 967 968 /** 969 * A test to verify that we correctly handles key pressed event from a HSP headset 970 */ 971 @Test testKeyPressedEventWhenIdleAndAudioOn_disconnectAudio()972 public void testKeyPressedEventWhenIdleAndAudioOn_disconnectAudio() { 973 setUpAudioOnState(); 974 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 975 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice)); 976 verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).disconnectAudio(mTestDevice); 977 } 978 979 /** 980 * A test to verfiy that we correctly handles AT+BIND event with driver safety case from HF 981 */ 982 @Test testAtBindWithDriverSafetyEventWhenConnecting()983 public void testAtBindWithDriverSafetyEventWhenConnecting() { 984 setUpConnectingState(); 985 986 String atString = "1"; 987 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 988 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIND, atString, mTestDevice)); 989 ArgumentCaptor<Intent> intentArgument = ArgumentCaptor.forClass(Intent.class); 990 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcast( 991 intentArgument.capture(), eq(BLUETOOTH_CONNECT), 992 any(Bundle.class)); 993 verify(mHeadsetService, times(1)).sendBroadcast(any(), any(), 994 any()); 995 Assert.assertEquals(mTestDevice, intentArgument.getValue().getExtra( 996 BluetoothDevice.EXTRA_DEVICE, null)); 997 Assert.assertEquals(HeadsetHalConstants.HF_INDICATOR_ENHANCED_DRIVER_SAFETY, 998 intentArgument.getValue().getIntExtra( 999 BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, -1)); 1000 Assert.assertEquals(-1, intentArgument.getValue().getIntExtra( 1001 BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, -2)); 1002 } 1003 1004 /** 1005 * A test to verfiy that we correctly handles AT+BIND event with battery level case from HF 1006 */ 1007 @Test testAtBindEventWithBatteryLevelEventWhenConnecting()1008 public void testAtBindEventWithBatteryLevelEventWhenConnecting() { 1009 setUpConnectingState(); 1010 1011 String atString = "2"; 1012 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 1013 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIND, atString, mTestDevice)); 1014 ArgumentCaptor<Intent> intentArgument = ArgumentCaptor.forClass(Intent.class); 1015 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcast( 1016 intentArgument.capture(), eq(BLUETOOTH_CONNECT), 1017 any(Bundle.class)); 1018 verify(mHeadsetService, times(1)).sendBroadcast(any(), any(), 1019 any()); 1020 Assert.assertEquals(mTestDevice, intentArgument.getValue().getExtra( 1021 BluetoothDevice.EXTRA_DEVICE, null)); 1022 Assert.assertEquals(HeadsetHalConstants.HF_INDICATOR_BATTERY_LEVEL_STATUS, 1023 intentArgument.getValue().getIntExtra( 1024 BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, -1)); 1025 Assert.assertEquals(-1, intentArgument.getValue().getIntExtra( 1026 BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, -2)); 1027 } 1028 1029 /** 1030 * A test to verfiy that we correctly handles AT+BIND event with error case from HF 1031 */ 1032 @Test testAtBindEventWithErrorEventWhenConnecting()1033 public void testAtBindEventWithErrorEventWhenConnecting() { 1034 setUpConnectingState(); 1035 1036 String atString = "err,A,123,,1"; 1037 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 1038 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIND, atString, mTestDevice)); 1039 ArgumentCaptor<Intent> intentArgument = ArgumentCaptor.forClass(Intent.class); 1040 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcast( 1041 intentArgument.capture(), eq(BLUETOOTH_CONNECT), 1042 any(Bundle.class)); 1043 verify(mHeadsetService, times(1)).sendBroadcast(any(), any(), 1044 any()); 1045 Assert.assertEquals(mTestDevice, intentArgument.getValue().getExtra( 1046 BluetoothDevice.EXTRA_DEVICE, null)); 1047 Assert.assertEquals(HeadsetHalConstants.HF_INDICATOR_ENHANCED_DRIVER_SAFETY, 1048 intentArgument.getValue().getIntExtra( 1049 BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, -1)); 1050 Assert.assertEquals(-1, intentArgument.getValue().getIntExtra( 1051 BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, -2)); 1052 } 1053 1054 /** 1055 * A test to verify that we correctly set AG indicator mask when enter/exit silence mode 1056 */ 1057 @Test testSetSilenceDevice()1058 public void testSetSilenceDevice() { 1059 doNothing().when(mPhoneState).listenForPhoneState(any(BluetoothDevice.class), anyInt()); 1060 mHeadsetStateMachine.setSilenceDevice(true); 1061 mHeadsetStateMachine.setSilenceDevice(false); 1062 verify(mPhoneState, times(2)).listenForPhoneState(mTestDevice, 1063 PhoneStateListener.LISTEN_NONE); 1064 } 1065 1066 /** 1067 * Setup Connecting State 1068 * @return number of times mHeadsetService.sendBroadcastAsUser() has been invoked 1069 */ setUpConnectingState()1070 private int setUpConnectingState() { 1071 // Put test state machine in connecting state 1072 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT, mTestDevice); 1073 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( 1074 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 1075 any(Bundle.class)); 1076 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 1077 BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, 1078 mIntentArgument.getValue()); 1079 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 1080 IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); 1081 return 1; 1082 } 1083 1084 /** 1085 * Setup Connected State 1086 * @return number of times mHeadsetService.sendBroadcastAsUser() has been invoked 1087 */ setUpConnectedState()1088 private int setUpConnectedState() { 1089 // Put test state machine into connected state 1090 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 1091 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 1092 HeadsetHalConstants.CONNECTION_STATE_CONNECTED, mTestDevice)); 1093 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser( 1094 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 1095 any(Bundle.class)); 1096 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 1097 BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED, 1098 mIntentArgument.getValue()); 1099 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 1100 IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class)); 1101 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 1102 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED, 1103 HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, mTestDevice)); 1104 verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastAsUser( 1105 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 1106 any(Bundle.class)); 1107 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 1108 BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, 1109 mIntentArgument.getValue()); 1110 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 1111 IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class)); 1112 return 2; 1113 } 1114 setUpAudioConnectingState()1115 private int setUpAudioConnectingState() { 1116 int numBroadcastsSent = setUpConnectedState(); 1117 // Send CONNECT_AUDIO 1118 numBroadcastsSent++; 1119 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO, mTestDevice); 1120 verify(mHeadsetService, 1121 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 1122 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 1123 any(Bundle.class)); 1124 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 1125 BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 1126 mIntentArgument.getValue()); 1127 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 1128 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioConnecting.class)); 1129 return numBroadcastsSent; 1130 } 1131 setUpAudioOnState()1132 private int setUpAudioOnState() { 1133 int numBroadcastsSent = setUpAudioConnectingState(); 1134 // Send StackEvent.AUDIO_DISCONNECTED message 1135 numBroadcastsSent++; 1136 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT, 1137 new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED, 1138 HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice)); 1139 verify(mHeadsetService, 1140 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 1141 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 1142 any(Bundle.class)); 1143 HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice, 1144 BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING, 1145 mIntentArgument.getValue()); 1146 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 1147 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class)); 1148 return numBroadcastsSent; 1149 } 1150 setUpAudioDisconnectingState()1151 private int setUpAudioDisconnectingState() { 1152 int numBroadcastsSent = setUpAudioOnState(); 1153 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO, mTestDevice); 1154 // No new broadcast due to lack of AUDIO_DISCONNECTING intent variable 1155 verify(mHeadsetService, 1156 after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 1157 any(Intent.class), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 1158 any(Bundle.class)); 1159 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 1160 IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class)); 1161 return numBroadcastsSent; 1162 } 1163 setUpDisconnectingState()1164 private int setUpDisconnectingState() { 1165 int numBroadcastsSent = setUpConnectedState(); 1166 // Send DISCONNECT message 1167 numBroadcastsSent++; 1168 mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT, mTestDevice); 1169 verify(mHeadsetService, 1170 timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser( 1171 mIntentArgument.capture(), eq(UserHandle.ALL), eq(BLUETOOTH_CONNECT), 1172 any(Bundle.class)); 1173 HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice, 1174 BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED, 1175 mIntentArgument.getValue()); 1176 Assert.assertThat(mHeadsetStateMachine.getCurrentState(), 1177 IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class)); 1178 return numBroadcastsSent; 1179 } 1180 } 1181