Merge "Add updates for the BT route for the UI." am: e3c69d3148 am: 5d0f794acf
am: 7413c03dc3

Change-Id: Icc335ae31811a75ed84551b26f9c8c01a983fa0b
diff --git a/src/com/android/server/telecom/CallAudioRoutePeripheralAdapter.java b/src/com/android/server/telecom/CallAudioRoutePeripheralAdapter.java
index a871dfc..2b6ba64 100644
--- a/src/com/android/server/telecom/CallAudioRoutePeripheralAdapter.java
+++ b/src/com/android/server/telecom/CallAudioRoutePeripheralAdapter.java
@@ -75,6 +75,12 @@
                 CallAudioRouteStateMachine.BT_AUDIO_DISCONNECTED);
     }
 
+    @Override
+    public void onUnexpectedBluetoothStateChange() {
+        mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
+                CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);
+    }
+
     /**
       * Updates the audio route when the headset plugged in state changes. For example, if audio is
       * being routed over speakerphone and a headset is plugged in then switch to wired headset.
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
index 8772cd5..e53488c 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
@@ -75,6 +75,12 @@
         void onBluetoothActiveDeviceGone();
         void onBluetoothAudioConnected();
         void onBluetoothAudioDisconnected();
+        /**
+         * This gets called when we get an unexpected state change from Bluetooth. Their stack does
+         * weird things sometimes, so this is really a signal for the listener to refresh their
+         * internal state and make sure it matches up with what the BT stack is doing.
+         */
+        void onUnexpectedBluetoothStateChange();
     }
 
     /**
@@ -186,6 +192,7 @@
                     case BT_AUDIO_LOST:
                         Log.i(LOG_TAG, "Received HFP off for device %s while HFP off.",
                                 (String) args.arg2);
+                        mListener.onUnexpectedBluetoothStateChange();
                         break;
                     case GET_CURRENT_STATE:
                         BlockingQueue<IState> sink = (BlockingQueue<IState>) args.arg3;
@@ -303,6 +310,7 @@
                         } else {
                             Log.w(LOG_TAG, "Got HFP lost message for device %s while" +
                                     " connecting to %s.", address, mDeviceAddress);
+                            mListener.onUnexpectedBluetoothStateChange();
                         }
                         break;
                     case GET_CURRENT_STATE:
@@ -412,6 +420,7 @@
                         } else {
                             Log.w(LOG_TAG, "Got HFP lost message for device %s while" +
                                     " connected to %s.", address, mDeviceAddress);
+                            mListener.onUnexpectedBluetoothStateChange();
                         }
                         break;
                     case GET_CURRENT_STATE:
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java b/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
index d2288c5..f87da3c 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
@@ -60,7 +60,7 @@
 public class BluetoothRouteTransitionTests extends TelecomTestCase {
     private enum ListenerUpdate {
         DEVICE_LIST_CHANGED, ACTIVE_DEVICE_PRESENT, ACTIVE_DEVICE_GONE,
-        AUDIO_CONNECTED, AUDIO_DISCONNECTED
+        AUDIO_CONNECTED, AUDIO_DISCONNECTED, UNEXPECTED_STATE_CHANGE
     }
 
     private static class BluetoothRouteTestParametersBuilder {
@@ -564,6 +564,19 @@
                 .build());
 
         result.add(new BluetoothRouteTestParametersBuilder()
+                .setName("Device gets audio-off while in another device's audio on state")
+                .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
+                .setInitialDevice(DEVICE2)
+                .setConnectedDevices(DEVICE2, DEVICE1)
+                .setMessageType(BluetoothRouteManager.BT_AUDIO_LOST)
+                .setMessageDevice(DEVICE1)
+                .setExpectedListenerUpdates(ListenerUpdate.UNEXPECTED_STATE_CHANGE)
+                .setExpectedBluetoothInteraction(NONE)
+                .setExpectedFinalStateName(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
+                        + ":" + DEVICE2)
+                .build());
+
+        result.add(new BluetoothRouteTestParametersBuilder()
                 .setName("Audio routing requests HFP disconnection while a device is active")
                 .setInitialBluetoothState(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX)
                 .setInitialDevice(DEVICE2)