aboutsummaryrefslogtreecommitdiffstats
path: root/java/direct_bt/tinyb/DBTAdapter.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-06-09 18:52:31 +0200
committerSven Gothel <[email protected]>2020-06-09 18:52:31 +0200
commit74d71479facbb4fc6eda6a2dbf9cb2ad23f99223 (patch)
tree1002500334470dee2e6b8b0062457f4a06ce8b9a /java/direct_bt/tinyb/DBTAdapter.java
parent2048b75e91eaa037821c1340dd3b604d1af6b35a (diff)
DBT Adapter/Device (java): Use AtomicBoolean for states and only handle results from AdapterStatusListener
- DBTAdapter.java: Explicitly lock user callbacks (like DBTDevice) - Remove unnecessary synchronized from methods, AtomicBoolean and explicit locks must suffice
Diffstat (limited to 'java/direct_bt/tinyb/DBTAdapter.java')
-rw-r--r--java/direct_bt/tinyb/DBTAdapter.java142
1 files changed, 86 insertions, 56 deletions
diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java
index 386dc0e2..4f0d1025 100644
--- a/java/direct_bt/tinyb/DBTAdapter.java
+++ b/java/direct_bt/tinyb/DBTAdapter.java
@@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.tinyb.AdapterSettings;
@@ -56,18 +57,18 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
private final String address;
private final String name;
- private final Object stateLock = new Object();
private final Object discoveredDevicesLock = new Object();
+ private final Object userCallbackLock = new Object();
- private BluetoothNotification<Boolean> discoverableNotification = null;
- private volatile boolean isDiscoverable = false;
- private BluetoothNotification<Boolean> discoveringNotification = null;
- private volatile boolean isDiscovering = false;
+ private BluetoothNotification<Boolean> userDiscoverableNotificationCB = null;
+ private final AtomicBoolean isDiscoverable = new AtomicBoolean(false);
+ private BluetoothNotification<Boolean> userDiscoveringNotificationCB = null;
+ private final AtomicBoolean isDiscovering = new AtomicBoolean(false);
- private BluetoothNotification<Boolean> poweredNotification = null;
- private volatile boolean isPowered = false;
- private BluetoothNotification<Boolean> pairableNotification = null;
- private volatile boolean isPairable = false;
+ private BluetoothNotification<Boolean> userPoweredNotificationCB = null;
+ private final AtomicBoolean isPowered = new AtomicBoolean(false);
+ private BluetoothNotification<Boolean> userPairableNotificationCB = null;
+ private final AtomicBoolean isPairable = new AtomicBoolean(false);
private final List<BluetoothDevice> discoveredDevices = new ArrayList<BluetoothDevice>();
@@ -196,55 +197,73 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
/* Java callbacks */
@Override
- public boolean getPowered() { return isPowered; }
+ public boolean getPowered() { return isPowered.get(); }
@Override
- public synchronized void enablePoweredNotifications(final BluetoothNotification<Boolean> callback) {
- poweredNotification = callback;
+ public void enablePoweredNotifications(final BluetoothNotification<Boolean> callback) {
+ synchronized(userCallbackLock) {
+ userPoweredNotificationCB = callback;
+ }
}
@Override
- public synchronized void disablePoweredNotifications() {
- poweredNotification = null;
+ public void disablePoweredNotifications() {
+ synchronized(userCallbackLock) {
+ userPoweredNotificationCB = null;
+ }
}
@Override
- public boolean getDiscoverable() { return isDiscoverable; }
+ public boolean getDiscoverable() { return isDiscoverable.get(); }
@Override
- public synchronized void enableDiscoverableNotifications(final BluetoothNotification<Boolean> callback) {
- discoverableNotification = callback;
+ public void enableDiscoverableNotifications(final BluetoothNotification<Boolean> callback) {
+ synchronized(userCallbackLock) {
+ userDiscoverableNotificationCB = callback;
+ }
}
@Override
- public synchronized void disableDiscoverableNotifications() {
- discoverableNotification = null;
+ public void disableDiscoverableNotifications() {
+ synchronized(userCallbackLock) {
+ userDiscoverableNotificationCB = null;
+ }
}
@Override
- public boolean getDiscovering() { return isDiscovering; }
+ public boolean getDiscovering() {
+ return isDiscovering.get();
+ }
@Override
- public synchronized void enableDiscoveringNotifications(final BluetoothNotification<Boolean> callback) {
- discoveringNotification = callback;
+ public void enableDiscoveringNotifications(final BluetoothNotification<Boolean> callback) {
+ synchronized(userCallbackLock) {
+ userDiscoveringNotificationCB = callback;
+ }
}
@Override
- public synchronized void disableDiscoveringNotifications() {
- discoveringNotification = null;
+ public void disableDiscoveringNotifications() {
+ synchronized(userCallbackLock) {
+ userDiscoveringNotificationCB = null;
+ }
}
@Override
- public boolean getPairable() { return isPairable; }
+ public boolean getPairable() { return isPairable.get(); }
@Override
- public synchronized void enablePairableNotifications(final BluetoothNotification<Boolean> callback) {
- pairableNotification = callback;
+ public void enablePairableNotifications(final BluetoothNotification<Boolean> callback) {
+ synchronized(userCallbackLock) {
+ userPairableNotificationCB = callback;
+ }
}
@Override
- public synchronized void disablePairableNotifications() {
- pairableNotification = null;
+ public void disablePairableNotifications() {
+ synchronized(userCallbackLock) {
+ userPairableNotificationCB = null;
+ }
}
@Override
@@ -287,19 +306,19 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
}
@Override
- public synchronized boolean startDiscovery(final boolean keepAlive) throws BluetoothException {
- removeDevices();
- final boolean res = startDiscoveryImpl(keepAlive);
- isDiscovering = res;
- return res;
+ public boolean startDiscovery(final boolean keepAlive) throws BluetoothException {
+ if( !isDiscovering.get() ) {
+ removeDevices();
+ return startDiscoveryImpl(keepAlive); // event callbacks will be generated by implementation
+ }
+ return true;
}
private native boolean startDiscoveryImpl(boolean keepAlive) throws BluetoothException;
@Override
- public synchronized boolean stopDiscovery() throws BluetoothException {
- if( isDiscovering ) {
- isDiscovering = false;
- return stopDiscoveryImpl();
+ public boolean stopDiscovery() throws BluetoothException {
+ if( isDiscovering.get() ) {
+ return stopDiscoveryImpl(); // event callbacks will be generated by implementation
}
return false;
}
@@ -319,7 +338,9 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
final int cj = removeDiscoveredDevices();
final int cn = removeDevicesImpl();
if( cj != cn ) {
- System.err.println("DBTAdapter::removeDevices: Inconsistent discovered device count: Native "+cn+", callback "+cj);
+ if( DEBUG ) {
+ System.err.println("DBTAdapter::removeDevices: Inconsistent discovered device count: Native "+cn+", callback "+cj);
+ }
}
return cn;
}
@@ -368,28 +389,37 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
}
{
if( changedmask.isSet(AdapterSettings.SettingType.POWERED) ) {
- isPowered = newmask.isSet(AdapterSettings.SettingType.POWERED);
- final BluetoothNotification<Boolean> _poweredNotification = poweredNotification;
- if( null != _poweredNotification ) {
- _poweredNotification.run(isPowered);
+ final boolean _isPowered = newmask.isSet(AdapterSettings.SettingType.POWERED);
+ if( isPowered.compareAndSet(!_isPowered, _isPowered) ) {
+ synchronized(userCallbackLock) {
+ if( null != userPoweredNotificationCB ) {
+ userPoweredNotificationCB.run(_isPowered);
+ }
+ }
}
}
}
{
if( changedmask.isSet(AdapterSettings.SettingType.DISCOVERABLE) ) {
- isDiscoverable = newmask.isSet(AdapterSettings.SettingType.DISCOVERABLE);
- final BluetoothNotification<Boolean> _discoverableNotification = discoverableNotification;
- if( null != _discoverableNotification ) {
- _discoverableNotification.run( isDiscoverable );
+ final boolean _isDiscoverable = newmask.isSet(AdapterSettings.SettingType.DISCOVERABLE);
+ if( isDiscoverable.compareAndSet(!_isDiscoverable, _isDiscoverable) ) {
+ synchronized(userCallbackLock) {
+ if( null != userDiscoverableNotificationCB ) {
+ userDiscoverableNotificationCB.run( _isDiscoverable );
+ }
+ }
}
}
}
{
if( changedmask.isSet(AdapterSettings.SettingType.BONDABLE) ) {
- isPairable = newmask.isSet(AdapterSettings.SettingType.BONDABLE);
- final BluetoothNotification<Boolean> _pairableNotification = pairableNotification;
- if( null != _pairableNotification ) {
- _pairableNotification.run( isPairable );
+ final boolean _isPairable = newmask.isSet(AdapterSettings.SettingType.BONDABLE);
+ if( isPairable.compareAndSet(!_isPairable, _isPairable) ) {
+ synchronized(userCallbackLock) {
+ if( null != userPairableNotificationCB ) {
+ userPairableNotificationCB.run( _isPairable );
+ }
+ }
}
}
}
@@ -399,13 +429,13 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
if( DEBUG ) {
System.err.println("Adapter.StatusListener.DISCOVERING: enabled "+enabled+", keepAlive "+keepAlive+" on "+adapter);
}
- if( isDiscovering != enabled ) {
- isDiscovering = enabled;
- if( null != discoveringNotification ) {
- discoveringNotification.run(enabled);
+ if( isDiscovering.compareAndSet(!enabled, enabled) ) {
+ synchronized(userCallbackLock) {
+ if( null != userDiscoveringNotificationCB ) {
+ userDiscoveringNotificationCB.run(enabled);
+ }
}
}
-
}
@Override
public void deviceFound(final BluetoothDevice device, final long timestamp) {