diff options
| -rw-r--r-- | core/java/android/bluetooth/BluetoothAdapter.java | 367 | ||||
| -rw-r--r-- | services/core/java/com/android/server/BluetoothManagerService.java | 271 |
2 files changed, 389 insertions, 249 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index d036d96257ef..4c8657810c71 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -57,6 +57,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Represents the local device Bluetooth adapter. The {@link BluetoothAdapter} @@ -483,6 +484,8 @@ public final class BluetoothAdapter { private final IBluetoothManager mManagerService; private IBluetooth mService; + private final ReentrantReadWriteLock mServiceLock = + new ReentrantReadWriteLock(); private final Object mLock = new Object(); private final Map<LeScanCallback, ScanCallback> mLeScanClients; @@ -517,8 +520,13 @@ public final class BluetoothAdapter { throw new IllegalArgumentException("bluetooth manager service is null"); } try { + mServiceLock.writeLock().lock(); mService = managerService.registerAdapter(mManagerCallback); - } catch (RemoteException e) {Log.e(TAG, "", e);} + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.writeLock().unlock(); + } mManagerService = managerService; mLeScanClients = new HashMap<LeScanCallback, ScanCallback>(); mToken = new Binder(); @@ -605,10 +613,14 @@ public final class BluetoothAdapter { @RequiresPermission(Manifest.permission.BLUETOOTH) public boolean isEnabled() { try { - synchronized(mManagerCallback) { - if (mService != null) return mService.isEnabled(); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.isEnabled(); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } + return false; } @@ -639,12 +651,12 @@ public final class BluetoothAdapter { * or OFF if BT is in BLE_ON state */ private void notifyUserAction(boolean enable) { - if (mService == null) { - Log.e(TAG, "mService is null"); - return; - } - try { + mServiceLock.readLock().lock(); + if (mService == null) { + Log.e(TAG, "mService is null"); + return; + } if (enable) { mService.onLeServiceUp(); //NA:TODO implementation pending } else { @@ -652,6 +664,8 @@ public final class BluetoothAdapter { } } catch (RemoteException e) { Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); } } @@ -783,26 +797,28 @@ public final class BluetoothAdapter { @RequiresPermission(Manifest.permission.BLUETOOTH) @AdapterState public int getState() { + int state = BluetoothAdapter.STATE_OFF; + try { - synchronized(mManagerCallback) { - if (mService != null) - { - int state= mService.getState(); - if (VDBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + state); - //consider all internal states as OFF - if (state == BluetoothAdapter.STATE_BLE_ON - || state == BluetoothAdapter.STATE_BLE_TURNING_ON - || state == BluetoothAdapter.STATE_BLE_TURNING_OFF) { - if (VDBG) Log.d(TAG, "Consider internal state as OFF"); - state = BluetoothAdapter.STATE_OFF; - } - return state; - } - // TODO(BT) there might be a small gap during STATE_TURNING_ON that - // mService is null, handle that case + mServiceLock.readLock().lock(); + if (mService != null) { + state = mService.getState(); } - } catch (RemoteException e) {Log.e(TAG, "", e);} - return STATE_OFF; + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } + + // Consider all internal states as OFF + if (state == BluetoothAdapter.STATE_BLE_ON + || state == BluetoothAdapter.STATE_BLE_TURNING_ON + || state == BluetoothAdapter.STATE_BLE_TURNING_OFF) { + if (VDBG) Log.d(TAG, "Consider internal state as OFF"); + state = BluetoothAdapter.STATE_OFF; + } + if (VDBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + state); + return state; } /** @@ -825,19 +841,21 @@ public final class BluetoothAdapter { @RequiresPermission(Manifest.permission.BLUETOOTH) @AdapterState public int getLeState() { + int state = BluetoothAdapter.STATE_OFF; + try { - synchronized(mManagerCallback) { - if (mService != null) - { - int state= mService.getState(); - if (VDBG) Log.d(TAG,"getLeState() returning " + state); - return state; - } + mServiceLock.readLock().lock(); + if (mService != null) { + state = mService.getState(); } } catch (RemoteException 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() { @@ -879,16 +897,21 @@ public final class BluetoothAdapter { */ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean enable() { - int state = STATE_OFF; - if (isEnabled() == true){ + int state = BluetoothAdapter.STATE_OFF; + if (isEnabled() == true) { if (DBG) Log.d(TAG, "enable(): BT is already enabled..!"); return true; } - //Use service interface to get the exact state - if (mService != null) { - try { - state = mService.getState(); - } catch (RemoteException e) {Log.e(TAG, "", e);} + // Use service interface to get the exact state + try { + mServiceLock.readLock().lock(); + if (mService != null) { + state = mService.getState(); + } + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); } if (state == BluetoothAdapter.STATE_BLE_ON) { @@ -993,10 +1016,13 @@ public final class BluetoothAdapter { */ public boolean configHciSnoopLog(boolean enable) { try { - synchronized(mManagerCallback) { - if (mService != null) return mService.configHciSnoopLog(enable); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.configHciSnoopLog(enable); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } return false; } @@ -1012,12 +1038,16 @@ public final class BluetoothAdapter { */ public boolean factoryReset() { try { + mServiceLock.readLock().lock(); if (mService != null) { 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; } @@ -1032,10 +1062,13 @@ public final class BluetoothAdapter { public ParcelUuid[] getUuids() { if (getState() != STATE_ON) return null; try { - synchronized(mManagerCallback) { - if (mService != null) return mService.getUuids(); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.getUuids(); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } return null; } @@ -1058,10 +1091,13 @@ public final class BluetoothAdapter { public boolean setName(String name) { if (getState() != STATE_ON) return false; try { - synchronized(mManagerCallback) { - if (mService != null) return mService.setName(name); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.setName(name); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } return false; } @@ -1086,10 +1122,13 @@ public final class BluetoothAdapter { public int getScanMode() { if (getState() != STATE_ON) return SCAN_MODE_NONE; try { - synchronized(mManagerCallback) { - if (mService != null) return mService.getScanMode(); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.getScanMode(); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } return SCAN_MODE_NONE; } @@ -1124,10 +1163,13 @@ public final class BluetoothAdapter { public boolean setScanMode(@ScanMode int mode, int duration) { if (getState() != STATE_ON) return false; try { - synchronized(mManagerCallback) { - if (mService != null) return mService.setScanMode(mode, duration); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.setScanMode(mode, duration); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } return false; } @@ -1142,10 +1184,13 @@ public final class BluetoothAdapter { public int getDiscoverableTimeout() { if (getState() != STATE_ON) return -1; try { - synchronized(mManagerCallback) { - if (mService != null) return mService.getDiscoverableTimeout(); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.getDiscoverableTimeout(); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } return -1; } @@ -1153,10 +1198,13 @@ public final class BluetoothAdapter { public void setDiscoverableTimeout(int timeout) { if (getState() != STATE_ON) return; try { - synchronized(mManagerCallback) { - if (mService != null) mService.setDiscoverableTimeout(timeout); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) mService.setDiscoverableTimeout(timeout); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } } /** @@ -1193,10 +1241,13 @@ public final class BluetoothAdapter { public boolean startDiscovery() { if (getState() != STATE_ON) return false; try { - synchronized(mManagerCallback) { - if (mService != null) return mService.startDiscovery(); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.startDiscovery(); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } return false; } @@ -1221,10 +1272,13 @@ public final class BluetoothAdapter { public boolean cancelDiscovery() { if (getState() != STATE_ON) return false; try { - synchronized(mManagerCallback) { - if (mService != null) return mService.cancelDiscovery(); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.cancelDiscovery(); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } return false; } @@ -1251,10 +1305,13 @@ public final class BluetoothAdapter { public boolean isDiscovering() { if (getState() != STATE_ON) return false; try { - synchronized(mManagerCallback) { - if (mService != null ) return mService.isDiscovering(); - } - } catch (RemoteException e) {Log.e(TAG, "", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.isDiscovering(); + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } return false; } @@ -1266,9 +1323,12 @@ public final class BluetoothAdapter { public boolean isMultipleAdvertisementSupported() { if (getState() != STATE_ON) return false; try { - return mService.isMultiAdvertisementSupported(); + mServiceLock.readLock().lock(); + if (mService != null) return mService.isMultiAdvertisementSupported(); } catch (RemoteException e) { Log.e(TAG, "failed to get isMultipleAdvertisementSupported, error: ", e); + } finally { + mServiceLock.readLock().unlock(); } return false; } @@ -1301,9 +1361,12 @@ public final class BluetoothAdapter { public boolean isPeripheralModeSupported() { if (getState() != STATE_ON) return false; try { - return mService.isPeripheralModeSupported(); + mServiceLock.readLock().lock(); + if (mService != null) return mService.isPeripheralModeSupported(); } catch (RemoteException e) { Log.e(TAG, "failed to get peripheral mode capability: ", e); + } finally { + mServiceLock.readLock().unlock(); } return false; } @@ -1316,9 +1379,12 @@ public final class BluetoothAdapter { public boolean isOffloadedFilteringSupported() { if (!getLeAccess()) return false; try { - return mService.isOffloadedFilteringSupported(); + mServiceLock.readLock().lock(); + if (mService != null) return mService.isOffloadedFilteringSupported(); } catch (RemoteException e) { Log.e(TAG, "failed to get isOffloadedFilteringSupported, error: ", e); + } finally { + mServiceLock.readLock().unlock(); } return false; } @@ -1331,9 +1397,12 @@ public final class BluetoothAdapter { public boolean isOffloadedScanBatchingSupported() { if (!getLeAccess()) return false; try { - return mService.isOffloadedScanBatchingSupported(); + mServiceLock.readLock().lock(); + if (mService != null) return mService.isOffloadedScanBatchingSupported(); } catch (RemoteException e) { Log.e(TAG, "failed to get isOffloadedScanBatchingSupported, error: ", e); + } finally { + mServiceLock.readLock().unlock(); } return false; } @@ -1399,15 +1468,15 @@ public final class BluetoothAdapter { */ public void requestControllerActivityEnergyInfo(ResultReceiver result) { try { - synchronized(mManagerCallback) { - if (mService != null) { - mService.requestActivityInfo(result); - result = null; - } + mServiceLock.readLock().lock(); + if (mService != null) { + mService.requestActivityInfo(result); + result = null; } } catch (RemoteException e) { Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e); } finally { + mServiceLock.readLock().unlock(); if (result != null) { // Only send an immediate result if we failed. result.send(0, null); @@ -1432,11 +1501,14 @@ public final class BluetoothAdapter { return toDeviceSet(new BluetoothDevice[0]); } try { - synchronized(mManagerCallback) { - if (mService != null) return toDeviceSet(mService.getBondedDevices()); - } + mServiceLock.readLock().lock(); + if (mService != null) return toDeviceSet(mService.getBondedDevices()); 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; } @@ -1456,10 +1528,13 @@ public final class BluetoothAdapter { public int getConnectionState() { if (getState() != STATE_ON) return BluetoothAdapter.STATE_DISCONNECTED; try { - synchronized(mManagerCallback) { - if (mService != null) return mService.getAdapterConnectionState(); - } - } catch (RemoteException e) {Log.e(TAG, "getConnectionState:", e);} + mServiceLock.readLock().lock(); + if (mService != null) return mService.getAdapterConnectionState(); + } catch (RemoteException e) { + Log.e(TAG, "getConnectionState:", e); + } finally { + mServiceLock.readLock().unlock(); + } return BluetoothAdapter.STATE_DISCONNECTED; } @@ -1482,11 +1557,12 @@ public final class BluetoothAdapter { public int getProfileConnectionState(int profile) { if (getState() != STATE_ON) return BluetoothProfile.STATE_DISCONNECTED; try { - synchronized(mManagerCallback) { - if (mService != null) return mService.getProfileConnectionState(profile); - } + mServiceLock.readLock().lock(); + if (mService != null) return mService.getProfileConnectionState(profile); } catch (RemoteException e) { Log.e(TAG, "getProfileConnectionState:", e); + } finally { + mServiceLock.readLock().unlock(); } return BluetoothProfile.STATE_DISCONNECTED; } @@ -1790,7 +1866,9 @@ public final class BluetoothAdapter { byte[] hash; 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; @@ -1803,7 +1881,12 @@ public final class BluetoothAdapter { } 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; } @@ -1939,17 +2022,21 @@ public final class BluetoothAdapter { new IBluetoothManagerCallback.Stub() { public void onBluetoothServiceUp(IBluetooth bluetoothService) { if (VDBG) Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService); - synchronized (mManagerCallback) { - mService = bluetoothService; - synchronized (mProxyServiceStateCallbacks) { - for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){ - try { - if (cb != null) { - cb.onBluetoothServiceUp(bluetoothService); - } else { - Log.d(TAG, "onBluetoothServiceUp: cb is null!!!"); - } - } catch (Exception e) { Log.e(TAG,"",e);} + + mServiceLock.writeLock().lock(); + mService = bluetoothService; + mServiceLock.writeLock().unlock(); + + synchronized (mProxyServiceStateCallbacks) { + for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ) { + try { + if (cb != null) { + cb.onBluetoothServiceUp(bluetoothService); + } else { + Log.d(TAG, "onBluetoothServiceUp: cb is null!!!"); + } + } catch (Exception e) { + Log.e(TAG,"",e); } } } @@ -1957,20 +2044,24 @@ public final class BluetoothAdapter { public void onBluetoothServiceDown() { if (VDBG) Log.d(TAG, "onBluetoothServiceDown: " + mService); - synchronized (mManagerCallback) { - mService = null; - if (mLeScanClients != null) mLeScanClients.clear(); - if (sBluetoothLeAdvertiser != null) sBluetoothLeAdvertiser.cleanup(); - if (sBluetoothLeScanner != null) sBluetoothLeScanner.cleanup(); - synchronized (mProxyServiceStateCallbacks) { - for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){ - try { - if (cb != null) { - cb.onBluetoothServiceDown(); - } else { - Log.d(TAG, "onBluetoothServiceDown: cb is null!!!"); - } - } catch (Exception e) { Log.e(TAG,"",e);} + + mServiceLock.writeLock().lock(); + mService = null; + if (mLeScanClients != null) mLeScanClients.clear(); + if (sBluetoothLeAdvertiser != null) sBluetoothLeAdvertiser.cleanup(); + if (sBluetoothLeScanner != null) sBluetoothLeScanner.cleanup(); + mServiceLock.writeLock().unlock(); + + synchronized (mProxyServiceStateCallbacks) { + for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){ + try { + if (cb != null) { + cb.onBluetoothServiceDown(); + } else { + Log.d(TAG, "onBluetoothServiceDown: cb is null!!!"); + } + } catch (Exception e) { + Log.e(TAG,"",e); } } } @@ -2033,11 +2124,17 @@ public final class BluetoothAdapter { //TODO(BT) /* try { - return mService.changeApplicationBluetoothState(on, new + mServiceLock.readLock().lock(); + if (mService != null) { + return mService.changeApplicationBluetoothState(on, new StateChangeCallbackWrapper(callback), new Binder()); + } } catch (RemoteException e) { Log.e(TAG, "changeBluetoothState", e); - }*/ + } finally { + mServiceLock.readLock().unlock(); + } + */ return false; } diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 5e8687a904c1..f30a126ba60e 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -52,6 +52,7 @@ import android.os.UserManager; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.util.Slog; +import java.util.concurrent.locks.ReentrantReadWriteLock; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -126,6 +127,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private IBinder mBluetoothBinder; private IBluetooth mBluetooth; private IBluetoothGatt mBluetoothGatt; + private final ReentrantReadWriteLock mBluetoothLock = + new ReentrantReadWriteLock(); private boolean mBinding; private boolean mUnbinding; // used inside handler thread @@ -190,12 +193,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } int st = BluetoothAdapter.STATE_OFF; - if (mBluetooth != null) { - try { + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth != null) { st = mBluetooth.getState(); - } catch (RemoteException e) { - Slog.e(TAG,"Unable to call getState", e); } + } catch (RemoteException e) { + Slog.e(TAG, "Unable to call getState", e); + } finally { + mBluetoothLock.readLock().unlock(); } Slog.d(TAG, "state" + st); @@ -208,12 +214,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (st == BluetoothAdapter.STATE_BLE_ON) { //if state is BLE_ON make sure you trigger disableBLE part try { + mBluetoothLock.readLock().lock(); if (mBluetooth != null) { mBluetooth.onBrEdrDown(); mEnableExternal = false; } - } catch(RemoteException e) { + } catch (RemoteException e) { Slog.e(TAG,"Unable to call onBrEdrDown", e); + } finally { + mBluetoothLock.readLock().lock(); } } else if (st == BluetoothAdapter.STATE_ON){ // disable without persisting the setting @@ -366,9 +375,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER); msg.obj = callback; mHandler.sendMessage(msg); - synchronized(mConnection) { - return mBluetooth; - } + + return mBluetooth; } public void unregisterAdapter(IBluetoothManagerCallback callback) { @@ -406,12 +414,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return false; } - synchronized(mConnection) { - try { - return (mBluetooth != null && mBluetooth.isEnabled()); - } catch (RemoteException e) { - Slog.e(TAG, "isEnabled()", e); - } + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth != null) return mBluetooth.isEnabled(); + } catch (RemoteException e) { + Slog.e(TAG, "isEnabled()", e); + } finally { + mBluetoothLock.readLock().unlock(); } return false; } @@ -424,11 +433,14 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mBleAppCount == 0) { if (DBG) Slog.d(TAG, "Disabling LE only mode after application crash"); try { + mBluetoothLock.readLock().lock(); if (mBluetooth != null) { mBluetooth.onBrEdrDown(); } - } catch(RemoteException e) { + } catch (RemoteException e) { Slog.e(TAG,"Unable to call onBrEdrDown", e); + } finally { + mBluetoothLock.readLock().unlock(); } } } @@ -456,9 +468,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub { disableBleScanMode(); clearBleApps(); try { + mBluetoothLock.readLock().lock(); if (mBluetooth != null) mBluetooth.onBrEdrDown(); } catch (RemoteException e) { Slog.e(TAG, "error when disabling bluetooth", e); + } finally { + mBluetoothLock.readLock().unlock(); } } } @@ -472,12 +487,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { // Disable ble scan only mode. private void disableBleScanMode() { try { + mBluetoothLock.writeLock().lock(); if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) { if (DBG) Slog.d(TAG, "Reseting the mEnable flag for clean disable"); mEnable = false; } } catch (RemoteException e) { Slog.e(TAG, "getState()", e); + } finally { + mBluetoothLock.writeLock().unlock(); } } @@ -536,7 +554,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { */ private void onBluetoothGattServiceUp() { if (DBG) Slog.d(TAG,"BluetoothGatt Service is Up"); - try{ + try { + mBluetoothLock.readLock().lock(); if (isBleAppPresent() == false && mBluetooth != null && mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) { mBluetooth.onLeServiceUp(); @@ -546,8 +565,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub { persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); Binder.restoreCallingIdentity(callingIdentity); } - } catch(RemoteException e) { - Slog.e(TAG,"Unable to call onServiceUp", e); + } catch (RemoteException e) { + Slog.e(TAG,"Unable to call onServiceUp", e); + } finally { + mBluetoothLock.readLock().unlock(); } } @@ -558,22 +579,25 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private void sendBrEdrDownCallback() { if (DBG) Slog.d(TAG,"Calling sendBrEdrDownCallback callbacks"); - if(mBluetooth == null) { + if (mBluetooth == null) { Slog.w(TAG, "Bluetooth handle is null"); return; } if (isBleAppPresent() == false) { try { - mBluetooth.onBrEdrDown(); - } catch(RemoteException e) { + mBluetoothLock.readLock().lock(); + if (mBluetooth != null) mBluetooth.onBrEdrDown(); + } catch (RemoteException e) { Slog.e(TAG, "Call to onBrEdrDown() failed.", e); + } finally { + mBluetoothLock.readLock().unlock(); } } else { // Need to stay at BLE ON. Disconnect all Gatt connections - try{ + try { mBluetoothGatt.unregAll(); - } catch(RemoteException e) { + } catch (RemoteException e) { Slog.e(TAG, "Unable to disconnect all apps.", e); } } @@ -673,7 +697,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { " mBinding = " + mBinding); } - synchronized (mConnection) { + try { + mBluetoothLock.writeLock().lock(); if (mUnbinding) return; mUnbinding = true; if (mBluetooth != null) { @@ -695,6 +720,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { mUnbinding=false; } mBluetoothGatt = null; + } finally { + mBluetoothLock.writeLock().unlock(); } } @@ -1010,14 +1037,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return BluetoothAdapter.DEFAULT_MAC_ADDRESS; } - synchronized(mConnection) { - if (mBluetooth != null) { - try { - return mBluetooth.getAddress(); - } catch (RemoteException e) { - Slog.e(TAG, "getAddress(): Unable to retrieve address remotely..Returning cached address",e); - } - } + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth != null) return mBluetooth.getAddress(); + } catch (RemoteException e) { + Slog.e(TAG, "getAddress(): Unable to retrieve address remotely. Returning cached address", e); + } finally { + mBluetoothLock.readLock().unlock(); } // mAddress is accessed from outside. @@ -1036,15 +1062,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return null; } - synchronized(mConnection) { - if (mBluetooth != null) { - try { - return mBluetooth.getName(); - } catch (RemoteException e) { - Slog.e(TAG, "getName(): Unable to retrieve name remotely..Returning cached name",e); - } - } + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth != null) return mBluetooth.getName(); + } catch (RemoteException e) { + Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e); + } finally { + mBluetoothLock.readLock().unlock(); } + // mName is accessed from outside. // It alright without a lock. Here, bluetooth is off, no other thread is // changing mName @@ -1101,7 +1127,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { switch (msg.what) { case MESSAGE_GET_NAME_AND_ADDRESS: if (DBG) Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS"); - synchronized(mConnection) { + try { + mBluetoothLock.writeLock().lock(); if ((mBluetooth == null) && (!mBinding)) { if (DBG) Slog.d(TAG, "Binding to service to get name and address"); mGetNameAddressOnly = true; @@ -1127,6 +1154,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } mGetNameAddressOnly = false; } + } finally { + mBluetoothLock.writeLock().unlock(); } break; @@ -1209,7 +1238,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (DBG) Slog.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1); IBinder service = (IBinder) msg.obj; - synchronized(mConnection) { + try { + mBluetoothLock.writeLock().lock(); if (msg.arg1 == SERVICE_IBLUETOOTHGATT) { mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service); onBluetoothGattServiceUp(); @@ -1264,6 +1294,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } catch (RemoteException e) { Slog.e(TAG,"Unable to call enable()",e); } + } finally { + mBluetoothLock.writeLock().unlock(); } if (!mEnable) { @@ -1275,9 +1307,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } case MESSAGE_TIMEOUT_BIND: { Slog.e(TAG, "MESSAGE_TIMEOUT_BIND"); - synchronized(mConnection) { - mBinding = false; - } + mBluetoothLock.writeLock().lock(); + mBinding = false; + mBluetoothLock.writeLock().unlock(); + break; } case MESSAGE_BLUETOOTH_STATE_CHANGE: @@ -1312,7 +1345,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: { Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: " + msg.arg1); - synchronized(mConnection) { + try { + mBluetoothLock.writeLock().lock(); if (msg.arg1 == SERVICE_IBLUETOOTH) { // if service is unbinded already, do nothing and return if (mBluetooth == null) break; @@ -1324,6 +1358,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { Slog.e(TAG, "Bad msg.arg1: " + msg.arg1); break; } + } finally { + mBluetoothLock.writeLock().unlock(); } if (mEnable) { @@ -1369,9 +1405,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub { case MESSAGE_TIMEOUT_UNBIND: { Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND"); - synchronized(mConnection) { - mUnbinding = false; - } + mBluetoothLock.writeLock().lock(); + mUnbinding = false; + mBluetoothLock.writeLock().unlock(); break; } @@ -1381,15 +1417,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { /* disable and enable BT when detect a user switch */ if (mEnable && mBluetooth != null) { - synchronized (mConnection) { + try { + mBluetoothLock.readLock().lock(); if (mBluetooth != null) { - //Unregister callback object - try { - mBluetooth.unregisterCallback(mBluetoothCallback); - } catch (RemoteException re) { - Slog.e(TAG, "Unable to unregister",re); - } + mBluetooth.unregisterCallback(mBluetoothCallback); } + } catch (RemoteException re) { + Slog.e(TAG, "Unable to unregister", re); + } finally { + mBluetoothLock.readLock().unlock(); } if (mState == BluetoothAdapter.STATE_TURNING_OFF) { @@ -1420,14 +1456,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub { bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, BluetoothAdapter.STATE_OFF); sendBluetoothServiceDownCallback(); - synchronized (mConnection) { - if (mBluetooth != null) { - mBluetooth = null; - //Unbind - mContext.unbindService(mConnection); - } - mBluetoothGatt = null; + + mBluetoothLock.writeLock().lock(); + if (mBluetooth != null) { + mBluetooth = null; + // Unbind + mContext.unbindService(mConnection); } + mBluetoothGatt = null; + mBluetoothLock.writeLock().unlock(); + SystemClock.sleep(100); mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); @@ -1450,14 +1488,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (DBG) Slog.d(TAG, "MESSAGE_USER_UNLOCKED"); mHandler.removeMessages(MESSAGE_USER_SWITCHED); - synchronized (mConnection) { - if (mEnable && !mBinding && (mBluetooth == null)) { - // We should be connected, but we gave up for some - // reason; maybe the Bluetooth service wasn't encryption - // aware, so try binding again. - if (DBG) Slog.d(TAG, "Enabled but not bound; retrying after unlock"); - handleEnable(mQuietEnable); - } + if (mEnable && !mBinding && (mBluetooth == null)) { + // We should be connected, but we gave up for some + // reason; maybe the Bluetooth service wasn't encryption + // aware, so try binding again. + if (DBG) Slog.d(TAG, "Enabled but not bound; retrying after unlock"); + handleEnable(mQuietEnable); } } } @@ -1467,7 +1503,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private void handleEnable(boolean quietMode) { mQuietEnable = quietMode; - synchronized(mConnection) { + try { + mBluetoothLock.writeLock().lock(); if ((mBluetooth == null) && (!mBinding)) { //Start bind timeout and bind Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); @@ -1496,6 +1533,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub { Slog.e(TAG,"Unable to call enable()",e); } } + } finally { + mBluetoothLock.writeLock().unlock(); } } @@ -1510,18 +1549,18 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } private void handleDisable() { - synchronized(mConnection) { + try { + mBluetoothLock.readLock().lock(); if (mBluetooth != null) { if (DBG) Slog.d(TAG,"Sending off request."); - - try { - if(!mBluetooth.disable()) { - Slog.e(TAG,"IBluetooth.disable() returned false"); - } - } catch (RemoteException e) { - Slog.e(TAG,"Unable to call disable()",e); + if (!mBluetooth.disable()) { + Slog.e(TAG,"IBluetooth.disable() returned false"); } } + } catch (RemoteException e) { + Slog.e(TAG,"Unable to call disable()",e); + } finally { + mBluetoothLock.readLock().unlock(); } } @@ -1648,20 +1687,21 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private boolean waitForOnOff(boolean on, boolean off) { int i = 0; while (i < 10) { - synchronized(mConnection) { - try { - if (mBluetooth == null) break; - if (on) { - if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) return true; - } else if (off) { - if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) return true; - } else { - if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) return true; - } - } catch (RemoteException e) { - Slog.e(TAG, "getState()", e); - break; + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth == null) break; + if (on) { + if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) return true; + } else if (off) { + if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) return true; + } else { + if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) return true; } + } catch (RemoteException e) { + Slog.e(TAG, "getState()", e); + break; + } finally { + mBluetoothLock.readLock().unlock(); } if (on || off) { SystemClock.sleep(300); @@ -1684,34 +1724,36 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } private boolean canUnbindBluetoothService() { - synchronized(mConnection) { + try { //Only unbind with mEnable flag not set //For race condition: disable and enable back-to-back //Avoid unbind right after enable due to callback from disable //Only unbind with Bluetooth at OFF state //Only unbind without any MESSAGE_BLUETOOTH_STATE_CHANGE message - try { - if (mEnable || (mBluetooth == null)) return false; - if (mHandler.hasMessages(MESSAGE_BLUETOOTH_STATE_CHANGE)) return false; - return (mBluetooth.getState() == BluetoothAdapter.STATE_OFF); - } catch (RemoteException e) { - Slog.e(TAG, "getState()", e); - } + mBluetoothLock.readLock().lock(); + if (mEnable || (mBluetooth == null)) return false; + if (mHandler.hasMessages(MESSAGE_BLUETOOTH_STATE_CHANGE)) return false; + return (mBluetooth.getState() == BluetoothAdapter.STATE_OFF); + } catch (RemoteException e) { + Slog.e(TAG, "getState()", e); + } finally { + mBluetoothLock.readLock().unlock(); } return false; } private void recoverBluetoothServiceFromError() { Slog.e(TAG,"recoverBluetoothServiceFromError"); - synchronized (mConnection) { + try { + mBluetoothLock.readLock().lock(); if (mBluetooth != null) { //Unregister callback object - try { - mBluetooth.unregisterCallback(mBluetoothCallback); - } catch (RemoteException re) { - Slog.e(TAG, "Unable to unregister",re); - } + mBluetooth.unregisterCallback(mBluetoothCallback); } + } catch (RemoteException re) { + Slog.e(TAG, "Unable to unregister", re); + } finally { + mBluetoothLock.readLock().unlock(); } SystemClock.sleep(500); @@ -1722,14 +1764,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub { waitForOnOff(false, true); sendBluetoothServiceDownCallback(); - synchronized (mConnection) { - if (mBluetooth != null) { - mBluetooth = null; - //Unbind - mContext.unbindService(mConnection); - } - mBluetoothGatt = null; + + mBluetoothLock.writeLock().lock(); + if (mBluetooth != null) { + mBluetooth = null; + // Unbind + mContext.unbindService(mConnection); } + mBluetoothGatt = null; + mBluetoothLock.writeLock().unlock(); mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); mState = BluetoothAdapter.STATE_OFF; |