#define BEYOND_EVENT_LISTENER_ON_EVENT_METHOD_SIGNATURE "(Lcom/samsung/android/beyond/EventObject;)V"
#define BEYOND_DISCOVERY_EVENT_OBJECT_CLASS_NAME "com/samsung/android/beyond/discovery/Discovery$DefaultEventObject"
-#define BEYOND_DISCOVERY_EVENT_OBJECT_CONSTRUCTOR_NAME "<init>"
-#define BEYOND_DISCOVERY_EVENT_OBJECT_CONSTRUCTOR_SIGANTURE "()V"
+#define BEYOND_DISCOVERY_INFO_CLASS_NAME "com/samsung/android/beyond/discovery/Discovery$Info"
+#define BEYOND_DISCOVERY_DEFAULT_CONSTRUCTOR_NAME "<init>"
+#define BEYOND_DISCOVERY_DEFAULT_CONSTRUCTOR_SIGANTURE "()V"
#define BEYOND_DISCOVERY_EVENT_OBJECT_EVENT_TYPE_FIELD_NAME "eventType"
#define BEYOND_DISCOVERY_EVENT_OBJECT_EVENT_DATA_FIELD_NAME "eventData"
};
jfieldID DiscoveryNativeInterface::eventListener = nullptr;
+DiscoveryNativeInterface::Info DiscoveryNativeInterface::infoObject = {
+ .klass = nullptr,
+ .constructor = nullptr,
+ .name = nullptr,
+ .host = nullptr,
+ .port = nullptr,
+ .uuid = nullptr,
+};
+
DiscoveryNativeInterface::DiscoveryNativeInterface(void)
: discovery(nullptr)
, looper(nullptr)
}
}
-void DiscoveryNativeInterface::Java_com_samsung_android_beyond_discovery_Discovery_initialize(JNIEnv *env, jclass klass)
+void DiscoveryNativeInterface::initializeInfo(JNIEnv *env, jclass klass)
+{
+ jclass infoKlass = env->FindClass(BEYOND_DISCOVERY_INFO_CLASS_NAME);
+ if (infoKlass == nullptr) {
+ ErrPrint("Unable to get the class");
+ return;
+ }
+
+ infoObject.klass = static_cast<jclass>(env->NewGlobalRef(infoKlass));
+ env->DeleteLocalRef(infoKlass);
+ if (infoObject.klass == nullptr) {
+ ErrPrint("Unable to get the Info class");
+ return;
+ }
+
+ infoObject.constructor = env->GetMethodID(infoObject.klass,
+ BEYOND_DISCOVERY_DEFAULT_CONSTRUCTOR_NAME,
+ BEYOND_DISCOVERY_DEFAULT_CONSTRUCTOR_SIGANTURE);
+ if (env->ExceptionCheck() == true) {
+ JNIHelper::PrintException(env, __FUNCTION__, __LINE__);
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+ if (infoObject.constructor == nullptr) {
+ ErrPrint("Unable to get the info constructor");
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+
+ infoObject.name = env->GetFieldID(infoObject.klass, "name", "Ljava/lang/String;");
+ if (env->ExceptionCheck() == true) {
+ JNIHelper::PrintException(env, __FUNCTION__, __LINE__);
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+ if (infoObject.host == nullptr) {
+ ErrPrint("Unable to get the host field from info");
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+
+ infoObject.host = env->GetFieldID(infoObject.klass, "host", "Ljava/lang/String;");
+ if (env->ExceptionCheck() == true) {
+ JNIHelper::PrintException(env, __FUNCTION__, __LINE__);
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+ if (infoObject.host == nullptr) {
+ ErrPrint("Unable to get the host field from info");
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+
+ infoObject.port = env->GetFieldID(infoObject.klass, "port", "I");
+ if (env->ExceptionCheck() == true) {
+ JNIHelper::PrintException(env, __FUNCTION__, __LINE__);
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+ if (infoObject.port == nullptr) {
+ ErrPrint("Unable to get the port field from info");
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+
+ infoObject.uuid = env->GetFieldID(infoObject.klass, "uuid", "Ljava/lang/String;");
+ if (env->ExceptionCheck() == true) {
+ JNIHelper::PrintException(env, __FUNCTION__, __LINE__);
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+ if (infoObject.uuid == nullptr) {
+ ErrPrint("Unable to get the uuid field from info");
+ env->DeleteGlobalRef(infoObject.klass);
+ infoObject.klass = nullptr;
+ return;
+ }
+}
+
+void DiscoveryNativeInterface::initializeEventObject(JNIEnv *env, jclass klass)
{
eventListener = env->GetFieldID(klass,
BEYOND_DISCOVERY_EVENT_LISTENER_FIELD_NAME,
}
eventObject.constructor = env->GetMethodID(eventObject.klass,
- BEYOND_DISCOVERY_EVENT_OBJECT_CONSTRUCTOR_NAME,
- BEYOND_DISCOVERY_EVENT_OBJECT_CONSTRUCTOR_SIGANTURE);
+ BEYOND_DISCOVERY_DEFAULT_CONSTRUCTOR_NAME,
+ BEYOND_DISCOVERY_DEFAULT_CONSTRUCTOR_SIGANTURE);
if (eventObject.constructor == nullptr) {
ErrPrint("Unable to find the event constructor metohd");
if (env->ExceptionCheck() == true) {
eventObject.klass = nullptr;
return;
}
+}
+void DiscoveryNativeInterface::Java_com_samsung_android_beyond_discovery_Discovery_initialize(JNIEnv *env, jclass klass)
+{
+ initializeInfo(env, klass);
+ initializeEventObject(env, klass);
DbgPrint("Discovery JNI cache initialized");
}
+jobject DiscoveryNativeInterface::NewEventObject(JNIEnv *env, jobject thiz, void *eventData)
+{
+ beyond_peer_info *info = static_cast<beyond_peer_info *>(eventData);
+ jstring host = nullptr;
+ jstring name = nullptr;
+
+ jobject object = env->NewObject(infoObject.klass, infoObject.constructor);
+ if (env->ExceptionCheck() == true) {
+ JNIPrintException(env);
+ return nullptr;
+ }
+ if (object == nullptr) {
+ ErrPrint("Failed to construct a new info object");
+ return nullptr;
+ }
+
+ if (info->host == nullptr) {
+ DbgPrint("There is no host information");
+ } else {
+ host = env->NewStringUTF(info->host);
+ if (env->ExceptionCheck() == true) {
+ JNIHelper::PrintException(env, __FUNCTION__, __LINE__);
+ env->DeleteLocalRef(object);
+ return nullptr;
+ }
+
+ if (host == nullptr) {
+ ErrPrint("host is not valid");
+ env->DeleteLocalRef(object);
+ return nullptr;
+ }
+
+ env->SetObjectField(object, infoObject.host, host);
+ }
+
+ if (info->name == nullptr) {
+ DbgPrint("There is no service name");
+ } else {
+ name = env->NewStringUTF(info->name);
+ if (env->ExceptionCheck() == true) {
+ JNIHelper::PrintException(env, __FUNCTION__, __LINE__);
+ env->DeleteLocalRef(object);
+ env->DeleteLocalRef(host);
+ return nullptr;
+ }
+
+ if (name == nullptr) {
+ ErrPrint("host is not valid");
+ env->DeleteLocalRef(object);
+ env->DeleteLocalRef(host);
+ return nullptr;
+ }
+
+ env->SetObjectField(object, infoObject.name, name);
+ }
+
+ jstring uuid = env->NewStringUTF(info->uuid);
+ if (env->ExceptionCheck() == true) {
+ JNIHelper::PrintException(env, __FUNCTION__, __LINE__);
+ env->DeleteLocalRef(object);
+ env->DeleteLocalRef(host);
+ env->DeleteLocalRef(name);
+ return nullptr;
+ }
+
+ if (uuid == nullptr) {
+ ErrPrint("uuid is not valid");
+ env->DeleteLocalRef(object);
+ env->DeleteLocalRef(host);
+ env->DeleteLocalRef(name);
+ return nullptr;
+ }
+
+ env->SetObjectField(object, infoObject.uuid, static_cast<jobject>(uuid));
+
+ // TODO:
+ // Port array should be changed to a single value
+ // No more need to keep the multiple port information
+ env->SetIntField(object, infoObject.port, static_cast<const int>(info->port[0]));
+
+ return object;
+}
+
int DiscoveryNativeInterface::InvokeEventListener(JNIEnv *env, jobject thiz, int eventType, void *eventData)
{
jobject eventListenerObject = env->GetObjectField(thiz, eventListener);
if (env->ExceptionCheck() == true) {
JNIPrintException(env);
}
+ env->DeleteLocalRef(eventListenerObject);
return -EFAULT;
}
env->SetIntField(object, eventObject.eventType, eventType);
+ jobject evtObj = nullptr;
if (eventData != nullptr) {
- // TODO: convert eventData to JAVA object
- // env->SetObjectField(object, eventObject.eventData, static_cast<jobject>(eventData));
+ evtObj = NewEventObject(env, thiz, eventData);
+ if (evtObj == nullptr) {
+ env->DeleteLocalRef(object);
+ env->DeleteLocalRef(eventListenerObject);
+ return -EFAULT;
+ }
+
+ env->SetObjectField(object, eventObject.eventData, evtObj);
}
+
int ret = JNIHelper::CallVoidMethod(env, eventListenerObject,
BEYOND_EVENT_LISTENER_ON_EVENT_METHOD_NAME,
BEYOND_EVENT_LISTENER_ON_EVENT_METHOD_SIGNATURE,
object);
env->DeleteLocalRef(object);
+ env->DeleteLocalRef(evtObj);
env->DeleteLocalRef(eventListenerObject);
return ret;
}