Imported Upstream version 6.0.1+r16

parents
/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NATIVEHELPER_ALOGPRIV_H_
#define NATIVEHELPER_ALOGPRIV_H_
#include <android/log.h>
#ifndef LOG_NDEBUG
#ifdef NDEBUG
#define LOG_NDEBUG 1
#else
#define LOG_NDEBUG 0
#endif
#endif
/*
* Basic log message macros intended to emulate the behavior of log/log.h
* in system core. This should be dependent only on ndk exposed logging
* functionality.
*/
#ifndef ALOG
#define ALOG(priority, tag, fmt...) \
__android_log_print(ANDROID_##priority, tag, fmt)
#endif
#ifndef ALOGV
#if LOG_NDEBUG
#define ALOGV(...) ((void)0)
#else
#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#endif
#endif
#ifndef ALOGD
#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#endif
#ifndef ALOGI
#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
#endif
#ifndef ALOGW
#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
#endif
#ifndef ALOGE
#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
#endif
#endif
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH := $(call my-dir)
local_src_files := \
JNIHelp.cpp \
JniConstants.cpp \
toStringArray.cpp
#
# Build for the target (device).
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
$(local_src_files) \
JniInvocation.cpp
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libnativehelper
LOCAL_CLANG := true
LOCAL_CFLAGS := -Werror -fvisibility=protected
LOCAL_C_INCLUDES := libcore/include
LOCAL_SHARED_LIBRARIES += libcutils libdl
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_SHARED_LIBRARY)
#
# NDK-only build for the target (device), using libc++.
# - Relies only on NDK exposed functionality.
# - This doesn't include JniInvocation.
#
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libnativehelper_compat_libc++
LOCAL_CLANG := true
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include/nativehelper
LOCAL_EXPORT_C_INCLUDE_DIRS := \
$(LOCAL_PATH)/include/nativehelper
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := $(local_src_files)
LOCAL_LDFLAGS := -llog -ldl
LOCAL_SDK_VERSION := 19
LOCAL_NDK_STL_VARIANT := c++_static
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_SHARED_LIBRARY)
#
# Build for the host.
#
include $(CLEAR_VARS)
LOCAL_MODULE := libnativehelper
LOCAL_MODULE_TAGS := optional
LOCAL_CLANG := true
LOCAL_SRC_FILES := \
$(local_src_files) \
JniInvocation.cpp
LOCAL_CFLAGS := -Werror -fvisibility=protected
LOCAL_C_INCLUDES := libcore/include
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_LDFLAGS := -ldl
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MULTILIB := both
include $(BUILD_HOST_SHARED_LIBRARY)
#
# Tests.
#
include $(LOCAL_PATH)/tests/Android.mk
This diff is collapsed.
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "JniConstants"
#include "ALog-priv.h"
#include "JniConstants.h"
#include "ScopedLocalRef.h"
#include <stdlib.h>
jclass JniConstants::bidiRunClass;
jclass JniConstants::bigDecimalClass;
jclass JniConstants::booleanClass;
jclass JniConstants::byteArrayClass;
jclass JniConstants::byteClass;
jclass JniConstants::calendarClass;
jclass JniConstants::characterClass;
jclass JniConstants::charsetICUClass;
jclass JniConstants::constructorClass;
jclass JniConstants::deflaterClass;
jclass JniConstants::doubleClass;
jclass JniConstants::errnoExceptionClass;
jclass JniConstants::fieldClass;
jclass JniConstants::fieldPositionIteratorClass;
jclass JniConstants::fileDescriptorClass;
jclass JniConstants::floatClass;
jclass JniConstants::gaiExceptionClass;
jclass JniConstants::inet6AddressClass;
jclass JniConstants::inetAddressClass;
jclass JniConstants::inetSocketAddressClass;
jclass JniConstants::inetUnixAddressClass;
jclass JniConstants::inflaterClass;
jclass JniConstants::inputStreamClass;
jclass JniConstants::integerClass;
jclass JniConstants::localeDataClass;
jclass JniConstants::longClass;
jclass JniConstants::methodClass;
jclass JniConstants::mutableIntClass;
jclass JniConstants::mutableLongClass;
jclass JniConstants::netlinkSocketAddressClass;
jclass JniConstants::objectClass;
jclass JniConstants::objectArrayClass;
jclass JniConstants::outputStreamClass;
jclass JniConstants::packetSocketAddressClass;
jclass JniConstants::parsePositionClass;
jclass JniConstants::patternSyntaxExceptionClass;
jclass JniConstants::realToStringClass;
jclass JniConstants::referenceClass;
jclass JniConstants::shortClass;
jclass JniConstants::socketClass;
jclass JniConstants::socketImplClass;
jclass JniConstants::stringClass;
jclass JniConstants::structAddrinfoClass;
jclass JniConstants::structFlockClass;
jclass JniConstants::structGroupReqClass;
jclass JniConstants::structGroupSourceReqClass;
jclass JniConstants::structLingerClass;
jclass JniConstants::structPasswdClass;
jclass JniConstants::structPollfdClass;
jclass JniConstants::structStatClass;
jclass JniConstants::structStatVfsClass;
jclass JniConstants::structTimevalClass;
jclass JniConstants::structUcredClass;
jclass JniConstants::structUtsnameClass;
jclass JniConstants::zipEntryClass;
static jclass findClass(JNIEnv* env, const char* name) {
ScopedLocalRef<jclass> localClass(env, env->FindClass(name));
jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
if (result == NULL) {
ALOGE("failed to find class '%s'", name);
abort();
}
return result;
}
void JniConstants::init(JNIEnv* env) {
bidiRunClass = findClass(env, "java/text/Bidi$Run");
bigDecimalClass = findClass(env, "java/math/BigDecimal");
booleanClass = findClass(env, "java/lang/Boolean");
byteClass = findClass(env, "java/lang/Byte");
byteArrayClass = findClass(env, "[B");
calendarClass = findClass(env, "java/util/Calendar");
characterClass = findClass(env, "java/lang/Character");
charsetICUClass = findClass(env, "java/nio/charset/CharsetICU");
constructorClass = findClass(env, "java/lang/reflect/Constructor");
floatClass = findClass(env, "java/lang/Float");
deflaterClass = findClass(env, "java/util/zip/Deflater");
doubleClass = findClass(env, "java/lang/Double");
errnoExceptionClass = findClass(env, "android/system/ErrnoException");
fieldClass = findClass(env, "java/lang/reflect/Field");
fieldPositionIteratorClass = findClass(env, "libcore/icu/NativeDecimalFormat$FieldPositionIterator");
fileDescriptorClass = findClass(env, "java/io/FileDescriptor");
gaiExceptionClass = findClass(env, "android/system/GaiException");
inet6AddressClass = findClass(env, "java/net/Inet6Address");
inetAddressClass = findClass(env, "java/net/InetAddress");
inetSocketAddressClass = findClass(env, "java/net/InetSocketAddress");
inetUnixAddressClass = findClass(env, "java/net/InetUnixAddress");
inflaterClass = findClass(env, "java/util/zip/Inflater");
inputStreamClass = findClass(env, "java/io/InputStream");
integerClass = findClass(env, "java/lang/Integer");
localeDataClass = findClass(env, "libcore/icu/LocaleData");
longClass = findClass(env, "java/lang/Long");
methodClass = findClass(env, "java/lang/reflect/Method");
mutableIntClass = findClass(env, "android/util/MutableInt");
mutableLongClass = findClass(env, "android/util/MutableLong");
netlinkSocketAddressClass = findClass(env, "android/system/NetlinkSocketAddress");
objectClass = findClass(env, "java/lang/Object");
objectArrayClass = findClass(env, "[Ljava/lang/Object;");
outputStreamClass = findClass(env, "java/io/OutputStream");
packetSocketAddressClass = findClass(env, "android/system/PacketSocketAddress");
parsePositionClass = findClass(env, "java/text/ParsePosition");
patternSyntaxExceptionClass = findClass(env, "java/util/regex/PatternSyntaxException");
realToStringClass = findClass(env, "java/lang/RealToString");
referenceClass = findClass(env, "java/lang/ref/Reference");
shortClass = findClass(env, "java/lang/Short");
socketClass = findClass(env, "java/net/Socket");
socketImplClass = findClass(env, "java/net/SocketImpl");
stringClass = findClass(env, "java/lang/String");
structAddrinfoClass = findClass(env, "android/system/StructAddrinfo");
structFlockClass = findClass(env, "android/system/StructFlock");
structGroupReqClass = findClass(env, "android/system/StructGroupReq");
structGroupSourceReqClass = findClass(env, "android/system/StructGroupSourceReq");
structLingerClass = findClass(env, "android/system/StructLinger");
structPasswdClass = findClass(env, "android/system/StructPasswd");
structPollfdClass = findClass(env, "android/system/StructPollfd");
structStatClass = findClass(env, "android/system/StructStat");
structStatVfsClass = findClass(env, "android/system/StructStatVfs");
structTimevalClass = findClass(env, "android/system/StructTimeval");
structUcredClass = findClass(env, "android/system/StructUcred");
structUtsnameClass = findClass(env, "android/system/StructUtsname");
zipEntryClass = findClass(env, "java/util/zip/ZipEntry");
}
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "JniInvocation.h"
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <cstddef>
#define LOG_TAG "JniInvocation"
#include "cutils/log.h"
#ifdef HAVE_ANDROID_OS
#include "cutils/properties.h"
#endif
JniInvocation* JniInvocation::jni_invocation_ = NULL;
JniInvocation::JniInvocation() :
handle_(NULL),
JNI_GetDefaultJavaVMInitArgs_(NULL),
JNI_CreateJavaVM_(NULL),
JNI_GetCreatedJavaVMs_(NULL) {
LOG_ALWAYS_FATAL_IF(jni_invocation_ != NULL, "JniInvocation instance already initialized");
jni_invocation_ = this;
}
JniInvocation::~JniInvocation() {
jni_invocation_ = NULL;
if (handle_ != NULL) {
dlclose(handle_);
}
}
#ifdef HAVE_ANDROID_OS
static const char* kLibrarySystemProperty = "persist.sys.dalvik.vm.lib.2";
static const char* kDebuggableSystemProperty = "ro.debuggable";
static const char* kDebuggableFallback = "0"; // Not debuggable.
#endif
static const char* kLibraryFallback = "libart.so";
template<typename T> void UNUSED(const T&) {}
const char* JniInvocation::GetLibrary(const char* library, char* buffer) {
#ifdef HAVE_ANDROID_OS
const char* default_library;
char debuggable[PROPERTY_VALUE_MAX];
property_get(kDebuggableSystemProperty, debuggable, kDebuggableFallback);
if (strcmp(debuggable, "1") != 0) {
// Not a debuggable build.
// Do not allow arbitrary library. Ignore the library parameter. This
// will also ignore the default library, but initialize to fallback
// for cleanliness.
library = kLibraryFallback;
default_library = kLibraryFallback;
} else {
// Debuggable build.
// Accept the library parameter. For the case it is NULL, load the default
// library from the system property.
if (buffer != NULL) {
property_get(kLibrarySystemProperty, buffer, kLibraryFallback);
default_library = buffer;
} else {
// No buffer given, just use default fallback.
default_library = kLibraryFallback;
}
}
#else
UNUSED(buffer);
const char* default_library = kLibraryFallback;
#endif
if (library == NULL) {
library = default_library;
}
return library;
}
bool JniInvocation::Init(const char* library) {
#ifdef HAVE_ANDROID_OS
char buffer[PROPERTY_VALUE_MAX];
#else
char* buffer = NULL;
#endif
library = GetLibrary(library, buffer);
handle_ = dlopen(library, RTLD_NOW);
if (handle_ == NULL) {
if (strcmp(library, kLibraryFallback) == 0) {
// Nothing else to try.
ALOGE("Failed to dlopen %s: %s", library, dlerror());
return false;
}
// Note that this is enough to get something like the zygote
// running, we can't property_set here to fix this for the future
// because we are root and not the system user. See
// RuntimeInit.commonInit for where we fix up the property to
// avoid future fallbacks. http://b/11463182
ALOGW("Falling back from %s to %s after dlopen error: %s",
library, kLibraryFallback, dlerror());
library = kLibraryFallback;
handle_ = dlopen(library, RTLD_NOW);
if (handle_ == NULL) {
ALOGE("Failed to dlopen %s: %s", library, dlerror());
return false;
}
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
"JNI_GetDefaultJavaVMInitArgs")) {
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
"JNI_CreateJavaVM")) {
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),
"JNI_GetCreatedJavaVMs")) {
return false;
}
return true;
}
jint JniInvocation::JNI_GetDefaultJavaVMInitArgs(void* vmargs) {
return JNI_GetDefaultJavaVMInitArgs_(vmargs);
}
jint JniInvocation::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
return JNI_CreateJavaVM_(p_vm, p_env, vm_args);
}
jint JniInvocation::JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) {
return JNI_GetCreatedJavaVMs_(vms, size, vm_count);
}
bool JniInvocation::FindSymbol(void** pointer, const char* symbol) {
*pointer = dlsym(handle_, symbol);
if (*pointer == NULL) {
ALOGE("Failed to find symbol %s: %s\n", symbol, dlerror());
dlclose(handle_);
handle_ = NULL;
return false;
}
return true;
}
JniInvocation& JniInvocation::GetJniInvocation() {
LOG_ALWAYS_FATAL_IF(jni_invocation_ == NULL,
"Failed to create JniInvocation instance before using JNI invocation API");
return *jni_invocation_;
}
extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) {
return JniInvocation::GetJniInvocation().JNI_GetDefaultJavaVMInitArgs(vm_args);
}
extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
return JniInvocation::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);
}
extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) {
return JniInvocation::GetJniInvocation().JNI_GetCreatedJavaVMs(vms, size, vm_count);
}
This diff is collapsed.
Support functions for Android's class libraries
These are VM-agnostic native functions that implement methods for system
class libraries. All code here:
- MUST not be associated with an android.* class (that code lives in
frameworks/base/).
- SHOULD be written in C rather than C++ where possible.
Some helper functions are defined in include/nativehelper/JNIHelp.h.
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* JNI helper functions.
*
* This file may be included by C or C++ code, which is trouble because jni.h
* uses different typedefs for JNIEnv in each language.
*
* TODO: remove C support.
*/
#ifndef NATIVEHELPER_JNIHELP_H_
#define NATIVEHELPER_JNIHELP_H_
#include "jni.h"
#include <errno.h>
#include <unistd.h>
#ifndef NELEM
# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Register one or more native methods with a particular class.
* "className" looks like "java/lang/String". Aborts on failure.
* TODO: fix all callers and change the return type to void.
*/
int jniRegisterNativeMethods(C_JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods);
/*
* Throw an exception with the specified class and an optional message.
*
* The "className" argument will be passed directly to FindClass, which
* takes strings with slashes (e.g. "java/lang/Object").
*
* If an exception is currently pending, we log a warning message and
* clear it.
*
* Returns 0 on success, nonzero if something failed (e.g. the exception
* class couldn't be found, so *an* exception will still be pending).
*
* Currently aborts the VM if it can't throw the exception.
*/
int jniThrowException(C_JNIEnv* env, const char* className, const char* msg);
/*
* Throw a java.lang.NullPointerException, with an optional message.
*/
int jniThrowNullPointerException(C_JNIEnv* env, const char* msg);
/*
* Throw a java.lang.RuntimeException, with an optional message.
*/
int jniThrowRuntimeException(C_JNIEnv* env, const char* msg);
/*
* Throw a java.io.IOException, generating the message from errno.
*/
int jniThrowIOException(C_JNIEnv* env, int errnum);
/*
* Return a pointer to a locale-dependent error string explaining errno
* value 'errnum'. The returned pointer may or may not be equal to 'buf'.
* This function is thread-safe (unlike strerror) and portable (unlike
* strerror_r).
*/
const char* jniStrError(int errnum, char* buf, size_t buflen);
/*
* Returns a new java.io.FileDescriptor for the given int fd.
*/
jobject jniCreateFileDescriptor(C_JNIEnv* env, int fd);
/*
* Returns the int fd from a java.io.FileDescriptor.
*/
int jniGetFDFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor);
/*
* Sets the int fd in a java.io.FileDescriptor.
*/
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.
*/
void jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable exception);
#ifdef __cplusplus
}
#endif
/*
* For C++ code, we provide inlines that map to the C functions. g++ always
* inlines these, even on non-optimized builds.
*/
#if defined(__cplusplus)
inline int jniRegisterNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods) {
return jniRegisterNativeMethods(&env->functions, className, gMethods, numMethods);
}
inline int jniThrowException(JNIEnv* env, const char* className, const char* msg) {
return jniThrowException(&env->functions, className, msg);
}
extern "C" int jniThrowExceptionFmt(C_JNIEnv* env, const char* className, const char* fmt, va_list args);
/*
* Equivalent to jniThrowException but with a printf-like format string and
* variable-length argument list. This is only available in C++.
*/
inline int jniThrowExceptionFmt(JNIEnv* env, const char* className, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
return jniThrowExceptionFmt(&env->functions, className, fmt, args);
va_end(args);
}
inline int jniThrowNullPointerException(JNIEnv* env, const char* msg) {
return jniThrowNullPointerException(&env->functions, msg);
}
inline int jniThrowRuntimeException(JNIEnv* env, const char* msg) {
return jniThrowRuntimeException(&env->functions, msg);
}
inline int jniThrowIOException(JNIEnv* env, int errnum) {
return jniThrowIOException(&env->functions, errnum);
}
inline jobject jniCreateFileDescriptor(JNIEnv* env, int fd) {
return jniCreateFileDescriptor(&env->functions, fd);
}
inline int jniGetFDFromFileDescriptor(JNIEnv* env, jobject fileDescriptor) {
return jniGetFDFromFileDescriptor(&env->functions, fileDescriptor);
}
inline void jniSetFileDescriptorOfFD(JNIEnv* env, jobject fileDescriptor, int value) {
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);
}
#if !defined(DISALLOW_COPY_AND_ASSIGN)
// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. It goes in the private:
// declarations in a class.
#if __cplusplus >= 201103L
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
void operator=(const TypeName&) = delete
#else
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#endif // __has_feature(cxx_deleted_functions)
#endif // !defined(DISALLOW_COPY_AND_ASSIGN)
#endif
/*
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
* <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
* not already defined, then define it here.
*/
#ifndef TEMP_FAILURE_RETRY
/* Used to retry syscalls that can return EINTR. */
#define TEMP_FAILURE_RETRY(exp) ({ \
typeof (exp) _rc; \
do { \
_rc = (exp); \
} while (_rc == -1 && errno == EINTR); \
_rc; })
#endif
#endif /* NATIVEHELPER_JNIHELP_H_ */
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef JNI_CONSTANTS_H_included
#define JNI_CONSTANTS_H_included
#include "JNIHelp.h"
/**
* A cache to avoid calling FindClass at runtime.
*
* Class lookup is relatively expensive, so we do these lookups at startup. This means that code
* that never uses, say, java.util.zip.Deflater still has to pay for the lookup, but it means that
* on device the cost is paid during boot and amortized. A central cache also removes the temptation
* to dynamically call FindClass rather than add a small cache to each file that needs one. Another
* cost is that each class cached here requires a global reference, though in practice we save
* enough by not having a global reference for each file that uses a class such as java.lang.String
* which is used in several files.
*
* FindClass is still called in a couple of situations: when throwing exceptions, and in some of
* the serialization code. The former is clearly not a performance case, and we're currently
* assuming that neither is the latter.