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

Commit b00058fc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "AudioService: fix A2DP (dis)connection during media playback" into...

Merge "AudioService: fix A2DP (dis)connection during media playback" into rvc-dev am: 11ddcad8 am: 54d9e184 am: 797dd0a8

Change-Id: I6cc44e6c4de276d986a533645dad9b5ff67aef65
parents 506fb719 797dd0a8
Loading
Loading
Loading
Loading
+45 −2
Original line number Original line Diff line number Diff line
@@ -199,18 +199,61 @@ public class AudioSystem
    /** @hide */
    /** @hide */
    public static final int AUDIO_FORMAT_LDAC           = 0x23000000;
    public static final int AUDIO_FORMAT_LDAC           = 0x23000000;


    /** @hide */
    @IntDef(flag = false, prefix = "AUDIO_FORMAT_", value = {
            AUDIO_FORMAT_INVALID,
            AUDIO_FORMAT_DEFAULT,
            AUDIO_FORMAT_AAC,
            AUDIO_FORMAT_SBC,
            AUDIO_FORMAT_APTX,
            AUDIO_FORMAT_APTX_HD,
            AUDIO_FORMAT_LDAC }
    )
    @Retention(RetentionPolicy.SOURCE)
    public @interface AudioFormatNativeEnumForBtCodec {}

    /**
    /**
     * @hide
     * @hide
     * Convert audio format enum values to Bluetooth codec values
     * Convert audio format enum values to Bluetooth codec values
     */
     */
    public static int audioFormatToBluetoothSourceCodec(int audioFormat) {
    public static int audioFormatToBluetoothSourceCodec(
            @AudioFormatNativeEnumForBtCodec int audioFormat) {
        switch (audioFormat) {
        switch (audioFormat) {
            case AUDIO_FORMAT_AAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC;
            case AUDIO_FORMAT_AAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC;
            case AUDIO_FORMAT_SBC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
            case AUDIO_FORMAT_SBC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
            case AUDIO_FORMAT_APTX: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
            case AUDIO_FORMAT_APTX: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
            case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
            case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
            case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
            case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
            default: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID;
            default:
                Log.e(TAG, "Unknown audio format 0x" + Integer.toHexString(audioFormat)
                        + " for conversion to BT codec");
                return BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID;
        }
    }

    /**
     * @hide
     * Convert a Bluetooth codec to an audio format enum
     * @param btCodec the codec to convert.
     * @return the audio format, or {@link #AUDIO_FORMAT_DEFAULT} if unknown
     */
    public static @AudioFormatNativeEnumForBtCodec int bluetoothCodecToAudioFormat(int btCodec) {
        switch (btCodec) {
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
                return AudioSystem.AUDIO_FORMAT_SBC;
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
                return AudioSystem.AUDIO_FORMAT_AAC;
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
                return AudioSystem.AUDIO_FORMAT_APTX;
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
                return AudioSystem.AUDIO_FORMAT_APTX_HD;
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
                return AudioSystem.AUDIO_FORMAT_LDAC;
            default:
                Log.e(TAG, "Unknown BT codec 0x" + Integer.toHexString(btCodec)
                        + " for conversion to audio format");
                // TODO returning DEFAULT is the current behavior, should this return INVALID?
                return AudioSystem.AUDIO_FORMAT_DEFAULT;
        }
        }
    }
    }


+76 −27
Original line number Original line Diff line number Diff line
@@ -255,7 +255,21 @@ import java.io.PrintWriter;
        // redefine equality op so we can match messages intended for this device
        // redefine equality op so we can match messages intended for this device
        @Override
        @Override
        public boolean equals(Object o) {
        public boolean equals(Object o) {
            return mDevice.equals(o);
            if (o == null) {
                return false;
            }
            if (this == o) {
                return true;
            }
            if (o instanceof BtDeviceConnectionInfo) {
                return mDevice.equals(((BtDeviceConnectionInfo) o).mDevice);
            }
            return false;
        }

        @Override
        public String toString() {
            return "BtDeviceConnectionInfo dev=" + mDevice.toString();
        }
        }
    }
    }


@@ -266,9 +280,13 @@ import java.io.PrintWriter;
        final BtDeviceConnectionInfo info = new BtDeviceConnectionInfo(device, state, profile,
        final BtDeviceConnectionInfo info = new BtDeviceConnectionInfo(device, state, profile,
                suppressNoisyIntent, a2dpVolume);
                suppressNoisyIntent, a2dpVolume);


        // when receiving a request to change the connection state of a device, this last request
        // operations of removing and posting messages related to A2DP device state change must be
        // is the source of truth, so cancel all previous requests
        // mutually exclusive
        removeAllA2dpConnectionEvents(device);
        synchronized (mDeviceStateLock) {
            // when receiving a request to change the connection state of a device, this last
            // request is the source of truth, so cancel all previous requests that are already in
            // the handler
            removeScheduledA2dpEvents(device);


            sendLMsgNoDelay(
            sendLMsgNoDelay(
                    state == BluetoothProfile.STATE_CONNECTED
                    state == BluetoothProfile.STATE_CONNECTED
@@ -276,17 +294,31 @@ import java.io.PrintWriter;
                            : MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION,
                            : MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION,
                    SENDMSG_QUEUE, info);
                    SENDMSG_QUEUE, info);
        }
        }
    }


    /** remove all previously scheduled connection and disconnection events for the given device */
    /** remove all previously scheduled connection and state change events for the given device */
    private void removeAllA2dpConnectionEvents(@NonNull BluetoothDevice device) {
    @GuardedBy("mDeviceStateLock")
        mBrokerHandler.removeMessages(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION,
    private void removeScheduledA2dpEvents(@NonNull BluetoothDevice device) {
                device);
        mBrokerHandler.removeEqualMessages(MSG_L_A2DP_DEVICE_CONFIG_CHANGE, device);
        mBrokerHandler.removeMessages(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION,

                device);
        final BtDeviceConnectionInfo connectionInfoToRemove = new BtDeviceConnectionInfo(device,
        mBrokerHandler.removeMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED,
                // the next parameters of the constructor will be ignored when finding the message
                device);
                // to remove as the equality of the message's object is tested on the device itself
        mBrokerHandler.removeMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED,
                // (see BtDeviceConnectionInfo.equals() method override)
                device);
                BluetoothProfile.STATE_CONNECTED, 0, false, -1);
        mBrokerHandler.removeEqualMessages(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION,
                connectionInfoToRemove);
        mBrokerHandler.removeEqualMessages(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION,
                connectionInfoToRemove);

        final BtHelper.BluetoothA2dpDeviceInfo devInfoToRemove =
                new BtHelper.BluetoothA2dpDeviceInfo(device);
        mBrokerHandler.removeEqualMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED,
                devInfoToRemove);
        mBrokerHandler.removeEqualMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED,
                devInfoToRemove);
        mBrokerHandler.removeEqualMessages(MSG_L_A2DP_ACTIVE_DEVICE_CHANGE,
                devInfoToRemove);
    }
    }


    private static final class HearingAidDeviceConnectionInfo {
    private static final class HearingAidDeviceConnectionInfo {
@@ -493,6 +525,7 @@ import java.io.PrintWriter;
        sendMsgNoDelay(MSG_BROADCAST_AUDIO_BECOMING_NOISY, SENDMSG_REPLACE);
        sendMsgNoDelay(MSG_BROADCAST_AUDIO_BECOMING_NOISY, SENDMSG_REPLACE);
    }
    }


    @GuardedBy("mDeviceStateLock")
    /*package*/ void postA2dpSinkConnection(@AudioService.BtProfileConnectionState int state,
    /*package*/ void postA2dpSinkConnection(@AudioService.BtProfileConnectionState int state,
            @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) {
            @NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) {
        sendILMsg(state == BluetoothA2dp.STATE_CONNECTED
        sendILMsg(state == BluetoothA2dp.STATE_CONNECTED
@@ -624,10 +657,12 @@ import java.io.PrintWriter;


    // must be called synchronized on mConnectedDevices
    // must be called synchronized on mConnectedDevices
    /*package*/ boolean hasScheduledA2dpSinkConnectionState(BluetoothDevice btDevice) {
    /*package*/ boolean hasScheduledA2dpSinkConnectionState(BluetoothDevice btDevice) {
        return (mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED,
        final BtHelper.BluetoothA2dpDeviceInfo devInfoToCheck =
                        new BtHelper.BluetoothA2dpDeviceInfo(btDevice))
                new BtHelper.BluetoothA2dpDeviceInfo(btDevice);
                || mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED,
        return (mBrokerHandler.hasEqualMessages(
                        new BtHelper.BluetoothA2dpDeviceInfo(btDevice)));
                    MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED, devInfoToCheck)
                || mBrokerHandler.hasEqualMessages(
                    MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED, devInfoToCheck));
    }
    }


    /*package*/ void setA2dpTimeout(String address, int a2dpCodec, int delayMs) {
    /*package*/ void setA2dpTimeout(String address, int a2dpCodec, int delayMs) {
@@ -808,6 +843,9 @@ import java.io.PrintWriter;
                    final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
                    final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
                    synchronized (mDeviceStateLock) {
                    synchronized (mDeviceStateLock) {
                        a2dpCodec = mBtHelper.getA2dpCodec(btDevice);
                        a2dpCodec = mBtHelper.getA2dpCodec(btDevice);
                        // TODO: name of method being called on AudioDeviceInventory is currently
                        //       misleading (config change vs active device change), to be
                        //       reconciliated once the BT side has been updated.
                        mDeviceInventory.onBluetoothA2dpActiveDeviceChange(
                        mDeviceInventory.onBluetoothA2dpActiveDeviceChange(
                                new BtHelper.BluetoothA2dpDeviceInfo(btDevice, -1, a2dpCodec),
                                new BtHelper.BluetoothA2dpDeviceInfo(btDevice, -1, a2dpCodec),
                                        BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
                                        BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
@@ -900,7 +938,7 @@ import java.io.PrintWriter;
                case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION: {
                case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION: {
                    final BtDeviceConnectionInfo info = (BtDeviceConnectionInfo) msg.obj;
                    final BtDeviceConnectionInfo info = (BtDeviceConnectionInfo) msg.obj;
                    AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
                    AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
                            "setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent "
                            "msg: setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent "
                                    + " state=" + info.mState
                                    + " state=" + info.mState
                                    // only querying address as this is the only readily available
                                    // only querying address as this is the only readily available
                                    // field on the device
                                    // field on the device
@@ -917,7 +955,7 @@ import java.io.PrintWriter;
                    final HearingAidDeviceConnectionInfo info =
                    final HearingAidDeviceConnectionInfo info =
                            (HearingAidDeviceConnectionInfo) msg.obj;
                            (HearingAidDeviceConnectionInfo) msg.obj;
                    AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
                    AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
                            "setHearingAidDeviceConnectionState state=" + info.mState
                            "msg: setHearingAidDeviceConnectionState state=" + info.mState
                                    + " addr=" + info.mDevice.getAddress()
                                    + " addr=" + info.mDevice.getAddress()
                                    + " supprNoisy=" + info.mSupprNoisy
                                    + " supprNoisy=" + info.mSupprNoisy
                                    + " src=" + info.mEventSource)).printLog(TAG));
                                    + " src=" + info.mEventSource)).printLog(TAG));
@@ -962,13 +1000,19 @@ import java.io.PrintWriter;
    private static final int MSG_IL_SET_HEARING_AID_CONNECTION_STATE = 8;
    private static final int MSG_IL_SET_HEARING_AID_CONNECTION_STATE = 8;
    private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
    private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
    private static final int MSG_IL_BTA2DP_TIMEOUT = 10;
    private static final int MSG_IL_BTA2DP_TIMEOUT = 10;

    // process change of A2DP device configuration, obj is BluetoothDevice
    private static final int MSG_L_A2DP_DEVICE_CONFIG_CHANGE = 11;
    private static final int MSG_L_A2DP_DEVICE_CONFIG_CHANGE = 11;

    private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 12;
    private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 12;
    private static final int MSG_REPORT_NEW_ROUTES = 13;
    private static final int MSG_REPORT_NEW_ROUTES = 13;
    private static final int MSG_II_SET_HEARING_AID_VOLUME = 14;
    private static final int MSG_II_SET_HEARING_AID_VOLUME = 14;
    private static final int MSG_I_SET_AVRCP_ABSOLUTE_VOLUME = 15;
    private static final int MSG_I_SET_AVRCP_ABSOLUTE_VOLUME = 15;
    private static final int MSG_I_DISCONNECT_BT_SCO = 16;
    private static final int MSG_I_DISCONNECT_BT_SCO = 16;

    // process active A2DP device change, obj is BtHelper.BluetoothA2dpDeviceInfo
    private static final int MSG_L_A2DP_ACTIVE_DEVICE_CHANGE = 18;
    private static final int MSG_L_A2DP_ACTIVE_DEVICE_CHANGE = 18;

    private static final int MSG_DISCONNECT_A2DP = 19;
    private static final int MSG_DISCONNECT_A2DP = 19;
    private static final int MSG_DISCONNECT_A2DP_SINK = 20;
    private static final int MSG_DISCONNECT_A2DP_SINK = 20;
    private static final int MSG_DISCONNECT_BT_HEARING_AID = 21;
    private static final int MSG_DISCONNECT_BT_HEARING_AID = 21;
@@ -977,13 +1021,18 @@ import java.io.PrintWriter;
    private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP_SINK = 24;
    private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP_SINK = 24;
    private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEARING_AID = 25;
    private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEARING_AID = 25;
    private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEADSET = 26;
    private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEADSET = 26;

    // process change of state, obj is BtHelper.BluetoothA2dpDeviceInfo
    private static final int MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED = 27;
    private static final int MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED = 27;
    private static final int MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED = 28;
    private static final int MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED = 28;
    // process external command to (dis)connect an A2DP device

    // process external command to (dis)connect an A2DP device, obj is BtDeviceConnectionInfo
    private static final int MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION = 29;
    private static final int MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION = 29;
    private static final int MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION = 30;
    private static final int MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION = 30;

    // process external command to (dis)connect a hearing aid device
    // process external command to (dis)connect a hearing aid device
    private static final int MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT = 31;
    private static final int MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT = 31;

    // a ScoClient died in BtHelper
    // a ScoClient died in BtHelper
    private static final int MSG_L_SCOCLIENT_DIED = 32;
    private static final int MSG_L_SCOCLIENT_DIED = 32;
    private static final int MSG_IL_SAVE_PREF_DEVICE_FOR_STRATEGY = 33;
    private static final int MSG_IL_SAVE_PREF_DEVICE_FOR_STRATEGY = 33;
+14 −14
Original line number Original line Diff line number Diff line
@@ -289,11 +289,11 @@ public class AudioDeviceInventory {
            address = "";
            address = "";
        }
        }


        final int a2dpCodec = btInfo.getCodec();
        final @AudioSystem.AudioFormatNativeEnumForBtCodec int a2dpCodec = btInfo.getCodec();


        AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
        AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
                "A2DP sink connected: device addr=" + address + " state=" + state
                "A2DP sink connected: device addr=" + address + " state=" + state
                        + " codec=" + a2dpCodec
                        + " codec=" + AudioSystem.audioFormatToString(a2dpCodec)
                        + " vol=" + a2dpVolume));
                        + " vol=" + a2dpVolume));


        new MediaMetrics.Item(mMetricsId + "a2dp")
        new MediaMetrics.Item(mMetricsId + "a2dp")
@@ -422,7 +422,7 @@ public class AudioDeviceInventory {
            Log.d(TAG, "onBluetoothA2dpActiveDeviceChange btDevice=" + btDevice);
            Log.d(TAG, "onBluetoothA2dpActiveDeviceChange btDevice=" + btDevice);
        }
        }
        int a2dpVolume = btInfo.getVolume();
        int a2dpVolume = btInfo.getVolume();
        final int a2dpCodec = btInfo.getCodec();
        @AudioSystem.AudioFormatNativeEnumForBtCodec final int a2dpCodec = btInfo.getCodec();


        String address = btDevice.getAddress();
        String address = btDevice.getAddress();
        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
@@ -435,7 +435,8 @@ public class AudioDeviceInventory {
        synchronized (mDevicesLock) {
        synchronized (mDevicesLock) {
            if (mDeviceBroker.hasScheduledA2dpSinkConnectionState(btDevice)) {
            if (mDeviceBroker.hasScheduledA2dpSinkConnectionState(btDevice)) {
                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
                        "A2dp config change ignored (scheduled connection change)"));
                        "A2dp config change ignored (scheduled connection change)")
                        .printLog(TAG));
                mmi.set(MediaMetrics.Property.EARLY_RETURN, "A2dp config change ignored")
                mmi.set(MediaMetrics.Property.EARLY_RETURN, "A2dp config change ignored")
                        .record();
                        .record();
                return;
                return;
@@ -476,8 +477,9 @@ public class AudioDeviceInventory {


            if (res != AudioSystem.AUDIO_STATUS_OK) {
            if (res != AudioSystem.AUDIO_STATUS_OK) {
                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
                        "APM handleDeviceConfigChange failed for A2DP device addr="
                        "APM handleDeviceConfigChange failed for A2DP device addr=" + address
                        + address + " codec=" + a2dpCodec).printLog(TAG));
                                + " codec=" + AudioSystem.audioFormatToString(a2dpCodec))
                        .printLog(TAG));


                int musicDevice = mDeviceBroker.getDeviceForStream(AudioSystem.STREAM_MUSIC);
                int musicDevice = mDeviceBroker.getDeviceForStream(AudioSystem.STREAM_MUSIC);
                // force A2DP device disconnection in case of error so that AudioService state is
                // force A2DP device disconnection in case of error so that AudioService state is
@@ -488,8 +490,9 @@ public class AudioDeviceInventory {
                        -1 /* a2dpVolume */);
                        -1 /* a2dpVolume */);
            } else {
            } else {
                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
                        "APM handleDeviceConfigChange success for A2DP device addr="
                        "APM handleDeviceConfigChange success for A2DP device addr=" + address
                                + address + " codec=" + a2dpCodec).printLog(TAG));
                                + " codec=" + AudioSystem.audioFormatToString(a2dpCodec))
                        .printLog(TAG));
            }
            }
        }
        }
        mmi.record();
        mmi.record();
@@ -816,20 +819,17 @@ public class AudioDeviceInventory {


            if (AudioService.DEBUG_DEVICES) {
            if (AudioService.DEBUG_DEVICES) {
                Log.i(TAG, "setBluetoothA2dpDeviceConnectionState device: " + device
                Log.i(TAG, "setBluetoothA2dpDeviceConnectionState device: " + device
                        + " state: " + state + " delay(ms): " + delay + "codec:" + a2dpCodec
                        + " state: " + state + " delay(ms): " + delay
                        + " codec:" + Integer.toHexString(a2dpCodec)
                        + " suppressNoisyIntent: " + suppressNoisyIntent);
                        + " suppressNoisyIntent: " + suppressNoisyIntent);
            }
            }


            final BtHelper.BluetoothA2dpDeviceInfo a2dpDeviceInfo =
            final BtHelper.BluetoothA2dpDeviceInfo a2dpDeviceInfo =
                    new BtHelper.BluetoothA2dpDeviceInfo(device, a2dpVolume, a2dpCodec);
                    new BtHelper.BluetoothA2dpDeviceInfo(device, a2dpVolume, a2dpCodec);
            if (profile == BluetoothProfile.A2DP) {
            if (profile == BluetoothProfile.A2DP) {
                if (delay == 0) {
                    onSetA2dpSinkConnectionState(a2dpDeviceInfo, state);
                } else {
                mDeviceBroker.postA2dpSinkConnection(state,
                mDeviceBroker.postA2dpSinkConnection(state,
                            a2dpDeviceInfo,
                            a2dpDeviceInfo,
                            delay);
                            delay);
                }
            } else { //profile == BluetoothProfile.A2DP_SINK
            } else { //profile == BluetoothProfile.A2DP_SINK
                mDeviceBroker.postA2dpSourceConnection(state,
                mDeviceBroker.postA2dpSourceConnection(state,
                        a2dpDeviceInfo,
                        a2dpDeviceInfo,
+17 −22
Original line number Original line Diff line number Diff line
@@ -135,7 +135,7 @@ public class BtHelper {
    /*package*/ static class BluetoothA2dpDeviceInfo {
    /*package*/ static class BluetoothA2dpDeviceInfo {
        private final @NonNull BluetoothDevice mBtDevice;
        private final @NonNull BluetoothDevice mBtDevice;
        private final int mVolume;
        private final int mVolume;
        private final int mCodec;
        private final @AudioSystem.AudioFormatNativeEnumForBtCodec int mCodec;


        BluetoothA2dpDeviceInfo(@NonNull BluetoothDevice btDevice) {
        BluetoothA2dpDeviceInfo(@NonNull BluetoothDevice btDevice) {
            this(btDevice, -1, AudioSystem.AUDIO_FORMAT_DEFAULT);
            this(btDevice, -1, AudioSystem.AUDIO_FORMAT_DEFAULT);
@@ -155,15 +155,26 @@ public class BtHelper {
            return mVolume;
            return mVolume;
        }
        }


        public int getCodec() {
        public @AudioSystem.AudioFormatNativeEnumForBtCodec int getCodec() {
            return mCodec;
            return mCodec;
        }
        }


        // redefine equality op so we can match messages intended for this device
        // redefine equality op so we can match messages intended for this device
        @Override
        @Override
        public boolean equals(Object o) {
        public boolean equals(Object o) {
            return mBtDevice.equals(o);
            if (o == null) {
                return false;
            }
            if (this == o) {
                return true;
            }
            if (o instanceof BluetoothA2dpDeviceInfo) {
                return mBtDevice.equals(((BluetoothA2dpDeviceInfo) o).getBtDevice());
            }
            return false;
        }
        }


    }
    }


    // A2DP device events
    // A2DP device events
@@ -249,7 +260,8 @@ public class BtHelper {
        mA2dp.setAvrcpAbsoluteVolume(index);
        mA2dp.setAvrcpAbsoluteVolume(index);
    }
    }


    /*package*/ synchronized int getA2dpCodec(@NonNull BluetoothDevice device) {
    /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getA2dpCodec(
            @NonNull BluetoothDevice device) {
        if (mA2dp == null) {
        if (mA2dp == null) {
            return AudioSystem.AUDIO_FORMAT_DEFAULT;
            return AudioSystem.AUDIO_FORMAT_DEFAULT;
        }
        }
@@ -261,7 +273,7 @@ public class BtHelper {
        if (btCodecConfig == null) {
        if (btCodecConfig == null) {
            return AudioSystem.AUDIO_FORMAT_DEFAULT;
            return AudioSystem.AUDIO_FORMAT_DEFAULT;
        }
        }
        return mapBluetoothCodecToAudioFormat(btCodecConfig.getCodecType());
        return AudioSystem.bluetoothCodecToAudioFormat(btCodecConfig.getCodecType());
    }
    }


    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
    // @GuardedBy("AudioDeviceBroker.mSetModeLock")
@@ -967,23 +979,6 @@ public class BtHelper {
        return result;
        return result;
    }
    }


    private int mapBluetoothCodecToAudioFormat(int btCodecType) {
        switch (btCodecType) {
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
                return AudioSystem.AUDIO_FORMAT_SBC;
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
                return AudioSystem.AUDIO_FORMAT_AAC;
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
                return AudioSystem.AUDIO_FORMAT_APTX;
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
                return AudioSystem.AUDIO_FORMAT_APTX_HD;
            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
                return AudioSystem.AUDIO_FORMAT_LDAC;
            default:
                return AudioSystem.AUDIO_FORMAT_DEFAULT;
        }
    }

    /**
    /**
     * Returns the String equivalent of the btCodecType.
     * Returns the String equivalent of the btCodecType.
     *
     *