Merge "Reduced the impact of "synchronized" statements"

am: 1c3b50a00e

* commit '1c3b50a00ea3ab23569a697ba1f1e756098a01a2':
  Reduced the impact of "synchronized" statements

Change-Id: I7ddeb85696efe31c52db3a97ec2a142cb03bee65
This commit is contained in:
Pavlin Radoslavov
2016-05-24 23:25:03 +00:00
committed by android-build-merger
2 changed files with 400 additions and 250 deletions

View File

@@ -53,6 +53,8 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/** /**
* Represents the local device Bluetooth adapter. The {@link BluetoothAdapter} * Represents the local device Bluetooth adapter. The {@link BluetoothAdapter}
@@ -487,6 +489,8 @@ public final class BluetoothAdapter {
private final IBluetoothManager mManagerService; private final IBluetoothManager mManagerService;
private IBluetooth mService; private IBluetooth mService;
private final ReentrantReadWriteLock mServiceLock =
new ReentrantReadWriteLock();
private final Object mLock = new Object(); private final Object mLock = new Object();
private final Map<LeScanCallback, ScanCallback> mLeScanClients; private final Map<LeScanCallback, ScanCallback> mLeScanClients;
@@ -521,8 +525,13 @@ public final class BluetoothAdapter {
throw new IllegalArgumentException("bluetooth manager service is null"); throw new IllegalArgumentException("bluetooth manager service is null");
} }
try { try {
mServiceLock.writeLock().lock();
mService = managerService.registerAdapter(mManagerCallback); mService = managerService.registerAdapter(mManagerCallback);
} catch (RemoteException e) {Log.e(TAG, "", e);} } catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.writeLock().unlock();
}
mManagerService = managerService; mManagerService = managerService;
mLeScanClients = new HashMap<LeScanCallback, ScanCallback>(); mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
mToken = new Binder(); mToken = new Binder();
@@ -609,10 +618,14 @@ public final class BluetoothAdapter {
@RequiresPermission(Manifest.permission.BLUETOOTH) @RequiresPermission(Manifest.permission.BLUETOOTH)
public boolean isEnabled() { public boolean isEnabled() {
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.isEnabled(); if (mService != null) return mService.isEnabled();
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false; return false;
} }
@@ -643,12 +656,12 @@ public final class BluetoothAdapter {
* or OFF if BT is in BLE_ON state * or OFF if BT is in BLE_ON state
*/ */
private void notifyUserAction(boolean enable) { private void notifyUserAction(boolean enable) {
try {
mServiceLock.readLock().lock();
if (mService == null) { if (mService == null) {
Log.e(TAG, "mService is null"); Log.e(TAG, "mService is null");
return; return;
} }
try {
if (enable) { if (enable) {
mService.onLeServiceUp(); //NA:TODO implementation pending mService.onLeServiceUp(); //NA:TODO implementation pending
} else { } else {
@@ -656,6 +669,8 @@ public final class BluetoothAdapter {
} }
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "", e); Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} }
@@ -787,27 +802,29 @@ public final class BluetoothAdapter {
@RequiresPermission(Manifest.permission.BLUETOOTH) @RequiresPermission(Manifest.permission.BLUETOOTH)
@AdapterState @AdapterState
public int getState() { public int getState() {
int state = BluetoothAdapter.STATE_OFF;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) if (mService != null) {
{ state = mService.getState();
int state= mService.getState(); }
if (VDBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + state); } catch (RemoteException e) {
//consider all internal states as OFF Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
}
// Consider all internal states as OFF
if (state == BluetoothAdapter.STATE_BLE_ON if (state == BluetoothAdapter.STATE_BLE_ON
|| state == BluetoothAdapter.STATE_BLE_TURNING_ON || state == BluetoothAdapter.STATE_BLE_TURNING_ON
|| state == BluetoothAdapter.STATE_BLE_TURNING_OFF) { || state == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
if (VDBG) Log.d(TAG, "Consider internal state as OFF"); if (VDBG) Log.d(TAG, "Consider internal state as OFF");
state = BluetoothAdapter.STATE_OFF; state = BluetoothAdapter.STATE_OFF;
} }
if (VDBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + state);
return state; return state;
} }
// TODO(BT) there might be a small gap during STATE_TURNING_ON that
// mService is null, handle that case
}
} catch (RemoteException e) {Log.e(TAG, "", e);}
return STATE_OFF;
}
/** /**
* Get the current state of the local Bluetooth adapter * Get the current state of the local Bluetooth adapter
@@ -829,19 +846,21 @@ public final class BluetoothAdapter {
@RequiresPermission(Manifest.permission.BLUETOOTH) @RequiresPermission(Manifest.permission.BLUETOOTH)
@AdapterState @AdapterState
public int getLeState() { public int getLeState() {
int state = BluetoothAdapter.STATE_OFF;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) if (mService != null) {
{ state = mService.getState();
int state= mService.getState();
if (VDBG) Log.d(TAG,"getLeState() returning " + state);
return state;
}
} }
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "", e); Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
return BluetoothAdapter.STATE_OFF;
if (VDBG) Log.d(TAG,"getLeState() returning " + state);
return state;
} }
boolean getLeAccess() { boolean getLeAccess() {
@@ -883,16 +902,21 @@ public final class BluetoothAdapter {
*/ */
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean enable() { public boolean enable() {
int state = STATE_OFF; int state = BluetoothAdapter.STATE_OFF;
if (isEnabled() == true) { if (isEnabled() == true) {
if (DBG) Log.d(TAG, "enable(): BT is already enabled..!"); if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
return true; return true;
} }
// Use service interface to get the exact state // Use service interface to get the exact state
if (mService != null) {
try { try {
mServiceLock.readLock().lock();
if (mService != null) {
state = mService.getState(); state = mService.getState();
} catch (RemoteException e) {Log.e(TAG, "", e);} }
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
if (state == BluetoothAdapter.STATE_BLE_ON) { if (state == BluetoothAdapter.STATE_BLE_ON) {
@@ -997,10 +1021,13 @@ public final class BluetoothAdapter {
*/ */
public boolean configHciSnoopLog(boolean enable) { public boolean configHciSnoopLog(boolean enable) {
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.configHciSnoopLog(enable); if (mService != null) return mService.configHciSnoopLog(enable);
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false; return false;
} }
@@ -1016,12 +1043,16 @@ public final class BluetoothAdapter {
*/ */
public boolean factoryReset() { public boolean factoryReset() {
try { try {
mServiceLock.readLock().lock();
if (mService != null) { if (mService != null) {
return mService.factoryReset(); return mService.factoryReset();
} else {
SystemProperties.set("persist.bluetooth.factoryreset", "true");
} }
} catch (RemoteException e) {Log.e(TAG, "", e);} SystemProperties.set("persist.bluetooth.factoryreset", "true");
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
}
return false; return false;
} }
@@ -1036,10 +1067,13 @@ public final class BluetoothAdapter {
public ParcelUuid[] getUuids() { public ParcelUuid[] getUuids() {
if (getState() != STATE_ON) return null; if (getState() != STATE_ON) return null;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.getUuids(); if (mService != null) return mService.getUuids();
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return null; return null;
} }
@@ -1062,10 +1096,13 @@ public final class BluetoothAdapter {
public boolean setName(String name) { public boolean setName(String name) {
if (getState() != STATE_ON) return false; if (getState() != STATE_ON) return false;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.setName(name); if (mService != null) return mService.setName(name);
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false; return false;
} }
@@ -1090,10 +1127,13 @@ public final class BluetoothAdapter {
public int getScanMode() { public int getScanMode() {
if (getState() != STATE_ON) return SCAN_MODE_NONE; if (getState() != STATE_ON) return SCAN_MODE_NONE;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.getScanMode(); if (mService != null) return mService.getScanMode();
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return SCAN_MODE_NONE; return SCAN_MODE_NONE;
} }
@@ -1128,10 +1168,13 @@ public final class BluetoothAdapter {
public boolean setScanMode(@ScanMode int mode, int duration) { public boolean setScanMode(@ScanMode int mode, int duration) {
if (getState() != STATE_ON) return false; if (getState() != STATE_ON) return false;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.setScanMode(mode, duration); if (mService != null) return mService.setScanMode(mode, duration);
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false; return false;
} }
@@ -1146,10 +1189,13 @@ public final class BluetoothAdapter {
public int getDiscoverableTimeout() { public int getDiscoverableTimeout() {
if (getState() != STATE_ON) return -1; if (getState() != STATE_ON) return -1;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.getDiscoverableTimeout(); if (mService != null) return mService.getDiscoverableTimeout();
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return -1; return -1;
} }
@@ -1157,10 +1203,13 @@ public final class BluetoothAdapter {
public void setDiscoverableTimeout(int timeout) { public void setDiscoverableTimeout(int timeout) {
if (getState() != STATE_ON) return; if (getState() != STATE_ON) return;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) mService.setDiscoverableTimeout(timeout); if (mService != null) mService.setDiscoverableTimeout(timeout);
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
} }
/** /**
@@ -1197,10 +1246,13 @@ public final class BluetoothAdapter {
public boolean startDiscovery() { public boolean startDiscovery() {
if (getState() != STATE_ON) return false; if (getState() != STATE_ON) return false;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.startDiscovery(); if (mService != null) return mService.startDiscovery();
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false; return false;
} }
@@ -1225,10 +1277,13 @@ public final class BluetoothAdapter {
public boolean cancelDiscovery() { public boolean cancelDiscovery() {
if (getState() != STATE_ON) return false; if (getState() != STATE_ON) return false;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.cancelDiscovery(); if (mService != null) return mService.cancelDiscovery();
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false; return false;
} }
@@ -1255,10 +1310,13 @@ public final class BluetoothAdapter {
public boolean isDiscovering() { public boolean isDiscovering() {
if (getState() != STATE_ON) return false; if (getState() != STATE_ON) return false;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.isDiscovering(); if (mService != null) return mService.isDiscovering();
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false; return false;
} }
@@ -1270,9 +1328,12 @@ public final class BluetoothAdapter {
public boolean isMultipleAdvertisementSupported() { public boolean isMultipleAdvertisementSupported() {
if (getState() != STATE_ON) return false; if (getState() != STATE_ON) return false;
try { try {
return mService.isMultiAdvertisementSupported(); mServiceLock.readLock().lock();
if (mService != null) return mService.isMultiAdvertisementSupported();
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "failed to get isMultipleAdvertisementSupported, error: ", e); Log.e(TAG, "failed to get isMultipleAdvertisementSupported, error: ", e);
} finally {
mServiceLock.readLock().unlock();
} }
return false; return false;
} }
@@ -1305,9 +1366,12 @@ public final class BluetoothAdapter {
public boolean isPeripheralModeSupported() { public boolean isPeripheralModeSupported() {
if (getState() != STATE_ON) return false; if (getState() != STATE_ON) return false;
try { try {
return mService.isPeripheralModeSupported(); mServiceLock.readLock().lock();
if (mService != null) return mService.isPeripheralModeSupported();
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "failed to get peripheral mode capability: ", e); Log.e(TAG, "failed to get peripheral mode capability: ", e);
} finally {
mServiceLock.readLock().unlock();
} }
return false; return false;
} }
@@ -1320,9 +1384,12 @@ public final class BluetoothAdapter {
public boolean isOffloadedFilteringSupported() { public boolean isOffloadedFilteringSupported() {
if (!getLeAccess()) return false; if (!getLeAccess()) return false;
try { try {
return mService.isOffloadedFilteringSupported(); mServiceLock.readLock().lock();
if (mService != null) return mService.isOffloadedFilteringSupported();
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "failed to get isOffloadedFilteringSupported, error: ", e); Log.e(TAG, "failed to get isOffloadedFilteringSupported, error: ", e);
} finally {
mServiceLock.readLock().unlock();
} }
return false; return false;
} }
@@ -1335,9 +1402,12 @@ public final class BluetoothAdapter {
public boolean isOffloadedScanBatchingSupported() { public boolean isOffloadedScanBatchingSupported() {
if (!getLeAccess()) return false; if (!getLeAccess()) return false;
try { try {
return mService.isOffloadedScanBatchingSupported(); mServiceLock.readLock().lock();
if (mService != null) return mService.isOffloadedScanBatchingSupported();
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "failed to get isOffloadedScanBatchingSupported, error: ", e); Log.e(TAG, "failed to get isOffloadedScanBatchingSupported, error: ", e);
} finally {
mServiceLock.readLock().unlock();
} }
return false; return false;
} }
@@ -1376,10 +1446,13 @@ public final class BluetoothAdapter {
public BluetoothActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) { public BluetoothActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
if (getState() != STATE_ON) return null; if (getState() != STATE_ON) return null;
try { try {
mServiceLock.readLock().lock();
BluetoothActivityEnergyInfo record; BluetoothActivityEnergyInfo record;
if (mService != null) {
if (!mService.isActivityAndEnergyReportingSupported()) { if (!mService.isActivityAndEnergyReportingSupported()) {
return null; return null;
} }
}
synchronized(this) { synchronized(this) {
if (updateType == ACTIVITY_ENERGY_INFO_REFRESHED) { if (updateType == ACTIVITY_ENERGY_INFO_REFRESHED) {
mService.getActivityEnergyInfoFromController(); mService.getActivityEnergyInfoFromController();
@@ -1396,6 +1469,8 @@ public final class BluetoothAdapter {
Log.e(TAG, "getControllerActivityEnergyInfoCallback wait interrupted: " + e); Log.e(TAG, "getControllerActivityEnergyInfoCallback wait interrupted: " + e);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e); Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
} finally {
mServiceLock.readLock().unlock();
} }
return null; return null;
} }
@@ -1417,11 +1492,14 @@ public final class BluetoothAdapter {
return toDeviceSet(new BluetoothDevice[0]); return toDeviceSet(new BluetoothDevice[0]);
} }
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return toDeviceSet(mService.getBondedDevices()); if (mService != null) return toDeviceSet(mService.getBondedDevices());
}
return toDeviceSet(new BluetoothDevice[0]); return toDeviceSet(new BluetoothDevice[0]);
} catch (RemoteException e) {Log.e(TAG, "", e);} } catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
}
return null; return null;
} }
@@ -1441,10 +1519,13 @@ public final class BluetoothAdapter {
public int getConnectionState() { public int getConnectionState() {
if (getState() != STATE_ON) return BluetoothAdapter.STATE_DISCONNECTED; if (getState() != STATE_ON) return BluetoothAdapter.STATE_DISCONNECTED;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.getAdapterConnectionState(); if (mService != null) return mService.getAdapterConnectionState();
} catch (RemoteException e) {
Log.e(TAG, "getConnectionState:", e);
} finally {
mServiceLock.readLock().unlock();
} }
} catch (RemoteException e) {Log.e(TAG, "getConnectionState:", e);}
return BluetoothAdapter.STATE_DISCONNECTED; return BluetoothAdapter.STATE_DISCONNECTED;
} }
@@ -1467,11 +1548,12 @@ public final class BluetoothAdapter {
public int getProfileConnectionState(int profile) { public int getProfileConnectionState(int profile) {
if (getState() != STATE_ON) return BluetoothProfile.STATE_DISCONNECTED; if (getState() != STATE_ON) return BluetoothProfile.STATE_DISCONNECTED;
try { try {
synchronized(mManagerCallback) { mServiceLock.readLock().lock();
if (mService != null) return mService.getProfileConnectionState(profile); if (mService != null) return mService.getProfileConnectionState(profile);
}
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "getProfileConnectionState:", e); Log.e(TAG, "getProfileConnectionState:", e);
} finally {
mServiceLock.readLock().unlock();
} }
return BluetoothProfile.STATE_DISCONNECTED; return BluetoothProfile.STATE_DISCONNECTED;
} }
@@ -1775,7 +1857,9 @@ public final class BluetoothAdapter {
byte[] hash; byte[] hash;
byte[] randomizer; byte[] randomizer;
byte[] ret = mService.readOutOfBandData(); byte[] ret = null;
mServiceLock.readLock().lock();
if (mService != null) mService.readOutOfBandData();
if (ret == null || ret.length != 32) return null; if (ret == null || ret.length != 32) return null;
@@ -1788,7 +1872,12 @@ public final class BluetoothAdapter {
} }
return new Pair<byte[], byte[]>(hash, randomizer); return new Pair<byte[], byte[]>(hash, randomizer);
} catch (RemoteException e) {Log.e(TAG, "", e);}*/ } catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
}
*/
return null; return null;
} }
@@ -1917,8 +2006,11 @@ public final class BluetoothAdapter {
new IBluetoothManagerCallback.Stub() { new IBluetoothManagerCallback.Stub() {
public void onBluetoothServiceUp(IBluetooth bluetoothService) { public void onBluetoothServiceUp(IBluetooth bluetoothService) {
if (VDBG) Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService); if (VDBG) Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService);
synchronized (mManagerCallback) {
mServiceLock.writeLock().lock();
mService = bluetoothService; mService = bluetoothService;
mServiceLock.writeLock().unlock();
synchronized (mProxyServiceStateCallbacks) { synchronized (mProxyServiceStateCallbacks) {
for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ) { for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ) {
try { try {
@@ -1927,7 +2019,8 @@ public final class BluetoothAdapter {
} else { } else {
Log.d(TAG, "onBluetoothServiceUp: cb is null!!!"); Log.d(TAG, "onBluetoothServiceUp: cb is null!!!");
} }
} catch (Exception e) { Log.e(TAG,"",e);} } catch (Exception e) {
Log.e(TAG,"",e);
} }
} }
} }
@@ -1935,11 +2028,14 @@ public final class BluetoothAdapter {
public void onBluetoothServiceDown() { public void onBluetoothServiceDown() {
if (VDBG) Log.d(TAG, "onBluetoothServiceDown: " + mService); if (VDBG) Log.d(TAG, "onBluetoothServiceDown: " + mService);
synchronized (mManagerCallback) {
mServiceLock.writeLock().lock();
mService = null; mService = null;
if (mLeScanClients != null) mLeScanClients.clear(); if (mLeScanClients != null) mLeScanClients.clear();
if (sBluetoothLeAdvertiser != null) sBluetoothLeAdvertiser.cleanup(); if (sBluetoothLeAdvertiser != null) sBluetoothLeAdvertiser.cleanup();
if (sBluetoothLeScanner != null) sBluetoothLeScanner.cleanup(); if (sBluetoothLeScanner != null) sBluetoothLeScanner.cleanup();
mServiceLock.writeLock().unlock();
synchronized (mProxyServiceStateCallbacks) { synchronized (mProxyServiceStateCallbacks) {
for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){ for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){
try { try {
@@ -1948,7 +2044,8 @@ public final class BluetoothAdapter {
} else { } else {
Log.d(TAG, "onBluetoothServiceDown: cb is null!!!"); Log.d(TAG, "onBluetoothServiceDown: cb is null!!!");
} }
} catch (Exception e) { Log.e(TAG,"",e);} } catch (Exception e) {
Log.e(TAG,"",e);
} }
} }
} }
@@ -2011,11 +2108,17 @@ public final class BluetoothAdapter {
//TODO(BT) //TODO(BT)
/* /*
try { try {
mServiceLock.readLock().lock();
if (mService != null) {
return mService.changeApplicationBluetoothState(on, new return mService.changeApplicationBluetoothState(on, new
StateChangeCallbackWrapper(callback), new Binder()); StateChangeCallbackWrapper(callback), new Binder());
}
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "changeBluetoothState", e); Log.e(TAG, "changeBluetoothState", e);
}*/ } finally {
mServiceLock.readLock().unlock();
}
*/
return false; return false;
} }

View File

@@ -54,6 +54,7 @@ import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException; import android.provider.Settings.SettingNotFoundException;
import android.util.Log; import android.util.Log;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.IOException; import java.io.IOException;
@@ -129,6 +130,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private IBinder mBluetoothBinder; private IBinder mBluetoothBinder;
private IBluetooth mBluetooth; private IBluetooth mBluetooth;
private IBluetoothGatt mBluetoothGatt; private IBluetoothGatt mBluetoothGatt;
private final ReentrantReadWriteLock mBluetoothLock =
new ReentrantReadWriteLock();
private boolean mBinding; private boolean mBinding;
private boolean mUnbinding; private boolean mUnbinding;
// used inside handler thread // used inside handler thread
@@ -193,12 +196,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} }
int st = BluetoothAdapter.STATE_OFF; int st = BluetoothAdapter.STATE_OFF;
if (mBluetooth != null) {
try { try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) {
st = mBluetooth.getState(); st = mBluetooth.getState();
}
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Unable to call getState", e); Log.e(TAG, "Unable to call getState", e);
} } finally {
mBluetoothLock.readLock().unlock();
} }
Log.d(TAG, "state" + st); Log.d(TAG, "state" + st);
@@ -211,12 +217,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (st == BluetoothAdapter.STATE_BLE_ON) { if (st == BluetoothAdapter.STATE_BLE_ON) {
//if state is BLE_ON make sure you trigger disableBLE part //if state is BLE_ON make sure you trigger disableBLE part
try { try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) { if (mBluetooth != null) {
mBluetooth.onBrEdrDown(); mBluetooth.onBrEdrDown();
mEnableExternal = false; mEnableExternal = false;
} }
} catch(RemoteException e) { } catch(RemoteException e) {
Log.e(TAG,"Unable to call onBrEdrDown", e); Log.e(TAG,"Unable to call onBrEdrDown", e);
} finally {
mBluetoothLock.readLock().lock();
} }
} else if (st == BluetoothAdapter.STATE_ON){ } else if (st == BluetoothAdapter.STATE_ON){
// disable without persisting the setting // disable without persisting the setting
@@ -369,10 +378,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER); Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
msg.obj = callback; msg.obj = callback;
mHandler.sendMessage(msg); mHandler.sendMessage(msg);
synchronized(mConnection) {
return mBluetooth; return mBluetooth;
} }
}
public void unregisterAdapter(IBluetoothManagerCallback callback) { public void unregisterAdapter(IBluetoothManagerCallback callback) {
if (callback == null) { if (callback == null) {
@@ -409,12 +417,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
return false; return false;
} }
synchronized(mConnection) {
try { try {
return (mBluetooth != null && mBluetooth.isEnabled()); mBluetoothLock.readLock().lock();
if (mBluetooth != null) return mBluetooth.isEnabled();
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "isEnabled()", e); Log.e(TAG, "isEnabled()", e);
} } finally {
mBluetoothLock.readLock().unlock();
} }
return false; return false;
} }
@@ -427,11 +436,14 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (mBleAppCount == 0) { if (mBleAppCount == 0) {
if (DBG) Log.d(TAG, "Disabling LE only mode after application crash"); if (DBG) Log.d(TAG, "Disabling LE only mode after application crash");
try { try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) { if (mBluetooth != null) {
mBluetooth.onBrEdrDown(); mBluetooth.onBrEdrDown();
} }
} catch(RemoteException e) { } catch(RemoteException e) {
Log.e(TAG,"Unable to call onBrEdrDown", e); Log.e(TAG,"Unable to call onBrEdrDown", e);
} finally {
mBluetoothLock.readLock().unlock();
} }
} }
} }
@@ -459,9 +471,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
disableBleScanMode(); disableBleScanMode();
clearBleApps(); clearBleApps();
try { try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) mBluetooth.onBrEdrDown(); if (mBluetooth != null) mBluetooth.onBrEdrDown();
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "error when disabling bluetooth", e); Log.e(TAG, "error when disabling bluetooth", e);
} finally {
mBluetoothLock.readLock().unlock();
} }
} }
} }
@@ -475,12 +490,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// Disable ble scan only mode. // Disable ble scan only mode.
private void disableBleScanMode() { private void disableBleScanMode() {
try { try {
mBluetoothLock.writeLock().lock();
if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) { if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) {
if (DBG) Log.d(TAG, "Reseting the mEnable flag for clean disable"); if (DBG) Log.d(TAG, "Reseting the mEnable flag for clean disable");
mEnable = false; mEnable = false;
} }
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "getState()", e); Log.e(TAG, "getState()", e);
} finally {
mBluetoothLock.writeLock().unlock();
} }
} }
@@ -540,6 +558,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private void onBluetoothGattServiceUp() { private void onBluetoothGattServiceUp() {
if (DBG) Log.d(TAG,"BluetoothGatt Service is Up"); if (DBG) Log.d(TAG,"BluetoothGatt Service is Up");
try { try {
mBluetoothLock.readLock().lock();
if (isBleAppPresent() == false && mBluetooth != null if (isBleAppPresent() == false && mBluetooth != null
&& mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) { && mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) {
mBluetooth.onLeServiceUp(); mBluetooth.onLeServiceUp();
@@ -551,6 +570,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} }
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG,"Unable to call onServiceUp", e); Log.e(TAG,"Unable to call onServiceUp", e);
} finally {
mBluetoothLock.readLock().unlock();
} }
} }
@@ -568,9 +589,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (isBleAppPresent() == false) { if (isBleAppPresent() == false) {
try { try {
mBluetooth.onBrEdrDown(); mBluetoothLock.readLock().lock();
if (mBluetooth != null) mBluetooth.onBrEdrDown();
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Call to onBrEdrDown() failed.", e); Log.e(TAG, "Call to onBrEdrDown() failed.", e);
} finally {
mBluetoothLock.readLock().unlock();
} }
} else { } else {
// Need to stay at BLE ON. Disconnect all Gatt connections // Need to stay at BLE ON. Disconnect all Gatt connections
@@ -672,7 +696,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
" mBinding = " + mBinding); " mBinding = " + mBinding);
} }
synchronized (mConnection) { try {
mBluetoothLock.writeLock().lock();
if (mUnbinding) return; if (mUnbinding) return;
mUnbinding = true; mUnbinding = true;
if (mBluetooth != null) { if (mBluetooth != null) {
@@ -695,6 +720,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mUnbinding=false; mUnbinding=false;
} }
mBluetoothGatt = null; mBluetoothGatt = null;
} finally {
mBluetoothLock.writeLock().unlock();
} }
} }
@@ -1007,15 +1034,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
return BluetoothAdapter.DEFAULT_MAC_ADDRESS; return BluetoothAdapter.DEFAULT_MAC_ADDRESS;
} }
synchronized(mConnection) {
if (mBluetooth != null) {
try { try {
return mBluetooth.getAddress(); mBluetoothLock.readLock().lock();
if (mBluetooth != null) return mBluetooth.getAddress();
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "getAddress(): Unable to retrieve address remotely..Returning cached address",e); Log.e(TAG, "getAddress(): Unable to retrieve address remotely. Returning cached address", e);
} } finally {
} mBluetoothLock.readLock().unlock();
} }
// mAddress is accessed from outside. // mAddress is accessed from outside.
// It is alright without a lock. Here, bluetooth is off, no other thread is // It is alright without a lock. Here, bluetooth is off, no other thread is
// changing mAddress // changing mAddress
@@ -1032,15 +1059,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
return null; return null;
} }
synchronized(mConnection) {
if (mBluetooth != null) {
try { try {
return mBluetooth.getName(); mBluetoothLock.readLock().lock();
if (mBluetooth != null) return mBluetooth.getName();
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "getName(): Unable to retrieve name remotely..Returning cached name",e); Log.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
} } finally {
} mBluetoothLock.readLock().unlock();
} }
// mName is accessed from outside. // mName is accessed from outside.
// It alright without a lock. Here, bluetooth is off, no other thread is // It alright without a lock. Here, bluetooth is off, no other thread is
// changing mName // changing mName
@@ -1104,10 +1131,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
if (DBG) Log.d (TAG, "Message: " + msg.what); if (DBG) Log.d (TAG, "Message: " + msg.what);
switch (msg.what) { switch (msg.what) {
case MESSAGE_GET_NAME_AND_ADDRESS: { case MESSAGE_GET_NAME_AND_ADDRESS:
if (DBG) Log.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS"); if (DBG) Log.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
synchronized(mConnection) { try {
//Start bind request mBluetoothLock.writeLock().lock();
if ((mBluetooth == null) && (!mBinding)) { if ((mBluetooth == null) && (!mBinding)) {
if (DBG) Log.d(TAG, "Binding to service to get name and address"); if (DBG) Log.d(TAG, "Binding to service to get name and address");
mConnection.setGetNameAddressOnly(true); mConnection.setGetNameAddressOnly(true);
@@ -1134,23 +1161,28 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mHandler.sendMessageDelayed(saveMsg, TIMEOUT_SAVE_MS); mHandler.sendMessageDelayed(saveMsg, TIMEOUT_SAVE_MS);
} }
} }
} finally {
mBluetoothLock.writeLock().unlock();
} }
break; break;
}
case MESSAGE_SAVE_NAME_AND_ADDRESS: { case MESSAGE_SAVE_NAME_AND_ADDRESS: {
boolean unbind = false; boolean unbind = false;
if (DBG) Log.d(TAG,"MESSAGE_SAVE_NAME_AND_ADDRESS"); if (DBG) Log.d(TAG,"MESSAGE_SAVE_NAME_AND_ADDRESS");
synchronized(mConnection) {
if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) {
try { try {
mBluetoothLock.readLock().lock();
if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) {
mBluetooth.enable(); mBluetooth.enable();
}
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG,"Unable to call enable()",e); Log.e(TAG,"Unable to call enable()",e);
} finally {
mBluetoothLock.readLock().unlock();
} }
}
}
if (mBluetooth != null && !mConnection.isGetNameAddressOnly()) waitForOnOff(true, false); if (mBluetooth != null && !mConnection.isGetNameAddressOnly()) waitForOnOff(true, false);
synchronized(mConnection) { try {
mBluetoothLock.writeLock().lock();
if (mBluetooth != null) { if (mBluetooth != null) {
String name = null; String name = null;
String address = null; String address = null;
@@ -1193,6 +1225,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS); Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
mHandler.sendMessage(getMsg); mHandler.sendMessage(getMsg);
} }
} finally {
mBluetoothLock.writeLock().unlock();
} }
if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) { if (!mEnable && mBluetooth != null && !mConnection.isGetNameAddressOnly()) {
waitForOnOff(false, true); waitForOnOff(false, true);
@@ -1281,7 +1315,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (DBG) Log.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1); if (DBG) Log.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
IBinder service = (IBinder) msg.obj; IBinder service = (IBinder) msg.obj;
synchronized(mConnection) { try {
mBluetoothLock.writeLock().lock();
if (msg.arg1 == SERVICE_IBLUETOOTHGATT) { if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service); mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service);
onBluetoothGattServiceUp(); onBluetoothGattServiceUp();
@@ -1338,6 +1373,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG,"Unable to call enable()",e); Log.e(TAG,"Unable to call enable()",e);
} }
} finally {
mBluetoothLock.writeLock().unlock();
} }
if (!mEnable) { if (!mEnable) {
@@ -1349,9 +1386,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} }
case MESSAGE_TIMEOUT_BIND: { case MESSAGE_TIMEOUT_BIND: {
Log.e(TAG, "MESSAGE_TIMEOUT_BIND"); Log.e(TAG, "MESSAGE_TIMEOUT_BIND");
synchronized(mConnection) { mBluetoothLock.writeLock().lock();
mBinding = false; mBinding = false;
} mBluetoothLock.writeLock().unlock();
break; break;
} }
case MESSAGE_BLUETOOTH_STATE_CHANGE: case MESSAGE_BLUETOOTH_STATE_CHANGE:
@@ -1386,7 +1423,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
{ {
Log.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: " + msg.arg1); Log.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: " + msg.arg1);
synchronized(mConnection) { try {
mBluetoothLock.writeLock().lock();
if (msg.arg1 == SERVICE_IBLUETOOTH) { if (msg.arg1 == SERVICE_IBLUETOOTH) {
// if service is unbinded already, do nothing and return // if service is unbinded already, do nothing and return
if (mBluetooth == null) break; if (mBluetooth == null) break;
@@ -1398,6 +1436,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Log.e(TAG, "Bad msg.arg1: " + msg.arg1); Log.e(TAG, "Bad msg.arg1: " + msg.arg1);
break; break;
} }
} finally {
mBluetoothLock.writeLock().unlock();
} }
if (mEnable) { if (mEnable) {
@@ -1445,9 +1485,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
case MESSAGE_TIMEOUT_UNBIND: case MESSAGE_TIMEOUT_UNBIND:
{ {
Log.e(TAG, "MESSAGE_TIMEOUT_UNBIND"); Log.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
synchronized(mConnection) { mBluetoothLock.writeLock().lock();
mUnbinding = false; mUnbinding = false;
} mBluetoothLock.writeLock().unlock();
break; break;
} }
@@ -1459,15 +1499,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mHandler.removeMessages(MESSAGE_USER_SWITCHED); mHandler.removeMessages(MESSAGE_USER_SWITCHED);
/* disable and enable BT when detect a user switch */ /* disable and enable BT when detect a user switch */
if (mEnable && mBluetooth != null) { if (mEnable && mBluetooth != null) {
synchronized (mConnection) {
if (mBluetooth != null) {
//Unregister callback object
try { try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) {
mBluetooth.unregisterCallback(mBluetoothCallback); mBluetooth.unregisterCallback(mBluetoothCallback);
}
} catch (RemoteException re) { } catch (RemoteException re) {
Log.e(TAG, "Unable to unregister", re); Log.e(TAG, "Unable to unregister", re);
} } finally {
} mBluetoothLock.readLock().unlock();
} }
if (mState == BluetoothAdapter.STATE_TURNING_OFF) { if (mState == BluetoothAdapter.STATE_TURNING_OFF) {
@@ -1498,14 +1538,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
BluetoothAdapter.STATE_OFF); BluetoothAdapter.STATE_OFF);
sendBluetoothServiceDownCallback(); sendBluetoothServiceDownCallback();
synchronized (mConnection) {
mBluetoothLock.writeLock().lock();
if (mBluetooth != null) { if (mBluetooth != null) {
mBluetooth = null; mBluetooth = null;
// Unbind // Unbind
mContext.unbindService(mConnection); mContext.unbindService(mConnection);
} }
mBluetoothGatt = null; mBluetoothGatt = null;
} mBluetoothLock.writeLock().unlock();
SystemClock.sleep(100); SystemClock.sleep(100);
mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
@@ -1531,7 +1573,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private void handleEnable(boolean quietMode) { private void handleEnable(boolean quietMode) {
mQuietEnable = quietMode; mQuietEnable = quietMode;
synchronized(mConnection) { try {
mBluetoothLock.writeLock().lock();
if ((mBluetooth == null) && (!mBinding)) { if ((mBluetooth == null) && (!mBinding)) {
//Start bind timeout and bind //Start bind timeout and bind
Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
@@ -1576,6 +1619,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Log.e(TAG,"Unable to call enable()",e); Log.e(TAG,"Unable to call enable()",e);
} }
} }
} finally {
mBluetoothLock.writeLock().unlock();
} }
} }
@@ -1590,20 +1635,18 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} }
private void handleDisable() { private void handleDisable() {
synchronized(mConnection) {
// don't need to disable if GetNameAddressOnly is set,
// service will be unbinded after Name and Address are saved
if ((mBluetooth != null) && (!mConnection.isGetNameAddressOnly())) {
if (DBG) Log.d(TAG,"Sending off request.");
try { try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) {
if (DBG) Log.d(TAG,"Sending off request.");
if (!mBluetooth.disable()) { if (!mBluetooth.disable()) {
Log.e(TAG,"IBluetooth.disable() returned false"); Log.e(TAG,"IBluetooth.disable() returned false");
} }
}
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG,"Unable to call disable()",e); Log.e(TAG,"Unable to call disable()",e);
} } finally {
} mBluetoothLock.readLock().unlock();
} }
} }
@@ -1730,8 +1773,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private boolean waitForOnOff(boolean on, boolean off) { private boolean waitForOnOff(boolean on, boolean off) {
int i = 0; int i = 0;
while (i < 10) { while (i < 10) {
synchronized(mConnection) {
try { try {
mBluetoothLock.readLock().lock();
if (mBluetooth == null) break; if (mBluetooth == null) break;
if (on) { if (on) {
if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) return true; if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) return true;
@@ -1743,7 +1786,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "getState()", e); Log.e(TAG, "getState()", e);
break; break;
} } finally {
mBluetoothLock.readLock().unlock();
} }
if (on || off) { if (on || off) {
SystemClock.sleep(300); SystemClock.sleep(300);
@@ -1766,34 +1810,36 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} }
private boolean canUnbindBluetoothService() { private boolean canUnbindBluetoothService() {
synchronized(mConnection) { try {
//Only unbind with mEnable flag not set //Only unbind with mEnable flag not set
//For race condition: disable and enable back-to-back //For race condition: disable and enable back-to-back
//Avoid unbind right after enable due to callback from disable //Avoid unbind right after enable due to callback from disable
//Only unbind with Bluetooth at OFF state //Only unbind with Bluetooth at OFF state
//Only unbind without any MESSAGE_BLUETOOTH_STATE_CHANGE message //Only unbind without any MESSAGE_BLUETOOTH_STATE_CHANGE message
try { mBluetoothLock.readLock().lock();
if (mEnable || (mBluetooth == null)) return false; if (mEnable || (mBluetooth == null)) return false;
if (mHandler.hasMessages(MESSAGE_BLUETOOTH_STATE_CHANGE)) return false; if (mHandler.hasMessages(MESSAGE_BLUETOOTH_STATE_CHANGE)) return false;
return (mBluetooth.getState() == BluetoothAdapter.STATE_OFF); return (mBluetooth.getState() == BluetoothAdapter.STATE_OFF);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "getState()", e); Log.e(TAG, "getState()", e);
} } finally {
mBluetoothLock.readLock().unlock();
} }
return false; return false;
} }
private void recoverBluetoothServiceFromError() { private void recoverBluetoothServiceFromError() {
Log.e(TAG,"recoverBluetoothServiceFromError"); Log.e(TAG,"recoverBluetoothServiceFromError");
synchronized (mConnection) { try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) { if (mBluetooth != null) {
//Unregister callback object //Unregister callback object
try {
mBluetooth.unregisterCallback(mBluetoothCallback); mBluetooth.unregisterCallback(mBluetoothCallback);
}
} catch (RemoteException re) { } catch (RemoteException re) {
Log.e(TAG, "Unable to unregister", re); Log.e(TAG, "Unable to unregister", re);
} } finally {
} mBluetoothLock.readLock().unlock();
} }
SystemClock.sleep(500); SystemClock.sleep(500);
@@ -1804,14 +1850,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
waitForOnOff(false, true); waitForOnOff(false, true);
sendBluetoothServiceDownCallback(); sendBluetoothServiceDownCallback();
synchronized (mConnection) {
mBluetoothLock.writeLock().lock();
if (mBluetooth != null) { if (mBluetooth != null) {
mBluetooth = null; mBluetooth = null;
// Unbind // Unbind
mContext.unbindService(mConnection); mContext.unbindService(mConnection);
} }
mBluetoothGatt = null; mBluetoothGatt = null;
} mBluetoothLock.writeLock().unlock();
mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
mState = BluetoothAdapter.STATE_OFF; mState = BluetoothAdapter.STATE_OFF;