public class DefaultEventObject extends EventObject {
}
- private EventListener eventListener;
private static final String TAG = "BEYOND_ANDROID_AUTH";
public Authenticator(String[] arguments) {
registerNativeInstance(create(arguments), (Long instance) -> destroy(instance));
Log.d(TAG, "Authenticator created");
- eventListener = null;
}
public void setEventListener(EventListener eventListener) {
- this.eventListener = eventListener;
- if (this.setEventListener(instance, eventListener != null) < 0) {
+ if (this.setEventListener(instance, eventListener) < 0) {
// TODO: throw an exception
}
}
private native int deactivate(long instance);
private native int activate(long instance);
private native int prepare(long instance);
- private native int setEventListener(long instance, boolean flag);
+ private native int setEventListener(long instance, EventListener eventListener);
}
}
private static final String TAG = "BEYOND_ANDROID_DISCOVERY";
- private EventListener eventListener;
public Discovery(Context context, String[] arguments) {
if (context == null || arguments == null || arguments.length == 0) {
}
registerNativeInstance(create(arguments), (Long instance) -> destroy(instance));
- eventListener = null;
if (this.configure(ConfigType.CONTEXT_ANDROID, context) != 0) {
Log.e(TAG, "Failed to configure the android context");
}
public void setEventListener(EventListener eventListener) {
- this.eventListener = eventListener;
- if (setEventListener(instance, this.eventListener != null) < 0) {
+ if (setEventListener(instance, eventListener) < 0) {
// TODO: throw an exception
}
}
private native int setItem(long instance, String key, byte[] value);
private native int removeItem(long instance, String key);
private native int configure(long instance, char type, Object obj);
- private native int setEventListener(long instance, boolean flag);
+ private native int setEventListener(long instance, EventListener eventListener);
}
#define BEYOND_AUTHENTICATOR_EVENT_OBJECT_EVENT_TYPE_FIELD_NAME "eventType"
#define BEYOND_AUTHENTICATOR_EVENT_OBJECT_EVENT_DATA_FIELD_NAME "eventData"
-#define BEYOND_AUTHENTICATOR_EVENT_LISTENER_FIELD_NAME "eventListener"
-
AuthenticatorNativeInterface::EventObject AuthenticatorNativeInterface::eventObject = {
.klass = nullptr,
.constructor = nullptr,
.eventType = nullptr,
.eventData = nullptr,
};
-jfieldID AuthenticatorNativeInterface::eventListener = nullptr;
AuthenticatorNativeInterface::AuthenticatorNativeInterface(void)
: authenticator(nullptr)
, looper(nullptr)
, jvm(nullptr)
- , thiz(nullptr)
+ , listener(nullptr)
{
}
// In the destructor, we are doing too much works
// It should be narrowed and simplified
// otherwise, the destructor code should be separated
- if (thiz != nullptr) {
+ if (listener != nullptr) {
JNIEnv *env = nullptr;
bool attached = false;
int JNIStatus = jvm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4);
// NOTE:
// this can be happens when the user calls "close" method directly
DbgPrint("Event listener is not cleared, forcibly delete the reference");
- env->DeleteGlobalRef(thiz);
- thiz = nullptr;
+ env->DeleteGlobalRef(listener);
+ listener = nullptr;
}
if (attached == true) {
void AuthenticatorNativeInterface::Java_com_samsung_android_beyond_Authenticator_initialize(JNIEnv *env, jclass klass)
{
- eventListener = env->GetFieldID(klass,
- BEYOND_AUTHENTICATOR_EVENT_LISTENER_FIELD_NAME,
- BEYOND_EVENT_LISTENER_CLASS_TYPE);
- if (env->ExceptionCheck() == true) {
- JNIPrintException(env);
- return;
- }
- if (eventListener == nullptr) {
- ErrPrint("Unable to find the field id of an eventListener");
- return;
- }
-
// NOTE:
// Holds the event object class
// And cache the field ids of it.
DbgPrint("Authenticator JNI cache initialized");
}
-int AuthenticatorNativeInterface::InvokeEventListener(JNIEnv *env, jobject thiz, int eventType, void *eventData)
+int AuthenticatorNativeInterface::InvokeEventListener(JNIEnv *env, int eventType, void *eventData)
{
- jobject eventListenerObject = env->GetObjectField(thiz, eventListener);
- if (eventListenerObject == nullptr) {
- DbgPrint("No listener registered");
- return 0;
- }
-
jobject object = env->NewObject(eventObject.klass, eventObject.constructor);
if (env->ExceptionCheck() == true) {
JNIPrintException(env);
env->SetObjectField(object, eventObject.eventData, static_cast<jobject>(eventData));
}
- int ret = JNIHelper::CallVoidMethod(env, eventListenerObject,
+ int ret = JNIHelper::CallVoidMethod(env, listener,
BEYOND_EVENT_LISTENER_ON_EVENT_METHOD_NAME,
BEYOND_EVENT_LISTENER_ON_EVENT_METHOD_SIGNATURE,
object);
env->DeleteLocalRef(object);
- env->DeleteLocalRef(eventListenerObject);
return ret;
}
}
}
- JNIEnv *env = nullptr;
- bool attached = false;
- int JNIStatus;
+ if (inst->listener != nullptr) {
+ JNIEnv *env = nullptr;
+ bool attached = false;
+ int JNIStatus;
- JNIStatus = inst->jvm->GetEnv((void **)(&env), JNI_VERSION_1_4);
- if (JNIStatus == JNI_EDETACHED) {
- if (inst->jvm->AttachCurrentThread(&env, nullptr) != 0) {
- ErrPrint("Failed to attach current thread");
- } else {
- attached = true;
+ JNIStatus = inst->jvm->GetEnv((void **)(&env), JNI_VERSION_1_4);
+ if (JNIStatus == JNI_EDETACHED) {
+ if (inst->jvm->AttachCurrentThread(&env, nullptr) != 0) {
+ ErrPrint("Failed to attach current thread");
+ } else {
+ attached = true;
+ }
+ } else if (JNIStatus == JNI_EVERSION) {
+ ErrPrint("GetEnv: Unsupported version");
}
- } else if (JNIStatus == JNI_EVERSION) {
- ErrPrint("GetEnv: Unsupported version");
- }
- if (env == nullptr) {
- ErrPrint("Failed to getEnv, event cannot be delivered to the managed code");
- } else {
- // NOTE:
- // Now, publish the event object to the event listener
- if (inst->thiz != nullptr) {
- status = inst->InvokeEventListener(env, inst->thiz, event.type, event.data);
+ if (env == nullptr) {
+ ErrPrint("Failed to getEnv, event cannot be delivered to the managed code");
+ } else {
+ // NOTE:
+ // Now, publish the event object to the event listener
+ status = inst->InvokeEventListener(env, event.type, event.data);
if (status < 0) {
ErrPrint("Failed to invoke the event listener");
}
- } else {
- DbgPrint("Event listener is not ready yet");
- }
- if (attached == true) {
- inst->jvm->DetachCurrentThread();
+ if (attached == true) {
+ inst->jvm->DetachCurrentThread();
+ }
}
+ } else {
+ DbgPrint("Event listener is not registered");
}
// NOTE:
return inst->authenticator->Deactivate();
}
-int AuthenticatorNativeInterface::Java_com_samsung_android_beyond_Authenticator_setEventListener(JNIEnv *env, jobject _thiz, jlong _inst, jboolean flag)
+int AuthenticatorNativeInterface::Java_com_samsung_android_beyond_Authenticator_setEventListener(JNIEnv *env, jobject _thiz, jlong _inst, jobject listener)
{
AuthenticatorNativeInterface *inst = reinterpret_cast<AuthenticatorNativeInterface *>(_inst);
if (inst == nullptr || inst->authenticator == nullptr) {
return -EFAULT;
}
- if (flag == true) {
- inst->thiz = env->NewGlobalRef(_thiz);
- if (inst->thiz == nullptr) {
+ if (inst->listener != nullptr) {
+ env->DeleteGlobalRef(inst->listener);
+ inst->listener = nullptr;
+ }
+
+ if (listener != nullptr) {
+ inst->listener = env->NewGlobalRef(listener);
+ if (inst->listener == nullptr) {
ErrPrint("Failed to get a global reference");
return -EFAULT;
}
- } else if (inst->thiz == _thiz) {
- env->DeleteGlobalRef(inst->thiz);
- inst->thiz = nullptr;
- } else {
- ErrPrint("This object corrupted");
- return -EFAULT;
}
return 0;
{ "prepare", "(J)I", reinterpret_cast<void *>(Java_com_samsung_android_beyond_Authenticator_prepare) },
{ "activate", "(J)I", reinterpret_cast<void *>(Java_com_samsung_android_beyond_Authenticator_activate) },
{ "deactivate", "(J)I", reinterpret_cast<void *>(Java_com_samsung_android_beyond_Authenticator_deactivate) },
- { "setEventListener", "(JZ)I", reinterpret_cast<void *>(Java_com_samsung_android_beyond_Authenticator_setEventListener) },
+ { "setEventListener", "(J" BEYOND_EVENT_LISTENER_CLASS_TYPE ")I", reinterpret_cast<void *>(Java_com_samsung_android_beyond_Authenticator_setEventListener) },
};
jclass klass = env->FindClass("com/samsung/android/beyond/authenticator/Authenticator");
static int Java_com_samsung_android_beyond_Authenticator_deactivate(JNIEnv *env, jobject thiz, jlong inst);
static void Java_com_samsung_android_beyond_Authenticator_initialize(JNIEnv *env, jclass klass);
static void Java_com_samsung_android_beyond_Authenticator_destroy(JNIEnv *env, jclass klass, jlong inst);
- static int Java_com_samsung_android_beyond_Authenticator_setEventListener(JNIEnv *env, jobject thiz, jlong inst, jboolean flag);
+ static int Java_com_samsung_android_beyond_Authenticator_setEventListener(JNIEnv *env, jobject thiz, jlong inst, jobject listener);
private:
static int Authenticator_eventHandler(int fd, int events, void *data);
jfieldID eventData;
};
- struct EventListener {
- jfieldID eventListener;
- };
-
private: // JNI Cache
static EventObject eventObject;
- static jfieldID eventListener;
private:
- int InvokeEventListener(JNIEnv *env, jobject thiz, int eventType, void *eventData);
+ int InvokeEventListener(JNIEnv *env, int eventType, void *eventData);
int AttachEventLoop(void);
private:
ALooper *looper;
JavaVM *jvm;
- jobject thiz;
+ jobject listener;
};
#endif // __BEYOND_ANDROID_AUTHENTICATOR_NATIVE_INTERFACE_H__
#define BEYOND_DISCOVERY_EVENT_OBJECT_EVENT_TYPE_FIELD_NAME "eventType"
#define BEYOND_DISCOVERY_EVENT_OBJECT_EVENT_DATA_FIELD_NAME "eventData"
-#define BEYOND_DISCOVERY_EVENT_LISTENER_FIELD_NAME "eventListener"
-
DiscoveryNativeInterface::EventObject DiscoveryNativeInterface::eventObject = {
.klass = nullptr,
.constructor = nullptr,
.eventType = nullptr,
.eventData = nullptr,
};
-jfieldID DiscoveryNativeInterface::eventListener = nullptr;
DiscoveryNativeInterface::Info DiscoveryNativeInterface::infoObject = {
.klass = nullptr,
: discovery(nullptr)
, looper(nullptr)
, jvm(nullptr)
- , thiz(nullptr)
+ , listener(nullptr)
{
}
discovery->Destroy();
discovery = nullptr;
}
+
+ if (listener != nullptr) {
+ JNIEnv *env = nullptr;
+ bool attached = false;
+ int JNIStatus = jvm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4);
+ if (JNIStatus == JNI_EDETACHED) {
+ if (jvm->AttachCurrentThread(&env, nullptr) != 0) {
+ ErrPrint("Failed to attach current thread");
+ } else {
+ attached = true;
+ }
+ } else if (JNIStatus == JNI_EVERSION) {
+ ErrPrint("GetEnv: Unsupported version");
+ }
+
+ if (env == nullptr) {
+ ErrPrint("Failed to get the environment object");
+ } else {
+ // NOTE:
+ // this can be happens when the user calls "close" method directly
+ DbgPrint("Event listener is not cleared, forcibly delete the reference");
+ env->DeleteGlobalRef(listener);
+ listener = nullptr;
+ }
+
+ if (attached == true) {
+ jvm->DetachCurrentThread();
+ }
+ }
+
+ jvm = nullptr;
}
void DiscoveryNativeInterface::initializeInfo(JNIEnv *env, jclass klass)
void DiscoveryNativeInterface::initializeEventObject(JNIEnv *env, jclass klass)
{
- eventListener = env->GetFieldID(klass,
- BEYOND_DISCOVERY_EVENT_LISTENER_FIELD_NAME,
- BEYOND_EVENT_LISTENER_CLASS_TYPE);
- if (eventListener == nullptr) {
- ErrPrint("Unable to find the field id of an eventListener");
- if (env->ExceptionCheck() == true) {
- JNIPrintException(env);
- }
- return;
- }
-
// NOTE:
// Holds the event object class
// And cache the field ids of it.
DbgPrint("Discovery JNI cache initialized");
}
-jobject DiscoveryNativeInterface::NewEventObject(JNIEnv *env, jobject thiz, void *eventData)
+jobject DiscoveryNativeInterface::NewEventObject(JNIEnv *env, void *eventData)
{
beyond_peer_info *info = static_cast<beyond_peer_info *>(eventData);
jstring host = nullptr;
return object;
}
-int DiscoveryNativeInterface::InvokeEventListener(JNIEnv *env, jobject thiz, int eventType, void *eventData)
+int DiscoveryNativeInterface::InvokeEventListener(JNIEnv *env, int eventType, void *eventData)
{
- jobject eventListenerObject = env->GetObjectField(thiz, eventListener);
- if (eventListenerObject == nullptr) {
- DbgPrint("No listener registered");
- return 0;
- }
-
jobject object = env->NewObject(eventObject.klass, eventObject.constructor);
if (object == nullptr) {
ErrPrint("Failed to construct a new event object");
if (env->ExceptionCheck() == true) {
JNIPrintException(env);
}
- env->DeleteLocalRef(eventListenerObject);
return -EFAULT;
}
env->SetIntField(object, eventObject.eventType, eventType);
jobject evtObj = nullptr;
if (eventData != nullptr) {
- evtObj = NewEventObject(env, thiz, eventData);
+ evtObj = NewEventObject(env, eventData);
if (evtObj == nullptr) {
env->DeleteLocalRef(object);
- env->DeleteLocalRef(eventListenerObject);
return -EFAULT;
}
env->SetObjectField(object, eventObject.eventData, evtObj);
}
- int ret = JNIHelper::CallVoidMethod(env, eventListenerObject,
+ int ret = JNIHelper::CallVoidMethod(env, listener,
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;
}
return 0;
}
- if (inst->thiz == nullptr) {
- DbgPrint("Event listener is not ready yet");
- return 0;
- }
-
int ret = 1;
int status;
beyond_event_info event = {
}
}
- JNIEnv *env = nullptr;
- int JNIStatus = inst->jvm->GetEnv((void **)(&env), JNI_VERSION_1_4);
- if (JNIStatus == JNI_OK) {
- // NOTE:
- // Now, publish the event object to the event listener
- status = inst->InvokeEventListener(env, inst->thiz, event.type, event.data);
- if (status < 0) {
- ErrPrint("Failed to invoke the event listener");
- }
- } else if (JNIStatus == JNI_EDETACHED) {
- if (inst->jvm->AttachCurrentThread(&env, nullptr) == 0) {
+ if (inst->listener != nullptr) {
+ JNIEnv *env = nullptr;
+ int JNIStatus = inst->jvm->GetEnv((void **)(&env), JNI_VERSION_1_4);
+ if (JNIStatus == JNI_OK) {
// NOTE:
// Now, publish the event object to the event listener
- status = inst->InvokeEventListener(env, inst->thiz, event.type, event.data);
+ status = inst->InvokeEventListener(env, event.type, event.data);
if (status < 0) {
ErrPrint("Failed to invoke the event listener");
}
-
- inst->jvm->DetachCurrentThread();
- } else {
- ErrPrint("Failed to attach current thread");
+ } else if (JNIStatus == JNI_EDETACHED) {
+ if (inst->jvm->AttachCurrentThread(&env, nullptr) == 0) {
+ // NOTE:
+ // Now, publish the event object to the event listener
+ status = inst->InvokeEventListener(env, event.type, event.data);
+ if (status < 0) {
+ ErrPrint("Failed to invoke the event listener");
+ }
+
+ inst->jvm->DetachCurrentThread();
+ } else {
+ ErrPrint("Failed to attach current thread");
+ }
+ } else if (JNIStatus == JNI_EVERSION) {
+ ErrPrint("GetEnv: Unsupported version");
}
- } else if (JNIStatus == JNI_EVERSION) {
- ErrPrint("GetEnv: Unsupported version");
+ } else {
+ DbgPrint("EventListener is not registered");
}
// NOTE:
return ret;
}
-jint DiscoveryNativeInterface::Java_com_samsung_android_beyond_discovery_Discovery_setEventListener(JNIEnv *env, jobject _thiz, jlong instance, jboolean flag)
+jint DiscoveryNativeInterface::Java_com_samsung_android_beyond_discovery_Discovery_setEventListener(JNIEnv *env, jobject _thiz, jlong instance, jobject listener)
{
auto inst = reinterpret_cast<DiscoveryNativeInterface *>(instance);
if (inst == nullptr || inst->discovery == nullptr) {
return -EFAULT;
}
- if (flag == JNI_TRUE) {
- inst->thiz = env->NewGlobalRef(_thiz);
- if (inst->thiz == nullptr) {
+ if (inst->listener != nullptr) {
+ env->DeleteGlobalRef(inst->listener);
+ inst->listener = nullptr;
+ }
+
+ if (listener != nullptr) {
+ inst->listener = env->NewGlobalRef(listener);
+ if (inst->listener == nullptr) {
ErrPrint("Failed to get a global reference");
return -EFAULT;
}
- } else if (inst->thiz == _thiz) {
- env->DeleteGlobalRef(inst->thiz);
- inst->thiz = nullptr;
- } else {
- ErrPrint("This object corrupted");
- return -EFAULT;
}
-
return 0;
}
{ "setItem", "(JLjava/lang/String;[B)I", reinterpret_cast<void *>(Java_com_samsung_android_beyond_discovery_Discovery_setItem) },
{ "removeItem", "(JLjava/lang/String;)I", reinterpret_cast<void *>(Java_com_samsung_android_beyond_discovery_Discovery_removeItem) },
{ "configure", "(JCLjava/lang/Object;)I", reinterpret_cast<void *>((int (*)(JNIEnv *, jobject, jlong, jchar, jobject))Java_com_samsung_android_beyond_discovery_Discovery_configure) },
- { "setEventListener", "(JZ)I", reinterpret_cast<void *>(Java_com_samsung_android_beyond_discovery_Discovery_setEventListener) },
+ { "setEventListener", "(J" BEYOND_EVENT_LISTENER_CLASS_TYPE ")I", reinterpret_cast<void *>(Java_com_samsung_android_beyond_discovery_Discovery_setEventListener) },
};
jclass klass = env->FindClass("com/samsung/android/beyond/discovery/Discovery");
private:
static void initializeEventObject(JNIEnv *env, jclass klass);
static void initializeInfo(JNIEnv *env, jclass klass);
- jobject NewEventObject(JNIEnv *env, jobject thiz, void *eventData);
+ jobject NewEventObject(JNIEnv *env, void *eventData);
private:
static void Java_com_samsung_android_beyond_discovery_Discovery_initialize(JNIEnv *env, jclass klass);
static jint Java_com_samsung_android_beyond_discovery_Discovery_setItem(JNIEnv *env, jobject thiz, jlong instance, jstring key, jbyteArray value);
static jint Java_com_samsung_android_beyond_discovery_Discovery_removeItem(JNIEnv *env, jobject thiz, jlong instance, jstring key);
static jint Java_com_samsung_android_beyond_discovery_Discovery_configure(JNIEnv *env, jobject thiz, jlong inst, jchar type, jobject obj);
- static jint Java_com_samsung_android_beyond_discovery_Discovery_setEventListener(JNIEnv *env, jobject thiz, jlong instance, jboolean flag);
+ static jint Java_com_samsung_android_beyond_discovery_Discovery_setEventListener(JNIEnv *env, jobject thiz, jlong instance, jobject listener);
private:
static int Discovery_eventHandler(int fd, int events, void *data);
private: // JNI Cache
static EventObject eventObject;
- static jfieldID eventListener;
static Info infoObject;
private:
- int InvokeEventListener(JNIEnv *env, jobject thiz, int eventType, void *eventData);
+ int InvokeEventListener(JNIEnv *env, int eventType, void *eventData);
int AttachEventLoop(void);
private:
beyond::Discovery *discovery;
ALooper *looper;
JavaVM *jvm;
- jobject thiz;
+ jobject listener;
};
#endif // __BEYOND_ANDROID_DISCOVERY_JNI_H__