From 469de115b3f4654c11ca7601f186571a15f29e92 Mon Sep 17 00:00:00 2001 From: Jack He Date: Tue, 8 May 2018 14:51:07 -0700 Subject: [PATCH] AudioService: Do not disconnect SCO started externally * AudioService should not disconnect Bluetooth SCO if it is started externally * When SCO has already started externally, all SCO connection attempts through AudioManager API will fail with SCO_AUDIO_STATE_DISCONNECTED intent * Remove SCO_STATE_DEACTIVATE_EXT_REQ state since AudioService could no longer disconnect SCO audio that is started externally * Change SCO_STATE_* values so that they are consecutive Bug: 79407565 Test: With Bluetooth HFP device connected: Test1: make a outgoing call Test2: make VoIP call during cellular call Test3: make a VoIP call during another VoIP call Change-Id: I1e0a10aeb0eac59d4826f9defa595aebd85f534c (cherry picked from commit 33c3a17113ee93bfd4575241cc15e78afc300f0e) --- .../android/server/audio/AudioService.java | 59 +++++-------------- 1 file changed, 14 insertions(+), 45 deletions(-) diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 8a643ed9a8063..8399ee2107d2f 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -486,16 +486,13 @@ public class AudioService extends IAudioService.Stub // SCO audio state is active or starting due to a request from AudioManager API private static final int SCO_STATE_ACTIVE_INTERNAL = 3; // SCO audio deactivation request waiting for headset service to connect - private static final int SCO_STATE_DEACTIVATE_REQ = 5; + private static final int SCO_STATE_DEACTIVATE_REQ = 4; // SCO audio deactivation in progress, waiting for Bluetooth audio intent - private static final int SCO_STATE_DEACTIVATING = 6; + private static final int SCO_STATE_DEACTIVATING = 5; // SCO audio state is active due to an action in BT handsfree (either voice recognition or // in call audio) private static final int SCO_STATE_ACTIVE_EXTERNAL = 2; - // Deactivation request for all SCO connections (initiated by audio mode change) - // waiting for headset service to connect - private static final int SCO_STATE_DEACTIVATE_EXT_REQ = 4; // Indicates the mode used for SCO audio connection. The mode is virtual call if the request // originated from an app targeting an API version before JB MR2 and raw audio after that. @@ -3332,33 +3329,19 @@ public class AudioService extends IAudioService.Stub return result; } + /** + * Disconnect all SCO connections started by {@link AudioManager} except those started by + * {@param exceptPid} + * + * @param exceptPid pid whose SCO connections through {@link AudioManager} should be kept + */ private void disconnectBluetoothSco(int exceptPid) { synchronized(mScoClients) { checkScoAudioState(); - if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL || - mScoAudioState == SCO_STATE_DEACTIVATE_EXT_REQ) { - if (mBluetoothHeadsetDevice != null) { - if (mBluetoothHeadset != null) { - boolean status = disconnectBluetoothScoAudioHelper(mBluetoothHeadset, - mBluetoothHeadsetDevice, SCO_MODE_RAW) - || disconnectBluetoothScoAudioHelper(mBluetoothHeadset, - mBluetoothHeadsetDevice, SCO_MODE_VIRTUAL_CALL) - || disconnectBluetoothScoAudioHelper(mBluetoothHeadset, - mBluetoothHeadsetDevice, SCO_MODE_VR); - if (status) { - mScoAudioState = SCO_STATE_DEACTIVATING; - } else { - clearAllScoClients(exceptPid, false); - mScoAudioState = SCO_STATE_INACTIVE; - } - } else if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL && - getBluetoothHeadset()) { - mScoAudioState = SCO_STATE_DEACTIVATE_EXT_REQ; - } - } - } else { - clearAllScoClients(exceptPid, true); + if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL) { + return; } + clearAllScoClients(exceptPid, true); } } @@ -3524,8 +3507,7 @@ public class AudioService extends IAudioService.Stub checkScoAudioState(); // Continue pending action if any if (mScoAudioState == SCO_STATE_ACTIVATE_REQ || - mScoAudioState == SCO_STATE_DEACTIVATE_REQ || - mScoAudioState == SCO_STATE_DEACTIVATE_EXT_REQ) { + mScoAudioState == SCO_STATE_DEACTIVATE_REQ) { boolean status = false; if (mBluetoothHeadsetDevice != null) { switch (mScoAudioState) { @@ -3543,17 +3525,6 @@ public class AudioService extends IAudioService.Stub mScoAudioState = SCO_STATE_DEACTIVATING; } break; - case SCO_STATE_DEACTIVATE_EXT_REQ: - status = disconnectBluetoothScoAudioHelper(mBluetoothHeadset, - mBluetoothHeadsetDevice, SCO_MODE_RAW) || - disconnectBluetoothScoAudioHelper(mBluetoothHeadset, - mBluetoothHeadsetDevice, SCO_MODE_VIRTUAL_CALL) || - disconnectBluetoothScoAudioHelper(mBluetoothHeadset, - mBluetoothHeadsetDevice, SCO_MODE_VR); - if (status) { - mScoAudioState = SCO_STATE_DEACTIVATING; - } - break; } } if (!status) { @@ -5828,8 +5799,7 @@ public class AudioService extends IAudioService.Stub case BluetoothHeadset.STATE_AUDIO_CONNECTED: scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED; if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL && - mScoAudioState != SCO_STATE_DEACTIVATE_REQ && - mScoAudioState != SCO_STATE_DEACTIVATE_EXT_REQ) { + mScoAudioState != SCO_STATE_DEACTIVATE_REQ) { mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL; } setBluetoothScoOn(true); @@ -5853,8 +5823,7 @@ public class AudioService extends IAudioService.Stub break; case BluetoothHeadset.STATE_AUDIO_CONNECTING: if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL && - mScoAudioState != SCO_STATE_DEACTIVATE_REQ && - mScoAudioState != SCO_STATE_DEACTIVATE_EXT_REQ) { + mScoAudioState != SCO_STATE_DEACTIVATE_REQ) { mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL; } default: