Merge "BT-HFP: Update Bluetooth headset state handler to Multi-HFP" am: 0aafefb113 am: a8505da2a6
am: 82a6cf1597
Change-Id: Ibb358a8270867752ce834429f914db21ec1c4c7d
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index f4c99f5..6a3ed14 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -138,7 +138,6 @@
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -771,7 +770,7 @@
// Register for device connection intent broadcasts.
IntentFilter intentFilter =
new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
- intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+ intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -2967,14 +2966,28 @@
}
public void setBluetoothScoOnInt(boolean on, String eventSource) {
+ if (DEBUG_DEVICES) {
+ Log.d(TAG, "setBluetoothScoOnInt: " + on + " " + eventSource);
+ }
if (on) {
// do not accept SCO ON if SCO audio is not connected
- synchronized(mScoClients) {
- if ((mBluetoothHeadset != null) &&
- (mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
- != BluetoothHeadset.STATE_AUDIO_CONNECTED)) {
- mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO;
- return;
+ synchronized (mScoClients) {
+ if (mBluetoothHeadset != null) {
+ if (mBluetoothHeadsetDevice == null) {
+ BluetoothDevice activeDevice = mBluetoothHeadset.getActiveDevice();
+ if (activeDevice != null) {
+ // setBtScoActiveDevice() might trigger resetBluetoothSco() which
+ // will call setBluetoothScoOnInt(false, "resetBluetoothSco")
+ setBtScoActiveDevice(activeDevice);
+ }
+ }
+ if (mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
+ != BluetoothHeadset.STATE_AUDIO_CONNECTED) {
+ mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO;
+ Log.w(TAG, "setBluetoothScoOnInt(true) failed because "
+ + mBluetoothHeadsetDevice + " is not in audio connected mode");
+ return;
+ }
}
}
mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
@@ -3362,24 +3375,23 @@
}
}
- void setBtScoDeviceConnectionState(BluetoothDevice btDevice, int state) {
+ private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
if (btDevice == null) {
- return;
+ return true;
}
-
String address = btDevice.getAddress();
BluetoothClass btClass = btDevice.getBluetoothClass();
int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
if (btClass != null) {
switch (btClass.getDeviceClass()) {
- case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
- case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
- outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
- break;
- case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
- outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
- break;
+ case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
+ case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
+ outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+ break;
+ case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
+ outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+ break;
}
}
@@ -3387,34 +3399,33 @@
address = "";
}
- boolean connected = (state == BluetoothProfile.STATE_CONNECTED);
-
String btDeviceName = btDevice.getName();
- boolean success =
- handleDeviceConnection(connected, outDevice, address, btDeviceName) &&
- handleDeviceConnection(connected, inDevice, address, btDeviceName);
+ boolean result = handleDeviceConnection(isActive, outDevice, address, btDeviceName);
+ // handleDeviceConnection() && result to make sure the method get executed
+ result = handleDeviceConnection(isActive, inDevice, address, btDeviceName) && result;
+ return result;
+ }
- if (!success) {
- return;
+ void setBtScoActiveDevice(BluetoothDevice btDevice) {
+ if (DEBUG_DEVICES) {
+ Log.d(TAG, "setBtScoActiveDevice(" + btDevice + ")");
}
-
- /* When one BT headset is disconnected while another BT headset
- * is connected, don't mess with the headset device.
- */
- if ((state == BluetoothProfile.STATE_DISCONNECTED ||
- state == BluetoothProfile.STATE_DISCONNECTING) &&
- mBluetoothHeadset != null &&
- mBluetoothHeadset.getAudioState(btDevice) == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
- Log.w(TAG, "SCO connected through another device, returning");
- return;
- }
-
synchronized (mScoClients) {
- if (connected) {
+ final BluetoothDevice previousActiveDevice = mBluetoothHeadsetDevice;
+ if (!Objects.equals(btDevice, previousActiveDevice)) {
+ if (!handleBtScoActiveDeviceChange(previousActiveDevice, false)) {
+ Log.w(TAG, "setBtScoActiveDevice() failed to remove previous device "
+ + previousActiveDevice);
+ }
+ if (!handleBtScoActiveDeviceChange(btDevice, true)) {
+ Log.e(TAG, "setBtScoActiveDevice() failed to add new device " + btDevice);
+ // set mBluetoothHeadsetDevice to null when failing to add new device
+ btDevice = null;
+ }
mBluetoothHeadsetDevice = btDevice;
- } else {
- mBluetoothHeadsetDevice = null;
- resetBluetoothSco();
+ if (mBluetoothHeadsetDevice == null) {
+ resetBluetoothSco();
+ }
}
}
}
@@ -3469,12 +3480,7 @@
// Discard timeout message
mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED);
mBluetoothHeadset = (BluetoothHeadset) proxy;
- deviceList = mBluetoothHeadset.getConnectedDevices();
- if (deviceList.size() > 0) {
- mBluetoothHeadsetDevice = deviceList.get(0);
- } else {
- mBluetoothHeadsetDevice = null;
- }
+ setBtScoActiveDevice(mBluetoothHeadset.getActiveDevice());
// Refresh SCO audio state
checkScoAudioState();
// Continue pending action if any
@@ -3595,10 +3601,7 @@
void disconnectHeadset() {
synchronized (mScoClients) {
- if (mBluetoothHeadsetDevice != null) {
- setBtScoDeviceConnectionState(mBluetoothHeadsetDevice,
- BluetoothProfile.STATE_DISCONNECTED);
- }
+ setBtScoActiveDevice(null);
mBluetoothHeadset = null;
}
}
@@ -5788,11 +5791,9 @@
AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config);
}
mDockState = dockState;
- } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
- state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
- BluetoothProfile.STATE_DISCONNECTED);
+ } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) {
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- setBtScoDeviceConnectionState(btDevice, state);
+ setBtScoActiveDevice(btDevice);
} else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
boolean broadcast = false;
int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;