Include Bluetooth in baseline route calculations
Include Bluetooth in baseline route calculations to handle the scenario
where a wired headset is connected-and-disconnected while a call is on
bluetooth.
Change-Id: Ia4e4f499f1eef74e9f67c5c06e21e04befa9adfd
Fixes: 62391035
Test: ran unit tests
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 6a91b18..ee5478f 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -406,7 +406,8 @@
return;
case CallAudioState.ROUTE_WIRED_OR_EARPIECE:
mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
- CallAudioRouteStateMachine.USER_SWITCH_BASELINE_ROUTE);
+ CallAudioRouteStateMachine.USER_SWITCH_BASELINE_ROUTE,
+ CallAudioRouteStateMachine.NO_INCLUDE_BLUETOOTH_IN_BASELINE);
return;
default:
Log.wtf(this, "Invalid route specified: %d", route);
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index 8663066..0585377 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -119,6 +119,10 @@
public static final int ACTIVE_FOCUS = 2;
public static final int RINGING_FOCUS = 3;
+ /** Valid values for the argument for SWITCH_BASELINE_ROUTE */
+ public static final int NO_INCLUDE_BLUETOOTH_IN_BASELINE = 0;
+ public static final int INCLUDE_BLUETOOTH_IN_BASELINE = 1;
+
private static final SparseArray<String> AUDIO_ROUTE_TO_LOG_EVENT = new SparseArray<String>() {{
put(CallAudioState.ROUTE_BLUETOOTH, LogUtils.Events.AUDIO_ROUTE_BT);
put(CallAudioState.ROUTE_EARPIECE, LogUtils.Events.AUDIO_ROUTE_EARPIECE);
@@ -273,10 +277,12 @@
removedRoutes |= ROUTE_BLUETOOTH;
break;
case SWITCH_BASELINE_ROUTE:
- sendInternalMessage(calculateBaselineRouteMessage(false));
+ sendInternalMessage(calculateBaselineRouteMessage(false,
+ msg.arg1 == INCLUDE_BLUETOOTH_IN_BASELINE));
return HANDLED;
case USER_SWITCH_BASELINE_ROUTE:
- sendInternalMessage(calculateBaselineRouteMessage(true));
+ sendInternalMessage(calculateBaselineRouteMessage(true,
+ msg.arg1 == INCLUDE_BLUETOOTH_IN_BASELINE));
return HANDLED;
case SWITCH_FOCUS:
mAudioFocusType = msg.arg1;
@@ -654,7 +660,7 @@
if (mWasOnSpeaker) {
sendInternalMessage(SWITCH_SPEAKER);
} else {
- sendInternalMessage(SWITCH_BASELINE_ROUTE);
+ sendInternalMessage(SWITCH_BASELINE_ROUTE, INCLUDE_BLUETOOTH_IN_BASELINE);
}
return HANDLED;
case BT_AUDIO_DISCONNECT:
@@ -744,7 +750,7 @@
}
return HANDLED;
case BT_AUDIO_DISCONNECT:
- sendInternalMessage(SWITCH_BASELINE_ROUTE);
+ sendInternalMessage(SWITCH_BASELINE_ROUTE, NO_INCLUDE_BLUETOOTH_IN_BASELINE);
return HANDLED;
default:
return NOT_HANDLED;
@@ -825,7 +831,7 @@
return HANDLED;
case BT_AUDIO_DISCONNECT:
// BT SCO might be connected when in-band ringing is enabled
- sendInternalMessage(SWITCH_BASELINE_ROUTE);
+ sendInternalMessage(SWITCH_BASELINE_ROUTE, NO_INCLUDE_BLUETOOTH_IN_BASELINE);
return HANDLED;
default:
return NOT_HANDLED;
@@ -920,7 +926,7 @@
// in the bluetooth route.
return HANDLED;
case DISCONNECT_BLUETOOTH:
- sendInternalMessage(SWITCH_BASELINE_ROUTE);
+ sendInternalMessage(SWITCH_BASELINE_ROUTE, NO_INCLUDE_BLUETOOTH_IN_BASELINE);
mWasOnSpeaker = false;
return HANDLED;
case DISCONNECT_WIRED_HEADSET:
@@ -1124,7 +1130,7 @@
// Nothing to do here
return HANDLED;
case DISCONNECT_DOCK:
- sendInternalMessage(SWITCH_BASELINE_ROUTE);
+ sendInternalMessage(SWITCH_BASELINE_ROUTE, INCLUDE_BLUETOOTH_IN_BASELINE);
return HANDLED;
default:
return NOT_HANDLED;
@@ -1486,6 +1492,10 @@
}
private void sendInternalMessage(int messageCode) {
+ sendInternalMessage(messageCode, 0);
+ }
+
+ private void sendInternalMessage(int messageCode, int arg1) {
// Internal messages are messages which the state machine sends to itself in the
// course of processing externally-sourced messages. We want to send these messages at
// the front of the queue in order to make actions appear atomic to the user and to
@@ -1500,9 +1510,9 @@
// 7. State machine handler processes SWITCH_HEADSET.
Session subsession = Log.createSubsession();
if(subsession != null) {
- sendMessageAtFrontOfQueue(messageCode, subsession);
+ sendMessageAtFrontOfQueue(messageCode, arg1, 0, subsession);
} else {
- sendMessageAtFrontOfQueue(messageCode);
+ sendMessageAtFrontOfQueue(messageCode, arg1);
}
}
@@ -1555,7 +1565,8 @@
return true;
}
- private int calculateBaselineRouteMessage(boolean isExplicitUserRequest) {
+ private int calculateBaselineRouteMessage(boolean isExplicitUserRequest,
+ boolean includeBluetooth) {
boolean isSkipEarpiece = false;
if (!isExplicitUserRequest) {
synchronized (mLock) {
@@ -1564,7 +1575,11 @@
isSkipEarpiece = mCallsManager.hasVideoCall();
}
}
- if ((mAvailableRoutes & ROUTE_EARPIECE) != 0 && !isSkipEarpiece) {
+ if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0
+ && !mHasUserExplicitlyLeftBluetooth
+ && includeBluetooth) {
+ return isExplicitUserRequest ? USER_SWITCH_BLUETOOTH : SWITCH_BLUETOOTH;
+ } else if ((mAvailableRoutes & ROUTE_EARPIECE) != 0 && !isSkipEarpiece) {
return isExplicitUserRequest ? USER_SWITCH_EARPIECE : SWITCH_EARPIECE;
} else if ((mAvailableRoutes & ROUTE_WIRED_HEADSET) != 0) {
return isExplicitUserRequest ? USER_SWITCH_HEADSET : SWITCH_HEADSET;
@@ -1592,7 +1607,7 @@
// Move to baseline route in the case the current route is no longer available.
if ((mAvailableRoutes & currentState.getRoute()) == 0) {
- sendInternalMessage(calculateBaselineRouteMessage(false));
+ sendInternalMessage(calculateBaselineRouteMessage(false, true));
}
}
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
index 95d6d51..8d5184d 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -516,7 +516,7 @@
NONE, // speakerInteraction
NONE, // bluetoothInteraction
CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
- CallAudioState.ROUTE_EARPIECE, // expectedRoute
+ CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
NotificationManager.INTERRUPTION_FILTER_ALARMS, // expectedNotificationFilter
true, // isNotificationChangeExpected