Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0a40ec21 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

Add Audio Manager support for Bluetooth A2DP Sink profile

Change-Id: Iff6035e85faf52647cc41a59f98ba2924300eb8d
parent 8c2a8288
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -103,6 +103,12 @@ public interface BluetoothProfile {
     */
    public static final int MAP = 9;

    /**
     * A2DP Sink Profile
     * @hide
     */
    public static final int A2DP_SINK = 10;

    /**
     * Default priority for devices that we try to auto-connect to and
     * and allow incoming connections for the profile
+7 −3
Original line number Diff line number Diff line
@@ -2818,18 +2818,22 @@ public class AudioManager {
    }

     /**
     * Indicate A2DP sink connection state change.
     * Indicate A2DP source or sink connection state change.
     * @param device Bluetooth device connected/disconnected
     * @param state  new connection state (BluetoothProfile.STATE_xxx)
     * @param profile profile for the A2DP device
     * (either {@link android.bluetooth.BluetoothProfile.A2DP} or
     * {@link android.bluetooth.BluetoothProfile.A2DP_SINK})
     * @return a delay in ms that the caller should wait before broadcasting
     * BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent.
     * {@hide}
     */
    public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state) {
    public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state,
            int profile) {
        IAudioService service = getService();
        int delay = 0;
        try {
            delay = service.setBluetoothA2dpDeviceConnectionState(device, state);
            delay = service.setBluetoothA2dpDeviceConnectionState(device, state, profile);
        } catch (RemoteException e) {
            Log.e(TAG, "Dead object in setBluetoothA2dpDeviceConnectionState "+e);
        } finally {
+98 −13
Original line number Diff line number Diff line
@@ -169,7 +169,8 @@ public class AudioService extends IAudioService.Stub {
    //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
    //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 100;
    private static final int MSG_SET_A2DP_CONNECTION_STATE = 101;
    private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101;
    private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102;
    // end of messages handled under wakelock

    private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
@@ -2374,7 +2375,7 @@ public class AudioService extends IAudioService.Stub {
                                                AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                                                (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
                            queueMsgUnderWakeLock(mAudioHandler,
                                    MSG_SET_A2DP_CONNECTION_STATE,
                                    MSG_SET_A2DP_SINK_CONNECTION_STATE,
                                    state,
                                    0,
                                    btDevice,
@@ -2384,6 +2385,22 @@ public class AudioService extends IAudioService.Stub {
                }
                break;

            case BluetoothProfile.A2DP_SINK:
                deviceList = proxy.getConnectedDevices();
                if (deviceList.size() > 0) {
                    btDevice = deviceList.get(0);
                    synchronized (mConnectedDevices) {
                        int state = proxy.getConnectionState(btDevice);
                        queueMsgUnderWakeLock(mAudioHandler,
                                MSG_SET_A2DP_SRC_CONNECTION_STATE,
                                state,
                                0,
                                btDevice,
                                0 /* delay */);
                    }
                }
                break;

            case BluetoothProfile.HEADSET:
                synchronized (mScoClients) {
                    // Discard timeout message
@@ -2452,6 +2469,15 @@ public class AudioService extends IAudioService.Stub {
                }
                break;

            case BluetoothProfile.A2DP_SINK:
                synchronized (mConnectedDevices) {
                    if (mConnectedDevices.containsKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP)) {
                        makeA2dpSrcUnavailable(
                                mConnectedDevices.get(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP));
                    }
                }
                break;

            case BluetoothProfile.HEADSET:
                synchronized (mScoClients) {
                    mBluetoothHeadset = null;
@@ -2863,14 +2889,22 @@ public class AudioService extends IAudioService.Stub {
        }
    }

    public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state)
    public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, int profile)
    {
        int delay;
        if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK) {
            throw new IllegalArgumentException("invalid profile " + profile);
        }
        synchronized (mConnectedDevices) {
            if (profile == BluetoothProfile.A2DP) {
                delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                                                (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
            } else {
                delay = 0;
            }
            queueMsgUnderWakeLock(mAudioHandler,
                    MSG_SET_A2DP_CONNECTION_STATE,
                    (profile == BluetoothProfile.A2DP ?
                        MSG_SET_A2DP_SINK_CONNECTION_STATE : MSG_SET_A2DP_SRC_CONNECTION_STATE),
                    state,
                    0,
                    device,
@@ -3726,8 +3760,13 @@ public class AudioService extends IAudioService.Stub {
                    mAudioEventWakeLock.release();
                    break;

                case MSG_SET_A2DP_CONNECTION_STATE:
                    onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
                case MSG_SET_A2DP_SRC_CONNECTION_STATE:
                    onSetA2dpSourceConnectionState((BluetoothDevice)msg.obj, msg.arg1);
                    mAudioEventWakeLock.release();
                    break;

                case MSG_SET_A2DP_SINK_CONNECTION_STATE:
                    onSetA2dpSinkConnectionState((BluetoothDevice)msg.obj, msg.arg1);
                    mAudioEventWakeLock.release();
                    break;

@@ -3853,6 +3892,23 @@ public class AudioService extends IAudioService.Stub {

    }

    // must be called synchronized on mConnectedDevices
    private void makeA2dpSrcAvailable(String address) {
        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
                AudioSystem.DEVICE_STATE_AVAILABLE,
                address);
        mConnectedDevices.put( new Integer(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP),
                address);
    }

    // must be called synchronized on mConnectedDevices
    private void makeA2dpSrcUnavailable(String address) {
        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
                AudioSystem.DEVICE_STATE_UNAVAILABLE,
                address);
        mConnectedDevices.remove(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP);
    }

    // must be called synchronized on mConnectedDevices
    private void cancelA2dpDeviceTimeout() {
        mAudioHandler.removeMessages(MSG_BTA2DP_DOCK_TIMEOUT);
@@ -3863,9 +3919,11 @@ public class AudioService extends IAudioService.Stub {
        return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT);
    }

    private void onSetA2dpConnectionState(BluetoothDevice btDevice, int state)
    private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state)
    {
        if (DEBUG_VOL) Log.d(TAG, "onSetA2dpConnectionState btDevice="+btDevice+" state="+state);
        if (DEBUG_VOL) {
            Log.d(TAG, "onSetA2dpSinkConnectionState btDevice="+btDevice+"state="+state);
        }
        if (btDevice == null) {
            return;
        }
@@ -3924,6 +3982,32 @@ public class AudioService extends IAudioService.Stub {
        }
    }

    private void onSetA2dpSourceConnectionState(BluetoothDevice btDevice, int state)
    {
        if (DEBUG_VOL) {
            Log.d(TAG, "onSetA2dpSourceConnectionState btDevice="+btDevice+" state="+state);
        }
        if (btDevice == null) {
            return;
        }
        String address = btDevice.getAddress();
        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
            address = "";
        }

        synchronized (mConnectedDevices) {
                boolean isConnected =
                (mConnectedDevices.containsKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP) &&
                 mConnectedDevices.get(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP).equals(address));

            if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
                makeA2dpSrcUnavailable(address);
            } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
                makeA2dpSrcAvailable(address);
            }
        }
    }

    public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
        // address is not used for now, but may be used when multiple a2dp devices are supported
        synchronized (mA2dpAvrcpLock) {
@@ -3989,7 +4073,8 @@ public class AudioService extends IAudioService.Stub {
            }
        }

        if (mAudioHandler.hasMessages(MSG_SET_A2DP_CONNECTION_STATE) ||
        if (mAudioHandler.hasMessages(MSG_SET_A2DP_SRC_CONNECTION_STATE) ||
                mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE) ||
                mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) {
            delay = 1000;
        }
+2 −1
Original line number Diff line number Diff line
@@ -299,7 +299,7 @@ public class AudioSystem
    public static final int DEVICE_IN_TV_TUNER = DEVICE_BIT_IN | 0x4000;
    public static final int DEVICE_IN_LINE = DEVICE_BIT_IN | 0x8000;
    public static final int DEVICE_IN_SPDIF = DEVICE_BIT_IN | 0x10000;

    public static final int DEVICE_IN_BLUETOOTH_A2DP = DEVICE_BIT_IN | 0x20000;
    public static final int DEVICE_IN_DEFAULT = DEVICE_BIT_IN | DEVICE_BIT_DEFAULT;

    public static final int DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION |
@@ -319,6 +319,7 @@ public class AudioSystem
                                             DEVICE_IN_TV_TUNER |
                                             DEVICE_IN_LINE |
                                             DEVICE_IN_SPDIF |
                                             DEVICE_IN_BLUETOOTH_A2DP |
                                             DEVICE_IN_DEFAULT);
    public static final int DEVICE_IN_ALL_SCO = DEVICE_IN_BLUETOOTH_SCO_HEADSET;
    public static final int DEVICE_IN_ALL_USB = (DEVICE_IN_USB_ACCESSORY |
+1 −1
Original line number Diff line number Diff line
@@ -232,7 +232,7 @@ interface IAudioService {
    int getMasterStreamType();

    void setWiredDeviceConnectionState(int device, int state, String name);
    int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state);
    int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state, int profile);

    AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);