From 4394d3b2eff118ae9fe8a81d3a706f1776865abe Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Sun, 10 May 2020 17:10:06 -0700 Subject: [PATCH] BtHelper: do not clear sco clients when sco audio is disconnected When sco audio is disconnected by BT stack, do not clear the list of pending activation requests by apps (mScoClients). Instead, restart sco audio if a client is still in the list. Also restore BT SCO forced usage when speakerphone is turned off and sco audio is connected. Bug: 154464603 Test: repro steps in bug. Test: manual regression tests with VoIP and cell calls Change-Id: I54930df9da9477dfb943dc08cebd78986b6568e9 --- .../android/server/audio/AudioDeviceBroker.java | 8 +++++++- .../java/com/android/server/audio/BtHelper.java | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 40b6f42309bd7..befd6b1cec0e1 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -211,7 +211,13 @@ import java.io.PrintWriter; } mForcedUseForComm = AudioSystem.FORCE_SPEAKER; } else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER) { - mForcedUseForComm = AudioSystem.FORCE_NONE; + if (mBtHelper.isBluetoothScoOn()) { + mForcedUseForComm = AudioSystem.FORCE_BT_SCO; + setForceUse_Async( + AudioSystem.FOR_RECORD, AudioSystem.FORCE_BT_SCO, eventSource); + } else { + mForcedUseForComm = AudioSystem.FORCE_NONE; + } } mForcedUseForCommExt = mForcedUseForComm; diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java index 0654f86c6a678..9e7b428d2cca0 100644 --- a/services/core/java/com/android/server/audio/BtHelper.java +++ b/services/core/java/com/android/server/audio/BtHelper.java @@ -307,8 +307,15 @@ public class BtHelper { case BluetoothHeadset.STATE_AUDIO_DISCONNECTED: mDeviceBroker.setBluetoothScoOn(false, "BtHelper.receiveBtEvent"); scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED; - // startBluetoothSco called after stopBluetoothSco - if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) { + // There are two cases where we want to immediately reconnect audio: + // 1) If a new start request was received while disconnecting: this was + // notified by requestScoState() setting state to SCO_STATE_ACTIVATE_REQ. + // 2) If audio was connected then disconnected via Bluetooth APIs and + // we still have pending activation requests by apps: this is indicated by + // state SCO_STATE_ACTIVE_EXTERNAL and the mScoClients list not empty. + if (mScoAudioState == SCO_STATE_ACTIVATE_REQ + || (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL + && !mScoClients.isEmpty())) { if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null && connectBluetoothScoAudioHelper(mBluetoothHeadset, mBluetoothHeadsetDevice, mScoAudioMode)) { @@ -318,7 +325,9 @@ public class BtHelper { } } // Tear down SCO if disconnected from external - clearAllScoClients(0, mScoAudioState == SCO_STATE_ACTIVE_INTERNAL); + if (mScoAudioState == SCO_STATE_DEACTIVATING) { + clearAllScoClients(0, false); + } mScoAudioState = SCO_STATE_INACTIVE; break; case BluetoothHeadset.STATE_AUDIO_CONNECTING: