BT settings wait for HS service before connect. DO NOT MERGE
Bluetooth connections from Settings app can sometimes fail if the connection to BluetoothHeadsetService isn't ready. Changed code to delay any headset connect or disconnect attempt when the service isn't connected until onServiceConnected() is called. Tested by adding a call to Thread.sleep(5000) before the return statement in BluetoothHeadsetService.onBind(). This makes it easier to kill the phone process and then attempt to connect in the settings app before the service restarts. Bug: 3048839 Change-Id: I2114ff8ad67c8c672fcf6ce0bf3de61fca7a49b3
This commit is contained in:
@@ -309,6 +309,8 @@ public abstract class LocalBluetoothProfileManager {
|
|||||||
private BluetoothHeadset mService;
|
private BluetoothHeadset mService;
|
||||||
private Handler mUiHandler = new Handler();
|
private Handler mUiHandler = new Handler();
|
||||||
private boolean profileReady = false;
|
private boolean profileReady = false;
|
||||||
|
private BluetoothDevice mDelayedConnectDevice = null;
|
||||||
|
private BluetoothDevice mDelayedDisconnectDevice = null;
|
||||||
|
|
||||||
public HeadsetProfileManager(LocalBluetoothManager localManager) {
|
public HeadsetProfileManager(LocalBluetoothManager localManager) {
|
||||||
super(localManager);
|
super(localManager);
|
||||||
@@ -318,19 +320,43 @@ public abstract class LocalBluetoothProfileManager {
|
|||||||
public void onServiceConnected() {
|
public void onServiceConnected() {
|
||||||
profileReady = true;
|
profileReady = true;
|
||||||
// This could be called on a non-UI thread, funnel to UI thread.
|
// This could be called on a non-UI thread, funnel to UI thread.
|
||||||
mUiHandler.post(new Runnable() {
|
// Delay for a few seconds to allow other proxies to connect.
|
||||||
|
mUiHandler.postDelayed(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
BluetoothDevice device = mService.getCurrentHeadset();
|
||||||
|
|
||||||
|
if (mDelayedConnectDevice != null) {
|
||||||
|
Log.i(TAG, "service ready: connecting...");
|
||||||
|
BluetoothDevice newDevice = mDelayedConnectDevice;
|
||||||
|
mDelayedConnectDevice = null;
|
||||||
|
|
||||||
|
if (!newDevice.equals(device)) {
|
||||||
|
if (device != null) {
|
||||||
|
Log.i(TAG, "disconnecting old headset");
|
||||||
|
mService.disconnectHeadset(device);
|
||||||
|
}
|
||||||
|
Log.i(TAG, "connecting to pending headset");
|
||||||
|
mService.connectHeadset(newDevice);
|
||||||
|
}
|
||||||
|
} else if (mDelayedDisconnectDevice != null) {
|
||||||
|
Log.i(TAG, "service ready: disconnecting...");
|
||||||
|
if (mDelayedDisconnectDevice.equals(device)) {
|
||||||
|
Log.i(TAG, "disconnecting headset");
|
||||||
|
mService.disconnectHeadset(device);
|
||||||
|
}
|
||||||
|
mDelayedDisconnectDevice = null;
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* We just bound to the service, so refresh the UI of the
|
* We just bound to the service, so refresh the UI of the
|
||||||
* headset device.
|
* headset device.
|
||||||
*/
|
*/
|
||||||
BluetoothDevice device = mService.getCurrentHeadset();
|
|
||||||
if (device == null) return;
|
if (device == null) return;
|
||||||
mLocalManager.getCachedDeviceManager()
|
mLocalManager.getCachedDeviceManager()
|
||||||
.onProfileStateChanged(device, Profile.HEADSET,
|
.onProfileStateChanged(device, Profile.HEADSET,
|
||||||
BluetoothHeadset.STATE_CONNECTED);
|
BluetoothHeadset.STATE_CONNECTED);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}, 2000); // wait 2 seconds for other proxies to connect
|
||||||
|
|
||||||
if (mServiceListeners.size() > 0) {
|
if (mServiceListeners.size() > 0) {
|
||||||
Iterator<ServiceListener> it = mServiceListeners.iterator();
|
Iterator<ServiceListener> it = mServiceListeners.iterator();
|
||||||
@@ -368,6 +394,16 @@ public abstract class LocalBluetoothProfileManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean connect(BluetoothDevice device) {
|
public boolean connect(BluetoothDevice device) {
|
||||||
|
// Delay connection until onServiceConnected() if the
|
||||||
|
// manager isn't ready
|
||||||
|
if (!isManagerReady()) {
|
||||||
|
Log.w(TAG, "HeadsetProfileManager delaying connect, "
|
||||||
|
+ "manager not ready");
|
||||||
|
mDelayedConnectDevice = device;
|
||||||
|
mDelayedDisconnectDevice = null;
|
||||||
|
return true; // hopefully it will succeed
|
||||||
|
}
|
||||||
|
|
||||||
// Since connectHeadset fails if already connected to a headset, we
|
// Since connectHeadset fails if already connected to a headset, we
|
||||||
// disconnect from any headset first
|
// disconnect from any headset first
|
||||||
BluetoothDevice currDevice = mService.getCurrentHeadset();
|
BluetoothDevice currDevice = mService.getCurrentHeadset();
|
||||||
@@ -379,6 +415,16 @@ public abstract class LocalBluetoothProfileManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean disconnect(BluetoothDevice device) {
|
public boolean disconnect(BluetoothDevice device) {
|
||||||
|
// Delay connection until onServiceConnected() if the
|
||||||
|
// manager isn't ready
|
||||||
|
if (!isManagerReady()) {
|
||||||
|
Log.w(TAG, "HeadsetProfileManager delaying disconnect, "
|
||||||
|
+ "manager not ready");
|
||||||
|
mDelayedConnectDevice = null;
|
||||||
|
mDelayedDisconnectDevice = device;
|
||||||
|
return true; // hopefully it will succeed
|
||||||
|
}
|
||||||
|
|
||||||
BluetoothDevice currDevice = mService.getCurrentHeadset();
|
BluetoothDevice currDevice = mService.getCurrentHeadset();
|
||||||
if (currDevice != null && currDevice.equals(device)) {
|
if (currDevice != null && currDevice.equals(device)) {
|
||||||
// Downgrade prority as user is disconnecting the headset.
|
// Downgrade prority as user is disconnecting the headset.
|
||||||
|
Reference in New Issue
Block a user