aboutsummaryrefslogtreecommitdiffstats
path: root/JNIHelp.cpp
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-11-11 21:24:56 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-11-11 21:24:56 +0000
commit5b211f8cd277b2797ccadb2d3b94fddb35b9f155 (patch)
tree0e1feaa1d877c9f624d1dea63127295f53b34e8a /JNIHelp.cpp
parent721695a8babcce4bdad0fd7134a3f6ab0c059ada (diff)
parentfcb38946a79ccfde12654834e936f0dee2c73350 (diff)
downloadplatform_libnativehelper-android10-mainline-resolv-release.tar.gz
platform_libnativehelper-android10-mainline-resolv-release.tar.bz2
platform_libnativehelper-android10-mainline-resolv-release.zip
Snap for 6001391 from fcb38946a79ccfde12654834e936f0dee2c73350 to qt-aml-resolv-releaseandroid-mainline-10.0.0_r8android10-mainline-resolv-release
Change-Id: Idb91a554fc5dda37e4d1bab3c8e6ed1bd87f86db
Diffstat (limited to 'JNIHelp.cpp')
-rw-r--r--JNIHelp.cpp211
1 files changed, 108 insertions, 103 deletions
diff --git a/JNIHelp.cpp b/JNIHelp.cpp
index 8432f7a..b57ec50 100644
--- a/JNIHelp.cpp
+++ b/JNIHelp.cpp
@@ -14,22 +14,23 @@
* limitations under the License.
*/
-#define LOG_TAG "JNIHelp"
-
#include "nativehelper/JNIHelp.h"
-#include "ALog-priv.h"
-
#include <string>
+#define LOG_TAG "JNIHelp"
+#include "ALog-priv.h"
+
+#include "jni.h"
#include "JniConstants.h"
-#include "nativehelper/ScopedLocalRef.h"
+
+namespace {
/**
* Equivalent to ScopedLocalRef, but for C_JNIEnv instead. (And slightly more powerful.)
*/
template<typename T>
-class scoped_local_ref {
+class scoped_local_ref final {
public:
explicit scoped_local_ref(C_JNIEnv* env, T localRef = NULL)
: mEnv(env), mLocalRef(localRef)
@@ -52,42 +53,28 @@ public:
}
private:
+ // scoped_local_ref does not support copy or move semantics.
+ scoped_local_ref(const scoped_local_ref&) = delete;
+ scoped_local_ref(scoped_local_ref&&) = delete;
+ scoped_local_ref& operator=(const scoped_local_ref&) = delete;
+ scoped_local_ref& operator=(scoped_local_ref&&) = delete;
+
+private:
C_JNIEnv* const mEnv;
T mLocalRef;
-
- DISALLOW_COPY_AND_ASSIGN(scoped_local_ref);
};
-static jclass findClass(C_JNIEnv* env, const char* className) {
+jclass findClass(C_JNIEnv* env, const char* className) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
return (*env)->FindClass(e, className);
}
-MODULE_API int jniRegisterNativeMethods(C_JNIEnv* env, const char* className,
- const JNINativeMethod* gMethods, int numMethods)
-{
- JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
-
- ALOGV("Registering %s's %d native methods...", className, numMethods);
-
- scoped_local_ref<jclass> c(env, findClass(env, className));
- ALOG_ALWAYS_FATAL_IF(c.get() == NULL,
- "Native registration unable to find class '%s'; aborting...",
- className);
-
- int result = e->RegisterNatives(c.get(), gMethods, numMethods);
- ALOG_ALWAYS_FATAL_IF(result < 0, "RegisterNatives failed for '%s'; aborting...",
- className);
-
- return 0;
-}
-
/*
* Returns a human-readable summary of an exception object. The buffer will
* be populated with the "binary" class name and, if present, the
* exception message.
*/
-static bool getExceptionSummary(C_JNIEnv* env, jthrowable exception, std::string& result) {
+bool getExceptionSummary(C_JNIEnv* env, jthrowable exception, std::string& result) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
/* get the name of the exception's class */
@@ -138,7 +125,7 @@ static bool getExceptionSummary(C_JNIEnv* env, jthrowable exception, std::string
/*
* Returns an exception (with stack trace) as a string.
*/
-static bool getStackTrace(C_JNIEnv* env, jthrowable exception, std::string& result) {
+bool getStackTrace(C_JNIEnv* env, jthrowable exception, std::string& result) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
scoped_local_ref<jclass> stringWriterClass(env, findClass(env, "java/io/StringWriter"));
@@ -196,58 +183,7 @@ static bool getStackTrace(C_JNIEnv* env, jthrowable exception, std::string& resu
return true;
}
-MODULE_API int jniThrowException(C_JNIEnv* env, const char* className, const char* msg) {
- JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
-
- if ((*env)->ExceptionCheck(e)) {
- /* TODO: consider creating the new exception with this as "cause" */
- scoped_local_ref<jthrowable> exception(env, (*env)->ExceptionOccurred(e));
- (*env)->ExceptionClear(e);
-
- if (exception.get() != NULL) {
- std::string text;
- getExceptionSummary(env, exception.get(), text);
- ALOGW("Discarding pending exception (%s) to throw %s", text.c_str(), className);
- }
- }
-
- scoped_local_ref<jclass> exceptionClass(env, findClass(env, className));
- if (exceptionClass.get() == NULL) {
- ALOGE("Unable to find exception class %s", className);
- /* ClassNotFoundException now pending */
- return -1;
- }
-
- if ((*env)->ThrowNew(e, exceptionClass.get(), msg) != JNI_OK) {
- ALOGE("Failed throwing '%s' '%s'", className, msg);
- /* an exception, most likely OOM, will now be pending */
- return -1;
- }
-
- return 0;
-}
-
-MODULE_API int jniThrowExceptionFmt(C_JNIEnv* env, const char* className, const char* fmt, va_list args) {
- char msgBuf[512];
- vsnprintf(msgBuf, sizeof(msgBuf), fmt, args);
- return jniThrowException(env, className, msgBuf);
-}
-
-MODULE_API int jniThrowNullPointerException(C_JNIEnv* env, const char* msg) {
- return jniThrowException(env, "java/lang/NullPointerException", msg);
-}
-
-MODULE_API int jniThrowRuntimeException(C_JNIEnv* env, const char* msg) {
- return jniThrowException(env, "java/lang/RuntimeException", msg);
-}
-
-MODULE_API int jniThrowIOException(C_JNIEnv* env, int errnum) {
- char buffer[80];
- const char* message = jniStrError(errnum, buffer, sizeof(buffer));
- return jniThrowException(env, "java/io/IOException", message);
-}
-
-static std::string jniGetStackTrace(C_JNIEnv* env, jthrowable exception) {
+std::string jniGetStackTrace(C_JNIEnv* env, jthrowable exception) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
scoped_local_ref<jthrowable> currentException(env, (*env)->ExceptionOccurred(e));
@@ -275,18 +211,12 @@ static std::string jniGetStackTrace(C_JNIEnv* env, jthrowable exception) {
return trace;
}
-MODULE_API void jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable exception) {
- std::string trace(jniGetStackTrace(env, exception));
- __android_log_write(priority, tag, trace.c_str());
-}
-
// Note: glibc has a nonstandard strerror_r that returns char* rather than POSIX's int.
// char *strerror_r(int errnum, char *buf, size_t n);
//
// Some versions of bionic support the glibc style call. Since the set of defines that determine
// which version is used is byzantine in its complexity we will just use this C++ template hack to
// select the correct jniStrError implementation based on the libc being used.
-namespace impl {
using GNUStrError = char* (*)(int,char*,size_t);
using POSIXStrError = int (*)(int,char*,size_t);
@@ -306,20 +236,95 @@ inline const char* realJniStrError(POSIXStrError func, int errnum, char* buf, si
return buf;
}
-} // namespace impl
+} // namespace
+
+int jniRegisterNativeMethods(C_JNIEnv* env, const char* className,
+ const JNINativeMethod* gMethods, int numMethods)
+{
+ JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
+
+ ALOGV("Registering %s's %d native methods...", className, numMethods);
+
+ scoped_local_ref<jclass> c(env, findClass(env, className));
+ ALOG_ALWAYS_FATAL_IF(c.get() == NULL,
+ "Native registration unable to find class '%s'; aborting...",
+ className);
+
+ int result = e->RegisterNatives(c.get(), gMethods, numMethods);
+ ALOG_ALWAYS_FATAL_IF(result < 0, "RegisterNatives failed for '%s'; aborting...",
+ className);
+
+ return 0;
+}
+
+int jniThrowException(C_JNIEnv* env, const char* className, const char* msg) {
+ JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
+
+ if ((*env)->ExceptionCheck(e)) {
+ /* TODO: consider creating the new exception with this as "cause" */
+ scoped_local_ref<jthrowable> exception(env, (*env)->ExceptionOccurred(e));
+ (*env)->ExceptionClear(e);
+
+ if (exception.get() != NULL) {
+ std::string text;
+ getExceptionSummary(env, exception.get(), text);
+ ALOGW("Discarding pending exception (%s) to throw %s", text.c_str(), className);
+ }
+ }
+
+ scoped_local_ref<jclass> exceptionClass(env, findClass(env, className));
+ if (exceptionClass.get() == NULL) {
+ ALOGE("Unable to find exception class %s", className);
+ /* ClassNotFoundException now pending */
+ return -1;
+ }
+
+ if ((*env)->ThrowNew(e, exceptionClass.get(), msg) != JNI_OK) {
+ ALOGE("Failed throwing '%s' '%s'", className, msg);
+ /* an exception, most likely OOM, will now be pending */
+ return -1;
+ }
+
+ return 0;
+}
+
+int jniThrowExceptionFmt(C_JNIEnv* env, const char* className, const char* fmt, va_list args) {
+ char msgBuf[512];
+ vsnprintf(msgBuf, sizeof(msgBuf), fmt, args);
+ return jniThrowException(env, className, msgBuf);
+}
+
+int jniThrowNullPointerException(C_JNIEnv* env, const char* msg) {
+ return jniThrowException(env, "java/lang/NullPointerException", msg);
+}
+
+int jniThrowRuntimeException(C_JNIEnv* env, const char* msg) {
+ return jniThrowException(env, "java/lang/RuntimeException", msg);
+}
+
+int jniThrowIOException(C_JNIEnv* env, int errnum) {
+ char buffer[80];
+ const char* message = jniStrError(errnum, buffer, sizeof(buffer));
+ return jniThrowException(env, "java/io/IOException", message);
+}
+
+void jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable exception) {
+ std::string trace(jniGetStackTrace(env, exception));
+ __android_log_write(priority, tag, trace.c_str());
+}
-MODULE_API const char* jniStrError(int errnum, char* buf, size_t buflen) {
+const char* jniStrError(int errnum, char* buf, size_t buflen) {
#ifdef _WIN32
strerror_s(buf, buflen, errnum);
return buf;
#else
// The magic of C++ overloading selects the correct implementation based on the declared type of
// strerror_r. The inline will ensure that we don't have any indirect calls.
- return impl::realJniStrError(strerror_r, errnum, buf, buflen);
+ return realJniStrError(strerror_r, errnum, buf, buflen);
#endif
}
-MODULE_API jobject jniCreateFileDescriptor(C_JNIEnv* env, int fd) {
+jobject jniCreateFileDescriptor(C_JNIEnv* env, int fd) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
jobject fileDescriptor = e->NewObject(JniConstants::GetFileDescriptorClass(e),
JniConstants::GetFileDescriptorInitMethod(e));
@@ -331,7 +336,7 @@ MODULE_API jobject jniCreateFileDescriptor(C_JNIEnv* env, int fd) {
return fileDescriptor;
}
-MODULE_API int jniGetFDFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor) {
+int jniGetFDFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
if (fileDescriptor != nullptr) {
return e->GetIntField(fileDescriptor,
@@ -341,7 +346,7 @@ MODULE_API int jniGetFDFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor)
}
}
-MODULE_API void jniSetFileDescriptorOfFD(C_JNIEnv* env, jobject fileDescriptor, int value) {
+void jniSetFileDescriptorOfFD(C_JNIEnv* env, jobject fileDescriptor, int value) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
if (fileDescriptor == nullptr) {
jniThrowNullPointerException(e, "null FileDescriptor");
@@ -350,12 +355,12 @@ MODULE_API void jniSetFileDescriptorOfFD(C_JNIEnv* env, jobject fileDescriptor,
}
}
-MODULE_API jlong jniGetOwnerIdFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor) {
+jlong jniGetOwnerIdFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
return e->GetLongField(fileDescriptor, JniConstants::GetFileDescriptorOwnerIdField(e));
}
-MODULE_API jarray jniGetNioBufferBaseArray(C_JNIEnv* env, jobject nioBuffer) {
+jarray jniGetNioBufferBaseArray(C_JNIEnv* env, jobject nioBuffer) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
jclass nioAccessClass = JniConstants::GetNioAccessClass(e);
jmethodID getBaseArrayMethod = JniConstants::GetNioAccessGetBaseArrayMethod(e);
@@ -363,14 +368,14 @@ MODULE_API jarray jniGetNioBufferBaseArray(C_JNIEnv* env, jobject nioBuffer) {
return static_cast<jarray>(object);
}
-MODULE_API int jniGetNioBufferBaseArrayOffset(C_JNIEnv* env, jobject nioBuffer) {
+int jniGetNioBufferBaseArrayOffset(C_JNIEnv* env, jobject nioBuffer) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
jclass nioAccessClass = JniConstants::GetNioAccessClass(e);
jmethodID getBaseArrayOffsetMethod = JniConstants::GetNioAccessGetBaseArrayOffsetMethod(e);
return e->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetMethod, nioBuffer);
}
-MODULE_API jlong jniGetNioBufferPointer(C_JNIEnv* env, jobject nioBuffer) {
+jlong jniGetNioBufferPointer(C_JNIEnv* env, jobject nioBuffer) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
jlong baseAddress = e->GetLongField(nioBuffer, JniConstants::GetNioBufferAddressField(e));
if (baseAddress != 0) {
@@ -382,8 +387,8 @@ MODULE_API jlong jniGetNioBufferPointer(C_JNIEnv* env, jobject nioBuffer) {
return baseAddress;
}
-MODULE_API jlong jniGetNioBufferFields(C_JNIEnv* env, jobject nioBuffer,
- jint* position, jint* limit, jint* elementSizeShift) {
+jlong jniGetNioBufferFields(C_JNIEnv* env, jobject nioBuffer,
+ jint* position, jint* limit, jint* elementSizeShift) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
*position = e->GetIntField(nioBuffer, JniConstants::GetNioBufferPositionField(e));
*limit = e->GetIntField(nioBuffer, JniConstants::GetNioBufferLimitField(e));
@@ -392,16 +397,16 @@ MODULE_API jlong jniGetNioBufferFields(C_JNIEnv* env, jobject nioBuffer,
return e->GetLongField(nioBuffer, JniConstants::GetNioBufferAddressField(e));
}
-MODULE_API jobject jniGetReferent(C_JNIEnv* env, jobject ref) {
+jobject jniGetReferent(C_JNIEnv* env, jobject ref) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
return e->CallObjectMethod(ref, JniConstants::GetReferenceGetMethod(e));
}
-MODULE_API jstring jniCreateString(C_JNIEnv* env, const jchar* unicodeChars, jsize len) {
+jstring jniCreateString(C_JNIEnv* env, const jchar* unicodeChars, jsize len) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
return e->NewString(unicodeChars, len);
}
-MODULE_API void jniUninitializeConstants() {
+void jniUninitializeConstants() {
JniConstants::Uninitialize();
}