From 9bb275197df8eb999eab4cdd0a2aff83c2bb2ef6 Mon Sep 17 00:00:00 2001 From: Jaikumar Ganesh Date: Mon, 28 Nov 2011 09:59:08 -0800 Subject: Cleanup references when turning BT off. Bug: 5572649 Change-Id: I62f9e0620832b69995d5c6e1c24634c9a3895a4b --- core/java/android/bluetooth/BluetoothA2dp.java | 4 ++++ core/java/android/bluetooth/BluetoothAdapter.java | 26 ++++++++++++++++---- .../bluetooth/BluetoothDeviceProfileState.java | 28 +++++++++++++++++++--- core/java/android/bluetooth/BluetoothHeadset.java | 1 + core/java/android/bluetooth/BluetoothHealth.java | 4 ++++ .../android/bluetooth/BluetoothInputDevice.java | 4 ++++ core/java/android/bluetooth/BluetoothPan.java | 6 ++++- core/java/android/bluetooth/BluetoothPbap.java | 3 ++- core/java/android/server/BluetoothService.java | 10 ++++---- 9 files changed, 73 insertions(+), 13 deletions(-) (limited to 'core') diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 96f3290..7300107 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -129,6 +129,10 @@ public final class BluetoothA2dp implements BluetoothProfile { } } + /*package*/ void close() { + mServiceListener = null; + } + /** * Initiate connection to a profile of the remote bluetooth device. * diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index d971652..5f5ba50 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1180,11 +1180,29 @@ public final class BluetoothAdapter { * @param proxy Profile proxy object */ public void closeProfileProxy(int profile, BluetoothProfile proxy) { - if (profile == BluetoothProfile.HEADSET) { - BluetoothHeadset headset = (BluetoothHeadset)proxy; - if (headset != null) { + if (proxy == null) return; + + switch (profile) { + case BluetoothProfile.HEADSET: + BluetoothHeadset headset = (BluetoothHeadset)proxy; headset.close(); - } + break; + case BluetoothProfile.A2DP: + BluetoothA2dp a2dp = (BluetoothA2dp)proxy; + a2dp.close(); + break; + case BluetoothProfile.INPUT_DEVICE: + BluetoothInputDevice iDev = (BluetoothInputDevice)proxy; + iDev.close(); + break; + case BluetoothProfile.PAN: + BluetoothPan pan = (BluetoothPan)proxy; + pan.close(); + break; + case BluetoothProfile.HEALTH: + BluetoothHealth health = (BluetoothHealth)proxy; + health.close(); + break; } } diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java index b1d0070..c9603bf 100644 --- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java +++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java @@ -109,6 +109,8 @@ public final class BluetoothDeviceProfileState extends StateMachine { private BluetoothA2dpService mA2dpService; private BluetoothHeadset mHeadsetService; private BluetoothPbap mPbapService; + private PbapServiceListener mPbap; + private BluetoothAdapter mAdapter; private boolean mPbapServiceConnected; private boolean mAutoConnectionPending; private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; @@ -249,11 +251,11 @@ public final class BluetoothDeviceProfileState extends StateMachine { mContext.registerReceiver(mBroadcastReceiver, filter); - BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); - adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener, + mAdapter = BluetoothAdapter.getDefaultAdapter(); + mAdapter.getProfileProxy(mContext, mBluetoothProfileServiceListener, BluetoothProfile.HEADSET); // TODO(): Convert PBAP to the new Profile APIs. - PbapServiceListener p = new PbapServiceListener(); + mPbap = new PbapServiceListener(); mIncomingConnections = mService.getIncomingState(address); mIncomingRejectTimer = readTimerValue(); @@ -414,6 +416,26 @@ public final class BluetoothDeviceProfileState extends StateMachine { case TRANSITION_TO_STABLE: // ignore. break; + case SM_QUIT_CMD: + mContext.unregisterReceiver(mBroadcastReceiver); + mBroadcastReceiver = null; + mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService); + mBluetoothProfileServiceListener = null; + mOutgoingHandsfree = null; + mPbap = null; + mPbapService.close(); + mPbapService = null; + mIncomingHid = null; + mOutgoingHid = null; + mIncomingHandsfree = null; + mOutgoingHandsfree = null; + mIncomingA2dp = null; + mOutgoingA2dp = null; + mBondedDevice = null; + // There is a problem in the State Machine code + // where things are not cleaned up properly, when quit message + // is handled so return NOT_HANDLED as a workaround. + return NOT_HANDLED; default: return NOT_HANDLED; } diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java index 8f2b3d8..2bbf008 100644 --- a/core/java/android/bluetooth/BluetoothHeadset.java +++ b/core/java/android/bluetooth/BluetoothHeadset.java @@ -245,6 +245,7 @@ public final class BluetoothHeadset implements BluetoothProfile { mContext.unbindService(mConnection); mConnection = null; } + mServiceListener = null; } /** diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java index 9b2b8ca..f850c02 100644 --- a/core/java/android/bluetooth/BluetoothHealth.java +++ b/core/java/android/bluetooth/BluetoothHealth.java @@ -452,6 +452,10 @@ public final class BluetoothHealth implements BluetoothProfile { } } + /*package*/ void close() { + mServiceListener = null; + } + private boolean isEnabled() { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java index 282b70a..1a9e011 100644 --- a/core/java/android/bluetooth/BluetoothInputDevice.java +++ b/core/java/android/bluetooth/BluetoothInputDevice.java @@ -118,6 +118,10 @@ public final class BluetoothInputDevice implements BluetoothProfile { } } + /*package*/ void close() { + mServiceListener = null; + } + /** * Initiate connection to a profile of the remote bluetooth device. * diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java index 7490f9e..5d9d8be 100644 --- a/core/java/android/bluetooth/BluetoothPan.java +++ b/core/java/android/bluetooth/BluetoothPan.java @@ -139,6 +139,10 @@ public final class BluetoothPan implements BluetoothProfile { } } + /*package*/ void close() { + mServiceListener = null; + } + /** * Initiate connection to a profile of the remote bluetooth device. * @@ -299,4 +303,4 @@ public final class BluetoothPan implements BluetoothProfile { private static void log(String msg) { Log.d(TAG, msg); } -} \ No newline at end of file +} diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java index 4be077c..2683bef 100644 --- a/core/java/android/bluetooth/BluetoothPbap.java +++ b/core/java/android/bluetooth/BluetoothPbap.java @@ -69,7 +69,7 @@ public class BluetoothPbap { private IBluetoothPbap mService; private final Context mContext; - private final ServiceListener mServiceListener; + private ServiceListener mServiceListener; /** There was an error trying to obtain the state */ public static final int STATE_ERROR = -1; @@ -138,6 +138,7 @@ public class BluetoothPbap { mContext.unbindService(mConnection); mConnection = null; } + mServiceListener = null; } /** diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java index 28e231e..a7d8cac 100755 --- a/core/java/android/server/BluetoothService.java +++ b/core/java/android/server/BluetoothService.java @@ -2374,16 +2374,18 @@ public class BluetoothService extends IBluetooth.Stub { } BluetoothDeviceProfileState addProfileState(String address, boolean setTrust) { - BluetoothDeviceProfileState state = mDeviceProfileState.get(address); - if (state != null) return state; - - state = new BluetoothDeviceProfileState(mContext, address, this, mA2dpService, setTrust); + BluetoothDeviceProfileState state = + new BluetoothDeviceProfileState(mContext, address, this, mA2dpService, setTrust); mDeviceProfileState.put(address, state); state.start(); return state; } void removeProfileState(String address) { + BluetoothDeviceProfileState state = mDeviceProfileState.get(address); + if (state == null) return; + + state.quit(); mDeviceProfileState.remove(address); } -- cgit v1.1