Set service priority of A2DP and Headset from BluetoothService via IPC call

We used to do the priority change in the 2 services after the broadcasted
intent reach them. But that left a small time gap that could reject
incoming connection due to undefined priorities.

Bug 4096186

Change-Id: I9bb6aedc7ed98c53a9b00c48eedd20b0cf5f1660
This commit is contained in:
Matthew Xie
2011-04-05 15:23:03 -07:00
parent 8d9f995334
commit abc3642d6c
2 changed files with 82 additions and 18 deletions

View File

@@ -83,19 +83,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
onBluetoothDisable();
break;
}
} else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
BluetoothDevice.ERROR);
switch(bondState) {
case BluetoothDevice.BOND_BONDED:
if (getPriority(device) == BluetoothA2dp.PRIORITY_UNDEFINED) {
setPriority(device, BluetoothA2dp.PRIORITY_ON);
}
break;
case BluetoothDevice.BOND_NONE:
setPriority(device, BluetoothA2dp.PRIORITY_UNDEFINED);
break;
}
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
synchronized (this) {
if (mAudioDevices.containsKey(device)) {
@@ -158,7 +145,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
mIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
mIntentFilter.addAction(AudioManager.VOLUME_CHANGED_ACTION);

View File

@@ -18,6 +18,9 @@ package android.server;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothHeadset;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
@@ -68,6 +71,8 @@ class BluetoothBondState {
private final Context mContext;
private final BluetoothService mService;
private final BluetoothInputProfileHandler mBluetoothInputProfileHandler;
private BluetoothA2dp mA2dpProxy;
private BluetoothHeadset mHeadsetProxy;
BluetoothBondState(Context context, BluetoothService service) {
mContext = context;
@@ -126,14 +131,15 @@ class BluetoothBondState {
if (state == BluetoothDevice.BOND_BONDED) {
mService.addProfileState(address);
} else if (state == BluetoothDevice.BOND_BONDING) {
if (mA2dpProxy == null || mHeadsetProxy == null) {
getProfileProxy();
}
} else if (state == BluetoothDevice.BOND_NONE) {
mService.removeProfileState(address);
}
// HID is handled by BluetoothService, other profiles
// will be handled by their respective services.
mBluetoothInputProfileHandler.setInitialInputDevicePriority(
mService.getRemoteDevice(address), state);
setProfilePriorities(address, state);
if (DBG) {
Log.d(TAG, address + " bond state " + oldState + " -> " + state
@@ -261,6 +267,52 @@ class BluetoothBondState {
mPinAttempt.put(address, new Integer(newAttempt));
}
private void getProfileProxy() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mA2dpProxy == null) {
bluetoothAdapter.getProfileProxy(mContext, mProfileServiceListener,
BluetoothProfile.A2DP);
}
if (mHeadsetProxy == null) {
bluetoothAdapter.getProfileProxy(mContext, mProfileServiceListener,
BluetoothProfile.HEADSET);
}
}
private void closeProfileProxy() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mA2dpProxy != null) {
bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mA2dpProxy);
}
if (mHeadsetProxy != null) {
bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetProxy);
}
}
private BluetoothProfile.ServiceListener mProfileServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.A2DP) {
mA2dpProxy = (BluetoothA2dp) proxy;
} else if (profile == BluetoothProfile.HEADSET) {
mHeadsetProxy = (BluetoothHeadset) proxy;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.A2DP) {
mA2dpProxy = null;
} else if (profile == BluetoothProfile.HEADSET) {
mHeadsetProxy = null;
}
}
};
private void copyAutoPairingData() {
FileInputStream in = null;
FileOutputStream out = null;
@@ -365,4 +417,30 @@ class BluetoothBondState {
}
}
}
// Set service priority of Hid, A2DP and Headset profiles depending on
// the bond state change
private void setProfilePriorities(String address, int state) {
BluetoothDevice remoteDevice = mService.getRemoteDevice(address);
// HID is handled by BluetoothService
mBluetoothInputProfileHandler.setInitialInputDevicePriority(remoteDevice, state);
// Set service priority of A2DP and Headset
// We used to do the priority change in the 2 services after the broadcast
// intent reach them. But that left a small time gap that could reject
// incoming connection due to undefined priorities.
if (state == BluetoothDevice.BOND_BONDED) {
if (mA2dpProxy.getPriority(remoteDevice) == BluetoothProfile.PRIORITY_UNDEFINED) {
mA2dpProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_ON);
}
if (mHeadsetProxy.getPriority(remoteDevice) == BluetoothProfile.PRIORITY_UNDEFINED) {
mHeadsetProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_ON);
}
} else if (state == BluetoothDevice.BOND_NONE) {
mA2dpProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_UNDEFINED);
mHeadsetProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_UNDEFINED);
}
}
}