diff options
author | Sven Gothel <[email protected]> | 2020-05-24 19:57:07 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-05-24 19:57:07 +0200 |
commit | 461c54a3212f003cbb5f9a0afaeef5fb80a9f57e (patch) | |
tree | 97e7da5d77bf57dd41fd295d98fdce8aa379a015 /java | |
parent | eb67f2d4e0100193822df670e17ed659b1debfd4 (diff) |
AdapterStatusListener (C++/Java): Add discoveringChanged(..), converge deviceConnected/deviceDisconnected
Add discoveringChanged(..), as it is of high interest to the user to adjust connect/disconnect and GATT operations.
Hence add it to this central adapter listener, also being used to synthesize the old fashion
TinyB 'discovering' callback.
We also expose the 'keepAlive' flag in this callback to the user.
Converge deviceConnected(..)/deviceDisconnected(..) -> deviceConnectionChanged(..)
to be a bit more efficient.
+++
DBTAdapter: keepAlive in startDiscovery defaults to false, aligned w/ TinyB.
A new startDiscovery(..) method has been added to the Java API, also adding keepAlive.
+++
Java TODO: Add the whitelist add/remove functionality
Diffstat (limited to 'java')
-rw-r--r-- | java/direct_bt/tinyb/DBTAdapter.java | 59 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTDevice.java | 15 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 233 | ||||
-rw-r--r-- | java/org/tinyb/AdapterStatusListener.java | 29 | ||||
-rw-r--r-- | java/org/tinyb/BluetoothAdapter.java | 12 | ||||
-rw-r--r-- | java/tinyb/dbus/DBusAdapter.java | 6 |
6 files changed, 195 insertions, 159 deletions
diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java index 727503c7..8f8ca0c6 100644 --- a/java/direct_bt/tinyb/DBTAdapter.java +++ b/java/direct_bt/tinyb/DBTAdapter.java @@ -56,15 +56,15 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter private final Object stateLock = new Object(); private final Object discoveredDevicesLock = new Object(); + private BluetoothNotification<Boolean> discoverableNotification = null; + private volatile boolean isDiscoverable = false; + private BluetoothNotification<Boolean> discoveringNotification = null; private volatile boolean isDiscovering = false; - private final long discoveringNotificationRef = 0; - private BluetoothNotification<Boolean> discoverableNotification = null; - private boolean isDiscoverable = false; private BluetoothNotification<Boolean> poweredNotification = null; - private boolean isPowered = false; + private volatile boolean isPowered = false; private BluetoothNotification<Boolean> pairableNotification = null; - private boolean isPairable = false; + private volatile boolean isPairable = false; private boolean isOpen = false; private final List<BluetoothDevice> discoveredDevices = new ArrayList<BluetoothDevice>(); @@ -192,6 +192,19 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } @Override + public boolean getDiscovering() { return isDiscovering; } + + @Override + public synchronized void enableDiscoveringNotifications(final BluetoothNotification<Boolean> callback) { + discoveringNotification = callback; + } + + @Override + public synchronized void disableDiscoveringNotifications() { + discoveringNotification = null; + } + + @Override public boolean getPairable() { return isPairable; } @Override @@ -240,8 +253,10 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter @Override public synchronized boolean startDiscovery() throws BluetoothException { - return startDiscovery(true); + return startDiscovery(false); } + + @Override public synchronized boolean startDiscovery(final boolean keepAlive) throws BluetoothException { removeDevices(); final boolean res = startDiscoveryImpl(keepAlive); @@ -290,9 +305,6 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } @Override - public boolean getDiscovering() { return isDiscovering; } - - @Override public native boolean addStatusListener(final AdapterStatusListener l, final BluetoothDevice deviceMatch); @Override @@ -302,12 +314,6 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter public native int removeAllStatusListener(); @Override - public native void enableDiscoveringNotifications(final BluetoothNotification<Boolean> callback); - - @Override - public native void disableDiscoveringNotifications(); - - @Override public void setDiscoveryFilter(final List<UUID> uuids, final int rssi, final int pathloss, final TransportType transportType) { final List<String> uuidsFmt = new ArrayList<>(uuids.size()); for (final UUID uuid : uuids) { @@ -361,6 +367,19 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } } @Override + public void discoveringChanged(final BluetoothAdapter adapter, final boolean enabled, final boolean keepAlive, final long timestamp) { + 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); + } + } + + } + @Override public void deviceFound(final BluetoothDevice device, final long timestamp) { if( DEBUG ) { System.err.println("Adapter.StatusListener.FOUND: "+device+" on "+device.getAdapter()); @@ -379,15 +398,9 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } @Override - public void deviceConnected(final BluetoothDevice device, final long timestamp) { - if( DEBUG ) { - System.err.println("Adapter.StatusListener.CONNECTED: "+device+" on "+device.getAdapter()); - } - } - @Override - public void deviceDisconnected(final BluetoothDevice device, final long timestamp) { + public void deviceConnectionChanged(final BluetoothDevice device, final boolean connected, final long timestamp) { if( DEBUG ) { - System.err.println("Adapter.StatusListener.DISCONNECTED: "+device+" on "+device.getAdapter()); + System.err.println("Adapter.StatusListener.CONNECTION: connected "+connected+": "+device+" on "+device.getAdapter()); } } }; diff --git a/java/direct_bt/tinyb/DBTDevice.java b/java/direct_bt/tinyb/DBTDevice.java index c34fa9bd..31146c03 100644 --- a/java/direct_bt/tinyb/DBTDevice.java +++ b/java/direct_bt/tinyb/DBTDevice.java @@ -72,20 +72,11 @@ public class DBTDevice extends DBTObject implements BluetoothDevice } } @Override - public void deviceConnected(final BluetoothDevice device, final long timestamp) { - connected = true; + public void deviceConnectionChanged(final BluetoothDevice device, final boolean connected, final long timestamp) { + DBTDevice.this.connected = connected; synchronized(userCallbackLock) { if( null != userConnectedNotificationsCB ) { - userConnectedNotificationsCB.run(true); - } - } - } - @Override - public void deviceDisconnected(final BluetoothDevice device, final long timestamp) { - connected = false; - synchronized(userCallbackLock) { - if( null != userConnectedNotificationsCB ) { - userConnectedNotificationsCB.run(false); + userConnectedNotificationsCB.run(connected); } } } diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index 030e193b..6945e72c 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -41,23 +41,28 @@ static const std::string _adapterSettingsClazzCtorArgs("(I)V"); static const std::string _eirDataTypeSetClassName("org/tinyb/EIRDataTypeSet"); static const std::string _eirDataTypeSetClazzCtorArgs("(I)V"); static const std::string _deviceClazzCtorArgs("(JLdirect_bt/tinyb/DBTAdapter;Ljava/lang/String;Ljava/lang/String;J)V"); + static const std::string _adapterSettingsChangedMethodArgs("(Lorg/tinyb/BluetoothAdapter;Lorg/tinyb/AdapterSettings;Lorg/tinyb/AdapterSettings;Lorg/tinyb/AdapterSettings;J)V"); -static const std::string _deviceStatusMethodArgs("(Lorg/tinyb/BluetoothDevice;J)V"); -static const std::string _deviceStatusUpdateMethodArgs("(Lorg/tinyb/BluetoothDevice;JLorg/tinyb/EIRDataTypeSet;)V"); +static const std::string _discoveringChangedMethodArgs("(Lorg/tinyb/BluetoothAdapter;ZZJ)V"); +static const std::string _deviceFoundMethodArgs("(Lorg/tinyb/BluetoothDevice;J)V"); +static const std::string _deviceUpdatedMethodArgs("(Lorg/tinyb/BluetoothDevice;JLorg/tinyb/EIRDataTypeSet;)V"); +static const std::string _deviceConnectionChangedMethodArgs("(Lorg/tinyb/BluetoothDevice;ZJ)V"); class JNIAdapterStatusListener : public AdapterStatusListener { private: /** package org.tinyb; - public interface AdapterStatusListener { + public abstract class AdapterStatusListener { + private long nativeInstance; + public void adapterSettingsChanged(final BluetoothAdapter adapter, - final AdapterSetting oldmask, final AdapterSetting newmask, - final AdapterSetting changedmask, final long timestamp); - public void deviceFound(final BluetoothDevice device, final long timestamp); - public void deviceUpdated(final BluetoothDevice device, final long timestamp, final EIRDataType updateMask); - public void deviceConnected(final BluetoothDevice device, final long timestamp); - public void deviceDisconnected(final BluetoothDevice device, final long timestamp); + final AdapterSettings oldmask, final AdapterSettings newmask, + final AdapterSettings changedmask, final long timestamp) { } + public void discoveringChanged(final BluetoothAdapter adapter, final boolean enabled, final boolean keepAlive, final long timestamp) { } + public void deviceFound(final BluetoothDevice device, final long timestamp) { } + public void deviceUpdated(final BluetoothDevice device, final long timestamp, final EIRDataTypeSet updateMask) { } + public void deviceConnectionChanged(final BluetoothDevice device, final boolean connected, final long timestamp) { } }; */ const DBTDevice * deviceMatchRef; @@ -71,10 +76,10 @@ class JNIAdapterStatusListener : public AdapterStatusListener { jfieldID deviceClazzTSUpdateField; std::unique_ptr<JNIGlobalRef> listenerObjRef; jmethodID mAdapterSettingsChanged = nullptr; + jmethodID mDiscoveringChanged = nullptr; jmethodID mDeviceFound = nullptr; jmethodID mDeviceUpdated = nullptr; - jmethodID mDeviceConnected = nullptr; - jmethodID mDeviceDisconnected = nullptr; + jmethodID mDeviceConnectionChanged = nullptr; public: @@ -149,25 +154,25 @@ class JNIAdapterStatusListener : public AdapterStatusListener { if( nullptr == mAdapterSettingsChanged ) { throw InternalError("AdapterStatusListener has no adapterSettingsChanged"+_adapterSettingsChangedMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); } - mDeviceFound = search_method(env, listenerClazz, "deviceFound", _deviceStatusMethodArgs.c_str(), false); + mDiscoveringChanged = search_method(env, listenerClazz, "discoveringChanged", _discoveringChangedMethodArgs.c_str(), false); java_exception_check_and_throw(env, E_FILE_LINE); - if( nullptr == mDeviceFound ) { - throw InternalError("AdapterStatusListener has no deviceFound"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); + if( nullptr == mDiscoveringChanged ) { + throw InternalError("AdapterStatusListener has no discoveringChanged"+_discoveringChangedMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); } - mDeviceUpdated = search_method(env, listenerClazz, "deviceUpdated", _deviceStatusUpdateMethodArgs.c_str(), false); + mDeviceFound = search_method(env, listenerClazz, "deviceFound", _deviceFoundMethodArgs.c_str(), false); java_exception_check_and_throw(env, E_FILE_LINE); - if( nullptr == mDeviceUpdated ) { - throw InternalError("AdapterStatusListener has no deviceUpdated"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); + if( nullptr == mDeviceFound ) { + throw InternalError("AdapterStatusListener has no deviceFound"+_deviceFoundMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); } - mDeviceConnected = search_method(env, listenerClazz, "deviceConnected", _deviceStatusMethodArgs.c_str(), false); + mDeviceUpdated = search_method(env, listenerClazz, "deviceUpdated", _deviceUpdatedMethodArgs.c_str(), false); java_exception_check_and_throw(env, E_FILE_LINE); - if( nullptr == mDeviceConnected ) { - throw InternalError("AdapterStatusListener has no deviceConnected"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); + if( nullptr == mDeviceUpdated ) { + throw InternalError("AdapterStatusListener has no deviceUpdated"+_deviceUpdatedMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); } - mDeviceDisconnected = search_method(env, listenerClazz, "deviceDisconnected", _deviceStatusMethodArgs.c_str(), false); + mDeviceConnectionChanged = search_method(env, listenerClazz, "deviceConnectionChanged", _deviceConnectionChangedMethodArgs.c_str(), false); java_exception_check_and_throw(env, E_FILE_LINE); - if( nullptr == mDeviceDisconnected ) { - throw InternalError("AdapterStatusListener has no deviceDisconnected"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); + if( nullptr == mDeviceConnectionChanged ) { + throw InternalError("AdapterStatusListener has no deviceConnectionChanged"+_deviceConnectionChangedMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); } } @@ -211,6 +216,23 @@ class JNIAdapterStatusListener : public AdapterStatusListener { } } + void discoveringChanged(DBTAdapter const &a, const bool enabled, const bool keepAlive, const uint64_t timestamp) override { + JNIEnv *env = *jni_env; + try { + #ifdef VERBOSE_ON + fprintf(stderr, "****** DBTAdapter Device DISCOVERING: enable %d, keepAlive %d: %s\n", enabled, keepAlive, a.toString().c_str()); + fprintf(stderr, "Status DBTAdapter:\n"); + fprintf(stderr, "%s\n", device->getAdapter().toString().c_str()); + #endif + (void)a; + env->CallVoidMethod(listenerObjRef->getObject(), mDiscoveringChanged, JavaGlobalObj::GetObject(adapterObjRef), + (jboolean)enabled, (jboolean)keepAlive, (jlong)timestamp); + java_exception_check_and_throw(env, E_FILE_LINE); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + } + void deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { JNIEnv *env = *jni_env; try { @@ -244,6 +266,7 @@ class JNIAdapterStatusListener : public AdapterStatusListener { rethrow_and_raise_java_exception(env); } } + void deviceUpdated(std::shared_ptr<DBTDevice> device, const uint64_t timestamp, const EIRDataType updateMask) override { JNIEnv *env = *jni_env; try { @@ -267,29 +290,12 @@ class JNIAdapterStatusListener : public AdapterStatusListener { rethrow_and_raise_java_exception(env); } } - void deviceConnected(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { - JNIEnv *env = *jni_env; - try { - #ifdef VERBOSE_ON - fprintf(stderr, "****** DBTAdapter Device CONNECTED: %s\n", device->toString().c_str()); - fprintf(stderr, "Status DBTAdapter:\n"); - fprintf(stderr, "%s\n", device->getAdapter().toString().c_str()); - #endif - std::shared_ptr<JavaAnonObj> jDeviceRef = device->getJavaObject(); - JavaGlobalObj::check(jDeviceRef, E_FILE_LINE); - env->SetLongField(JavaGlobalObj::GetObject(jDeviceRef), deviceClazzTSUpdateField, (jlong)timestamp); - java_exception_check_and_throw(env, E_FILE_LINE); - env->CallVoidMethod(listenerObjRef->getObject(), mDeviceConnected, JavaGlobalObj::GetObject(jDeviceRef), (jlong)timestamp); - java_exception_check_and_throw(env, E_FILE_LINE); - } catch(...) { - rethrow_and_raise_java_exception(env); - } - } - void deviceDisconnected(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { + + void deviceConnectionChanged(std::shared_ptr<DBTDevice> device, const bool connected, const uint64_t timestamp) override { JNIEnv *env = *jni_env; try { #ifdef VERBOSE_ON - fprintf(stderr, "****** DBTAdapter Device DISCONNECTED: %s\n", device->toString().c_str()); + fprintf(stderr, "****** DBTAdapter Device CONNECTION: %d: %s\n", connected, device->toString().c_str()); fprintf(stderr, "Status DBTAdapter:\n"); fprintf(stderr, "%s\n", device->getAdapter().toString().c_str()); #endif @@ -297,7 +303,8 @@ class JNIAdapterStatusListener : public AdapterStatusListener { JavaGlobalObj::check(jDeviceRef, E_FILE_LINE); env->SetLongField(JavaGlobalObj::GetObject(jDeviceRef), deviceClazzTSUpdateField, (jlong)timestamp); java_exception_check_and_throw(env, E_FILE_LINE); - env->CallVoidMethod(listenerObjRef->getObject(), mDeviceDisconnected, JavaGlobalObj::GetObject(jDeviceRef), (jlong)timestamp); + env->CallVoidMethod(listenerObjRef->getObject(), mDeviceConnectionChanged, JavaGlobalObj::GetObject(jDeviceRef), + (jboolean)connected, (jlong)timestamp); java_exception_check_and_throw(env, E_FILE_LINE); } catch(...) { rethrow_and_raise_java_exception(env); @@ -450,74 +457,6 @@ jint Java_direct_1bt_tinyb_DBTAdapter_removeDevicesImpl(JNIEnv *env, jobject obj } // -// Discovering -// - -static void disableDiscoveringNotifications(JNIEnv *env, jobject obj, DBTManager &mgmt) -{ - InvocationFunc<bool, std::shared_ptr<MgmtEvent>> * funcptr = - getObjectRef<InvocationFunc<bool, std::shared_ptr<MgmtEvent>>>(env, obj, "discoveringNotificationRef"); - if( nullptr != funcptr ) { - FunctionDef<bool, std::shared_ptr<MgmtEvent>> funcDef( funcptr ); - funcptr = nullptr; - setObjectRef(env, obj, funcptr, "discoveringNotificationRef"); // clear java ref - int count; - if( 1 != ( count = mgmt.removeMgmtEventCallback(MgmtEvent::Opcode::DISCOVERING, funcDef) ) ) { - throw direct_bt::InternalError(std::string("removeMgmtEventCallback of ")+funcDef.toString()+" not 1 but "+std::to_string(count), E_FILE_LINE); - } - } -} -void Java_direct_1bt_tinyb_DBTAdapter_disableDiscoveringNotifications(JNIEnv *env, jobject obj) -{ - // org.tinyb.AdapterStatusListener - try { - DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); - JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); - DBTManager & mgmt = adapter->getManager(); - - disableDiscoveringNotifications(env, obj, mgmt); - } catch(...) { - rethrow_and_raise_java_exception(env); - } -} -void Java_direct_1bt_tinyb_DBTAdapter_enableDiscoveringNotifications(JNIEnv *env, jobject obj, jobject javaCallback) -{ - // org.tinyb.AdapterStatusListener - try { - DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); - JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); - DBTManager & mgmt = adapter->getManager(); - - disableDiscoveringNotifications(env, obj, mgmt); - - bool(*nativeCallback)(JNIGlobalRef&, std::shared_ptr<MgmtEvent>) = - [](JNIGlobalRef& javaCallback_ref, std::shared_ptr<MgmtEvent> e)->bool { - const MgmtEvtDiscovering &event = *static_cast<const MgmtEvtDiscovering *>(e.get()); - - jclass notification = search_class(*jni_env, *javaCallback_ref); - jmethodID method = search_method(*jni_env, notification, "run", "(Ljava/lang/Object;)V", false); - jni_env->DeleteLocalRef(notification); - - jclass boolean_cls = search_class(*jni_env, "java/lang/Boolean"); - jmethodID constructor = search_method(*jni_env, boolean_cls, "<init>", "(Z)V", false); - - jobject result = jni_env->NewObject(boolean_cls, constructor, event.getEnabled() ? JNI_TRUE : JNI_FALSE); - jni_env->DeleteLocalRef(boolean_cls); - - jni_env->CallVoidMethod(*javaCallback_ref, method, result); - jni_env->DeleteLocalRef(result); - return true; - }; - // move JNIGlobalRef into CaptureInvocationFunc and operator== includes javaCallback comparison - FunctionDef<bool, std::shared_ptr<MgmtEvent>> funcDef = bindCaptureFunc(JNIGlobalRef(javaCallback), nativeCallback); - setObjectRef(env, obj, funcDef.cloneFunction(), "discoveringNotificationRef"); // set java ref - mgmt.addMgmtEventCallback(adapter->dev_id, MgmtEvent::Opcode::DISCOVERING, funcDef); - } catch(...) { - rethrow_and_raise_java_exception(env); - } -} - -// // misc // @@ -605,3 +544,73 @@ void Java_direct_1bt_tinyb_DBTAdapter_setPairable(JNIEnv *env, jobject obj, jboo rethrow_and_raise_java_exception(env); } } + +#if 0 +// +// Discovering +// + +static void disableDiscoveringNotifications(JNIEnv *env, jobject obj, DBTManager &mgmt) +{ + InvocationFunc<bool, std::shared_ptr<MgmtEvent>> * funcptr = + getObjectRef<InvocationFunc<bool, std::shared_ptr<MgmtEvent>>>(env, obj, "discoveringNotificationRef"); + if( nullptr != funcptr ) { + FunctionDef<bool, std::shared_ptr<MgmtEvent>> funcDef( funcptr ); + funcptr = nullptr; + setObjectRef(env, obj, funcptr, "discoveringNotificationRef"); // clear java ref + int count; + if( 1 != ( count = mgmt.removeMgmtEventCallback(MgmtEvent::Opcode::DISCOVERING, funcDef) ) ) { + throw direct_bt::InternalError(std::string("removeMgmtEventCallback of ")+funcDef.toString()+" not 1 but "+std::to_string(count), E_FILE_LINE); + } + } +} +void Java_direct_1bt_tinyb_DBTAdapter_disableDiscoveringNotifications(JNIEnv *env, jobject obj) +{ + // org.tinyb.AdapterStatusListener + try { + DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); + DBTManager & mgmt = adapter->getManager(); + + disableDiscoveringNotifications(env, obj, mgmt); + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} +void Java_direct_1bt_tinyb_DBTAdapter_enableDiscoveringNotifications(JNIEnv *env, jobject obj, jobject javaCallback) +{ + // org.tinyb.AdapterStatusListener + try { + DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE); + DBTManager & mgmt = adapter->getManager(); + + disableDiscoveringNotifications(env, obj, mgmt); + + bool(*nativeCallback)(JNIGlobalRef&, std::shared_ptr<MgmtEvent>) = + [](JNIGlobalRef& javaCallback_ref, std::shared_ptr<MgmtEvent> e)->bool { + const MgmtEvtDiscovering &event = *static_cast<const MgmtEvtDiscovering *>(e.get()); + + jclass notification = search_class(*jni_env, *javaCallback_ref); + jmethodID method = search_method(*jni_env, notification, "run", "(Ljava/lang/Object;)V", false); + jni_env->DeleteLocalRef(notification); + + jclass boolean_cls = search_class(*jni_env, "java/lang/Boolean"); + jmethodID constructor = search_method(*jni_env, boolean_cls, "<init>", "(Z)V", false); + + jobject result = jni_env->NewObject(boolean_cls, constructor, event.getEnabled() ? JNI_TRUE : JNI_FALSE); + jni_env->DeleteLocalRef(boolean_cls); + + jni_env->CallVoidMethod(*javaCallback_ref, method, result); + jni_env->DeleteLocalRef(result); + return true; + }; + // move JNIGlobalRef into CaptureInvocationFunc and operator== includes javaCallback comparison + FunctionDef<bool, std::shared_ptr<MgmtEvent>> funcDef = bindCaptureFunc(JNIGlobalRef(javaCallback), nativeCallback); + setObjectRef(env, obj, funcDef.cloneFunction(), "discoveringNotificationRef"); // set java ref + mgmt.addMgmtEventCallback(adapter->dev_id, MgmtEvent::Opcode::DISCOVERING, funcDef); + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} +#endif diff --git a/java/org/tinyb/AdapterStatusListener.java b/java/org/tinyb/AdapterStatusListener.java index 9d74cc41..d5d1c128 100644 --- a/java/org/tinyb/AdapterStatusListener.java +++ b/java/org/tinyb/AdapterStatusListener.java @@ -54,18 +54,23 @@ public abstract class AdapterStatusListener { /** A {@link BluetoothAdapter} setting has been changed. */ public void adapterSettingsChanged(final BluetoothAdapter adapter, final AdapterSettings oldmask, final AdapterSettings newmask, - final AdapterSettings changedmask, final long timestamp) { - } + final AdapterSettings changedmask, final long timestamp) { } + + /** + * {@link BluetoothAdapter}'s discovery state has changed, i.e. enabled or disabled. + * @param adapter the adapter which state has changed. + * @param enabled the new discovery state + * @param keepAlive if {@code true}, the discovery will be re-enabled if disabled by the underlying Bluetooth implementation. + * @param timestamp the time in monotonic milliseconds when this event occured. + */ + public void discoveringChanged(final BluetoothAdapter adapter, final boolean enabled, final boolean keepAlive, final long timestamp) { } + /** A {@link BluetoothDevice} has been newly discovered. */ - public void deviceFound(final BluetoothDevice device, final long timestamp) { - } + public void deviceFound(final BluetoothDevice device, final long timestamp) { } + /** An already discovered {@link BluetoothDevice} has been updated. */ - public void deviceUpdated(final BluetoothDevice device, final long timestamp, final EIRDataTypeSet updateMask) { - } - /** {@link BluetoothDevice} has been connected. */ - public void deviceConnected(final BluetoothDevice device, final long timestamp) { - } - /** {@link BluetoothDevice} has been disconnected. */ - public void deviceDisconnected(final BluetoothDevice device, final long timestamp) { - } + public void deviceUpdated(final BluetoothDevice device, final long timestamp, final EIRDataTypeSet updateMask) { } + + /** {@link BluetoothDevice}'s connection status has changed. */ + public void deviceConnectionChanged(final BluetoothDevice device, final boolean connected, final long timestamp) { } }; diff --git a/java/org/tinyb/BluetoothAdapter.java b/java/org/tinyb/BluetoothAdapter.java index 5a8b4542..a017b4b9 100644 --- a/java/org/tinyb/BluetoothAdapter.java +++ b/java/org/tinyb/BluetoothAdapter.java @@ -71,9 +71,21 @@ public interface BluetoothAdapter extends BluetoothObject /** Turns on device discovery if it is disabled. * @return TRUE if discovery was successfully enabled + * @deprecated since 2.0.0, use {@link #startDiscovery(boolean)}. */ + @Deprecated public boolean startDiscovery() throws BluetoothException; + /** + * Turns on device discovery if it is disabled. + * @param keepAlive if {@code true}, indicates that discovery shall be restarted + * if stopped by the underlying Bluetooth implementation (BlueZ, ..). + * @return TRUE if discovery was successfully enabled + * @throws BluetoothException + * @since 2.0.0 + */ + public boolean startDiscovery(final boolean keepAlive) throws BluetoothException; + /** Turns off device discovery if it is enabled. * @return TRUE if discovery was successfully disabled */ diff --git a/java/tinyb/dbus/DBusAdapter.java b/java/tinyb/dbus/DBusAdapter.java index 5b4b26fb..8666e8d3 100644 --- a/java/tinyb/dbus/DBusAdapter.java +++ b/java/tinyb/dbus/DBusAdapter.java @@ -66,9 +66,15 @@ public class DBusAdapter extends DBusObject implements BluetoothAdapter /* D-Bus method calls: */ @Override + @Deprecated public native boolean startDiscovery() throws BluetoothException; @Override + public synchronized boolean startDiscovery(final boolean keepAlive) throws BluetoothException { + return startDiscovery(); // FIXME keepAlive + } + + @Override public native boolean stopDiscovery() throws BluetoothException; @Override |