Fix tests for CallAudioRouteStateMachine

Fix tests that were broken, add some more for untested new
functionality.

Test: unit tests
Change-Id: I688592bf68187b2dda7bc1f02009e3fb360ea0ab
Fix: 33252757
(cherry picked from commit cff959e60f914754961fde4bcca1a97cd363d1ad)
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index fe254d5..18c9c05 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -1078,7 +1078,7 @@
         }
     }
 
-    int getSupportedAudioRoutes() {
+    public int getSupportedAudioRoutes() {
         return mSupportedAudioRoutes;
     }
 
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index 69742ac..f80239e 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -205,16 +205,6 @@
         Log.endSession();
     }
 
-    private int getCurrentCallSupportedRoutes() {
-        int supportedRoutes = CallAudioState.ROUTE_ALL;
-
-        if (mCallsManager.getForegroundCall() != null) {
-            supportedRoutes &= mCallsManager.getForegroundCall().getSupportedAudioRoutes();
-        }
-
-        return supportedRoutes;
-    }
-
     abstract class AudioState extends State {
         @Override
         public void enter() {
@@ -287,18 +277,6 @@
         abstract public boolean isActive();
     }
 
-    private int modifyRoutes(int base, int remove, int add, boolean considerCurrentCall) {
-        base &= ~remove;
-
-        if (considerCurrentCall) {
-            add &= getCurrentCallSupportedRoutes();
-        }
-
-        base |= add;
-
-        return base;
-    }
-
     class ActiveEarpieceRoute extends EarpieceRoute {
         @Override
         public String getName() {
@@ -1236,14 +1214,14 @@
 
     public void initialize(CallAudioState initState) {
         if ((initState.getRoute() & getCurrentCallSupportedRoutes()) == 0) {
-            Log.e(this, new IllegalArgumentException(), "Route " + initState.getRoute()
-                    + "specified when supported call routes are:" + getCurrentCallSupportedRoutes());
+            Log.e(this, new IllegalArgumentException(), "Route %d specified when supported call" +
+                    " routes are: %d", initState.getRoute(), getCurrentCallSupportedRoutes());
         }
 
         mCurrentCallAudioState = initState;
         mLastKnownCallAudioState = initState;
         mDeviceSupportedRoutes = initState.getSupportedRouteMask();
-        mAvailableRoutes = mDeviceSupportedRoutes;
+        mAvailableRoutes = mDeviceSupportedRoutes & getCurrentCallSupportedRoutes();
         mIsMuted = initState.isMuted();
         mWasOnSpeaker = false;
 
@@ -1552,13 +1530,8 @@
             return isExplicitUserRequest ? USER_SWITCH_EARPIECE : SWITCH_EARPIECE;
         } else if ((mAvailableRoutes & ROUTE_WIRED_HEADSET) != 0) {
             return isExplicitUserRequest ? USER_SWITCH_HEADSET : SWITCH_HEADSET;
-        } else if (!mDoesDeviceSupportEarpieceRoute) {
-            return isExplicitUserRequest ? USER_SWITCH_SPEAKER : SWITCH_SPEAKER;
         } else {
-            Log.e(this, new IllegalStateException(),
-                    "Neither headset nor earpiece are available, but there is an " +
-                            "earpiece on the device. Defaulting to earpiece.");
-            return isExplicitUserRequest ? USER_SWITCH_EARPIECE : SWITCH_EARPIECE;
+            return isExplicitUserRequest ? USER_SWITCH_SPEAKER : SWITCH_SPEAKER;
         }
     }
 
@@ -1584,4 +1557,26 @@
             sendInternalMessage(calculateBaselineRouteMessage(false));
         }
     }
+
+    private int getCurrentCallSupportedRoutes() {
+        int supportedRoutes = CallAudioState.ROUTE_ALL;
+
+        if (mCallsManager.getForegroundCall() != null) {
+            supportedRoutes &= mCallsManager.getForegroundCall().getSupportedAudioRoutes();
+        }
+
+        return supportedRoutes;
+    }
+
+    private int modifyRoutes(int base, int remove, int add, boolean considerCurrentCall) {
+        base &= ~remove;
+
+        if (considerCurrentCall) {
+            add &= getCurrentCallSupportedRoutes();
+        }
+
+        base |= add;
+
+        return base;
+    }
 }
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
index dddf9e6..0766b72 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -86,6 +86,8 @@
         public boolean doesDeviceSupportEarpiece; // set to false in the case of Wear devices
         public boolean shouldRunWithFocus;
 
+        public int callSupportedRoutes = CallAudioState.ROUTE_ALL;
+
         public RoutingTestParameters(String name, int initialRoute,
                 int initialNotificationFilter, int availableRoutes, int speakerInteraction,
                 int bluetoothInteraction, int action, int expectedRoute,
@@ -107,6 +109,11 @@
             this.shouldRunWithFocus = shouldRunWithFocus;
         }
 
+        public RoutingTestParameters setCallSupportedRoutes(int routes) {
+            callSupportedRoutes = routes;
+            return this;
+        }
+
         @Override
         public String toString() {
             return "RoutingTestParameters{" +
@@ -159,6 +166,7 @@
         when(mockCallsManager.getLock()).thenReturn(mLock);
         when(fakeCall.getConnectionService()).thenReturn(mockConnectionServiceWrapper);
         when(fakeCall.isAlive()).thenReturn(true);
+        when(fakeCall.getSupportedAudioRoutes()).thenReturn(CallAudioState.ROUTE_ALL);
         setupInterruptionFilterMocks();
 
         doNothing().when(mockConnectionServiceWrapper).onCallAudioStateChanged(any(Call.class),
@@ -878,6 +886,38 @@
                 shouldRunWithFocus
         ));
 
+        params.add(new RoutingTestParameters(
+                "Disconnect wired headset when call doesn't support earpiece", // name
+                CallAudioState.ROUTE_WIRED_HEADSET, // initialRoute
+                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
+                CallAudioState.ROUTE_WIRED_HEADSET, // availableRoutes
+                ON, // speakerInteraction
+                NONE, // bluetoothInteraction
+                CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
+                CallAudioState.ROUTE_SPEAKER, // expectedRoute
+                CallAudioState.ROUTE_SPEAKER, // expectedAvailableRoutes
+                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
+                false, // isNotificationChangeExpected
+                true, // doesDeviceSupportEarpiece
+                shouldRunWithFocus
+        ).setCallSupportedRoutes(CallAudioState.ROUTE_ALL & ~CallAudioState.ROUTE_EARPIECE));
+
+        params.add(new RoutingTestParameters(
+                "Disconnect bluetooth when call does not support earpiece", // name
+                CallAudioState.ROUTE_BLUETOOTH, // initialRoute
+                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
+                CallAudioState.ROUTE_BLUETOOTH,  // availableRoutes
+                ON, // speakerInteraction
+                OFF, // bluetoothInteraction
+                CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
+                CallAudioState.ROUTE_SPEAKER, // expectedRoute
+                CallAudioState.ROUTE_SPEAKER, // expectedAvailableRoutes
+                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
+                false, // isNotificationChangeExpected
+                true, // doesDeviceSupportEarpiece
+                shouldRunWithFocus
+        ).setCallSupportedRoutes(CallAudioState.ROUTE_ALL & ~CallAudioState.ROUTE_EARPIECE));
+
         return params;
     }
 
@@ -916,6 +956,7 @@
                         || (params.expectedAvailableRoutes & CallAudioState.ROUTE_BLUETOOTH) != 0);
         doReturn(params.initialRoute == CallAudioState.ROUTE_SPEAKER).when(mockAudioManager).
                 isSpeakerphoneOn();
+        when(fakeCall.getSupportedAudioRoutes()).thenReturn(params.callSupportedRoutes);
 
         // Set the initial CallAudioState object
         final CallAudioState initState = new CallAudioState(false,
@@ -999,6 +1040,7 @@
                 || (params.expectedAvailableRoutes & CallAudioState.ROUTE_BLUETOOTH) != 0);
         when(mockAudioManager.isSpeakerphoneOn()).thenReturn(
                 params.initialRoute == CallAudioState.ROUTE_SPEAKER);
+        when(fakeCall.getSupportedAudioRoutes()).thenReturn(params.callSupportedRoutes);
 
         // Set the initial CallAudioState object
         CallAudioState initState = new CallAudioState(false,
@@ -1051,10 +1093,13 @@
 
     private void resetMocks() {
         reset(mockAudioManager, mockBluetoothManager, mockCallsManager,
-                mockConnectionServiceWrapper, mMockInterruptionFilterProxy);
+                mockConnectionServiceWrapper, mMockInterruptionFilterProxy, fakeCall);
         mMockInterruptionFilterProxy = mock(InterruptionFilterProxy.class);
         setupInterruptionFilterMocks();
         when(mockCallsManager.getForegroundCall()).thenReturn(fakeCall);
+        when(fakeCall.getConnectionService()).thenReturn(mockConnectionServiceWrapper);
+        when(fakeCall.isAlive()).thenReturn(true);
+        when(fakeCall.getSupportedAudioRoutes()).thenReturn(CallAudioState.ROUTE_ALL);
         when(mockCallsManager.getLock()).thenReturn(mLock);
         doNothing().when(mockConnectionServiceWrapper).onCallAudioStateChanged(any(Call.class),
                 any(CallAudioState.class));