diff options
author | Sven Gothel <[email protected]> | 2020-05-02 03:40:59 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-05-02 03:40:59 +0200 |
commit | 51fe35b8c9128f9cc46be604a1d5d073c5ac1aca (patch) | |
tree | 0f3092334568d846fdf6d63ccf43eb14c2799376 /java | |
parent | bc3784a6950cfd6ea24a27e194540f9e4629d370 (diff) |
DBTManager Java: Add getAdapterListImpl()
getAdapterListImpl() JNI code utilizes new convert_vector_to_jobject(..)
with given ctor function defined ad-hoc via lambda.
Diffstat (limited to 'java')
-rw-r--r-- | java/direct_bt/tinyb/DBTAdapter.java | 51 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTManager.java | 1 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 30 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTManager.cxx | 57 |
4 files changed, 96 insertions, 43 deletions
diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java index 5b2087bc..2bc028b2 100644 --- a/java/direct_bt/tinyb/DBTAdapter.java +++ b/java/direct_bt/tinyb/DBTAdapter.java @@ -189,13 +189,23 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter private native void initImpl(final BluetoothDeviceStatusListener l); + private synchronized void open() { + if( !isOpen ) { + isOpen = openImpl(); + } + } + private native boolean openImpl(); + boolean isOpen = false; + @Override protected native void deleteImpl(); /* discovery */ @Override - public boolean startDiscovery() throws BluetoothException { + public synchronized boolean startDiscovery() throws BluetoothException { + open(); + removeDevices(); final boolean res = startDiscoveryImpl(); isDiscovering = res; synchronized( stateLock ) { @@ -207,7 +217,8 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter private native boolean startDiscoveryImpl() throws BluetoothException; @Override - public boolean stopDiscovery() throws BluetoothException { + public synchronized boolean stopDiscovery() throws BluetoothException { + open(); isDiscovering = false; final boolean res = stopDiscoveryImpl(); synchronized( stateLock ) { @@ -220,11 +231,16 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter @Override public List<BluetoothDevice> getDevices() { - return getDiscoveredDevices(); + synchronized(discoveredDevicesLock) { + return new ArrayList<BluetoothDevice>(discoveredDevices); + } } + // std::vector<std::shared_ptr<direct_bt::HCIDevice>> discoveredDevices = adapter.getDiscoveredDevices(); + private native List<BluetoothDevice> getDiscoveredDevicesImpl(); @Override public int removeDevices() throws BluetoothException { + open(); final int cj = removeDiscoveredDevices(); final int cn = removeDevicesImpl(); if( cj != cn ) { @@ -233,6 +249,13 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter return cn; } private native int removeDevicesImpl() throws BluetoothException; + private int removeDiscoveredDevices() { + synchronized(discoveredDevicesLock) { + final int n = discoveredDevices.size(); + discoveredDevices = new ArrayList<BluetoothDevice>(); + return n; + } + } @Override public boolean getDiscovering() { return isDiscovering; } @@ -270,9 +293,6 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter private native void setDiscoveryFilter(List<String> uuids, int rssi, int pathloss, int transportType); - // std::vector<std::shared_ptr<direct_bt::HCIDevice>> discoveredDevices = adapter.getDiscoveredDevices(); - private native List<BluetoothDevice> getDiscoveredDevicesImpl(); - //////////////////////////////////// private final Object stateLock = new Object(); @@ -286,7 +306,7 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter @Override public void deviceFound(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp) { final BluetoothDeviceStatusListener l = userDeviceStatusListener; - System.err.println("DBTAdapter.DeviceStatusListener.added: "+device+" on "+a); + System.err.println("DBTAdapter.DeviceStatusListener.found: "+device+" on "+a); synchronized(discoveredDevicesLock) { discoveredDevices.add(device); } @@ -314,32 +334,17 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter public void deviceDisconnected(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp) { final BluetoothDeviceStatusListener l = userDeviceStatusListener; System.err.println("DBTAdapter.DeviceStatusListener.disconnected: "+device+" on "+a); - synchronized(discoveredDevicesLock) { - discoveredDevices.remove(device); - } if( null != l ) { l.deviceDisconnected(a, device, timestamp); } } }; - public void setDiscoveringNotificationCallback(final BluetoothNotification<Boolean> cb) { + private void setDiscoveringNotificationCallback(final BluetoothNotification<Boolean> cb) { synchronized( stateLock ) { discoveringNotificationCB = cb; stateLock.notifyAll(); } } - public List<BluetoothDevice> getDiscoveredDevices() { - synchronized(discoveredDevicesLock) { - return new ArrayList<BluetoothDevice>(discoveredDevices); - } - } - public int removeDiscoveredDevices() { - synchronized(discoveredDevicesLock) { - final int n = discoveredDevices.size(); - discoveredDevices = new ArrayList<BluetoothDevice>(); - return n; - } - } private static AtomicInteger globThreadID = new AtomicInteger(0); private static int discoverTimeoutMS = 100; } diff --git a/java/direct_bt/tinyb/DBTManager.java b/java/direct_bt/tinyb/DBTManager.java index e5f17ad6..4b200da3 100644 --- a/java/direct_bt/tinyb/DBTManager.java +++ b/java/direct_bt/tinyb/DBTManager.java @@ -114,6 +114,7 @@ public class DBTManager implements BluetoothManager * @throws BluetoothException in case adapter is invalid or could not have been opened. */ private native DBTAdapter getDefaultAdapterImpl() throws BluetoothException; + private native List<BluetoothAdapter> getAdapterListImpl(); private native void initImpl() throws BluetoothException; private native void deleteImpl(); diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index 9c445639..5b5dff42 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -222,6 +222,21 @@ void Java_direct_1bt_tinyb_DBTAdapter_initImpl(JNIEnv *env, jobject obj, jobject } } +jboolean Java_direct_1bt_tinyb_DBTAdapter_openImpl(JNIEnv *env, jobject obj) { + try { + DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + DBG_PRINT("Java_direct_1bt_tinyb_DBTAdapter_deleteImpl %s", adapter->toString().c_str()); + std::shared_ptr<direct_bt::HCISession> session = adapter->open(); + if( nullptr == session ) { + throw BluetoothException("Couldn't open adapter "+adapter->toString(), E_FILE_LINE); + } + return JNI_TRUE; + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return JNI_FALSE; +} + void Java_direct_1bt_tinyb_DBTAdapter_deleteImpl(JNIEnv *env, jobject obj) { try { @@ -262,13 +277,14 @@ jobject Java_direct_1bt_tinyb_DBTAdapter_getDiscoveredDevicesImpl(JNIEnv *env, j try { DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); /** - std::function<jobject(JNIEnv*, jclass, jmethodID, DBTDevice*)> ctor_device = [&](JNIEnv *env, jclass clazz, jmethodID clazz_ctor, DBTDevice *elem) { - // Device(final long nativeInstance, final Adapter adptr, final String address, final String name) - jstring addr = from_string_to_jstring(env, elem->getAddressString()); - jstring name = from_string_to_jstring(env, elem->getName()); - jobject object = env->NewObject(clazz, clazz_ctor, (jlong)elem, obj, addr, name); - return object; - }; + std::function<jobject(JNIEnv*, jclass, jmethodID, DBTDevice*)> ctor_device = + [](JNIEnv *env, jclass clazz, jmethodID clazz_ctor, DBTDevice *elem) -> jobject { + // Device(final long nativeInstance, final Adapter adptr, final String address, final String name) + jstring addr = from_string_to_jstring(env, elem->getAddressString()); + jstring name = from_string_to_jstring(env, elem->getName()); + jobject object = env->NewObject(clazz, clazz_ctor, (jlong)elem, obj, addr, name); + return object; + }; return convert_vector_to_jobject<DBTDevice>(env, array, "(JLdirect_bt/tinyb/Adapter;Ljava/lang/String;Ljava/lang/String;)V", ctor_device); */ std::vector<std::shared_ptr<DBTDevice>> array = adapter->getDiscoveredDevices(); diff --git a/java/jni/direct_bt/DBTManager.cxx b/java/jni/direct_bt/DBTManager.cxx index 9f045d3b..21f01f8f 100644 --- a/java/jni/direct_bt/DBTManager.cxx +++ b/java/jni/direct_bt/DBTManager.cxx @@ -80,26 +80,13 @@ jobject Java_direct_1bt_tinyb_DBTManager_getDefaultAdapterImpl(JNIEnv *env, jobj delete adapter; throw BluetoothException("Invalid default adapter dev-id "+std::to_string(defAdapterIdx), E_FILE_LINE); } - std::shared_ptr<direct_bt::HCISession> session = adapter->open(); - if( nullptr == session ) { - delete adapter; - throw BluetoothException("Couldn't open default adapter "+std::to_string(defAdapterIdx), E_FILE_LINE); - } // prepare adapter ctor const jstring addr = from_string_to_jstring(env, adapter->getAddressString()); const jstring name = from_string_to_jstring(env, adapter->getName()); if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; } const jclass clazz = search_class(env, *adapter); - if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; } - if( nullptr == clazz ) { - throw InternalError("Adapter class not found: "+DBTAdapter::java_class(), E_FILE_LINE); - } const jmethodID clazz_ctor = search_method(env, clazz, "<init>", _adapterClazzCtorArgs.c_str(), false); - if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; } - if( nullptr == clazz_ctor ) { - throw InternalError("Adapter ctor not found: "+DBTAdapter::java_class()+".<init>"+_adapterClazzCtorArgs, E_FILE_LINE); - } jobject jAdapter = env->NewObject(clazz, clazz_ctor, (jlong)adapter, addr, name); if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; } JNIGlobalRef::check(jAdapter, E_FILE_LINE); @@ -114,3 +101,47 @@ jobject Java_direct_1bt_tinyb_DBTManager_getDefaultAdapterImpl(JNIEnv *env, jobj return nullptr; } +jobject Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl(JNIEnv *env, jobject obj) +{ + try { + DBTManager *manager = getInstance<DBTManager>(env, obj); + DBG_PRINT("Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl: Manager %s", manager->toString().c_str()); + + // index == dev_id + const int adapterCount = manager->getAdapterCount(); + std::vector<std::shared_ptr<DBTAdapter>> adapters(adapterCount); + for(int idx = 0; idx < adapterCount; idx++) { + std::shared_ptr<DBTAdapter> adapter(new DBTAdapter( idx ) ); + if( !adapter->isValid() ) { + throw BluetoothException("Invalid adapter @ idx "+std::to_string( idx ), E_FILE_LINE); + } + if( !adapter->hasDevId() ) { + throw BluetoothException("Invalid adapter dev-id @ idx "+std::to_string( idx ), E_FILE_LINE); + } + if( idx != adapter->dev_id ) { // just make sure idx == dev_id + throw BluetoothException("Invalid adapter dev-id "+std::to_string( adapter->dev_id )+" != index "+std::to_string( idx ), E_FILE_LINE); + } + adapters.push_back(adapter); + } + std::function<jobject(JNIEnv*, jclass, jmethodID, DBTAdapter*)> ctor_adapter= + [](JNIEnv *env, jclass clazz, jmethodID clazz_ctor, DBTAdapter *adapter)->jobject { + // prepare adapter ctor + const jstring addr = from_string_to_jstring(env, adapter->getAddressString()); + const jstring name = from_string_to_jstring(env, adapter->getName()); + if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; } + jobject jAdapter = env->NewObject(clazz, clazz_ctor, (jlong)adapter, addr, name); + if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; } + JNIGlobalRef::check(jAdapter, E_FILE_LINE); + std::shared_ptr<JavaAnonObj> jAdapterRef = adapter->getJavaObject(); + JavaGlobalObj::check(jAdapterRef, E_FILE_LINE); + + DBG_PRINT("Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl: New Adapter %s", adapter->toString().c_str()); + return JavaGlobalObj::GetObject(jAdapterRef); + }; + return convert_vector_to_jobject<DBTAdapter>(env, adapters, _adapterClazzCtorArgs.c_str(), ctor_adapter); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return nullptr; +} + |