Add API to get Active Sinks.

Allow incoming connections only when there are no active sinks.

Dr No: Eastham
Bug: 2133530
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 7df3637..fda9b81 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -199,6 +199,22 @@
         }
     }
 
+    /** Check if any A2DP sink is in Non Disconnected state
+     * i.e playing, connected, connecting, disconnecting.
+     * @return a unmodifiable set of connected A2DP sinks, or null on error.
+     * @hide
+     */
+    public Set<BluetoothDevice> getNonDisconnectedSinks() {
+        if (DBG) log("getNonDisconnectedSinks()");
+        try {
+            return Collections.unmodifiableSet(
+                    new HashSet<BluetoothDevice>(Arrays.asList(mService.getNonDisconnectedSinks())));
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+            return null;
+        }
+    }
+
     /** Get the state of an A2DP sink
      *  @param device Remote BT device.
      *  @return State code, one of STATE_
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index 002cf4e..168fe3b 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -29,6 +29,7 @@
     boolean suspendSink(in BluetoothDevice device);
     boolean resumeSink(in BluetoothDevice device);
     BluetoothDevice[] getConnectedSinks();  // change to Set<> once AIDL supports
+    BluetoothDevice[] getNonDisconnectedSinks();  // change to Set<> once AIDL supports
     int getSinkState(in BluetoothDevice device);
     boolean setSinkPriority(in BluetoothDevice device, int priority);
     int getSinkPriority(in BluetoothDevice device);
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index 46de708..f2e132b 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -376,6 +376,16 @@
         return sinks.toArray(new BluetoothDevice[sinks.size()]);
     }
 
+    public synchronized BluetoothDevice[] getNonDisconnectedSinks() {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        Set<BluetoothDevice> sinks = lookupSinksMatchingStates(
+                new int[] {BluetoothA2dp.STATE_CONNECTED,
+                           BluetoothA2dp.STATE_PLAYING,
+                           BluetoothA2dp.STATE_CONNECTING,
+                           BluetoothA2dp.STATE_DISCONNECTING});
+        return sinks.toArray(new BluetoothDevice[sinks.size()]);
+    }
+
     public synchronized int getSinkState(BluetoothDevice device) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         Integer state = mAudioDevices.get(device);
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index e960491..0d0d245 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -546,12 +546,14 @@
 
         boolean authorized = false;
         ParcelUuid uuid = ParcelUuid.fromString(deviceUuid);
+        BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+
         // Bluez sends the UUID of the local service being accessed, _not_ the
         // remote service
         if (mBluetoothService.isEnabled() &&
                 (BluetoothUuid.isAudioSource(uuid) || BluetoothUuid.isAvrcpTarget(uuid)
-                        || BluetoothUuid.isAdvAudioDist(uuid))) {
-            BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+                        || BluetoothUuid.isAdvAudioDist(uuid)) &&
+                        (a2dp.getNonDisconnectedSinks().size() == 0)) {
             BluetoothDevice device = mAdapter.getRemoteDevice(address);
             authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF;
             if (authorized) {