OSDN Git Service

BT: Multi A2dp support in Settings App.
authorGaurav Asati <gasati@codeaurora.org>
Tue, 28 Jul 2015 15:27:29 +0000 (20:57 +0530)
committerLinux Build Service Account <lnxbuild@localhost>
Wed, 24 Aug 2016 14:13:59 +0000 (08:13 -0600)
1. The connected sinks are not disconnected from
A2dpProfile when new sink is connecting.
2. Also return correct connection status for
specific HS.
3. Sets priority for specific HS while disconnecting.

Change-Id: I56142d1527aa86d2bb47fb7166b2f3ab451d9b17

Bluetooth: Add support of two A2dp connections.

Audio Service will now manage two a2dp connections
and makes sure that BT a2dp connections are
consistently seen by other applications.
The change removes the BD address usage in BT
names, and uses a new Strin "BluetoothA2dp"
in order to show A2dp connected devices.

Change-Id: I59b8f8eff7bbc8033fcd46d0ac21d94ee338ca36

Purge A2dp connected device list

Purge A2dp connected device list on A2dp service connect incase the
same is not purged during service disconnect earlier.

Change-Id: Ie4e7e79530eaf2ec138bb5d0c51996d4172eb4b9

Update A2DP device connection state properly.

Update Audio devices only for first connected
and last disconnected A2DP devices.

Change-Id: I3ac83e507e2b8c638a08881cd70f7900c9312391

packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java [changed mode: 0755->0644]
services/core/java/com/android/server/audio/AudioService.java

old mode 100755 (executable)
new mode 100644 (file)
index b9fb5aa..873d392
@@ -128,18 +128,36 @@ public final class A2dpProfile implements LocalBluetoothProfile {
 
     public boolean disconnect(BluetoothDevice device) {
         if (mService == null) return false;
-        // Downgrade priority as user is disconnecting the headset.
-        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
-            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+        if (!deviceList.isEmpty()) {
+            for (BluetoothDevice dev : deviceList) {
+                if (dev.equals(device)) {
+                    if (V) Log.d(TAG,"Downgrade priority as user" +
+                            "is disconnecting the headset");
+                    // Downgrade priority as user is disconnecting the headset.
+                    if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
+                        mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+                    }
+                    return mService.disconnect(device);
+                }
+            }
         }
-        return mService.disconnect(device);
+        return false;
     }
 
     public int getConnectionStatus(BluetoothDevice device) {
         if (mService == null) {
             return BluetoothProfile.STATE_DISCONNECTED;
         }
-        return mService.getConnectionState(device);
+        List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+        if (!deviceList.isEmpty()) {
+            for (BluetoothDevice dev : deviceList) {
+                if (dev.equals(device)) {
+                    return mService.getConnectionState(device);
+                }
+            }
+        }
+        return BluetoothProfile.STATE_DISCONNECTED;
     }
 
     public boolean isPreferred(BluetoothDevice device) {
index ee87713..4d8612e 100644 (file)
@@ -431,6 +431,11 @@ public class AudioService extends IAudioService.Stub {
 
     private final ArrayMap<String, DeviceListSpec> mConnectedDevices = new ArrayMap<>();
 
+    private String mA2dpConnectedDevice = ""; //Used for BT a2dp connection
+    //Add connected A2dp devices in this list
+    private ArrayList<BluetoothDevice> mConnectedBTDevicesList =
+            new ArrayList<BluetoothDevice>();
+
     // Forced device usage for communications
     private int mForcedUseForComm;
 
@@ -3131,9 +3136,18 @@ public class AudioService extends IAudioService.Stub {
                 synchronized (mConnectedDevices) {
                     synchronized (mA2dpAvrcpLock) {
                         mA2dp = (BluetoothA2dp) proxy;
+                        if (mConnectedBTDevicesList.size() > 0) {
+                            Log.d(TAG,"A2dp connection list not empty, purge it, size " +
+                                    mConnectedBTDevicesList.size());
+                            mConnectedBTDevicesList.clear();
+                        }
+                        //In Dual A2dp, we can have two devices connected
                         deviceList = mA2dp.getConnectedDevices();
-                        if (deviceList.size() > 0) {
-                            btDevice = deviceList.get(0);
+                        Log.d(TAG, "onServiceConnected: A2dp Service connected: " +
+                                deviceList.size());
+                        for (int i = 0; i < deviceList.size(); i++) {
+                            //Add the device in Connected list
+                            btDevice = deviceList.get(i);
                             int state = mA2dp.getConnectionState(btDevice);
                             int delay = checkSendBecomingNoisyIntent(
                                                 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
@@ -3256,6 +3270,10 @@ public class AudioService extends IAudioService.Stub {
         synchronized (mConnectedDevices) {
             synchronized (mA2dpAvrcpLock) {
                 ArraySet<String> toRemove = null;
+                Log.d(TAG,"mConnectedBTDevicesList size " + mConnectedBTDevicesList.size());
+                if (mConnectedBTDevicesList.size() > 0) {
+                    mConnectedBTDevicesList.clear();
+                }
                 // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices
                 for (int i = 0; i < mConnectedDevices.size(); i++) {
                     DeviceListSpec deviceSpec = mConnectedDevices.valueAt(i);
@@ -3813,10 +3831,41 @@ public class AudioService extends IAudioService.Stub {
 
     public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, int profile)
     {
-        int delay;
+        int delay = 0;
         if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK) {
             throw new IllegalArgumentException("invalid profile " + profile);
         }
+        /*check the state of the currnt device*/
+        if (state == BluetoothA2dp.STATE_CONNECTING) {
+            Log.d(TAG, "Device is still connecting ");
+            return delay;
+        }
+        if ((mConnectedBTDevicesList.contains(device) &&
+            (state == BluetoothA2dp.STATE_CONNECTED))) {
+            Log.d(TAG, "Device conn is updated again, ignore ");
+            return delay;
+        }
+        if (!mConnectedBTDevicesList.contains(device) &&
+            (state == BluetoothA2dp.STATE_CONNECTED)) {
+            /*add the device in the list*/
+            Log.d(TAG, "Add new connected device in the list: " + device);
+            mConnectedBTDevicesList.add(device);
+            if (mConnectedBTDevicesList.size() > 1) {
+                Log.d(TAG, "Second device connected, add new device ");
+                return delay;
+            }
+        } else if ((state == BluetoothA2dp.STATE_DISCONNECTED) ||
+            (state == BluetoothA2dp.STATE_DISCONNECTING)) {
+            Log.d(TAG, "Device is getting disconnected: " + device);
+            if (mConnectedBTDevicesList.contains(device)) {
+                Log.d(TAG, "Remove the BT device ");
+                mConnectedBTDevicesList.remove(device);
+            }
+            if (mConnectedBTDevicesList.size() > 0) {
+                Log.d(TAG, "Not all are disconnected ");
+                return delay;
+            }
+        }
         synchronized (mConnectedDevices) {
             if (profile == BluetoothProfile.A2DP) {
                 delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
@@ -4883,11 +4932,12 @@ public class AudioService extends IAudioService.Stub {
                         // introduction of a delay for transient disconnections of docks when
                         // power is rapidly turned off/on, this message will be canceled if
                         // we reconnect the dock under a preset delay
-                        makeA2dpDeviceUnavailableLater(address, BTA2DP_DOCK_TIMEOUT_MILLIS);
+                        makeA2dpDeviceUnavailableLater(btDevice.getAddress(), BTA2DP_DOCK_TIMEOUT_MILLIS);
                         // the next time isConnected is evaluated, it will be false for the dock
                     }
                 } else {
-                    makeA2dpDeviceUnavailableNow(address);
+                    Log.d(TAG, "All devices are disconneted, update Policymanager ");
+                    makeA2dpDeviceUnavailableNow(btDevice.getAddress());
                 }
                 synchronized (mCurAudioRoutes) {
                     if (mCurAudioRoutes.bluetoothName != null) {
@@ -4897,21 +4947,24 @@ public class AudioService extends IAudioService.Stub {
                     }
                 }
             } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
+                //This function is not implemented
+                mA2dpConnectedDevice = "BluetoothA2dp"; // Add this String
                 if (btDevice.isBluetoothDock()) {
                     // this could be a reconnection after a transient disconnection
                     cancelA2dpDeviceTimeout();
-                    mDockAddress = address;
+                    mDockAddress =  mA2dpConnectedDevice;
                 } else {
                     // this could be a connection of another A2DP device before the timeout of
                     // a dock: cancel the dock timeout, and make the dock unavailable now
                     if(hasScheduledA2dpDockTimeout()) {
                         cancelA2dpDeviceTimeout();
-                        makeA2dpDeviceUnavailableNow(mDockAddress);
+                        makeA2dpDeviceUnavailableNow(btDevice.getAddress());
                     }
                 }
-                makeA2dpDeviceAvailable(address, btDevice.getName());
+                makeA2dpDeviceAvailable(btDevice.getAddress(), btDevice.getName());
+                //Updated the Router for a2dp device
                 synchronized (mCurAudioRoutes) {
-                    String name = btDevice.getAliasName();
+                    String name = mA2dpConnectedDevice;
                     if (!TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) {
                         mCurAudioRoutes.bluetoothName = name;
                         sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
@@ -4928,6 +4981,7 @@ public class AudioService extends IAudioService.Stub {
             Log.d(TAG, "onSetA2dpSourceConnectionState btDevice="+btDevice+" state="+state);
         }
         if (btDevice == null) {
+            Log.d(TAG, "onSetA2dpSourceConnectionState device is null"); //gasati
             return;
         }
         String address = btDevice.getAddress();
@@ -5011,8 +5065,14 @@ public class AudioService extends IAudioService.Stub {
     // Called synchronized on mConnectedDevices
     private int checkSendBecomingNoisyIntent(int device, int state) {
         int delay = 0;
+        if (mConnectedBTDevicesList.size() > 1) {
+            Log.d(TAG, "checkSendBecomingNoisyIntent on state: " + state);
+            return delay;
+        }
+
         if ((state == 0) && ((device & mBecomingNoisyIntentDevices) != 0)) {
             int devices = 0;
+            Log.d(TAG, "checkSendBecomingNoisyIntent update the noise");
             for (int i = 0; i < mConnectedDevices.size(); i++) {
                 int dev = mConnectedDevices.valueAt(i).mDeviceType;
                 if (((dev & AudioSystem.DEVICE_BIT_IN) == 0)