Add a helper to get the referent of a Reference.
Change-Id: I8ac5a69fab563e220d48c94e254f5ed3055abe5f
diff --git a/JNIHelp.cpp b/JNIHelp.cpp
index 4430c56..bc0b49c 100644
--- a/JNIHelp.cpp
+++ b/JNIHelp.cpp
@@ -306,11 +306,15 @@
}
}
-static struct CachedFields {
- jclass fileDescriptorClass;
- jmethodID fileDescriptorCtor;
- jfieldID descriptorField;
-} gCachedFields;
+static struct {
+ jclass clazz;
+ jmethodID ctor;
+ jfieldID descriptor;
+} gFileDescriptorClassInfo;
+
+static struct {
+ jmethodID get;
+} gReferenceClassInfo;
jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv* env;
@@ -319,21 +323,31 @@
abort();
}
- gCachedFields.fileDescriptorClass =
+ gFileDescriptorClassInfo.clazz =
reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass("java/io/FileDescriptor")));
- if (gCachedFields.fileDescriptorClass == NULL) {
+ if (gFileDescriptorClassInfo.clazz == NULL) {
abort();
}
- gCachedFields.fileDescriptorCtor =
- env->GetMethodID(gCachedFields.fileDescriptorClass, "<init>", "()V");
- if (gCachedFields.fileDescriptorCtor == NULL) {
+ gFileDescriptorClassInfo.ctor =
+ env->GetMethodID(gFileDescriptorClassInfo.clazz, "<init>", "()V");
+ if (gFileDescriptorClassInfo.ctor == NULL) {
abort();
}
- gCachedFields.descriptorField =
- env->GetFieldID(gCachedFields.fileDescriptorClass, "descriptor", "I");
- if (gCachedFields.descriptorField == NULL) {
+ gFileDescriptorClassInfo.descriptor =
+ env->GetFieldID(gFileDescriptorClassInfo.clazz, "descriptor", "I");
+ if (gFileDescriptorClassInfo.descriptor == NULL) {
+ abort();
+ }
+
+ jclass clazz = reinterpret_cast<jclass>(env->FindClass("java/lang/ref/Reference"));
+ if (clazz == NULL) {
+ abort();
+ }
+
+ gReferenceClassInfo.get = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");
+ if (gReferenceClassInfo.get == NULL) {
abort();
}
@@ -343,19 +357,24 @@
jobject jniCreateFileDescriptor(C_JNIEnv* env, int fd) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
jobject fileDescriptor = (*env)->NewObject(e,
- gCachedFields.fileDescriptorClass, gCachedFields.fileDescriptorCtor);
+ gFileDescriptorClassInfo.clazz, gFileDescriptorClassInfo.ctor);
jniSetFileDescriptorOfFD(env, fileDescriptor, fd);
return fileDescriptor;
}
int jniGetFDFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
- return (*env)->GetIntField(e, fileDescriptor, gCachedFields.descriptorField);
+ return (*env)->GetIntField(e, fileDescriptor, gFileDescriptorClassInfo.descriptor);
}
void jniSetFileDescriptorOfFD(C_JNIEnv* env, jobject fileDescriptor, int value) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
- (*env)->SetIntField(e, fileDescriptor, gCachedFields.descriptorField, value);
+ (*env)->SetIntField(e, fileDescriptor, gFileDescriptorClassInfo.descriptor, value);
+}
+
+jobject jniGetReferent(C_JNIEnv* env, jobject ref) {
+ JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
+ return (*env)->CallObjectMethod(e, ref, gReferenceClassInfo.get);
}
/*
diff --git a/include/nativehelper/JNIHelp.h b/include/nativehelper/JNIHelp.h
index 446a710..2fadcdf 100644
--- a/include/nativehelper/JNIHelp.h
+++ b/include/nativehelper/JNIHelp.h
@@ -97,6 +97,11 @@
void jniSetFileDescriptorOfFD(C_JNIEnv* env, jobject fileDescriptor, int value);
/*
+ * Returns the reference from a java.lang.ref.Reference.
+ */
+jobject jniGetReferent(C_JNIEnv* env, jobject ref);
+
+/*
* Log a message and an exception.
* If exception is NULL, logs the current exception in the JNI environment.
*/
@@ -157,6 +162,10 @@
jniSetFileDescriptorOfFD(&env->functions, fileDescriptor, value);
}
+inline jobject jniGetReferent(JNIEnv* env, jobject ref) {
+ return jniGetReferent(&env->functions, ref);
+}
+
inline void jniLogException(JNIEnv* env, int priority, const char* tag, jthrowable exception = NULL) {
jniLogException(&env->functions, priority, tag, exception);
}