diff options
author | Sven Gothel <[email protected]> | 2020-04-20 07:21:35 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-04-20 07:21:35 +0200 |
commit | 6fdcdb13db5e13f11c44f0f9bba088252d9ffa18 (patch) | |
tree | 8c9c321dd2064eb53438544f0faba91306629c8c /java/jni/helper_base.hpp | |
parent | 6505f49b63db200d817817d1d01a14005a3d732c (diff) |
Initial working Java binding for the direct_bt C++ module
Example ScannerTinyB01 demonstrates efficient scanning devices using the new BluetoothDeviceDiscoveryListener interface.
The C++ HCIObject extends JavaUplink, which handles the java object references
via 'std::shared_ptr<JavaAnonObj>', where JavaAnonObj relies on later polymorph specialization.
JavaAnonObj gets derived in the java/jni of direct_bt, where the JNI header + libraries are available.
+++
The java inplementing NativeDownlink implementations
store the nativeInstance to the C++ instances
as well as handle their java references within the native instances.
The C++ JavaUplink and Java NativeDownlink interfaces are complete
the cross referencing java <-> native.
+++
Native libraries are now split into pairs:
- tinyb + javatinyb
- direct_bt + javadirect_bt
TODO: BluetoothFactory must chose the proper bundle!
+++
The Java Adapter received a BluetoothDeviceDiscoveryListener hook,
matching C++ Adapter's HCIDeviceDiscoveryListener.
Since the Java Adapter implements its own discovery thread,
using the BluetoothDeviceDiscoveryListener is more efficient then polling
over a list of Devices fetched.
++++
TODO: Align Java and C++ class names, foremost in the C++ direct_bt space.
TODO: Bind the whole C++ GATT functionality
More testing.
Diffstat (limited to 'java/jni/helper_base.hpp')
-rw-r--r-- | java/jni/helper_base.hpp | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/java/jni/helper_base.hpp b/java/jni/helper_base.hpp index 153faa9b..4cbda995 100644 --- a/java/jni/helper_base.hpp +++ b/java/jni/helper_base.hpp @@ -26,10 +26,15 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#pragma once +#ifndef HELPER_BASE_HPP_ +#define HELPER_BASE_HPP_ #include <vector> #include <memory> +#include <functional> +#include <jni.h> + +#include "BasicTypes.hpp" jfieldID getInstanceField(JNIEnv *env, jobject obj); @@ -41,10 +46,20 @@ jfieldID search_field(JNIEnv *env, jclass clazz, const char *field_name, const char *type, bool is_static); bool from_jboolean_to_bool(jboolean val); std::string from_jstring_to_string(JNIEnv *env, jstring str); +jstring from_string_to_jstring(JNIEnv *env, const std::string & str); jobject get_bluetooth_type(JNIEnv *env, const char *field_name); jobject get_new_arraylist(JNIEnv *env, unsigned int size, jmethodID *add); template <typename T> +T *castInstance(jlong instance) +{ + T *t = reinterpret_cast<T *>(instance); + if (t == nullptr) + throw std::runtime_error("Trying to cast null object"); + return t; +} + +template <typename T> T *getInstance(JNIEnv *env, jobject obj) { jlong instance = env->GetLongField(obj, getInstanceField(env, obj)); @@ -111,7 +126,58 @@ jobject convert_vector_to_jobject(JNIEnv *env, std::vector<std::unique_ptr<T>>& return result; } +template <typename T> +jobject convert_vector_to_jobject(JNIEnv *env, std::vector<std::shared_ptr<T>>& array, + const char *ctor_prototype, std::function<jobject(JNIEnv*, jclass, jmethodID, T*)> ctor) +{ + unsigned int array_size = array.size(); + + jmethodID arraylist_add; + jobject result = get_new_arraylist(env, array_size, &arraylist_add); + + if (array_size == 0) + { + return result; + } + + jclass clazz = search_class(env, T::java_class().c_str()); + jmethodID clazz_ctor = search_method(env, clazz, "<init>", ctor_prototype, false); + + for (unsigned int i = 0; i < array_size; ++i) + { + T *elem = array.at(i).get(); + jobject object = ctor(env, clazz, clazz_ctor, elem); + if (!object) + { + throw std::runtime_error("cannot create instance of class\n"); + } + env->CallBooleanMethod(result, arraylist_add, object); + } + return result; +} + void raise_java_exception(JNIEnv *env, std::exception &e); void raise_java_runtime_exception(JNIEnv *env, std::runtime_error &e); +void raise_java_runtime_exception(JNIEnv *env, direct_bt::RuntimeException &e); void raise_java_oom_exception(JNIEnv *env, std::bad_alloc &e); void raise_java_invalid_arg_exception(JNIEnv *env, std::invalid_argument &e); +void raise_java_bluetooth_exception(JNIEnv *env, direct_bt::BluetoothException &e); + +void exception_check_raise_and_throw(JNIEnv *env, const char* file, int line); + +#define CATCH_EXCEPTION_AND_RAISE_JAVA(env, e) \ + catch (std::bad_alloc &e) { \ + raise_java_oom_exception(env, e); \ +} catch (direct_bt::BluetoothException &e) { \ + raise_java_bluetooth_exception(env, e); \ +} catch (direct_bt::RuntimeException &e) { \ + raise_java_runtime_exception(env, e); \ +} catch (std::runtime_error &e) { \ + raise_java_runtime_exception(env, e); \ +} catch (std::invalid_argument &e) { \ + raise_java_invalid_arg_exception(env, e); \ +} catch (std::exception &e) { \ + raise_java_exception(env, e); \ +} + +#endif /* HELPER_BASE_HPP_ */ |