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

Commit 4c637b9e authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Fix bug 2578813 Delay pausing music and routing audio for car docks

Moved broadcast of ACTION_AUDIO_BECOMING_NOISY from BluetoothA2dpService
to AudioService.
Broadcast ACTION_AUDIO_BECOMING_NOISY when disconnecting an A2DP
device.
Disconnect from A2DP docks with a delay to handle transient
disconnections.
Cancel delayed A2DP disconnections when connecting to a dock as this
can be a reconnection after a transient disconnection.

Change-Id: I1ee9e99f3ffa20727af38a4c4c8711942894a696
parent bcac4960
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -487,12 +487,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
        if (state != prevState) {
            if (state == BluetoothA2dp.STATE_DISCONNECTED ||
                    state == BluetoothA2dp.STATE_DISCONNECTING) {
                if (prevState == BluetoothA2dp.STATE_CONNECTED ||
                        prevState == BluetoothA2dp.STATE_PLAYING) {
                   // disconnecting or disconnected
                   Intent intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
                   mContext.sendBroadcast(intent);
                }
                mSinkCount--;
            } else if (state == BluetoothA2dp.STATE_CONNECTED) {
                mSinkCount ++;
+56 −11
Original line number Diff line number Diff line
@@ -102,6 +102,9 @@ public class AudioService extends IAudioService.Stub {
    private static final int MSG_MEDIA_SERVER_DIED = 5;
    private static final int MSG_MEDIA_SERVER_STARTED = 6;
    private static final int MSG_PLAY_SOUND_EFFECT = 7;
    private static final int MSG_BTA2DP_DOCK_TIMEOUT = 8;

    private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;

    /** @see AudioSystemThread */
    private AudioSystemThread mAudioSystemThread;
@@ -1651,6 +1654,11 @@ public class AudioService extends IAudioService.Stub {
                case MSG_PLAY_SOUND_EFFECT:
                    playSoundEffect(msg.arg1, msg.arg2);
                    break;

                case MSG_BTA2DP_DOCK_TIMEOUT:
                    // msg.obj  == address of BTA2DP device
                    makeA2dpDeviceUnavailableNow( (String) msg.obj );
                    break;
            }
        }
    }
@@ -1705,6 +1713,38 @@ public class AudioService extends IAudioService.Stub {
        }
    }

    private void makeA2dpDeviceAvailable(String address) {
        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                AudioSystem.DEVICE_STATE_AVAILABLE,
                address);
        // Reset A2DP suspend state each time a new sink is connected
        AudioSystem.setParameters("A2dpSuspended=false");
        mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP),
                address);
    }

    private void makeA2dpDeviceUnavailableNow(String address) {
        Intent noisyIntent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
        mContext.sendBroadcast(noisyIntent);
        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                AudioSystem.DEVICE_STATE_UNAVAILABLE,
                address);
        mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
    }

    private void makeA2dpDeviceUnavailableLater(String address) {
        // the device will be made unavailable later, so consider it disconnected right away
        mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
        // send the delayed message to make the device unavailable later
        Message msg = mAudioHandler.obtainMessage(MSG_BTA2DP_DOCK_TIMEOUT, address);
        mAudioHandler.sendMessageDelayed(msg, BTA2DP_DOCK_TIMEOUT_MILLIS);

    }

    private void cancelA2dpDeviceTimeout(String address) {
        mAudioHandler.removeMessages(MSG_BTA2DP_DOCK_TIMEOUT);
    }

    /**
     * Receiver for misc intent broadcasts the Phone app cares about.
     */
@@ -1739,20 +1779,25 @@ public class AudioService extends IAudioService.Stub {

                if (isConnected &&
                    state != BluetoothA2dp.STATE_CONNECTED && state != BluetoothA2dp.STATE_PLAYING) {
                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                            AudioSystem.DEVICE_STATE_UNAVAILABLE,
                            address);
                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
                    if (btDevice.isBluetoothDock()) {
                        if (state == BluetoothA2dp.STATE_DISCONNECTED) {
                            // 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);
                            // the next time isConnected is evaluated, it will be false for the dock
                        }
                    } else {
                        makeA2dpDeviceUnavailableNow(address);
                    }
                } else if (!isConnected &&
                             (state == BluetoothA2dp.STATE_CONNECTED ||
                              state == BluetoothA2dp.STATE_PLAYING)) {
                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                                                         AudioSystem.DEVICE_STATE_AVAILABLE,
                                                         address);
                    // Reset A2DP suspend state each time a new sink is connected
                    AudioSystem.setParameters("A2dpSuspended=false");
                    mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP),
                            address);
                    if (btDevice.isBluetoothDock()) {
                        // this could be a reconnection after a transient disconnection
                        cancelA2dpDeviceTimeout(address);
                    }
                    makeA2dpDeviceAvailable(address);
                }
            } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,