Merge "Switch to active BT route when changing focus" into pi-dev
diff --git a/src/com/android/server/telecom/BluetoothHeadsetProxy.java b/src/com/android/server/telecom/BluetoothHeadsetProxy.java
index f32f454..0f492df 100644
--- a/src/com/android/server/telecom/BluetoothHeadsetProxy.java
+++ b/src/com/android/server/telecom/BluetoothHeadsetProxy.java
@@ -56,8 +56,8 @@
return mBluetoothHeadset.getConnectionState(device);
}
- public boolean isAudioConnected(BluetoothDevice device) {
- return mBluetoothHeadset.isAudioConnected(device);
+ public int getAudioState(BluetoothDevice device) {
+ return mBluetoothHeadset.getAudioState(device);
}
public boolean connectAudio() {
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index 0d96ccb..4274017 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -1452,7 +1452,10 @@
BluetoothDevice connectedDevice =
mBluetoothRouteManager.getBluetoothAudioConnectedDevice();
if (address == null && connectedDevice != null) {
- // null means connect to any device, so don't bother reconnecting
+ // null means connect to any device, so don't bother reconnecting. Also, send a
+ // message to ourselves telling us that BT audio is already connected.
+ Log.i(this, "HFP audio already on. Skipping connecting.");
+ sendInternalMessage(BT_AUDIO_CONNECTED);
return;
}
if (connectedDevice == null || !Objects.equals(address, connectedDevice.getAddress())) {
@@ -1630,7 +1633,7 @@
return UserHandle.USER_OWNER;
}
- private boolean isInActiveState() {
+ public boolean isInActiveState() {
AudioState currentState = (AudioState) getCurrentState();
if (currentState == null) {
Log.w(this, "Current state is null, assuming inactive state");
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
index 298129a..ba56145 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
@@ -17,6 +17,7 @@
package com.android.server.telecom.bluetooth;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
import android.content.Context;
import android.os.Message;
import android.telecom.Log;
@@ -653,7 +654,8 @@
for (int i = 0; i < deviceList.size(); i++) {
BluetoothDevice device = deviceList.get(i);
- boolean isAudioOn = bluetoothHeadset.isAudioConnected(device);
+ boolean isAudioOn = bluetoothHeadset.getAudioState(device)
+ != BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
Log.v(this, "isBluetoothAudioConnected: ==> isAudioOn = " + isAudioOn
+ "for headset: " + device);
if (isAudioOn) {
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java b/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
index 30848f8..5b45828 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
@@ -17,6 +17,7 @@
package com.android.server.telecom.tests;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
import android.content.ContentResolver;
import android.os.Parcel;
import android.telecom.Log;
@@ -130,7 +131,8 @@
when(mDeviceManager.getConnectedDevices()).thenReturn(Arrays.asList(devices));
when(mHeadsetProxy.getConnectedDevices()).thenReturn(Arrays.asList(devices));
if (activeDevice != null) {
- when(mHeadsetProxy.isAudioConnected(eq(activeDevice))).thenReturn(true);
+ when(mHeadsetProxy.getAudioState(eq(activeDevice)))
+ .thenReturn(BluetoothHeadset.STATE_AUDIO_CONNECTED);
}
doAnswer(invocation -> {
BluetoothDevice first = getFirstExcluding(devices,
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java b/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
index b9c1427..e7cd6ee 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
@@ -17,6 +17,7 @@
package com.android.server.telecom.tests;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
import android.content.ContentResolver;
import android.test.suitebuilder.annotation.SmallTest;
@@ -306,7 +307,8 @@
when(mHeadsetProxy.getConnectedDevices()).thenReturn(Arrays.asList(devices));
when(mHeadsetProxy.getActiveDevice()).thenReturn(activeDevice);
if (audioOnDevice != null) {
- when(mHeadsetProxy.isAudioConnected(eq(audioOnDevice))).thenReturn(true);
+ when(mHeadsetProxy.getAudioState(eq(audioOnDevice)))
+ .thenReturn(BluetoothHeadset.STATE_AUDIO_CONNECTED);
}
doAnswer(invocation -> {
BluetoothDevice first = getFirstExcluding(devices,
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
index 6330996..9c90d3e 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -433,6 +433,46 @@
@SmallTest
@Test
+ public void testFocusChangeWithAlreadyActiveBtDevice() {
+ CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
+ mContext,
+ mockCallsManager,
+ mockBluetoothRouteManager,
+ mockWiredHeadsetManager,
+ mockStatusBarNotifier,
+ mAudioServiceFactory,
+ CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
+ stateMachine.setCallAudioManager(mockCallAudioManager);
+ List<BluetoothDevice> availableDevices =
+ Arrays.asList(bluetoothDevice1, bluetoothDevice2);
+
+ // Set up a state where there's an HFP connected bluetooth device already.
+ when(mockAudioManager.isSpeakerphoneOn()).thenReturn(false);
+ when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(true);
+ when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
+ when(mockBluetoothRouteManager.getConnectedDevices()).thenReturn(availableDevices);
+ when(mockBluetoothRouteManager.getBluetoothAudioConnectedDevice())
+ .thenReturn(bluetoothDevice1);
+
+ // We want to be in the QuiescentBluetoothRoute because there's no call yet
+ CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
+ CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH,
+ bluetoothDevice1, availableDevices);
+ stateMachine.initialize(initState);
+
+ // Switch to active, pretending that a call came in.
+ stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
+ CallAudioRouteStateMachine.ACTIVE_FOCUS);
+ waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);
+
+ // Make sure that we've successfully switched to the active BT route without actually
+ // calling connectAudio.
+ verify(mockBluetoothRouteManager, never()).connectBluetoothAudio(nullable(String.class));
+ assertTrue(stateMachine.isInActiveState());
+ }
+
+ @SmallTest
+ @Test
public void testInitializationWithEarpieceNoHeadsetNoBluetooth() {
CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_EARPIECE,
CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER);