Merge "BT-HFP: Update Bluetooth headset state handler to Multi-HFP"

This commit is contained in:
Treehugger Robot
2018-01-24 18:03:21 +00:00
committed by Gerrit Code Review

View File

@@ -136,7 +136,6 @@ import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@@ -768,7 +767,7 @@ public class AudioService extends IAudioService.Stub
// Register for device connection intent broadcasts. // Register for device connection intent broadcasts.
IntentFilter intentFilter = IntentFilter intentFilter =
new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); 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_DOCK_EVENT);
intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF); intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -2929,14 +2928,28 @@ public class AudioService extends IAudioService.Stub
} }
public void setBluetoothScoOnInt(boolean on, String eventSource) { public void setBluetoothScoOnInt(boolean on, String eventSource) {
if (DEBUG_DEVICES) {
Log.d(TAG, "setBluetoothScoOnInt: " + on + " " + eventSource);
}
if (on) { if (on) {
// do not accept SCO ON if SCO audio is not connected // do not accept SCO ON if SCO audio is not connected
synchronized(mScoClients) { synchronized (mScoClients) {
if ((mBluetoothHeadset != null) && if (mBluetoothHeadset != null) {
(mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice) if (mBluetoothHeadsetDevice == null) {
!= BluetoothHeadset.STATE_AUDIO_CONNECTED)) { BluetoothDevice activeDevice = mBluetoothHeadset.getActiveDevice();
mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO; if (activeDevice != null) {
return; // 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; mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
@@ -3324,24 +3337,23 @@ public class AudioService extends IAudioService.Stub
} }
} }
void setBtScoDeviceConnectionState(BluetoothDevice btDevice, int state) { private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
if (btDevice == null) { if (btDevice == null) {
return; return true;
} }
String address = btDevice.getAddress(); String address = btDevice.getAddress();
BluetoothClass btClass = btDevice.getBluetoothClass(); BluetoothClass btClass = btDevice.getBluetoothClass();
int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET; int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
if (btClass != null) { if (btClass != null) {
switch (btClass.getDeviceClass()) { switch (btClass.getDeviceClass()) {
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
break; break;
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
break; break;
} }
} }
@@ -3349,34 +3361,33 @@ public class AudioService extends IAudioService.Stub
address = ""; address = "";
} }
boolean connected = (state == BluetoothProfile.STATE_CONNECTED);
String btDeviceName = btDevice.getName(); String btDeviceName = btDevice.getName();
boolean success = boolean result = handleDeviceConnection(isActive, outDevice, address, btDeviceName);
handleDeviceConnection(connected, outDevice, address, btDeviceName) && // handleDeviceConnection() && result to make sure the method get executed
handleDeviceConnection(connected, inDevice, address, btDeviceName); result = handleDeviceConnection(isActive, inDevice, address, btDeviceName) && result;
return result;
}
if (!success) { void setBtScoActiveDevice(BluetoothDevice btDevice) {
return; 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) { 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; mBluetoothHeadsetDevice = btDevice;
} else { if (mBluetoothHeadsetDevice == null) {
mBluetoothHeadsetDevice = null; resetBluetoothSco();
resetBluetoothSco(); }
} }
} }
} }
@@ -3431,12 +3442,7 @@ public class AudioService extends IAudioService.Stub
// Discard timeout message // Discard timeout message
mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED); mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED);
mBluetoothHeadset = (BluetoothHeadset) proxy; mBluetoothHeadset = (BluetoothHeadset) proxy;
deviceList = mBluetoothHeadset.getConnectedDevices(); setBtScoActiveDevice(mBluetoothHeadset.getActiveDevice());
if (deviceList.size() > 0) {
mBluetoothHeadsetDevice = deviceList.get(0);
} else {
mBluetoothHeadsetDevice = null;
}
// Refresh SCO audio state // Refresh SCO audio state
checkScoAudioState(); checkScoAudioState();
// Continue pending action if any // Continue pending action if any
@@ -3557,10 +3563,7 @@ public class AudioService extends IAudioService.Stub
void disconnectHeadset() { void disconnectHeadset() {
synchronized (mScoClients) { synchronized (mScoClients) {
if (mBluetoothHeadsetDevice != null) { setBtScoActiveDevice(null);
setBtScoDeviceConnectionState(mBluetoothHeadsetDevice,
BluetoothProfile.STATE_DISCONNECTED);
}
mBluetoothHeadset = null; mBluetoothHeadset = null;
} }
} }
@@ -5732,11 +5735,9 @@ public class AudioService extends IAudioService.Stub
AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config); AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config);
} }
mDockState = dockState; mDockState = dockState;
} else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) {
state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
BluetoothProfile.STATE_DISCONNECTED);
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
setBtScoDeviceConnectionState(btDevice, state); setBtScoActiveDevice(btDevice);
} else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) { } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
boolean broadcast = false; boolean broadcast = false;
int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;