Merge "Show the connected device more reliably"
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 41f9f09..3d879f5 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -22,6 +22,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
 import java.util.TreeSet;
 
 /**
@@ -176,6 +177,19 @@
         }
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        AudioDeviceInfo that = (AudioDeviceInfo) o;
+        return Objects.equals(getPort(), that.getPort());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getPort());
+    }
+
     private final AudioDevicePort mPort;
 
     AudioDeviceInfo(AudioDevicePort port) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index b031bdd..9aee00e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -59,7 +59,9 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
@@ -109,8 +111,10 @@
     private boolean mShowVolumeDialog;
     private boolean mShowSafetyWarning;
     private DeviceCallback mDeviceCallback = new DeviceCallback();
-    private AudioDeviceInfo mConnectedDevice;
     private final NotificationManager mNotificationManager;
+    @GuardedBy("mLock")
+    private List<AudioDeviceInfo> mConnectedDevices = new ArrayList<>();
+    private Object mLock = new Object();
 
     private boolean mDestroyed;
     private VolumePolicy mVolumePolicy;
@@ -1055,26 +1059,25 @@
 
     protected final class DeviceCallback extends AudioDeviceCallback {
         public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
-            for (AudioDeviceInfo info : addedDevices) {
-                if (info.isSink()
-                        && (info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
-                        || info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_SCO)) {
-                    mConnectedDevice = info;
-                    mCallbacks.onConnectedDeviceChanged(info.getProductName().toString());
+            synchronized (mLock) {
+                for (AudioDeviceInfo info : addedDevices) {
+                    if (info.isSink()
+                            && (info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
+                            || info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_SCO)) {
+                        mConnectedDevices.add(info);
+                        mCallbacks.onConnectedDeviceChanged(info.getProductName().toString());
+                    }
                 }
             }
         }
 
         public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
-            if (mConnectedDevice == null) {
-                mCallbacks.onConnectedDeviceChanged(null);
-                return;
-            }
-            for (AudioDeviceInfo info : removedDevices) {
-                if (info.isSink() == mConnectedDevice.isSink()
-                        && Objects.equals(info.getProductName(), mConnectedDevice.getProductName())
-                        && info.getType() == mConnectedDevice.getType()) {
-                    mConnectedDevice = null;
+            synchronized (mLock) {
+                for (AudioDeviceInfo info : removedDevices) {
+                    mConnectedDevices.remove(info);
+                }
+
+                if (mConnectedDevices.size() == 0) {
                     mCallbacks.onConnectedDeviceChanged(null);
                 }
             }