Extract common code for JNI
authorSung-jae Park <nicesj.park@samsung.com>
Wed, 27 Oct 2021 03:05:23 +0000 (12:05 +0900)
committerYoungjae Shin <yj99.shin@samsung.com>
Thu, 28 Oct 2021 10:52:41 +0000 (19:52 +0900)
[Problem] Getting ENV code is duplicated and spread every component
[Solution] Collect them to a method and reuse it for all other components

Change-Id: I10f90b0d3b2288a73c056e22016f352d246ea914
Signed-off-by: Sung-jae Park <nicesj.park@samsung.com>
subprojects/libbeyond-android/src/main/jni/JNIHelper.cc
subprojects/libbeyond-android/src/main/jni/JNIHelper.h
subprojects/libbeyond-android/src/main/jni/authenticator/beyond-authenticator_jni.cc
subprojects/libbeyond-android/src/main/jni/discovery/beyond-discovery_jni.cc

index d5b2387b8f4230908d48ca7a12c3e40338d7659b..7037bebe16df1c1b2ae97795754833b08edc856a 100644 (file)
@@ -106,3 +106,37 @@ void JNIHelper::checkEnvException(JNIEnv *env)
         throw std::exception();
     }
 }
+
+int JNIHelper::ExecuteWithEnv(JavaVM *jvm, const std::function<int(JNIEnv *, void *)> &callback, void *data)
+{
+    if (jvm == nullptr) {
+        ErrPrint("Invalid arguments, jvm(%p)", jvm);
+        return -EINVAL;
+    }
+
+    JNIEnv *env = nullptr;
+
+    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");
+            return -EFAULT;
+        }
+    } else if (JNIStatus == JNI_EVERSION) {
+        ErrPrint("GetEnv: Unsupported version");
+        return -ENOTSUP;
+    }
+
+    if (env == nullptr) {
+        ErrPrint("Failed to get the environment object");
+        return -EFAULT;
+    }
+
+    int ret = callback(env, data);
+
+    if (JNIStatus == JNI_EDETACHED) {
+        jvm->DetachCurrentThread();
+    }
+
+    return ret;
+}
index 3c770fd19c7da375ea22c7d3e55c81846e18fe45..fc45ee9345c7bf40662dcbdba144ea29a1322f8e 100644 (file)
@@ -23,6 +23,7 @@
 #include <cerrno>
 #include <jni.h>
 #include <string>
+#include <functional>
 
 #define JNI_LONG_TYPE "J"
 #define JNI_OBJECT_TYPE "Ljava/lang/Object;"
@@ -53,6 +54,7 @@ public:
     static jclass FindClass(JNIEnv *env, const char *name);
     static jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *signature);
     static void checkEnvException(JNIEnv *env);
+    static int ExecuteWithEnv(JavaVM *jvm, const std::function<int(JNIEnv *, void *)> &callback, void *data = nullptr);
 
 private:
     JNIHelper(void);
index 5fd2ae7a59a299e3bb0131b42f64c0e490e4f9e4..53cb3c9052f1fc2cf274eed06b00eb800454adef 100644 (file)
@@ -85,32 +85,14 @@ AuthenticatorNativeInterface::~AuthenticatorNativeInterface(void)
     // It should be narrowed and simplified
     // otherwise, the destructor code should be separated
     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 {
+        JNIHelper::ExecuteWithEnv(jvm, [&](JNIEnv *env, void *data) -> int {
             // 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();
-        }
+            return 0;
+        });
     }
 
     jvm = nullptr;
@@ -269,35 +251,15 @@ int AuthenticatorNativeInterface::Authenticator_eventHandler(int fd, int events,
     }
 
     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;
-            }
-        } 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 {
+        JNIHelper::ExecuteWithEnv(inst->jvm, [inst, &event](JNIEnv *env, void *data) -> int {
             // NOTE:
             // Now, publish the event object to the event listener
-            status = inst->InvokeEventListener(env, event.type, event.data);
+            int status = inst->InvokeEventListener(env, event.type, event.data);
             if (status < 0) {
                 ErrPrint("Failed to invoke the event listener");
             }
-
-            if (attached == true) {
-                inst->jvm->DetachCurrentThread();
-            }
-        }
+            return status;
+        });
     } else {
         DbgPrint("Event listener is not registered");
     }
index 13af5a1f8d7176ceb81f10dd798096d5047ee0b9..a07b77e7d49e6b706f328be2e3185a853f5c92b9 100644 (file)
@@ -71,32 +71,14 @@ DiscoveryNativeInterface::~DiscoveryNativeInterface(void)
     }
 
     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 {
+        JNIHelper::ExecuteWithEnv(jvm, [&](JNIEnv *env, void *data) -> int {
             // 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();
-        }
+            return 0;
+        });
     }
 
     jvm = nullptr;
@@ -428,31 +410,15 @@ int DiscoveryNativeInterface::Discovery_eventHandler(int fd, int events, void *d
     }
 
     if (inst->listener != nullptr) {
-        JNIEnv *env = nullptr;
-        int JNIStatus = inst->jvm->GetEnv((void **)(&env), JNI_VERSION_1_4);
-        if (JNIStatus == JNI_OK) {
+        JNIHelper::ExecuteWithEnv(inst->jvm, [inst, &event](JNIEnv *env, void *data) -> int {
             // NOTE:
             // Now, publish the event object to the event listener
-            status = inst->InvokeEventListener(env, event.type, event.data);
+            int status = inst->InvokeEventListener(env, 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) {
-                // 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");
-        }
+            return status;
+        });
     } else {
         DbgPrint("EventListener is not registered");
     }