blob: 80192a65848352672cf2ddce195a119800fcfc9e [file] [log] [blame]
/*
* Copyright 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.bluetooth.hfp;
import static org.mockito.Mockito.*;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.media.AudioManager;
import android.net.Uri;
import android.os.HandlerThread;
import android.os.UserHandle;
import android.provider.CallLog;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.PhoneStateListener;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import com.android.bluetooth.R;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import org.hamcrest.core.IsInstanceOf;
import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Tests for {@link HeadsetStateMachine}
*/
@MediumTest
@RunWith(AndroidJUnit4.class)
public class HeadsetStateMachineTest {
private static final int CONNECT_TIMEOUT_TEST_MILLIS = 1000;
private static final int CONNECT_TIMEOUT_TEST_WAIT_MILLIS = CONNECT_TIMEOUT_TEST_MILLIS * 3 / 2;
private static final int ASYNC_CALL_TIMEOUT_MILLIS = 250;
private static final String TEST_PHONE_NUMBER = "1234567890";
private Context mTargetContext;
private BluetoothAdapter mAdapter;
private HandlerThread mHandlerThread;
private HeadsetStateMachine mHeadsetStateMachine;
private BluetoothDevice mTestDevice;
private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class);
@Mock private AdapterService mAdapterService;
@Mock private HeadsetService mHeadsetService;
@Mock private HeadsetSystemInterface mSystemInterface;
@Mock private AudioManager mAudioManager;
@Mock private HeadsetPhoneState mPhoneState;
private MockContentResolver mMockContentResolver;
private HeadsetNativeInterface mNativeInterface;
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getTargetContext();
Assume.assumeTrue("Ignore test when HeadsetService is not enabled",
mTargetContext.getResources().getBoolean(R.bool.profile_supported_hs_hfp));
// Setup mocks and test assets
MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
// Stub system interface
when(mSystemInterface.getHeadsetPhoneState()).thenReturn(mPhoneState);
when(mSystemInterface.getAudioManager()).thenReturn(mAudioManager);
// This line must be called to make sure relevant objects are initialized properly
mAdapter = BluetoothAdapter.getDefaultAdapter();
// Get a device for testing
mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05");
// Spy on native interface
mNativeInterface = spy(HeadsetNativeInterface.getInstance());
doNothing().when(mNativeInterface).init(anyInt(), anyBoolean());
doReturn(true).when(mNativeInterface).connectHfp(mTestDevice);
doReturn(true).when(mNativeInterface).disconnectHfp(mTestDevice);
doReturn(true).when(mNativeInterface).connectAudio(mTestDevice);
doReturn(true).when(mNativeInterface).disconnectAudio(mTestDevice);
// Stub headset service
mMockContentResolver = new MockContentResolver();
when(mHeadsetService.getContentResolver()).thenReturn(mMockContentResolver);
doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService)
.getBondState(any(BluetoothDevice.class));
when(mHeadsetService.bindService(any(Intent.class), any(ServiceConnection.class), anyInt()))
.thenReturn(true);
when(mHeadsetService.getResources()).thenReturn(
InstrumentationRegistry.getTargetContext().getResources());
when(mHeadsetService.getPackageManager()).thenReturn(
InstrumentationRegistry.getContext().getPackageManager());
when(mHeadsetService.getPriority(any(BluetoothDevice.class))).thenReturn(
BluetoothProfile.PRIORITY_ON);
when(mHeadsetService.getForceScoAudio()).thenReturn(true);
when(mHeadsetService.okToAcceptConnection(any(BluetoothDevice.class))).thenReturn(true);
when(mHeadsetService.isScoAcceptable(any(BluetoothDevice.class))).thenReturn(true);
// Setup thread and looper
mHandlerThread = new HandlerThread("HeadsetStateMachineTestHandlerThread");
mHandlerThread.start();
// Modify CONNECT timeout to a smaller value for test only
HeadsetStateMachine.sConnectTimeoutMs = CONNECT_TIMEOUT_TEST_MILLIS;
mHeadsetStateMachine = HeadsetObjectsFactory.getInstance()
.makeStateMachine(mTestDevice, mHandlerThread.getLooper(), mHeadsetService,
mAdapterService, mNativeInterface, mSystemInterface);
}
@After
public void tearDown() throws Exception {
if (!mTargetContext.getResources().getBoolean(R.bool.profile_supported_hs_hfp)) {
return;
}
HeadsetObjectsFactory.getInstance().destroyStateMachine(mHeadsetStateMachine);
mHandlerThread.quit();
TestUtils.clearAdapterService(mAdapterService);
}
/**
* Test that default state is Disconnected
*/
@Test
public void testDefaultDisconnectedState() {
Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED,
mHeadsetStateMachine.getConnectionState());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class));
}
/**
* Test that state is Connected after calling setUpConnectedState()
*/
@Test
public void testSetupConnectedState() {
setUpConnectedState();
Assert.assertEquals(BluetoothProfile.STATE_CONNECTED,
mHeadsetStateMachine.getConnectionState());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class));
}
/**
* Test state transition from Disconnected to Connecting state via CONNECT message
*/
@Test
public void testStateTransition_DisconnectedToConnecting_Connect() {
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT, mTestDevice);
verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class));
}
/**
* Test state transition from Disconnected to Connecting state via StackEvent.CONNECTED message
*/
@Test
public void testStateTransition_DisconnectedToConnecting_StackConnected() {
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_CONNECTED, mTestDevice));
verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class));
}
/**
* Test state transition from Disconnected to Connecting state via StackEvent.CONNECTING message
*/
@Test
public void testStateTransition_DisconnectedToConnecting_StackConnecting() {
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_CONNECTING, mTestDevice));
verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class));
}
/**
* Test state transition from Connecting to Disconnected state via StackEvent.DISCONNECTED
* message
*/
@Test
public void testStateTransition_ConnectingToDisconnected_StackDisconnected() {
int numBroadcastsSent = setUpConnectingState();
// Indicate disconnecting to test state machine, which should do nothing
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice));
// Should do nothing new
verify(mHeadsetService,
after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
any(Intent.class), any(UserHandle.class), anyString());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class));
// Indicate connection failed to test state machine
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice));
numBroadcastsSent++;
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class));
}
/**
* Test state transition from Connecting to Disconnected state via CONNECT_TIMEOUT message
*/
@Test
public void testStateTransition_ConnectingToDisconnected_Timeout() {
int numBroadcastsSent = setUpConnectingState();
// Let the connection timeout
numBroadcastsSent++;
verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times(
numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(),
eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class));
}
/**
* Test state transition from Connecting to Connected state via StackEvent.SLC_CONNECTED message
*/
@Test
public void testStateTransition_ConnectingToConnected_StackSlcConnected() {
int numBroadcastsSent = setUpConnectingState();
// Indicate connecting to test state machine
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_CONNECTING, mTestDevice));
// Should do nothing
verify(mHeadsetService,
after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
any(Intent.class), any(UserHandle.class), anyString());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class));
// Indicate RFCOMM connection is successful to test state machine
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_CONNECTED, mTestDevice));
// Should do nothing
verify(mHeadsetService,
after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
any(Intent.class), any(UserHandle.class), anyString());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class));
// Indicate SLC connection is successful to test state machine
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class));
}
/**
* Test state transition from Disconnecting to Disconnected state via StackEvent.DISCONNECTED
* message
*/
@Test
public void testStateTransition_DisconnectingToDisconnected_StackDisconnected() {
int numBroadcastsSent = setUpDisconnectingState();
// Send StackEvent.DISCONNECTED message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class));
}
/**
* Test state transition from Disconnecting to Disconnected state via CONNECT_TIMEOUT
* message
*/
@Test
public void testStateTransition_DisconnectingToDisconnected_Timeout() {
int numBroadcastsSent = setUpDisconnectingState();
// Let the connection timeout
numBroadcastsSent++;
verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times(
numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(),
eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class));
}
/**
* Test state transition from Disconnecting to Connected state via StackEvent.SLC_CONNECTED
* message
*/
@Test
public void testStateTransition_DisconnectingToConnected_StackSlcCconnected() {
int numBroadcastsSent = setUpDisconnectingState();
// Send StackEvent.SLC_CONNECTED message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class));
}
/**
* Test state transition from Connected to Disconnecting state via DISCONNECT message
*/
@Test
public void testStateTransition_ConnectedToDisconnecting_Disconnect() {
int numBroadcastsSent = setUpConnectedState();
// Send DISCONNECT message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT, mTestDevice);
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class));
}
/**
* Test state transition from Connected to Disconnecting state via StackEvent.DISCONNECTING
* message
*/
@Test
public void testStateTransition_ConnectedToDisconnecting_StackDisconnecting() {
int numBroadcastsSent = setUpConnectedState();
// Send StackEvent.DISCONNECTING message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class));
}
/**
* Test state transition from Connected to Disconnected state via StackEvent.DISCONNECTED
* message
*/
@Test
public void testStateTransition_ConnectedToDisconnected_StackDisconnected() {
int numBroadcastsSent = setUpConnectedState();
// Send StackEvent.DISCONNECTED message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class));
}
/**
* Test state transition from Connected to AudioConnecting state via CONNECT_AUDIO message
*/
@Test
public void testStateTransition_ConnectedToAudioConnecting_ConnectAudio() {
int numBroadcastsSent = setUpConnectedState();
// Send CONNECT_AUDIO message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO, mTestDevice);
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioConnecting.class));
}
/**
* Test state transition from Connected to AudioConnecting state via
* StackEvent.AUDIO_CONNECTING message
*/
@Test
public void testStateTransition_ConnectedToAudioConnecting_StackAudioConnecting() {
int numBroadcastsSent = setUpConnectedState();
// Send StackEvent.AUDIO_CONNECTING message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED,
HeadsetHalConstants.AUDIO_STATE_CONNECTING, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioConnecting.class));
}
/**
* Test state transition from Connected to AudioOn state via StackEvent.AUDIO_CONNECTED message
*/
@Test
public void testStateTransition_ConnectedToAudioOn_StackAudioConnected() {
int numBroadcastsSent = setUpConnectedState();
// Send StackEvent.AUDIO_CONNECTED message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED,
HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class));
}
/**
* Test state transition from AudioConnecting to Connected state via CONNECT_TIMEOUT message
*/
@Test
public void testStateTransition_AudioConnectingToConnected_Timeout() {
int numBroadcastsSent = setUpAudioConnectingState();
// Wait for connection to timeout
numBroadcastsSent++;
verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times(
numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(),
eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class));
}
/**
* Test state transition from AudioConnecting to Connected state via
* StackEvent.AUDIO_DISCONNECTED message
*/
@Test
public void testStateTransition_AudioConnectingToConnected_StackAudioDisconnected() {
int numBroadcastsSent = setUpAudioConnectingState();
// Send StackEvent.AUDIO_DISCONNECTED message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED,
HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class));
}
/**
* Test state transition from AudioConnecting to Disconnected state via
* StackEvent.DISCONNECTED message
*/
@Test
public void testStateTransition_AudioConnectingToDisconnected_StackDisconnected() {
int numBroadcastsSent = setUpAudioConnectingState();
// Send StackEvent.DISCONNECTED message
numBroadcastsSent += 2;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1));
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class));
}
/**
* Test state transition from AudioConnecting to Disconnecting state via
* StackEvent.DISCONNECTING message
*/
@Test
public void testStateTransition_AudioConnectingToDisconnecting_StackDisconnecting() {
int numBroadcastsSent = setUpAudioConnectingState();
// Send StackEvent.DISCONNECTED message
numBroadcastsSent += 2;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1));
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class));
}
/**
* Test state transition from AudioConnecting to AudioOn state via
* StackEvent.AUDIO_CONNECTED message
*/
@Test
public void testStateTransition_AudioConnectingToAudioOn_StackAudioConnected() {
int numBroadcastsSent = setUpAudioConnectingState();
// Send StackEvent.AUDIO_DISCONNECTED message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED,
HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class));
}
/**
* Test state transition from AudioOn to AudioDisconnecting state via
* StackEvent.AUDIO_DISCONNECTING message
*/
@Test
public void testStateTransition_AudioOnToAudioDisconnecting_StackAudioDisconnecting() {
int numBroadcastsSent = setUpAudioOnState();
// Send StackEvent.AUDIO_DISCONNECTING message
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED,
HeadsetHalConstants.AUDIO_STATE_DISCONNECTING, mTestDevice));
verify(mHeadsetService,
after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
any(Intent.class), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class));
}
/**
* Test state transition from AudioOn to AudioDisconnecting state via
* DISCONNECT_AUDIO message
*/
@Test
public void testStateTransition_AudioOnToAudioDisconnecting_DisconnectAudio() {
int numBroadcastsSent = setUpAudioOnState();
// Send DISCONNECT_AUDIO message
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO, mTestDevice);
// Should not sent any broadcast due to lack of AUDIO_DISCONNECTING intent value
verify(mHeadsetService,
after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
any(Intent.class), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class));
}
/**
* Test state transition from AudioOn to AudioDisconnecting state via
* Stack.AUDIO_DISCONNECTED message
*/
@Test
public void testStateTransition_AudioOnToConnected_StackAudioDisconnected() {
int numBroadcastsSent = setUpAudioOnState();
// Send DISCONNECT_AUDIO message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED,
HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class));
}
/**
* Test state transition from AudioOn to Disconnected state via
* Stack.DISCONNECTED message
*/
@Test
public void testStateTransition_AudioOnToDisconnected_StackDisconnected() {
int numBroadcastsSent = setUpAudioOnState();
// Send StackEvent.DISCONNECTED message
numBroadcastsSent += 2;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1));
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class));
}
/**
* Test state transition from AudioOn to Disconnecting state via
* Stack.DISCONNECTING message
*/
@Test
public void testStateTransition_AudioOnToDisconnecting_StackDisconnecting() {
int numBroadcastsSent = setUpAudioOnState();
// Send StackEvent.DISCONNECTING message
numBroadcastsSent += 2;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1));
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class));
}
/**
* Test state transition from AudioDisconnecting to Connected state via
* CONNECT_TIMEOUT message
*/
@Test
public void testStateTransition_AudioDisconnectingToConnected_Timeout() {
int numBroadcastsSent = setUpAudioDisconnectingState();
// Wait for connection to timeout
numBroadcastsSent++;
verify(mHeadsetService, timeout(CONNECT_TIMEOUT_TEST_WAIT_MILLIS).times(
numBroadcastsSent)).sendBroadcastAsUser(mIntentArgument.capture(),
eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class));
}
/**
* Test state transition from AudioDisconnecting to Connected state via
* Stack.AUDIO_DISCONNECTED message
*/
@Test
public void testStateTransition_AudioDisconnectingToConnected_StackAudioDisconnected() {
int numBroadcastsSent = setUpAudioDisconnectingState();
// Send Stack.AUDIO_DISCONNECTED message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED,
HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class));
}
/**
* Test state transition from AudioDisconnecting to AudioOn state via
* Stack.AUDIO_CONNECTED message
*/
@Test
public void testStateTransition_AudioDisconnectingToAudioOn_StackAudioConnected() {
int numBroadcastsSent = setUpAudioDisconnectingState();
// Send Stack.AUDIO_CONNECTED message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED,
HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice));
verify(mHeadsetService,
after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class));
}
/**
* Test state transition from AudioDisconnecting to Disconnecting state via
* Stack.DISCONNECTING message
*/
@Test
public void testStateTransition_AudioDisconnectingToDisconnecting_StackDisconnecting() {
int numBroadcastsSent = setUpAudioDisconnectingState();
// Send StackEvent.DISCONNECTING message
numBroadcastsSent += 2;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1));
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class));
}
/**
* Test state transition from AudioDisconnecting to Disconnecting state via
* Stack.DISCONNECTED message
*/
@Test
public void testStateTransition_AudioDisconnectingToDisconnected_StackDisconnected() {
int numBroadcastsSent = setUpAudioDisconnectingState();
// Send StackEvent.DISCONNECTED message
numBroadcastsSent += 2;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 2));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getAllValues().get(mIntentArgument.getAllValues().size() - 1));
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnected.class));
}
/**
* A test to verify that we correctly subscribe to phone state updates for service and signal
* strength information and further updates via AT+BIA command results in update
*/
@Test
public void testAtBiaEvent_initialSubscriptionWithUpdates() {
setUpConnectedState();
verify(mPhoneState).listenForPhoneState(mTestDevice, PhoneStateListener.LISTEN_SERVICE_STATE
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA,
new HeadsetAgIndicatorEnableState(true, true, false, false), mTestDevice));
verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice,
PhoneStateListener.LISTEN_SERVICE_STATE);
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA,
new HeadsetAgIndicatorEnableState(false, true, true, false), mTestDevice));
verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice,
PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_BIA,
new HeadsetAgIndicatorEnableState(false, true, false, false), mTestDevice));
verify(mPhoneState, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).listenForPhoneState(mTestDevice,
PhoneStateListener.LISTEN_NONE);
}
/**
* A test to verify that we correctly handles key pressed event from a HSP headset
*/
@Test
public void testKeyPressedEventWhenIdleAndAudioOff_dialCall() {
setUpConnectedState();
Cursor cursor = mock(Cursor.class);
when(cursor.getCount()).thenReturn(1);
when(cursor.moveToNext()).thenReturn(true);
int magicNumber = 42;
when(cursor.getColumnIndexOrThrow(CallLog.Calls.NUMBER)).thenReturn(magicNumber);
when(cursor.getString(magicNumber)).thenReturn(TEST_PHONE_NUMBER);
MockContentProvider mockContentProvider = new MockContentProvider() {
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
if (uri == null || !uri.equals(CallLog.Calls.CONTENT_URI)) {
return null;
}
if (projection == null || (projection.length == 0) || !projection[0].equals(
CallLog.Calls.NUMBER)) {
return null;
}
if (selection == null || !selection.equals(
CallLog.Calls.TYPE + "=" + CallLog.Calls.OUTGOING_TYPE)) {
return null;
}
if (selectionArgs != null) {
return null;
}
if (sortOrder == null || !sortOrder.equals(
CallLog.Calls.DEFAULT_SORT_ORDER + " LIMIT 1")) {
return null;
}
return cursor;
}
};
mMockContentResolver.addProvider(CallLog.AUTHORITY, mockContentProvider);
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice));
verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).dialOutgoingCall(mTestDevice,
TEST_PHONE_NUMBER);
}
/**
* A test to verify that we correctly handles key pressed event from a HSP headset
*/
@Test
public void testKeyPressedEventDuringRinging_answerCall() {
setUpConnectedState();
when(mSystemInterface.isRinging()).thenReturn(true);
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice));
verify(mSystemInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).answerCall(mTestDevice);
}
/**
* A test to verify that we correctly handles key pressed event from a HSP headset
*/
@Test
public void testKeyPressedEventInCallButAudioOff_setActiveDevice() {
setUpConnectedState();
when(mSystemInterface.isInCall()).thenReturn(true);
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice));
verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setActiveDevice(mTestDevice);
}
/**
* A test to verify that we correctly handles key pressed event from a HSP headset
*/
@Test
public void testKeyPressedEventInCallAndAudioOn_hangupCall() {
setUpAudioOnState();
when(mSystemInterface.isInCall()).thenReturn(true);
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice));
verify(mSystemInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).hangupCall(mTestDevice);
}
/**
* A test to verify that we correctly handles key pressed event from a HSP headset
*/
@Test
public void testKeyPressedEventWhenIdleAndAudioOn_disconnectAudio() {
setUpAudioOnState();
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_KEY_PRESSED, mTestDevice));
verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).disconnectAudio(mTestDevice);
}
/**
* Setup Connecting State
* @return number of times mHeadsetService.sendBroadcastAsUser() has been invoked
*/
private int setUpConnectingState() {
// Put test state machine in connecting state
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT, mTestDevice);
verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class));
return 1;
}
/**
* Setup Connected State
* @return number of times mHeadsetService.sendBroadcastAsUser() has been invoked
*/
private int setUpConnectedState() {
// Put test state machine into connected state
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_CONNECTED, mTestDevice));
verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connecting.class));
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED,
HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED, mTestDevice));
verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Connected.class));
return 2;
}
private int setUpAudioConnectingState() {
int numBroadcastsSent = setUpConnectedState();
// Send CONNECT_AUDIO
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.CONNECT_AUDIO, mTestDevice);
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_CONNECTING, BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioConnecting.class));
return numBroadcastsSent;
}
private int setUpAudioOnState() {
int numBroadcastsSent = setUpAudioConnectingState();
// Send StackEvent.AUDIO_DISCONNECTED message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.STACK_EVENT,
new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED,
HeadsetHalConstants.AUDIO_STATE_CONNECTED, mTestDevice));
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyAudioStateBroadcast(mTestDevice,
BluetoothHeadset.STATE_AUDIO_CONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTING,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioOn.class));
return numBroadcastsSent;
}
private int setUpAudioDisconnectingState() {
int numBroadcastsSent = setUpAudioOnState();
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT_AUDIO, mTestDevice);
// No new broadcast due to lack of AUDIO_DISCONNECTING intent variable
verify(mHeadsetService,
after(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
any(Intent.class), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.AudioDisconnecting.class));
return numBroadcastsSent;
}
private int setUpDisconnectingState() {
int numBroadcastsSent = setUpConnectedState();
// Send DISCONNECT message
numBroadcastsSent++;
mHeadsetStateMachine.sendMessage(HeadsetStateMachine.DISCONNECT, mTestDevice);
verify(mHeadsetService,
timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(numBroadcastsSent)).sendBroadcastAsUser(
mIntentArgument.capture(), eq(UserHandle.ALL), eq(HeadsetService.BLUETOOTH_PERM));
HeadsetTestUtils.verifyConnectionStateBroadcast(mTestDevice,
BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED,
mIntentArgument.getValue());
Assert.assertThat(mHeadsetStateMachine.getCurrentState(),
IsInstanceOf.instanceOf(HeadsetStateMachine.Disconnecting.class));
return numBroadcastsSent;
}
}