Don't track speakerphone state outside calls

To prevent calls from starting in speakerphone, stop tracking
speakerphone state when not in a call.

Test: atest CallAudioRouteTransitionTests
Test: manual -- receive call while playing voicemail over speaker
Fixes: 152939693
Fixes: 161781504
Change-Id: I78d7e46fa6c99bf1e974f98fd4980077a99b39fe
(cherry picked from commit b40771835afff63619e9999d497df608b2755e1c)
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index a562021..28f9df9 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -459,6 +459,8 @@
             switch (msg.what) {
                 case SWITCH_EARPIECE:
                 case USER_SWITCH_EARPIECE:
+                case SPEAKER_ON:
+                    // Ignore speakerphone state changes outside of calls.
                 case SPEAKER_OFF:
                     // Nothing to do here
                     return HANDLED;
@@ -484,7 +486,6 @@
                     return HANDLED;
                 case SWITCH_SPEAKER:
                 case USER_SWITCH_SPEAKER:
-                case SPEAKER_ON:
                     transitionTo(mQuiescentSpeakerRoute);
                     return HANDLED;
                 case SWITCH_FOCUS:
@@ -677,12 +678,13 @@
                     return HANDLED;
                 case SWITCH_HEADSET:
                 case USER_SWITCH_HEADSET:
+                case SPEAKER_ON:
+                    // Ignore speakerphone state changes outside of calls.
                 case SPEAKER_OFF:
                     // Nothing to do
                     return HANDLED;
                 case SWITCH_SPEAKER:
                 case USER_SWITCH_SPEAKER:
-                case SPEAKER_ON:
                     transitionTo(mQuiescentSpeakerRoute);
                     return HANDLED;
                 case SWITCH_FOCUS:
@@ -1012,6 +1014,8 @@
                     return HANDLED;
                 case SWITCH_BLUETOOTH:
                 case USER_SWITCH_BLUETOOTH:
+                case SPEAKER_ON:
+                    // Ignore speakerphone state changes outside of calls.
                 case SPEAKER_OFF:
                     // Nothing to do
                     return HANDLED;
@@ -1025,7 +1029,6 @@
                     return HANDLED;
                 case SWITCH_SPEAKER:
                 case USER_SWITCH_SPEAKER:
-                case SPEAKER_ON:
                     transitionTo(mQuiescentSpeakerRoute);
                     return HANDLED;
                 case SWITCH_FOCUS:
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
index 58f1ee7..bf105e5 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteTransitionTests.java
@@ -384,8 +384,12 @@
         // rest of the system
         verifyNoSystemAudioChanges();
 
+        // Special case for SPEAKER_ON -- we don't expect any route transitions to happen when
+        // there are no calls, so set the expected state to the initial route.
+        int expectedRoute = (mParams.action == CallAudioRouteStateMachine.SPEAKER_ON)
+                ? mParams.initialRoute : mParams.expectedRoute;
         // Verify the end state
-        CallAudioState expectedState = new CallAudioState(false, mParams.expectedRoute,
+        CallAudioState expectedState = new CallAudioState(false, expectedRoute,
                 mParams.expectedAvailableRoutes | CallAudioState.ROUTE_SPEAKER,
                 mParams.expectedBluetoothDevice, mParams.availableBluetoothDevices);
         assertEquals(expectedState, stateMachine.getCurrentCallAudioState());