am 025f78eb: Merge "DO NOT MERGE Fix auto connection with headsets which don\'t send incoming connections for all profiles." into gingerbread
This commit is contained in:
@@ -72,6 +72,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
public static final int UNPAIR = 100;
|
public static final int UNPAIR = 100;
|
||||||
public static final int AUTO_CONNECT_PROFILES = 101;
|
public static final int AUTO_CONNECT_PROFILES = 101;
|
||||||
public static final int TRANSITION_TO_STABLE = 102;
|
public static final int TRANSITION_TO_STABLE = 102;
|
||||||
|
public static final int CONNECT_OTHER_PROFILES = 103;
|
||||||
|
|
||||||
private static final int AUTO_CONNECT_DELAY = 6000; // 6 secs
|
private static final int AUTO_CONNECT_DELAY = 6000; // 6 secs
|
||||||
|
|
||||||
@@ -129,10 +130,6 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
sendMessage(TRANSITION_TO_STABLE);
|
sendMessage(TRANSITION_TO_STABLE);
|
||||||
}
|
}
|
||||||
} else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
|
} else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
|
||||||
if (!getCurrentState().equals(mBondedDevice)) {
|
|
||||||
Log.e(TAG, "State is: " + getCurrentState());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Message msg = new Message();
|
Message msg = new Message();
|
||||||
msg.what = AUTO_CONNECT_PROFILES;
|
msg.what = AUTO_CONNECT_PROFILES;
|
||||||
sendMessageDelayed(msg, AUTO_CONNECT_DELAY);
|
sendMessageDelayed(msg, AUTO_CONNECT_DELAY);
|
||||||
@@ -274,16 +271,39 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
if (mHeadsetService.getPriority(mDevice) ==
|
if (mHeadsetService.getPriority(mDevice) ==
|
||||||
BluetoothHeadset.PRIORITY_AUTO_CONNECT &&
|
BluetoothHeadset.PRIORITY_AUTO_CONNECT &&
|
||||||
!mHeadsetService.isConnected(mDevice)) {
|
!mHeadsetService.isConnected(mDevice)) {
|
||||||
|
Log.i(TAG, "Headset:Auto Connect Profiles");
|
||||||
mHeadsetService.connectHeadset(mDevice);
|
mHeadsetService.connectHeadset(mDevice);
|
||||||
}
|
}
|
||||||
if (mA2dpService != null &&
|
if (mA2dpService != null &&
|
||||||
mA2dpService.getSinkPriority(mDevice) ==
|
mA2dpService.getSinkPriority(mDevice) ==
|
||||||
BluetoothA2dp.PRIORITY_AUTO_CONNECT &&
|
BluetoothA2dp.PRIORITY_AUTO_CONNECT &&
|
||||||
mA2dpService.getConnectedSinks().length == 0) {
|
mA2dpService.getConnectedSinks().length == 0) {
|
||||||
|
Log.i(TAG, "A2dp:Auto Connect Profiles");
|
||||||
mA2dpService.connectSink(mDevice);
|
mA2dpService.connectSink(mDevice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CONNECT_OTHER_PROFILES:
|
||||||
|
if (isPhoneDocked(mDevice)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (message.arg1 == CONNECT_A2DP_OUTGOING) {
|
||||||
|
if (mA2dpService != null &&
|
||||||
|
mA2dpService.getConnectedSinks().length == 0) {
|
||||||
|
Log.i(TAG, "A2dp:Connect Other Profiles");
|
||||||
|
mA2dpService.connectSink(mDevice);
|
||||||
|
}
|
||||||
|
} else if (message.arg1 == CONNECT_HFP_OUTGOING) {
|
||||||
|
if (!mHeadsetServiceConnected) {
|
||||||
|
deferMessage(message);
|
||||||
|
} else {
|
||||||
|
if (!mHeadsetService.isConnected(mDevice)) {
|
||||||
|
Log.i(TAG, "Headset:Connect Other Profiles");
|
||||||
|
mHeadsetService.connectHeadset(mDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TRANSITION_TO_STABLE:
|
case TRANSITION_TO_STABLE:
|
||||||
// ignore.
|
// ignore.
|
||||||
break;
|
break;
|
||||||
@@ -377,6 +397,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
case DISCONNECT_PBAP_OUTGOING:
|
case DISCONNECT_PBAP_OUTGOING:
|
||||||
case UNPAIR:
|
case UNPAIR:
|
||||||
case AUTO_CONNECT_PROFILES:
|
case AUTO_CONNECT_PROFILES:
|
||||||
|
case CONNECT_OTHER_PROFILES:
|
||||||
deferMessage(message);
|
deferMessage(message);
|
||||||
break;
|
break;
|
||||||
case TRANSITION_TO_STABLE:
|
case TRANSITION_TO_STABLE:
|
||||||
@@ -449,6 +470,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
case DISCONNECT_PBAP_OUTGOING:
|
case DISCONNECT_PBAP_OUTGOING:
|
||||||
case UNPAIR:
|
case UNPAIR:
|
||||||
case AUTO_CONNECT_PROFILES:
|
case AUTO_CONNECT_PROFILES:
|
||||||
|
case CONNECT_OTHER_PROFILES:
|
||||||
deferMessage(message);
|
deferMessage(message);
|
||||||
break;
|
break;
|
||||||
case TRANSITION_TO_STABLE:
|
case TRANSITION_TO_STABLE:
|
||||||
@@ -541,6 +563,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
case DISCONNECT_PBAP_OUTGOING:
|
case DISCONNECT_PBAP_OUTGOING:
|
||||||
case UNPAIR:
|
case UNPAIR:
|
||||||
case AUTO_CONNECT_PROFILES:
|
case AUTO_CONNECT_PROFILES:
|
||||||
|
case CONNECT_OTHER_PROFILES:
|
||||||
deferMessage(message);
|
deferMessage(message);
|
||||||
break;
|
break;
|
||||||
case TRANSITION_TO_STABLE:
|
case TRANSITION_TO_STABLE:
|
||||||
@@ -611,6 +634,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
case DISCONNECT_PBAP_OUTGOING:
|
case DISCONNECT_PBAP_OUTGOING:
|
||||||
case UNPAIR:
|
case UNPAIR:
|
||||||
case AUTO_CONNECT_PROFILES:
|
case AUTO_CONNECT_PROFILES:
|
||||||
|
case CONNECT_OTHER_PROFILES:
|
||||||
deferMessage(message);
|
deferMessage(message);
|
||||||
break;
|
break;
|
||||||
case TRANSITION_TO_STABLE:
|
case TRANSITION_TO_STABLE:
|
||||||
@@ -656,6 +680,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
} else if (mHeadsetState == BluetoothHeadset.STATE_CONNECTING) {
|
} else if (mHeadsetState == BluetoothHeadset.STATE_CONNECTING) {
|
||||||
return mHeadsetService.acceptIncomingConnect(mDevice);
|
return mHeadsetService.acceptIncomingConnect(mDevice);
|
||||||
} else if (mHeadsetState == BluetoothHeadset.STATE_DISCONNECTED) {
|
} else if (mHeadsetState == BluetoothHeadset.STATE_DISCONNECTED) {
|
||||||
|
handleConnectionOfOtherProfiles(command);
|
||||||
return mHeadsetService.createIncomingConnect(mDevice);
|
return mHeadsetService.createIncomingConnect(mDevice);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -665,6 +690,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CONNECT_A2DP_INCOMING:
|
case CONNECT_A2DP_INCOMING:
|
||||||
|
handleConnectionOfOtherProfiles(command);
|
||||||
// ignore, Bluez takes care
|
// ignore, Bluez takes care
|
||||||
return true;
|
return true;
|
||||||
case DISCONNECT_HFP_OUTGOING:
|
case DISCONNECT_HFP_OUTGOING:
|
||||||
@@ -713,6 +739,61 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleConnectionOfOtherProfiles(int command) {
|
||||||
|
// The white paper recommendations mentions that when there is a
|
||||||
|
// link loss, it is the responsibility of the remote device to connect.
|
||||||
|
// Many connect only 1 profile - and they connect the second profile on
|
||||||
|
// some user action (like play being pressed) and so we need this code.
|
||||||
|
// Auto Connect code only connects to the last connected device - which
|
||||||
|
// is useful in cases like when the phone reboots. But consider the
|
||||||
|
// following case:
|
||||||
|
// User is connected to the car's phone and A2DP profile.
|
||||||
|
// User comes to the desk and places the phone in the dock
|
||||||
|
// (or any speaker or music system or even another headset) and thus
|
||||||
|
// gets connected to the A2DP profile. User goes back to the car.
|
||||||
|
// Ideally the car's system is supposed to send incoming connections
|
||||||
|
// from both Handsfree and A2DP profile. But they don't. The Auto
|
||||||
|
// connect code, will not work here because we only auto connect to the
|
||||||
|
// last connected device for that profile which in this case is the dock.
|
||||||
|
// Now suppose a user is using 2 headsets simultaneously, one for the
|
||||||
|
// phone profile one for the A2DP profile. If this is the use case, we
|
||||||
|
// expect the user to use the preference to turn off the A2DP profile in
|
||||||
|
// the Settings screen for the first headset. Else, after link loss,
|
||||||
|
// there can be an incoming connection from the first headset which
|
||||||
|
// might result in the connection of the A2DP profile (if the second
|
||||||
|
// headset is slower) and thus the A2DP profile on the second headset
|
||||||
|
// will never get connected.
|
||||||
|
//
|
||||||
|
// TODO(): Handle other profiles here.
|
||||||
|
switch (command) {
|
||||||
|
case CONNECT_HFP_INCOMING:
|
||||||
|
// Connect A2DP if there is no incoming connection
|
||||||
|
// If the priority is OFF - don't auto connect.
|
||||||
|
// If the priority is AUTO_CONNECT, auto connect code takes care.
|
||||||
|
if (mA2dpService.getSinkPriority(mDevice) == BluetoothA2dp.PRIORITY_ON) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = CONNECT_OTHER_PROFILES;
|
||||||
|
msg.arg1 = CONNECT_A2DP_OUTGOING;
|
||||||
|
sendMessageDelayed(msg, AUTO_CONNECT_DELAY);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CONNECT_A2DP_INCOMING:
|
||||||
|
// This is again against spec. HFP incoming connections should be made
|
||||||
|
// before A2DP, so we should not hit this case. But many devices
|
||||||
|
// don't follow this.
|
||||||
|
if (mHeadsetService.getPriority(mDevice) == BluetoothHeadset.PRIORITY_ON) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = CONNECT_OTHER_PROFILES;
|
||||||
|
msg.arg1 = CONNECT_HFP_OUTGOING;
|
||||||
|
sendMessageDelayed(msg, AUTO_CONNECT_DELAY);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*package*/ BluetoothDevice getDevice() {
|
/*package*/ BluetoothDevice getDevice() {
|
||||||
return mDevice;
|
return mDevice;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user