summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java32
-rw-r--r--services/core/java/com/android/server/audio/BtHelper.java100
2 files changed, 74 insertions, 58 deletions
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 6203977dc877..1d21ccb62b8c 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -413,24 +413,24 @@ public class AudioDeviceBroker {
if (client == null) {
return;
}
-
- boolean isBtScoRequested = isBluetoothScoRequested();
- if (isBtScoRequested && (!wasBtScoRequested || !isBluetoothScoActive())) {
- if (!mBtHelper.startBluetoothSco(scoAudioMode, eventSource)) {
- Log.w(TAG, "setCommunicationRouteForClient: failure to start BT SCO for uid: "
- + uid);
- // clean up or restore previous client selection
- if (prevClientDevice != null) {
- addCommunicationRouteClient(cb, uid, prevClientDevice, prevPrivileged);
- } else {
- removeCommunicationRouteClient(cb, true);
+ if (!mScoManagedByAudio) {
+ boolean isBtScoRequested = isBluetoothScoRequested();
+ if (isBtScoRequested && (!wasBtScoRequested || !isBluetoothScoActive())) {
+ if (!mBtHelper.startBluetoothSco(scoAudioMode, eventSource)) {
+ Log.w(TAG, "setCommunicationRouteForClient: failure to start BT SCO for uid: "
+ + uid);
+ // clean up or restore previous client selection
+ if (prevClientDevice != null) {
+ addCommunicationRouteClient(cb, uid, prevClientDevice, prevPrivileged);
+ } else {
+ removeCommunicationRouteClient(cb, true);
+ }
+ postBroadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
}
- postBroadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+ } else if (!isBtScoRequested && wasBtScoRequested) {
+ mBtHelper.stopBluetoothSco(eventSource);
}
- } else if (!isBtScoRequested && wasBtScoRequested) {
- mBtHelper.stopBluetoothSco(eventSource);
}
-
// In BT classic for communication, the device changes from a2dp to sco device, but for
// LE Audio it stays the same and we must trigger the proper stream volume alignment, if
// LE Audio communication device is activated after the audio system has already switched to
@@ -2526,7 +2526,7 @@ public class AudioDeviceBroker {
setCommunicationRouteForClient(crc.getBinder(), crc.getUid(), crc.getDevice(),
BtHelper.SCO_MODE_UNDEFINED, crc.isPrivileged(), eventSource);
} else {
- if (!isBluetoothScoRequested() && wasBtScoRequested) {
+ if (!mScoManagedByAudio && !isBluetoothScoRequested() && wasBtScoRequested) {
mBtHelper.stopBluetoothSco(eventSource);
}
updateCommunicationRoute(eventSource);
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 07daecdfc9f6..fe6b06781cf2 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -401,50 +401,67 @@ public class BtHelper {
private void onScoAudioStateChanged(int state) {
boolean broadcast = false;
int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;
- switch (state) {
- 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_ACTIVE_EXTERNAL;
- } else if (mDeviceBroker.isBluetoothScoRequested()) {
- // broadcast intent if the connection was initated by AudioService
+ if (mDeviceBroker.isScoManagedByAudio()) {
+ switch (state) {
+ case BluetoothHeadset.STATE_AUDIO_CONNECTED:
+ mDeviceBroker.setBluetoothScoOn(true, "BtHelper.onScoAudioStateChanged");
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
broadcast = true;
- }
- mDeviceBroker.setBluetoothScoOn(true, "BtHelper.onScoAudioStateChanged");
- break;
- case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
- mDeviceBroker.setBluetoothScoOn(false, "BtHelper.onScoAudioStateChanged");
- scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
- // 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 BT SCO is requested.
- if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) {
- if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
- && connectBluetoothScoAudioHelper(mBluetoothHeadset,
- mBluetoothHeadsetDevice, mScoAudioMode)) {
- mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
- scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTING;
+ break;
+ case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
+ mDeviceBroker.setBluetoothScoOn(false, "BtHelper.onScoAudioStateChanged");
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
+ broadcast = true;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (state) {
+ 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_ACTIVE_EXTERNAL;
+ } else if (mDeviceBroker.isBluetoothScoRequested()) {
+ // broadcast intent if the connection was initated by AudioService
broadcast = true;
- break;
}
- }
- if (mScoAudioState != SCO_STATE_ACTIVE_EXTERNAL) {
- broadcast = true;
- }
- mScoAudioState = SCO_STATE_INACTIVE;
- break;
- case BluetoothHeadset.STATE_AUDIO_CONNECTING:
- if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
- && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
- mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
- }
- break;
- default:
- break;
+ mDeviceBroker.setBluetoothScoOn(true, "BtHelper.onScoAudioStateChanged");
+ break;
+ case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
+ mDeviceBroker.setBluetoothScoOn(false, "BtHelper.onScoAudioStateChanged");
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
+ // 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 BT SCO is requested.
+ if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) {
+ if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
+ && connectBluetoothScoAudioHelper(mBluetoothHeadset,
+ mBluetoothHeadsetDevice, mScoAudioMode)) {
+ mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+ scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTING;
+ broadcast = true;
+ break;
+ }
+ }
+ if (mScoAudioState != SCO_STATE_ACTIVE_EXTERNAL) {
+ broadcast = true;
+ }
+ mScoAudioState = SCO_STATE_INACTIVE;
+ break;
+ case BluetoothHeadset.STATE_AUDIO_CONNECTING:
+ if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
+ && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
+ mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+ }
+ break;
+ default:
+ break;
+ }
}
if (broadcast) {
broadcastScoConnectionState(scoAudioState);
@@ -454,7 +471,6 @@ public class BtHelper {
newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, scoAudioState);
sendStickyBroadcastToAll(newIntent);
}
-
}
/**
*