summaryrefslogtreecommitdiffstats
path: root/java/jni/direct_bt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-05-04 15:42:06 +0200
committerSven Gothel <[email protected]>2020-05-04 15:42:06 +0200
commit28554c22cc963ee050cb123499d4f7b3d5a2eb0c (patch)
treef4be86cb3dc1afe39a561c3e9d976110a4651e30 /java/jni/direct_bt
parent25a2fd41ea185cbab1964463fa8fe30d535b5f58 (diff)
JNI DBTAdapter: Enhance callback pattern (here DiscoveringNotifications); PoweredNotification has been dropped ..
JNI DBTAdapter: Enhance callback pattern (here DiscoveringNotifications) - Use 1:1 native methods for java callback API w/o need for intermediate java code - get/set/clear the corresponding jlong InvocationFunc<..> callback field, holding the identity copy instance of used callback. We use 'funcDef.cloneFunction()' for this purpose - Use JNIGlobalRef's move-ctor to have it placed within CaptureInvocationFunc - Use JNIGlobalRed's operator== to have the actuall callback included in equality operation (callback identity) +++ PoweredNotification has been dropped .. - NEW_SETTINGS deduced callbacks are derived from BluetoothAdapterStatusListener callback
Diffstat (limited to 'java/jni/direct_bt')
-rw-r--r--java/jni/direct_bt/DBTAdapter.cxx162
1 files changed, 33 insertions, 129 deletions
diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx
index 03ab2d00..deb35e49 100644
--- a/java/jni/direct_bt/DBTAdapter.cxx
+++ b/java/jni/direct_bt/DBTAdapter.cxx
@@ -388,166 +388,70 @@ jint Java_direct_1bt_tinyb_DBTAdapter_removeDevicesImpl(JNIEnv *env, jobject obj
return 0;
}
-jlong Java_direct_1bt_tinyb_DBTAdapter_addDiscoveringNotificationsImpl(JNIEnv *env, jobject obj, jobject javaCallback)
-{
- // org.tinyb.BluetoothDeviceDiscoveryListener
- try {
- DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj);
- JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE);
- DBTManager & mgmt = adapter->getManager();
- std::shared_ptr<JNIGlobalRef> javaCallback_ptr(new JNIGlobalRef(javaCallback));
-
-#if 1
- // this function instance satisfies to be key for identity,
- // as it is uniquely created for this javaCallback.
- bool(*nativeCallback)(std::shared_ptr<JNIGlobalRef>, std::shared_ptr<MgmtEvent>) =
- [](std::shared_ptr<JNIGlobalRef> javaCallback_ptr, std::shared_ptr<MgmtEvent> e)->bool {
- const MgmtEvtDiscovering &event = *static_cast<const MgmtEvtDiscovering *>(e.get());
-
- jclass notification = search_class(*jni_env, **javaCallback_ptr);
- 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_ptr, method, result);
- jni_env->DeleteLocalRef(result);
- return true;
- };
- mgmt.addMgmtEventCallback(adapter->dev_id, MgmtEvent::Opcode::DISCOVERING, bindCaptureFunc(javaCallback_ptr, nativeCallback, false));
- // hack to convert function pointer to void *: '*((void**)&function)'
- return (jlong)( *((void**)&nativeCallback) );
-#elif 0
- const uint64_t id = (jlong)obj;
- std::function<bool(std::shared_ptr<MgmtEvent> e)> nativeCallback = [javaCallback_ptr](std::shared_ptr<MgmtEvent> e)->bool {
- const MgmtEvtDiscovering &event = *static_cast<const MgmtEvtDiscovering *>(e.get());
-
- jclass notification = search_class(*jni_env, **javaCallback_ptr);
- 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_ptr, method, result);
- jni_env->DeleteLocalRef(result);
- return true;
- };
- mgmt.addMgmtEventCallback(adapter->dev_id, MgmtEvent::Opcode::DISCOVERING, bindStdFunc(id, nativeCallback));
- return id;
-#else
- // Capturing Lambda -> EventCallbackFunc type issues, need to learn how std::function does it!
- typedef bool(*EventCallbackFunc)(std::shared_ptr<MgmtEvent>);
- EventCallbackFunc nativeCallback = [javaCallback_ptr](std::shared_ptr<MgmtEvent> e)->bool {
- const MgmtEvtDiscovering &event = *static_cast<const MgmtEvtDiscovering *>(e.get());
-
- jclass notification = search_class(*jni_env, **javaCallback_ptr);
- jmethodID method = search_method(*jni_env, notification, "run", "(Ljava/lang/Object;)V", false);
- jni_env->DeleteLocalRef(notification);
+//
+// Discovering
+//
- 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_ptr, method, result);
- jni_env->DeleteLocalRef(result);
- return true;
- };
- mgmt.addMgmtEventCallback(adapter->dev_id, MgmtEvent::Opcode::DISCOVERING, bindPlainFunc(nativeCallback));
- // hack to convert function pointer to void *: '*((void**)&function)'
- return (jlong)( *((void**)&nativeCallback) );
-#endif
- } catch(...) {
- rethrow_and_raise_java_exception(env);
+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);
+ }
}
- return 0;
}
-
-int Java_direct_1bt_tinyb_DBTAdapter_removeDiscoveringNotificationsImpl(JNIEnv *env, jobject obj, jlong jNativeCallback)
+void Java_direct_1bt_tinyb_DBTAdapter_disableDiscoveringNotifications(JNIEnv *env, jobject obj)
{
- // org.tinyb.BluetoothDeviceDiscoveryListener
+ // org.tinyb.BluetoothAdapterStatusListener
try {
DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj);
JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE);
DBTManager & mgmt = adapter->getManager();
-#if 1
- bool(*nativeCallback)(std::shared_ptr<JNIGlobalRef>, std::shared_ptr<MgmtEvent>) =
- (bool(*)(std::shared_ptr<JNIGlobalRef>, std::shared_ptr<MgmtEvent>)) ( void *) jNativeCallback;
- return mgmt.removeMgmtEventCallback(MgmtEvent::Opcode::DISCOVERING, bindCaptureFunc(std::shared_ptr<JNIGlobalRef>(nullptr), nativeCallback, false));
-#elif 0
- const uint64_t id = (uint64_t)jNativeCallback;
- return mgmt.removeMgmtEventCallback(MgmtEvent::Opcode::DISCOVERING, bindStdFunc<bool, std::shared_ptr<MgmtEvent>>(id));
-#else
- bool(*nativeCallback)(std::shared_ptr<MgmtEvent>) = (bool(*)(std::shared_ptr<MgmtEvent>)) ( (void *)jNativeCallback );
- return mgmt.removeMgmtEventCallback(MgmtEvent::Opcode::DISCOVERING, bindPlainFunc(nativeCallback));
-#endif
+
+ disableDiscoveringNotifications(env, obj, mgmt);
} catch(...) {
rethrow_and_raise_java_exception(env);
}
- return 0;
}
-
-jlong Java_direct_1bt_tinyb_DBTAdapter_addPoweredNotificationsImpl(JNIEnv *env, jobject obj, jobject javaCallback)
+void Java_direct_1bt_tinyb_DBTAdapter_enableDiscoveringNotifications(JNIEnv *env, jobject obj, jobject javaCallback)
{
- // org.tinyb.BluetoothDeviceDiscoveryListener
+ // org.tinyb.BluetoothAdapterStatusListener
try {
DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj);
JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE);
DBTManager & mgmt = adapter->getManager();
- std::shared_ptr<JNIGlobalRef> javaCallback_ptr(new JNIGlobalRef(javaCallback));
- // this function instance satisfies to be key for identity,
- // as it is uniquely created for this javaCallback.
- bool(*nativeCallback)(std::shared_ptr<JNIGlobalRef>, std::shared_ptr<MgmtEvent>) =
- [](std::shared_ptr<JNIGlobalRef> javaCallback_ptr, std::shared_ptr<MgmtEvent> e)->bool {
- const MgmtEvtNewSettings &event = *static_cast<const MgmtEvtNewSettings *>(e.get());
+ 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_ptr);
+ 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, ( 0 != ( event.getSettings() & MGMT_SETTING_POWERED ) ) ? JNI_TRUE : JNI_FALSE);
+ jobject result = jni_env->NewObject(boolean_cls, constructor, event.getEnabled() ? JNI_TRUE : JNI_FALSE);
jni_env->DeleteLocalRef(boolean_cls);
- jni_env->CallVoidMethod(**javaCallback_ptr, method, result);
+ jni_env->CallVoidMethod(*javaCallback_ref, method, result);
jni_env->DeleteLocalRef(result);
return true;
};
- mgmt.addMgmtEventCallback(adapter->dev_id, MgmtEvent::Opcode::NEW_SETTINGS, bindCaptureFunc(javaCallback_ptr, nativeCallback, false));
- // hack to convert function pointer to void *: '*((void**)&function)'
- return (jlong)( *((void**)&nativeCallback) );
- } catch(...) {
- rethrow_and_raise_java_exception(env);
- }
- return 0;
-}
-
-int Java_direct_1bt_tinyb_DBTAdapter_removePoweredNotificationsImpl(JNIEnv *env, jobject obj, jlong jNativeCallback)
-{
- // org.tinyb.BluetoothDeviceDiscoveryListener
- try {
- DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj);
- JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE);
- DBTManager & mgmt = adapter->getManager();
-
- bool(*nativeCallback)(std::shared_ptr<JNIGlobalRef>, std::shared_ptr<MgmtEvent>) =
- (bool(*)(std::shared_ptr<JNIGlobalRef>, std::shared_ptr<MgmtEvent>)) ( void *) jNativeCallback;
- return mgmt.removeMgmtEventCallback(MgmtEvent::Opcode::NEW_SETTINGS, bindCaptureFunc(std::shared_ptr<JNIGlobalRef>(nullptr), nativeCallback, false));
+ // 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);
}
- return 0;
}
-