Collapse native/{fb,jni,xplatinit} into one DSO

Reviewed By: dcolascione

Differential Revision: D3201488

fbshipit-source-id: 0cf965ee16e360329285d834a4c575d8f1061f15
This commit is contained in:
Tobias Ritzau 2016-05-16 22:45:05 -07:00 коммит произвёл Facebook Github Bot 1
Родитель c779e233b6
Коммит ee77e50c4a
85 изменённых файлов: 840 добавлений и 405 удалений

Просмотреть файл

@ -29,7 +29,7 @@ public class Prerequisites {
private static final int EGL_OPENGL_ES2_BIT = 0x0004;
public static void ensure() {
SoLoader.loadLibrary("fbjni");
SoLoader.loadLibrary("fb");
}
// Code is simplified version of getDetectedVersion()

Просмотреть файл

@ -3,12 +3,25 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
assert.cpp \
jni/ByteBuffer.cpp \
jni/Countable.cpp \
jni/Environment.cpp \
jni/Exceptions.cpp \
jni/fbjni.cpp \
jni/Hybrid.cpp \
jni/jni_helpers.cpp \
jni/LocalString.cpp \
jni/OnLoad.cpp \
jni/References.cpp \
jni/WeakReference.cpp \
log.cpp \
lyra/lyra.cpp \
onload.cpp \
LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.. $(LOCAL_PATH)/include
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CFLAGS := -DLOG_TAG=\"libfb\"
LOCAL_CFLAGS := -DLOG_TAG=\"libfb\" -DDISABLE_XPLAT -fexceptions -frtti
LOCAL_CFLAGS += -Wall -Werror
# include/utils/threads.h has unused parameters
LOCAL_CFLAGS += -Wno-unused-parameter
@ -17,7 +30,7 @@ ifeq ($(TOOLCHAIN_PERMISSIVE),true)
endif
LOCAL_CFLAGS += -DHAVE_POSIX_CLOCKS
CXX11_FLAGS := -std=c++11
CXX11_FLAGS := -std=gnu++11
LOCAL_CFLAGS += $(CXX11_FLAGS)
LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS)
@ -27,4 +40,5 @@ LOCAL_EXPORT_LDLIBS := -llog
LOCAL_MODULE := libfb
include $(BUILD_SHARED_LIBRARY)
include $(BUILD_SHARED_LIBRARY)

Просмотреть файл

@ -1,28 +0,0 @@
include_defs('//ReactAndroid/DEFS')
cxx_library(
name = 'fb',
soname = 'libfb.so',
srcs = [
'assert.cpp',
'log.cpp',
],
header_namespace='fb',
exported_headers=subdir_glob([
('', '*.h'),
('include/fb', '*.h'),
]),
preprocessor_flags=[
'-DLOG_TAG="libfb"',
],
# We want to use this library during bootstrap
can_be_asset = False,
deps = [
react_native_target('jni/third-party/android-ndk:android'),
react_native_target('jni/third-party/android-ndk:log'),
react_native_target('jni/third-party/glibc:dl'),
],
visibility = [
'PUBLIC'
],
)

Просмотреть файл

@ -0,0 +1,15 @@
PROJECT_NAME = "Facebook Android Support"
JAVADOC_AUTOBRIEF = YES
EXTRACT_ALL = YES
RECURSIVE = YES
EXCLUDE = tests
EXCLUDE_PATTERNS = *.cpp
GENERATE_HTML = YES
GENERATE_LATEX = NO
ENABLE_PREPROCESSING = YES
HIDE_UNDOC_MEMBERS = YES
HIDE_SCOPE_NAMES = YES
HIDE_FRIEND_COMPOUNDS = YES
HIDE_UNDOC_CLASSES = YES
SHOW_INCLUDE_FILES = NO
#ENABLED_SECTIONS = INTERNAL

Просмотреть файл

@ -11,40 +11,56 @@
#include <string>
#include <jni.h>
#include <fb/visibility.h>
namespace facebook {
namespace jni {
// Keeps a thread-local reference to the current thread's JNIEnv.
struct Environment {
// May be null if this thread isn't attached to the JVM
static JNIEnv* current();
FBEXPORT static JNIEnv* current();
static void initialize(JavaVM* vm);
static JNIEnv* ensureCurrentThreadIsAttached();
static void detachCurrentThread();
FBEXPORT static JNIEnv* ensureCurrentThreadIsAttached();
FBEXPORT static void detachCurrentThread();
};
/**
* RAII Object that attaches a thread to the JVM. Failing to detach from a thread before it
* exits will cause a crash, as will calling Detach an extra time, and this guard class helps
* keep that straight. In addition, it remembers whether it performed the attach or not, so it
* is safe to nest it with itself or with non-fbjni code that manages the attachment correctly.
* RAII Object that attaches a thread to the JVM. Failing to detach from a
* thread before it
* exits will cause a crash, as will calling Detach an extra time, and this
* guard class helps
* keep that straight. In addition, it remembers whether it performed the attach
* or not, so it
* is safe to nest it with itself or with non-fbjni code that manages the
* attachment correctly.
*
* Potential concerns:
* - Attaching to the JVM is fast (~100us on MotoG), but ideally you would attach while the
* - Attaching to the JVM is fast (~100us on MotoG), but ideally you would
* attach while the
* app is not busy.
* - Having a thread detach at arbitrary points is not safe in Dalvik; you need to be sure that
* there is no Java code on the current stack or you run the risk of a crash like:
* - Having a thread detach at arbitrary points is not safe in Dalvik; you need
* to be sure that
* there is no Java code on the current stack or you run the risk of a crash
* like:
* ERROR: detaching thread with interp frames (count=18)
* (More detail at https://groups.google.com/forum/#!topic/android-ndk/2H8z5grNqjo)
* ThreadScope won't do a detach if the thread was already attached before the guard is
* (More detail at
* https://groups.google.com/forum/#!topic/android-ndk/2H8z5grNqjo)
* ThreadScope won't do a detach if the thread was already attached before
* the guard is
* instantiated, but there's probably some usage that could trip this up.
* - Newly attached C++ threads only get the bootstrap class loader -- i.e. java language
* classes, not any of our application's classes. This will be different behavior than threads
* that were initiated on the Java side. A workaround is to pass a global reference for a
* class or instance to the new thread; this bypasses the need for the class loader.
* (See http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#attach_current_thread)
* - Newly attached C++ threads only get the bootstrap class loader -- i.e.
* java language
* classes, not any of our application's classes. This will be different
* behavior than threads
* that were initiated on the Java side. A workaround is to pass a global
* reference for a
* class or instance to the new thread; this bypasses the need for the class
* loader.
* (See
* http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#attach_current_thread)
*/
class ThreadScope {
class FBEXPORT ThreadScope {
public:
ThreadScope();
ThreadScope(ThreadScope&) = delete;
@ -56,6 +72,5 @@ class ThreadScope {
private:
bool attachedWithThisScope_;
};
} }
}
}

Просмотреть файл

@ -10,6 +10,8 @@
#ifndef FBASSERT_H
#define FBASSERT_H
#include <fb/visibility.h>
namespace facebook {
#define ENABLE_FBASSERT 1
@ -24,7 +26,7 @@ namespace facebook {
#define FBCRASH(msg, ...) facebook::assertInternal("Fatal error (%s:%d): " msg, __FILE__, __LINE__, ##__VA_ARGS__)
#define FBUNREACHABLE() facebook::assertInternal("This code should be unreachable (%s:%d)", __FILE__, __LINE__)
void assertInternal(const char* formatstr, ...) __attribute__((noreturn));
FBEXPORT void assertInternal(const char* formatstr, ...) __attribute__((noreturn));
// This allows storing the assert message before the current process terminates due to a crash
typedef void (*AssertHandler)(const char* message);

Просмотреть файл

@ -0,0 +1,24 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <jni.h>
#include <fb/Environment.h>
#include <fb/ALog.h>
#include <fb/fbjni/Common.h>
#include <fb/fbjni/Exceptions.h>
#include <fb/fbjni/ReferenceAllocators.h>
#include <fb/fbjni/References.h>
#include <fb/fbjni/Meta.h>
#include <fb/fbjni/CoreClasses.h>
#include <fb/fbjni/Iterator.h>
#include <fb/fbjni/Hybrid.h>
#include <fb/fbjni/Registration.h>

Просмотреть файл

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include "CoreClasses.h"
namespace facebook {
namespace jni {
namespace detail {
template <typename T, typename jprim>
struct JPrimitive : JavaClass<T> {
using typename JavaClass<T>::javaobject;
using JavaClass<T>::javaClassStatic;
static local_ref<javaobject> valueOf(jprim val) {
static auto cls = javaClassStatic();
static auto method =
cls->template getStaticMethod<javaobject(jprim)>("valueOf");
return method(cls, val);
}
jprim value() const {
static auto method =
javaClassStatic()->template getMethod<jprim()>(T::kValueMethod);
return method(this->self());
}
};
} // namespace detail
#define DEFINE_BOXED_PRIMITIVE(LITTLE, BIG) \
struct J ## BIG : detail::JPrimitive<J ## BIG, j ## LITTLE> { \
static auto constexpr kJavaDescriptor = "Ljava/lang/" #BIG ";"; \
static auto constexpr kValueMethod = #LITTLE "Value"; \
j ## LITTLE LITTLE ## Value() const { \
return value(); \
} \
}; \
inline local_ref<jobject> autobox(j ## LITTLE val) { \
return J ## BIG::valueOf(val); \
}
DEFINE_BOXED_PRIMITIVE(boolean, Boolean)
DEFINE_BOXED_PRIMITIVE(byte, Byte)
DEFINE_BOXED_PRIMITIVE(char, Character)
DEFINE_BOXED_PRIMITIVE(short, Short)
DEFINE_BOXED_PRIMITIVE(int, Integer)
DEFINE_BOXED_PRIMITIVE(long, Long)
DEFINE_BOXED_PRIMITIVE(float, Float)
DEFINE_BOXED_PRIMITIVE(double, Double)
#undef DEFINE_BOXED_PRIMITIVE
inline local_ref<jobject> autobox(alias_ref<jobject> val) {
return make_local(val);
}
}}

Просмотреть файл

@ -9,6 +9,8 @@
#pragma once
#include <fb/visibility.h>
#include "CoreClasses.h"
#include "References-forward.h"
@ -17,7 +19,7 @@ namespace jni {
// JNI's NIO support has some awkward preconditions and error reporting. This
// class provides much more user-friendly access.
class JByteBuffer : public JavaClass<JByteBuffer> {
class FBEXPORT JByteBuffer : public JavaClass<JByteBuffer> {
public:
static constexpr const char* kJavaDescriptor = "Ljava/nio/ByteBuffer;";

Просмотреть файл

@ -18,7 +18,8 @@
#include <jni.h>
#include <jni/Environment.h>
#include <fb/visibility.h>
#include <fb/Environment.h>
#ifdef FBJNI_DEBUG_REFS
# ifdef __ANDROID__
@ -47,7 +48,7 @@ namespace jni {
* unhelpful way (typically a segfault) while trying to handle an exception
* which occurs later.
*/
jint initialize(JavaVM*, std::function<void()>&&) noexcept;
FBEXPORT jint initialize(JavaVM*, std::function<void()>&&) noexcept;
namespace internal {

Просмотреть файл

@ -23,6 +23,8 @@
#include <jni.h>
#include <fb/visibility.h>
namespace facebook {
namespace jni {
@ -38,7 +40,7 @@ class JObject;
/// in a "static auto" variable, or a static global.
///
/// @return Returns a leaked global reference to the class
alias_ref<JClass> findClassStatic(const char* name);
FBEXPORT alias_ref<JClass> findClassStatic(const char* name);
/// Lookup a class by name. Note this functions returns a local reference,
/// which means that it must not be stored in a static variable.
@ -47,12 +49,12 @@ alias_ref<JClass> findClassStatic(const char* name);
/// (like caching method ids).
///
/// @return Returns a global reference to the class
local_ref<JClass> findClassLocal(const char* name);
FBEXPORT local_ref<JClass> findClassLocal(const char* name);
/// Check to see if two references refer to the same object. Comparison with nullptr
/// returns true if and only if compared to another nullptr. A weak reference that
/// refers to a reclaimed object count as nullptr.
bool isSameObject(alias_ref<JObject> lhs, alias_ref<JObject> rhs) noexcept;
FBEXPORT bool isSameObject(alias_ref<JObject> lhs, alias_ref<JObject> rhs) noexcept;
// Together, these classes allow convenient use of any class with the fbjni
// helpers. To use:
@ -95,7 +97,7 @@ static local_ref<JC> newInstance(Args... args);
class MonitorLock;
class JObject : detail::JObjectBase {
class FBEXPORT JObject : detail::JObjectBase {
public:
static constexpr auto kJavaDescriptor = "Ljava/lang/Object;";
@ -191,7 +193,7 @@ struct JTypeFor<T, Base, void> {
// jthrowable) to be used as javaobject. This should only be necessary for
// built-in jni types and not user-defined ones.
template <typename T, typename Base = JObject, typename JType = void>
class JavaClass : public Base {
class FBEXPORT JavaClass : public Base {
using JObjType = typename detail::JTypeFor<T, Base, JType>;
public:
using _javaobject = typename JObjType::_javaobject;
@ -219,7 +221,7 @@ protected:
/// Wrapper to provide functionality to jclass references
struct NativeMethod;
class JClass : public JavaClass<JClass, JObject, jclass> {
class FBEXPORT JClass : public JavaClass<JClass, JObject, jclass> {
public:
/// Java type descriptor
static constexpr const char* kJavaDescriptor = "Ljava/lang/Class;";
@ -324,7 +326,7 @@ private:
void registerNatives(const char* name, std::initializer_list<NativeMethod> methods);
/// Wrapper to provide functionality to jstring references
class JString : public JavaClass<JString, JObject, jstring> {
class FBEXPORT JString : public JavaClass<JString, JObject, jstring> {
public:
/// Java type descriptor
static constexpr const char* kJavaDescriptor = "Ljava/lang/String;";
@ -335,11 +337,11 @@ class JString : public JavaClass<JString, JObject, jstring> {
/// Convenience functions to convert a std::string or const char* into a @ref local_ref to a
/// jstring
local_ref<JString> make_jstring(const char* modifiedUtf8);
local_ref<JString> make_jstring(const std::string& modifiedUtf8);
FBEXPORT local_ref<JString> make_jstring(const char* modifiedUtf8);
FBEXPORT local_ref<JString> make_jstring(const std::string& modifiedUtf8);
/// Wrapper to provide functionality to jthrowable references
class JThrowable : public JavaClass<JThrowable, JObject, jthrowable> {
class FBEXPORT JThrowable : public JavaClass<JThrowable, JObject, jthrowable> {
public:
static constexpr const char* kJavaDescriptor = "Ljava/lang/Throwable;";
};
@ -370,7 +372,7 @@ class ElementProxy {
}
namespace detail {
class JArray : public JavaClass<JArray, JObject, jarray> {
class FBEXPORT JArray : public JavaClass<JArray, JObject, jarray> {
public:
// This cannot be used in a scope that derives a descriptor (like in a method
// signature). Use a more derived type instead (like JArrayInt or
@ -382,7 +384,7 @@ class JArray : public JavaClass<JArray, JObject, jarray> {
// This is used so that the JArrayClass<T> javaobject extends jni's
// jobjectArray. This class should not be used directly. A general Object[]
// should use JArrayClass<jobject>.
class JTypeArray : public JavaClass<JTypeArray, JArray, jobjectArray> {
class FBEXPORT JTypeArray : public JavaClass<JTypeArray, JArray, jobjectArray> {
// This cannot be used in a scope that derives a descriptor (like in a method
// signature).
static constexpr const char* kJavaDescriptor = nullptr;
@ -452,7 +454,7 @@ template <typename T> class PinnedCriticalAlloc;
/// This is an empty holder by itself. Construct a PinnedPrimitiveArray to actually interact with
/// the elements of the array.
template <typename JArrayType>
class JPrimitiveArray :
class FBEXPORT JPrimitiveArray :
public JavaClass<JPrimitiveArray<JArrayType>, detail::JArray, JArrayType> {
static_assert(is_jni_primitive_array<JArrayType>(), "");
public:
@ -492,14 +494,14 @@ private:
void releaseElements(T* elements, jint mode);
};
local_ref<jbooleanArray> make_boolean_array(jsize size);
local_ref<jbyteArray> make_byte_array(jsize size);
local_ref<jcharArray> make_char_array(jsize size);
local_ref<jshortArray> make_short_array(jsize size);
local_ref<jintArray> make_int_array(jsize size);
local_ref<jlongArray> make_long_array(jsize size);
local_ref<jfloatArray> make_float_array(jsize size);
local_ref<jdoubleArray> make_double_array(jsize size);
FBEXPORT local_ref<jbooleanArray> make_boolean_array(jsize size);
FBEXPORT local_ref<jbyteArray> make_byte_array(jsize size);
FBEXPORT local_ref<jcharArray> make_char_array(jsize size);
FBEXPORT local_ref<jshortArray> make_short_array(jsize size);
FBEXPORT local_ref<jintArray> make_int_array(jsize size);
FBEXPORT local_ref<jlongArray> make_long_array(jsize size);
FBEXPORT local_ref<jfloatArray> make_float_array(jsize size);
FBEXPORT local_ref<jdoubleArray> make_double_array(jsize size);
using JArrayBoolean = JPrimitiveArray<jbooleanArray>;
using JArrayByte = JPrimitiveArray<jbyteArray>;

Просмотреть файл

@ -26,6 +26,8 @@
#include <jni.h>
#include <fb/visibility.h>
#include "Common.h"
// If a pending JNI Java exception is found, wraps it in a JniException object and throws it as
@ -50,7 +52,7 @@ namespace internal {
* Before using any of the state initialized above, call this. It
* will assert if initialization has not yet occurred.
*/
void assertIfExceptionsNotInitialized();
FBEXPORT void assertIfExceptionsNotInitialized();
// JniException ////////////////////////////////////////////////////////////////////////////////////
@ -62,7 +64,7 @@ void assertIfExceptionsNotInitialized();
*
* Note: the what() method of this class is not thread-safe (t6900503).
*/
class JniException : public std::exception {
class FBEXPORT JniException : public std::exception {
public:
JniException();
@ -93,15 +95,15 @@ class JniException : public std::exception {
// Functions that throw C++ exceptions
void throwPendingJniExceptionAsCppException();
FBEXPORT void throwPendingJniExceptionAsCppException();
void throwCppExceptionIf(bool condition);
FBEXPORT void throwCppExceptionIf(bool condition);
static const int kMaxExceptionMessageBufferSize = 512;
[[noreturn]] void throwNewJavaException(jthrowable);
[[noreturn]] FBEXPORT void throwNewJavaException(jthrowable);
[[noreturn]] void throwNewJavaException(const char* throwableName, const char* msg);
[[noreturn]] FBEXPORT void throwNewJavaException(const char* throwableName, const char* msg);
// These methods are the preferred way to throw a Java exception from
// a C++ function. They create and throw a C++ exception which wraps

Просмотреть файл

@ -11,7 +11,10 @@
#include <memory>
#include <type_traits>
#include <fb/assert.h>
#include <fb/visibility.h>
#include "CoreClasses.h"
namespace facebook {
@ -24,7 +27,7 @@ public:
virtual ~BaseHybridClass() {}
};
struct HybridData : public JavaClass<HybridData> {
struct FBEXPORT HybridData : public JavaClass<HybridData> {
constexpr static auto kJavaDescriptor = "Lcom/facebook/jni/HybridData;";
void setNativePointer(std::unique_ptr<BaseHybridClass> new_value);
BaseHybridClass* getNativePointer();
@ -65,7 +68,7 @@ struct HybridTraits<
// convert to HybridClass* from jhybridobject
template <typename T>
struct Convert<
struct FBEXPORT Convert<
T, typename std::enable_if<
std::is_base_of<BaseHybridClass, typename std::remove_pointer<T>::type>::value>::type> {
typedef typename std::remove_pointer<T>::type::jhybridobject jniType;
@ -90,7 +93,7 @@ struct RefReprType<T, typename std::enable_if<std::is_base_of<BaseHybridClass, T
}
template <typename T, typename Base = detail::BaseHybridClass>
class HybridClass : public detail::HybridTraits<Base>::CxxBase {
class FBEXPORT HybridClass : public detail::HybridTraits<Base>::CxxBase {
public:
struct JavaPart : JavaClass<JavaPart, typename detail::HybridTraits<Base>::JavaBase> {
// At this point, T is incomplete, and so we cannot access

Просмотреть файл

@ -19,7 +19,7 @@ class JStaticMethod;
template<typename F>
class JNonvirtualMethod;
template<typename F>
class JConstructor;
struct JConstructor;
template<typename F>
class JField;
template<typename F>

Просмотреть файл

@ -15,6 +15,11 @@
#include "Exceptions.h"
#include "MetaConvert.h"
#include "References.h"
#include "Boxed.h"
#if defined(__ANDROID__)
#include <sys/system_properties.h>
#endif
namespace facebook {
namespace jni {
@ -33,9 +38,72 @@ inline jmethodID JMethodBase::getId() const noexcept {
return method_id_;
}
namespace {
template <int idx, typename... Args>
struct ArgsArraySetter;
template <int idx, typename Arg, typename... Args>
struct ArgsArraySetter<idx, Arg, Args...> {
static void set(alias_ref<JArrayClass<jobject>::javaobject> array, Arg arg0, Args... args) {
// TODO(xxxxxxxx): Use Convert<Args>... to do conversions like the fast path.
(*array)[idx] = autobox(arg0);
ArgsArraySetter<idx + 1, Args...>::set(array, args...);
}
};
template <int idx>
struct ArgsArraySetter<idx> {
static void set(alias_ref<JArrayClass<jobject>::javaobject> array) {
}
};
template <typename... Args>
local_ref<JArrayClass<jobject>::javaobject> makeArgsArray(Args... args) {
auto arr = JArrayClass<jobject>::newArray(sizeof...(args));
ArgsArraySetter<0, Args...>::set(arr, args...);
return arr;
}
bool needsSlowPath(alias_ref<jobject> obj) {
#if defined(__ANDROID__)
// On Android 6.0, art crashes when attempting to call a function on a Proxy.
// So, when we detect that case we must use the safe, slow workaround. That is,
// we resolve the method id to the corresponding java.lang.reflect.Method object
// and make the call via it's invoke() method.
static auto android_sdk = ([] {
char sdk_version_str[PROP_VALUE_MAX];
__system_property_get("ro.build.version.sdk", sdk_version_str);
return atoi(sdk_version_str);
})();
static auto is_bad_android = android_sdk == 23;
if (!is_bad_android) return false;
static auto proxy_class = findClassStatic("java/lang/reflect/Proxy");
return obj->isInstanceOf(proxy_class);
#else
return false;
#endif
}
}
template <typename... Args>
local_ref<jobject> slowCall(jmethodID method_id, alias_ref<jobject> self, Args... args) {
static auto invoke = findClassStatic("java/lang/reflect/Method")
->getMethod<jobject(jobject, JArrayClass<jobject>::javaobject)>("invoke");
// TODO(xxxxxxx): Provide fbjni interface to ToReflectedMethod.
auto reflected = adopt_local(Environment::current()->ToReflectedMethod(self->getClass().get(), method_id, JNI_FALSE));
FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
if (!reflected) throw JniException();
auto argsArray = makeArgsArray(args...);
// No need to check for exceptions since invoke is itself a JMethod that will do that for us.
return invoke(reflected, self.get(), argsArray.get());
}
template<typename... Args>
inline void JMethod<void(Args...)>::operator()(alias_ref<jobject> self, Args... args) {
const auto env = internal::getEnv();
const auto env = Environment::current();
env->CallVoidMethod(
self.get(),
getId(),
@ -45,7 +113,7 @@ inline void JMethod<void(Args...)>::operator()(alias_ref<jobject> self, Args...
#pragma push_macro("DEFINE_PRIMITIVE_CALL")
#undef DEFINE_PRIMITIVE_CALL
#define DEFINE_PRIMITIVE_CALL(TYPE, METHOD) \
#define DEFINE_PRIMITIVE_CALL(TYPE, METHOD, CLASS) \
template<typename... Args> \
inline TYPE JMethod<TYPE(Args...)>::operator()(alias_ref<jobject> self, Args... args) { \
const auto env = internal::getEnv(); \
@ -57,17 +125,16 @@ inline TYPE JMethod<TYPE(Args...)>::operator()(alias_ref<jobject> self, Args...
return result; \
}
DEFINE_PRIMITIVE_CALL(jboolean, Boolean)
DEFINE_PRIMITIVE_CALL(jbyte, Byte)
DEFINE_PRIMITIVE_CALL(jchar, Char)
DEFINE_PRIMITIVE_CALL(jshort, Short)
DEFINE_PRIMITIVE_CALL(jint, Int)
DEFINE_PRIMITIVE_CALL(jlong, Long)
DEFINE_PRIMITIVE_CALL(jfloat, Float)
DEFINE_PRIMITIVE_CALL(jdouble, Double)
DEFINE_PRIMITIVE_CALL(jboolean, Boolean, JBoolean)
DEFINE_PRIMITIVE_CALL(jbyte, Byte, JByte)
DEFINE_PRIMITIVE_CALL(jchar, Char, JCharacter)
DEFINE_PRIMITIVE_CALL(jshort, Short, JShort)
DEFINE_PRIMITIVE_CALL(jint, Int, JInteger)
DEFINE_PRIMITIVE_CALL(jlong, Long, JLong)
DEFINE_PRIMITIVE_CALL(jfloat, Float, JFloat)
DEFINE_PRIMITIVE_CALL(jdouble, Double, JDouble)
#pragma pop_macro("DEFINE_PRIMITIVE_CALL")
/// JMethod specialization for references that wraps the return value in a @ref local_ref
template<typename R, typename... Args>
class JMethod<R(Args...)> : public JMethodBase {
@ -80,19 +147,22 @@ class JMethod<R(Args...)> : public JMethodBase {
JMethod(const JMethod& other) noexcept = default;
/// Invoke a method and return a local reference wrapping the result
local_ref<JniRet> operator()(alias_ref<jobject> self, Args... args) {
const auto env = internal::getEnv();
auto result = env->CallObjectMethod(
self.get(),
getId(),
detail::callToJni(detail::Convert<typename std::decay<Args>::type>::toCall(args))...);
FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
return adopt_local(static_cast<JniRet>(result));
}
local_ref<JniRet> operator()(alias_ref<jobject> self, Args... args);
friend class JClass;
};
template<typename R, typename... Args>
inline auto JMethod<R(Args...)>::operator()(alias_ref<jobject> self, Args... args) -> local_ref<JniRet> {
const auto env = Environment::current();
auto result = env->CallObjectMethod(
self.get(),
getId(),
detail::callToJni(detail::Convert<typename std::decay<Args>::type>::toCall(args))...);
FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
return adopt_local(static_cast<JniRet>(result));
}
template<typename... Args>
inline void JStaticMethod<void(Args...)>::operator()(alias_ref<jclass> cls, Args... args) {
const auto env = internal::getEnv();

Просмотреть файл

@ -35,6 +35,12 @@
namespace facebook {
namespace jni {
// This will get the reflected Java Method from the method_id, get it's invoke
// method, and call the method via that. This shouldn't ever be needed, but
// Android 6.0 crashes when calling a method on a java.lang.Proxy via jni.
template <typename... Args>
local_ref<jobject> slowCall(jmethodID method_id, alias_ref<jobject> self, Args... args);
class JObject;

Просмотреть файл

@ -16,12 +16,14 @@
#pragma once
#include <fb/visibility.h>
#include "Common.h"
namespace facebook { namespace jni {
/// Allocator that handles local references
class LocalReferenceAllocator {
class FBEXPORT LocalReferenceAllocator {
public:
jobject newReference(jobject original) const;
void deleteReference(jobject reference) const noexcept;
@ -29,7 +31,7 @@ class LocalReferenceAllocator {
};
/// Allocator that handles global references
class GlobalReferenceAllocator {
class FBEXPORT GlobalReferenceAllocator {
public:
jobject newReference(jobject original) const;
void deleteReference(jobject reference) const noexcept;
@ -37,7 +39,7 @@ class GlobalReferenceAllocator {
};
/// Allocator that handles weak global references
class WeakGlobalReferenceAllocator {
class FBEXPORT WeakGlobalReferenceAllocator {
public:
jobject newReference(jobject original) const;
void deleteReference(jobject reference) const noexcept;
@ -50,7 +52,7 @@ namespace internal {
/**
* @return true iff env->GetObjectRefType is expected to work properly.
*/
bool doesGetObjectRefTypeWork();
FBEXPORT bool doesGetObjectRefTypeWork();
}
/// @endcond

Просмотреть файл

@ -198,7 +198,9 @@ template<typename T, typename Alloc>
template<typename U>
inline base_owned_ref<T, Alloc>::base_owned_ref(const base_owned_ref<U, Alloc>& other)
: storage_{static_cast<javaobject>(Alloc{}.newReference(other.get()))}
{}
{
static_assert(std::is_convertible<JniType<U>, javaobject>::value, "");
}
template<typename T, typename Alloc>
inline facebook::jni::base_owned_ref<T, Alloc>::base_owned_ref(

Просмотреть файл

@ -77,6 +77,8 @@
#include <jni.h>
#include <fb/visibility.h>
#include "ReferenceAllocators.h"
#include "TypeTraits.h"
#include "References-forward.h"
@ -555,7 +557,7 @@ class alias_ref {
* This is useful when you have a call which is initiated from C++-land, and therefore
* doesn't automatically get a local JNI frame managed for you by the JNI framework.
*/
class JniLocalScope {
class FBEXPORT JniLocalScope {
public:
JniLocalScope(JNIEnv* p_env, jint capacity);
~JniLocalScope();

Просмотреть файл

@ -88,14 +88,14 @@ inline NativeMethodWrapper* exceptionWrapJNIMethod(void (*)(alias_ref<C>, Args..
template<typename F, F func, typename C, typename R, typename... Args>
inline NativeMethodWrapper* exceptionWrapJNIMethod(R (*)(alias_ref<C>, Args... args)) {
struct funcWrapper {
typedef typename Convert<typename std::decay<R>::type>::jniType jniRet;
JNI_ENTRY_POINT static jniRet call(JNIEnv*, jobject obj,
JNI_ENTRY_POINT static typename Convert<typename std::decay<R>::type>::jniType call(JNIEnv*, jobject obj,
typename Convert<typename std::decay<Args>::type>::jniType... args) {
try {
return Convert<typename std::decay<R>::type>::toJniRet(
(*func)(static_cast<JniType<C>>(obj), Convert<typename std::decay<Args>::type>::fromJni(args)...));
} catch (...) {
using jniRet = typename Convert<typename std::decay<R>::type>::jniType;
translatePendingCppExceptionToJavaException();
return jniRet{};
}
@ -138,9 +138,8 @@ inline NativeMethodWrapper* exceptionWrapJNIMethod(void (C::*method0)(Args... ar
template<typename M, M method, typename C, typename R, typename... Args>
inline NativeMethodWrapper* exceptionWrapJNIMethod(R (C::*method0)(Args... args)) {
struct funcWrapper {
typedef typename Convert<typename std::decay<R>::type>::jniType jniRet;
JNI_ENTRY_POINT static jniRet call(JNIEnv* env, jobject obj,
JNI_ENTRY_POINT static typename Convert<typename std::decay<R>::type>::jniType call(JNIEnv* env, jobject obj,
typename Convert<typename std::decay<Args>::type>::jniType... args) {
try {
try {
@ -156,6 +155,7 @@ inline NativeMethodWrapper* exceptionWrapJNIMethod(R (C::*method0)(Args... args)
throw;
}
} catch (...) {
using jniRet = typename Convert<typename std::decay<R>::type>::jniType;
translatePendingCppExceptionToJavaException();
return jniRet{};
}

Просмотреть файл

@ -41,6 +41,8 @@
//
#pragma once
#include <fb/visibility.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -48,35 +50,36 @@ extern "C" {
#ifdef ANDROID
#include <android/log.h>
#else
// These declarations are needed for our internal use even on non-Android builds.
// (they are borrowed from <android/log.h>)
// These declarations are needed for our internal use even on non-Android
// builds.
// (they are borrowed from <android/log.h>)
/*
* Android log priority values, in ascending priority order.
*/
typedef enum android_LogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
/*
* Android log priority values, in ascending priority order.
*/
typedef enum android_LogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
/*
* Send a simple string to the log.
*/
int __android_log_write(int prio, const char *tag, const char *text);
/*
* Send a simple string to the log.
*/
int __android_log_write(int prio, const char *tag, const char *text);
/*
* Send a formatted string to the log, used like printf(fmt,...)
*/
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
/*
* Send a formatted string to the log, used like printf(fmt,...)
*/
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
#if defined(__GNUC__)
__attribute__ ((format(printf, 3, 4)))
__attribute__((format(printf, 3, 4)))
#endif
;
@ -113,22 +116,21 @@ extern "C" {
*/
#ifndef FBLOGV
#if FBLOG_NDEBUG
#define FBLOGV(...) ((void)0)
#define FBLOGV(...) ((void)0)
#else
#define FBLOGV(...) ((void)FBLOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#endif
#endif
#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
#define CONDITION(cond) (__builtin_expect((cond) != 0, 0))
#ifndef FBLOGV_IF
#if FBLOG_NDEBUG
#define FBLOGV_IF(cond, ...) ((void)0)
#define FBLOGV_IF(cond, ...) ((void)0)
#else
#define FBLOGV_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)FBLOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define FBLOGV_IF(cond, ...) \
((CONDITION(cond)) ? ((void)FBLOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
#endif
@ -141,9 +143,7 @@ extern "C" {
#ifndef FBLOGD_IF
#define FBLOGD_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)FBLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
((CONDITION(cond)) ? ((void)FBLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) : (void)0)
#endif
/*
@ -155,9 +155,7 @@ extern "C" {
#ifndef FBLOGI_IF
#define FBLOGI_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)FBLOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
((CONDITION(cond)) ? ((void)FBLOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) : (void)0)
#endif
/*
@ -169,9 +167,7 @@ extern "C" {
#ifndef FBLOGW_IF
#define FBLOGW_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)FBLOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
((CONDITION(cond)) ? ((void)FBLOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) : (void)0)
#endif
/*
@ -183,9 +179,7 @@ extern "C" {
#ifndef FBLOGE_IF
#define FBLOGE_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)FBLOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
((CONDITION(cond)) ? ((void)FBLOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) : (void)0)
#endif
// ---------------------------------------------------------------------
@ -234,7 +228,6 @@ extern "C" {
#define IF_FBLOGE() IF_FBLOG(LOG_ERROR, LOG_TAG)
#endif
// ---------------------------------------------------------------------
/*
@ -243,13 +236,12 @@ extern "C" {
* It is NOT stripped from release builds. Note that the condition test
* is -inverted- from the normal assert() semantics.
*/
#define FBLOG_ALWAYS_FATAL_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)fb_printAssert(#cond, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define FBLOG_ALWAYS_FATAL_IF(cond, ...) \
((CONDITION(cond)) ? ((void)fb_printAssert(#cond, LOG_TAG, __VA_ARGS__)) \
: (void)0)
#define FBLOG_ALWAYS_FATAL(...) \
( ((void)fb_printAssert(NULL, LOG_TAG, __VA_ARGS__)) )
(((void)fb_printAssert(NULL, LOG_TAG, __VA_ARGS__)))
/*
* Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
@ -286,20 +278,19 @@ extern "C" {
*/
#ifndef FBLOG
#define FBLOG(priority, tag, ...) \
FBLOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
FBLOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#endif
#ifndef FBLOG_BY_DELIMS
#define FBLOG_BY_DELIMS(priority, tag, delims, msg, ...) \
logPrintByDelims(ANDROID_##priority, tag, delims, msg, ##__VA_ARGS__)
logPrintByDelims(ANDROID_##priority, tag, delims, msg, ##__VA_ARGS__)
#endif
/*
* Log macro that allows you to specify a number for the priority.
*/
#ifndef FBLOG_PRI
#define FBLOG_PRI(priority, tag, ...) \
fb_printLog(priority, tag, __VA_ARGS__)
#define FBLOG_PRI(priority, tag, ...) fb_printLog(priority, tag, __VA_ARGS__)
#endif
/*
@ -307,44 +298,40 @@ extern "C" {
*/
#ifndef FBLOG_PRI_VA
#define FBLOG_PRI_VA(priority, tag, fmt, args) \
fb_vprintLog(priority, NULL, tag, fmt, args)
fb_vprintLog(priority, NULL, tag, fmt, args)
#endif
/*
* Conditional given a desired logging priority and tag.
*/
#ifndef IF_FBLOG
#define IF_FBLOG(priority, tag) \
if (fb_testLog(ANDROID_##priority, tag))
#define IF_FBLOG(priority, tag) if (fb_testLog(ANDROID_##priority, tag))
#endif
typedef void (*LogHandler)(int priority, const char* tag, const char* message);
void setLogHandler(LogHandler logHandler);
FBEXPORT void setLogHandler(LogHandler logHandler);
/*
* ===========================================================================
*
* The stuff in the rest of this file should not be used directly.
*/
int fb_printLog(int prio, const char *tag, const char *fmt, ...)
FBEXPORT int fb_printLog(int prio, const char* tag, const char* fmt, ...)
#if defined(__GNUC__)
__attribute__ ((format(printf, 3, 4)))
__attribute__((format(printf, 3, 4)))
#endif
;
;
#define fb_vprintLog(prio, cond, tag, fmt...) \
__android_log_vprint(prio, tag, fmt)
__android_log_vprint(prio, tag, fmt)
#define fb_printAssert(cond, tag, fmt...) \
__android_log_assert(cond, tag, fmt)
#define fb_printAssert(cond, tag, fmt...) __android_log_assert(cond, tag, fmt)
#define fb_writeLog(prio, tag, text) \
__android_log_write(prio, tag, text)
#define fb_writeLog(prio, tag, text) __android_log_write(prio, tag, text)
#define fb_bWriteLog(tag, payload, len) \
__android_log_bwrite(tag, payload, len)
#define fb_bWriteLog(tag, payload, len) __android_log_bwrite(tag, payload, len)
#define fb_btWriteLog(tag, type, payload, len) \
__android_log_btwrite(tag, type, payload, len)
__android_log_btwrite(tag, type, payload, len)
#define fb_testLog(prio, tag) (1)
@ -354,8 +341,6 @@ int fb_printLog(int prio, const char *tag, const char *fmt, ...)
void logPrintByDelims(int priority, const char* tag, const char* delims,
const char* msg, ...);
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -0,0 +1,168 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#pragma once
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <fb/visibility.h>
namespace facebook {
namespace lyra {
constexpr size_t kDefaultLimit = 64;
using InstructionPointer = const void*;
class FBEXPORT StackTraceElement {
public:
StackTraceElement(InstructionPointer absoluteProgramCounter,
InstructionPointer libraryBase,
InstructionPointer functionAddress, std::string libraryName,
std::string functionName)
: absoluteProgramCounter_{absoluteProgramCounter},
libraryBase_{libraryBase},
functionAddress_{functionAddress},
libraryName_{std::move(libraryName)},
functionName_{std::move(functionName)} {}
InstructionPointer libraryBase() const noexcept { return libraryBase_; }
InstructionPointer functionAddress() const noexcept {
return functionAddress_;
}
InstructionPointer absoluteProgramCounter() const noexcept {
return absoluteProgramCounter_;
}
const std::string& libraryName() const noexcept { return libraryName_; }
const std::string& functionName() const noexcept { return functionName_; }
/**
* The offset of the program counter to the base of the library (i.e. the
* address that addr2line takes as input>
*/
std::ptrdiff_t libraryOffset() const noexcept {
auto absoluteLibrary = static_cast<const char*>(libraryBase_);
auto absoluteabsoluteProgramCounter =
static_cast<const char*>(absoluteProgramCounter_);
return absoluteabsoluteProgramCounter - absoluteLibrary;
}
/**
* The offset within the current function
*/
int functionOffset() const noexcept {
auto absoluteSymbol = static_cast<const char*>(functionAddress_);
auto absoluteabsoluteProgramCounter =
static_cast<const char*>(absoluteProgramCounter_);
return absoluteabsoluteProgramCounter - absoluteSymbol;
}
private:
const InstructionPointer absoluteProgramCounter_;
const InstructionPointer libraryBase_;
const InstructionPointer functionAddress_;
const std::string libraryName_;
const std::string functionName_;
};
/**
* Populate the vector with the current stack trace
*
* Note that this trace needs to be symbolicated to get the library offset even
* if it is to be symbolicated off-line.
*
* Beware of a bug on some platforms, which makes the trace loop until the
* buffer is full when it reaches a noexpr function. It seems to be fixed in
* newer versions of gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846
*
* @param stackTrace The vector that will receive the stack trace. Before
* filling the vector it will be cleared. The vector will never grow so the
* number of frames captured is limited by the capacity of it.
*
* @param skip The number of frames to skip before capturing the trace
*/
FBEXPORT void getStackTrace(std::vector<InstructionPointer>& stackTrace,
size_t skip = 0);
/**
* Creates a vector and populates it with the current stack trace
*
* Note that this trace needs to be symbolicated to get the library offset even
* if it is to be symbolicated off-line.
*
* Beware of a bug on some platforms, which makes the trace loop until the
* buffer is full when it reaches a noexpr function. It seems to be fixed in
* newer versions of gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846
*
* @param skip The number of frames to skip before capturing the trace
*
* @limit The maximum number of frames captured
*/
FBEXPORT inline std::vector<InstructionPointer> getStackTrace(
size_t skip = 0,
size_t limit = kDefaultLimit) {
auto stackTrace = std::vector<InstructionPointer>{};
stackTrace.reserve(limit);
getStackTrace(stackTrace, skip + 1);
return stackTrace;
}
/**
* Symbolicates a stack trace into a given vector
*
* @param symbols The vector to receive the output. The vector is cleared and
* enough room to keep the frames are reserved.
*
* @param stackTrace The input stack trace
*/
FBEXPORT void getStackTraceSymbols(std::vector<StackTraceElement>& symbols,
const std::vector<InstructionPointer>& trace);
/**
* Symbolicates a stack trace into a new vector
*
* @param stackTrace The input stack trace
*/
FBEXPORT inline std::vector<StackTraceElement> getStackTraceSymbols(
const std::vector<InstructionPointer>& trace) {
auto symbols = std::vector<StackTraceElement>{};
getStackTraceSymbols(symbols, trace);
return symbols;
}
/**
* Captures and symbolicates a stack trace
*
* Beware of a bug on some platforms, which makes the trace loop until the
* buffer is full when it reaches a noexpr function. It seems to be fixed in
* newer versions of gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846
*
* @param skip The number of frames before capturing the trace
*
* @param limit The maximum number of frames captured
*/
FBEXPORT inline std::vector<StackTraceElement> getStackTraceSymbols(
size_t skip = 0,
size_t limit = kDefaultLimit) {
return getStackTraceSymbols(getStackTrace(skip + 1, limit));
}
/**
* Formatting a stack trace element
*/
FBEXPORT std::ostream& operator<<(std::ostream& out, const StackTraceElement& elm);
/**
* Formatting a stack trace
*/
FBEXPORT std::ostream& operator<<(std::ostream& out,
const std::vector<StackTraceElement>& trace);
}
}

Просмотреть файл

@ -0,0 +1,12 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#define FBEXPORT __attribute__((visibility("default")))

Просмотреть файл

@ -8,14 +8,17 @@
*/
#pragma once
#include <jni.h>
#include <fb/Countable.h>
#include <fb/RefPtr.h>
#include <fb/visibility.h>
namespace facebook {
namespace jni {
const RefPtr<Countable>& countableFromJava(JNIEnv* env, jobject obj);
FBEXPORT const RefPtr<Countable>& countableFromJava(JNIEnv* env, jobject obj);
template <typename T> RefPtr<T> extractRefPtr(JNIEnv* env, jobject obj) {
return static_cast<RefPtr<T>>(countableFromJava(env, obj));
@ -25,7 +28,7 @@ template <typename T> RefPtr<T> extractPossiblyNullRefPtr(JNIEnv* env, jobject o
return obj ? extractRefPtr<T>(env, obj) : nullptr;
}
void setCountableForJava(JNIEnv* env, jobject obj, RefPtr<Countable>&& countable);
FBEXPORT void setCountableForJava(JNIEnv* env, jobject obj, RefPtr<Countable>&& countable);
void CountableOnLoad(JNIEnv* env);

Просмотреть файл

@ -14,7 +14,7 @@
#include <jni.h>
#include <jni/Environment.h>
#include <fb/Environment.h>
namespace facebook { namespace jni {

Просмотреть файл

@ -14,7 +14,7 @@
#include <jni.h>
#include <jni/Environment.h>
#include <fb/Environment.h>
namespace facebook {
namespace jni {
@ -27,7 +27,7 @@ struct LocalReferenceDeleter {
if (localReference != nullptr) {
Environment::current()->DeleteLocalRef(localReference);
}
}
}
};
template<class T>

Просмотреть файл

@ -8,9 +8,13 @@
*/
#pragma once
#include <string>
#include <jni.h>
#include <fb/visibility.h>
namespace facebook {
namespace jni {
@ -41,7 +45,7 @@ std::string utf16toUTF8(const uint16_t* utf16Bytes, size_t len);
// - http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html
// - https://docs.oracle.com/javase/6/docs/api/java/io/DataInput.html#modified-utf-8
class LocalString {
class FBEXPORT LocalString {
public:
// Assumes UTF8 encoding and make a required convertion to modified UTF-8 when the string
// contains unicode supplementary characters.
@ -85,6 +89,6 @@ private:
// The string from JNI is converted to standard UTF-8 if the string contains supplementary
// characters.
std::string fromJString(JNIEnv* env, jstring str);
FBEXPORT std::string fromJString(JNIEnv* env, jstring str);
} }

Просмотреть файл

@ -12,11 +12,13 @@
#include <jni.h>
#include <fb/noncopyable.h>
#include <fb/Countable.h>
#include <fb/visibility.h>
namespace facebook {
namespace jni {
class WeakReference : public Countable {
class FBEXPORT WeakReference : public Countable {
public:
typedef RefPtr<WeakReference> Ptr;
WeakReference(jobject strongRef);
@ -31,7 +33,7 @@ private:
// This class is intended to take a weak reference and turn it into a strong
// local reference. Consequently, it should only be allocated on the stack.
class ResolvedWeakReference : public noncopyable {
class FBEXPORT ResolvedWeakReference : public noncopyable {
public:
ResolvedWeakReference(jobject weakRef);
ResolvedWeakReference(const RefPtr<WeakReference>& weakRef);

Просмотреть файл

@ -11,6 +11,8 @@
#include <jni.h>
#include <fb/visibility.h>
namespace facebook {
/**
@ -22,7 +24,7 @@ namespace facebook {
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
jint throwException(JNIEnv* pEnv, const char* szClassName, const char* szFmt, va_list va_args);
FBEXPORT jint throwException(JNIEnv* pEnv, const char* szClassName, const char* szFmt, va_list va_args);
/**
* Instructs the JNI environment to throw a NoClassDefFoundError.
@ -32,7 +34,7 @@ jint throwException(JNIEnv* pEnv, const char* szClassName, const char* szFmt, va
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...);
FBEXPORT jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw a RuntimeException.
@ -42,7 +44,7 @@ jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...);
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...);
FBEXPORT jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw a IllegalArgumentException.
@ -52,7 +54,7 @@ jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...);
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, ...);
FBEXPORT jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw a IllegalStateException.
@ -62,7 +64,7 @@ jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, ...);
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...);
FBEXPORT jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw an IOException.
@ -72,7 +74,7 @@ jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...);
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...);
FBEXPORT jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw an AssertionError.
@ -82,7 +84,7 @@ jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...);
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...);
FBEXPORT jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Instructs the JNI environment to throw an OutOfMemoryError.
@ -92,7 +94,7 @@ jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...);
* @param ... sprintf-style args
* @return 0 on success; a negative value on failure
*/
jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...);
FBEXPORT jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...);
/**
* Finds the specified class. If it's not found, instructs the JNI environment to throw an
@ -103,7 +105,7 @@ jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...);
* @return the class or NULL if not found (in which case a pending exception will be queued). This
* returns a global reference (JNIEnv::NewGlobalRef).
*/
jclass findClassOrThrow(JNIEnv *pEnv, const char* szClassName);
FBEXPORT jclass findClassOrThrow(JNIEnv *pEnv, const char* szClassName);
/**
* Finds the specified field of the specified class. If it's not found, instructs the JNI
@ -115,7 +117,7 @@ jclass findClassOrThrow(JNIEnv *pEnv, const char* szClassName);
* @param szSig the signature of the field
* @return the field or NULL if not found (in which case a pending exception will be queued)
*/
jfieldID getFieldIdOrThrow(JNIEnv* pEnv, jclass clazz, const char* szFieldName, const char* szSig);
FBEXPORT jfieldID getFieldIdOrThrow(JNIEnv* pEnv, jclass clazz, const char* szFieldName, const char* szSig);
/**
* Finds the specified method of the specified class. If it's not found, instructs the JNI
@ -127,7 +129,7 @@ jfieldID getFieldIdOrThrow(JNIEnv* pEnv, jclass clazz, const char* szFieldName,
* @param szSig the signature of the method
* @return the method or NULL if not found (in which case a pending exception will be queued)
*/
jmethodID getMethodIdOrThrow(
FBEXPORT jmethodID getMethodIdOrThrow(
JNIEnv* pEnv,
jclass clazz,
const char* szMethodName,

Просмотреть файл

@ -7,11 +7,12 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "ByteBuffer.h"
#include <fb/fbjni/ByteBuffer.h>
#include "References.h"
#include <stdexcept>
#include <fb/fbjni/References.h>
namespace facebook {
namespace jni {

Просмотреть файл

@ -9,7 +9,7 @@
#include <cstdint>
#include <jni/Countable.h>
#include <jni/Environment.h>
#include <fb/Environment.h>
#include <jni/Registration.h>
namespace facebook {
@ -41,7 +41,7 @@ void setCountableForJava(JNIEnv* env, jobject obj, RefPtr<Countable>&& countable
*
* This method deletes the corresponding native object on whatever thread the method is called
* on. In the common case when this is called by Countable#finalize(), this will be called on the
* system finalizer thread. If you manually call dispose on the Java object, the native object
* system finalizer thread. If you manually call dispose on the Java object, the native object
* will be deleted synchronously on that thread.
*/
void dispose(JNIEnv* env, jobject obj) {

Просмотреть файл

@ -11,7 +11,7 @@
#include <fb/log.h>
#include <fb/StaticInitialized.h>
#include <fb/ThreadLocal.h>
#include <jni/Environment.h>
#include <fb/Environment.h>
namespace facebook {
namespace jni {

Просмотреть файл

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "jni/fbjni.h"
#include "fb/fbjni.h"
#include <fb/assert.h>
@ -26,7 +26,7 @@ namespace jni {
// CommonJniExceptions /////////////////////////////////////////////////////////////////////////////
class CommonJniExceptions {
class FBEXPORT CommonJniExceptions {
public:
static void init();
@ -226,7 +226,7 @@ void setNewJavaException(const char* className, const char* fmt, ARGS... args) {
// Functions that throw C++ exceptions
// TODO(T6618159) Take a stack dump here to save context if it results in a crash when propagated
void throwPendingJniExceptionAsCppException() {
FBEXPORT void throwPendingJniExceptionAsCppException() {
assertIfExceptionsNotInitialized();
JNIEnv* env = internal::getEnv();
if (env->ExceptionCheck() == JNI_FALSE) {
@ -257,11 +257,13 @@ void throwCppExceptionIf(bool condition) {
throw JniException();
}
void throwNewJavaException(jthrowable throwable) {
FBEXPORT void throwNewJavaException(jthrowable throwable) {
throw JniException(throwable);
}
void throwNewJavaException(const char* throwableName, const char* msg) {
FBEXPORT void throwNewJavaException(
const char* throwableName,
const char* msg) {
// If anything of the fbjni calls fail, an exception of a suitable
// form will be thrown, which is what we want.
auto throwableClass = findClassLocal(throwableName);
@ -273,7 +275,7 @@ void throwNewJavaException(const char* throwableName, const char* msg) {
// Translate C++ to Java Exception
void translatePendingCppExceptionToJavaException() noexcept {
FBEXPORT void translatePendingCppExceptionToJavaException() noexcept {
assertIfExceptionsNotInitialized();
try {
try {

Просмотреть файл

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "jni/fbjni.h"
#include "fb/fbjni.h"
namespace facebook {

Просмотреть файл

@ -8,7 +8,7 @@
*/
#include <jni/LocalString.h>
#include <jni/Environment.h>
#include <fb/Environment.h>
#include <fb/assert.h>
#include <vector>

Просмотреть файл

@ -0,0 +1,19 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include <jni/Countable.h>
#include <fb/Environment.h>
#include <fb/fbjni.h>
using namespace facebook::jni;
void initialize_fbjni() {
CountableOnLoad(Environment::current());
HybridDataOnLoad();
}

Просмотреть файл

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "References.h"
#include <fb/fbjni/References.h>
namespace facebook {
namespace jni {

Просмотреть файл

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include <jni/Environment.h>
#include <fb/Environment.h>
#include <jni/WeakReference.h>
namespace facebook {

Просмотреть файл

@ -7,11 +7,12 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "fbjni.h"
#include <fb/fbjni.h>
#include <mutex>
#include <vector>
#include <jni/LocalString.h>
#include <fb/log.h>
namespace facebook {
namespace jni {
@ -44,6 +45,9 @@ jint initialize(JavaVM* vm, std::function<void()>&& init_fn) noexcept {
}
init_fn();
} catch (const std::exception& e) {
FBLOGE("error %s", e.what());
translatePendingCppExceptionToJavaException();
} catch (...) {
translatePendingCppExceptionToJavaException();
// So Java will handle the translated exception, fall through and
@ -113,6 +117,7 @@ local_ref<JString> make_jstring(const char* utf8) {
#define DEFINE_PRIMITIVE_METHODS(TYPE, NAME, SMALLNAME) \
\
template<> \
FBEXPORT \
TYPE* JPrimitiveArray<TYPE ## Array>::getElements(jboolean* isCopy) { \
auto env = internal::getEnv(); \
TYPE* res = env->Get ## NAME ## ArrayElements(self(), isCopy); \
@ -121,6 +126,7 @@ TYPE* JPrimitiveArray<TYPE ## Array>::getElements(jboolean* isCopy) { \
} \
\
template<> \
FBEXPORT \
void JPrimitiveArray<TYPE ## Array>::releaseElements( \
TYPE* elements, jint mode) { \
auto env = internal::getEnv(); \
@ -129,6 +135,7 @@ void JPrimitiveArray<TYPE ## Array>::releaseElements( \
} \
\
template<> \
FBEXPORT \
void JPrimitiveArray<TYPE ## Array>::getRegion( \
jsize start, jsize length, TYPE* buf) { \
auto env = internal::getEnv(); \
@ -137,6 +144,7 @@ void JPrimitiveArray<TYPE ## Array>::getRegion( \
} \
\
template<> \
FBEXPORT \
void JPrimitiveArray<TYPE ## Array>::setRegion( \
jsize start, jsize length, const TYPE* elements) { \
auto env = internal::getEnv(); \
@ -144,6 +152,7 @@ void JPrimitiveArray<TYPE ## Array>::setRegion( \
FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); \
} \
\
FBEXPORT \
local_ref<TYPE ## Array> make_ ## SMALLNAME ## _array(jsize size) { \
auto array = internal::getEnv()->New ## NAME ## Array(size); \
FACEBOOK_JNI_THROW_EXCEPTION_IF(!array); \
@ -151,6 +160,7 @@ local_ref<TYPE ## Array> make_ ## SMALLNAME ## _array(jsize size) { \
} \
\
template<> \
FBEXPORT \
local_ref<TYPE ## Array> JArray ## NAME::newArray(size_t count) { \
return make_ ## SMALLNAME ## _array(count); \
} \
@ -170,9 +180,9 @@ DEFINE_PRIMITIVE_METHODS(jdouble, Double, double)
namespace internal {
ReferenceStats g_reference_stats;
FBEXPORT ReferenceStats g_reference_stats;
void facebook::jni::internal::ReferenceStats::reset() noexcept {
FBEXPORT void facebook::jni::internal::ReferenceStats::reset() noexcept {
locals_deleted = globals_deleted = weaks_deleted = 0;
}

Просмотреть файл

@ -0,0 +1,20 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.jni;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public class CppException extends RuntimeException {
@DoNotStrip
public CppException(String message) {
super(message);
}
}

Просмотреть файл

@ -0,0 +1,27 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.jni;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public class CppSystemErrorException extends CppException {
int errorCode;
@DoNotStrip
public CppSystemErrorException(String message, int errorCode) {
super(message);
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
}

Просмотреть файл

@ -0,0 +1,25 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.jni;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public class UnknownCppException extends CppException {
@DoNotStrip
public UnknownCppException() {
super("Unknown");
}
@DoNotStrip
public UnknownCppException(String message) {
super(message);
}
}

Просмотреть файл

@ -11,6 +11,8 @@
#include <stddef.h>
#include <cstdio>
#include <jni/jni_helpers.h>
#define MSG_SIZE 1024
namespace facebook {

Просмотреть файл

@ -0,0 +1,100 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#include <fb/lyra.h>
#include <memory>
#include <vector>
#include <dlfcn.h>
#include <unwind.h>
using namespace std;
namespace facebook {
namespace lyra {
namespace {
struct BacktraceState {
size_t skip;
vector<InstructionPointer>& stackTrace;
};
_Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg) {
BacktraceState* state = reinterpret_cast<BacktraceState*>(arg);
auto absoluteProgramCounter =
reinterpret_cast<InstructionPointer>(_Unwind_GetIP(context));
if (state->skip > 0) {
--state->skip;
return _URC_NO_REASON;
}
if (state->stackTrace.size() == state->stackTrace.capacity()) {
return _URC_END_OF_STACK;
}
state->stackTrace.push_back(absoluteProgramCounter);
return _URC_NO_REASON;
}
void captureBacktrace(size_t skip, vector<InstructionPointer>& stackTrace) {
// Beware of a bug on some platforms, which makes the trace loop until the
// buffer is full when it reaches a noexcept function. It seems to be fixed in
// newer versions of gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846
// TODO(t10738439): Investigate workaround for the stack trace bug
BacktraceState state = {skip, stackTrace};
_Unwind_Backtrace(unwindCallback, &state);
}
}
void getStackTrace(vector<InstructionPointer>& stackTrace, size_t skip) {
stackTrace.clear();
captureBacktrace(skip + 1, stackTrace);
}
// TODO(t10737622): Improve on-device symbolification
void getStackTraceSymbols(vector<StackTraceElement>& symbols,
const vector<InstructionPointer>& trace) {
symbols.clear();
symbols.reserve(trace.size());
for (size_t i = 0; i < trace.size(); ++i) {
Dl_info info;
if (dladdr(trace[i], &info)) {
symbols.emplace_back(trace[i], info.dli_fbase, info.dli_saddr,
info.dli_fname ? info.dli_fname : "",
info.dli_sname ? info.dli_sname : "");
}
}
}
ostream& operator<<(ostream& out, const StackTraceElement& elm) {
// TODO(t10748683): Add build id to the output
out << "{dso=" << elm.libraryName() << " offset=" << hex
<< showbase << elm.libraryOffset();
if (!elm.functionName().empty()) {
out << " func=" << elm.functionName() << "()+" << elm.functionOffset();
}
out << " build-id=" << hex << setw(8) << 0
<< "}";
return out;
}
// TODO(t10737667): The implement a tool that parse the stack trace and
// symbolicate it
ostream& operator<<(ostream& out, const vector<StackTraceElement>& trace) {
auto i = 0;
out << "Backtrace:\n";
for (auto& elm : trace) {
out << " #" << dec << setfill('0') << setw(2) << i++ << " " << elm << '\n';
}
return out;
}
}
}

Просмотреть файл

@ -8,16 +8,18 @@
*/
#include <jni.h>
#include <fb/assert.h>
#include <jni/Countable.h>
#include <jni/Environment.h>
#include <jni/fbjni.h>
#include <fb/fbjni.h>
using namespace facebook::jni;
void initialize_xplatinit();
void initialize_fbjni();
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
return facebook::jni::initialize(vm, [] {
CountableOnLoad(Environment::current());
HybridDataOnLoad();
});
initialize_fbjni();
#ifndef DISABLE_XPLAT
initialize_xplatinit();
#endif
});
}

Просмотреть файл

@ -1,36 +0,0 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
Countable.cpp \
Environment.cpp \
fbjni.cpp \
jni_helpers.cpp \
LocalString.cpp \
OnLoad.cpp \
WeakReference.cpp \
fbjni/ByteBuffer.cpp \
fbjni/Exceptions.cpp \
fbjni/Hybrid.cpp \
fbjni/References.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_CFLAGS := -DLOG_TAG=\"fbjni\" -fexceptions -frtti
LOCAL_CFLAGS += -Wall -Werror
CXX11_FLAGS := -std=gnu++11
LOCAL_CFLAGS += $(CXX11_FLAGS)
LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS)
LOCAL_LDLIBS := -landroid
LOCAL_SHARED_LIBRARIES := libfb
LOCAL_MODULE := libfbjni
include $(BUILD_SHARED_LIBRARY)
$(call import-module,fb)

Просмотреть файл

@ -1,51 +0,0 @@
include_defs('//ReactAndroid/DEFS')
cxx_library(
name = 'jni',
srcs = [
'Countable.cpp',
'Environment.cpp',
'fbjni.cpp',
'jni_helpers.cpp',
'LocalString.cpp',
'OnLoad.cpp',
'WeakReference.cpp',
'fbjni/ByteBuffer.cpp',
'fbjni/Exceptions.cpp',
'fbjni/Hybrid.cpp',
'fbjni/References.cpp',
],
platform_srcs = [
(r'.*\bandroid\b.*', [
'fbjni/android/ReferenceChecking.cpp',
]),
],
exported_headers = glob(['*.h', 'fbjni/*.h']),
header_namespace = 'jni',
soname = 'libfbjni.so',
preprocessor_flags = [
'-fexceptions',
'-DLOG_TAG="fbjni"',
],
compiler_flags = [
'-fexceptions',
'-frtti',
],
# We want to use this library during bootstrap
can_be_asset = False,
exported_deps = [
react_native_target('jni/first-party/fb:fb'),
react_native_target('jni/third-party/android-ndk:log'),
],
deps = [
# TODO Is this needed? Not used in the Gradle build.
# '//native/jni-hack:jni-hack',
# TODO should be react_native_target('java/com/facebook/jni:jni') but might not be needed as the bridge already depends on it.
# '//native/jni/java:java',
],
visibility = ['PUBLIC'],
)
project_config(
src_target = ':jni',
)

Просмотреть файл

@ -1,24 +0,0 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#pragma once
#include <jni.h>
#include "Environment.h"
#include "ALog.h"
#include "fbjni/Common.h"
#include "fbjni/Exceptions.h"
#include "fbjni/ReferenceAllocators.h"
#include "fbjni/References.h"
#include "fbjni/Meta.h"
#include "fbjni/CoreClasses.h"
#include "fbjni/Iterator.h"
#include "fbjni/Hybrid.h"
#include "fbjni/Registration.h"

Просмотреть файл

@ -1,37 +0,0 @@
/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef __ANDROID__
#error "This file should only be compiled for Android."
#endif
#include <jni/fbjni/References.h>
#include <jni/fbjni/CoreClasses.h>
namespace facebook {
namespace jni {
namespace internal {
static int32_t getApiLevel() {
auto cls = findClassLocal("android/os/Build$VERSION");
auto fld = cls->getStaticField<int32_t>("SDK_INT");
if (fld) {
return cls->getStaticFieldValue(fld);
}
return 0;
}
bool doesGetObjectRefTypeWork() {
static auto level = getApiLevel();
return level >= 14;
}
}
}
}

Просмотреть файл

@ -24,12 +24,11 @@ CXX11_FLAGS := -std=c++11
LOCAL_CFLAGS += $(CXX11_FLAGS)
LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS)
LOCAL_SHARED_LIBRARIES := libfb libfbjni libfolly_json libjsc libglog
LOCAL_SHARED_LIBRARIES := libfb libfolly_json libjsc libglog
include $(BUILD_STATIC_LIBRARY)
$(call import-module,fb)
$(call import-module,jni)
$(call import-module,folly)
$(call import-module,jsc)
$(call import-module,glog)

Просмотреть файл

@ -5,7 +5,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := reactnativejni
LOCAL_SRC_FILES := \
JExecutorToken.cpp \
JExecutorToken.cpp \
JMessageQueueThread.cpp \
JSCPerfLogging.cpp \
JSLoader.cpp \
@ -23,7 +23,7 @@ LOCAL_CFLAGS += $(CXX11_FLAGS)
LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS)
LOCAL_LDLIBS += -landroid
LOCAL_SHARED_LIBRARIES := libfolly_json libfbjni libjsc libglog_init
LOCAL_SHARED_LIBRARIES := libfolly_json libfb libjsc libglog_init
LOCAL_STATIC_LIBRARIES := libreactnative
include $(BUILD_SHARED_LIBRARY)
@ -32,5 +32,5 @@ $(call import-module,react)
$(call import-module,jsc)
$(call import-module,folly)
$(call import-module,fbgloginit)
$(call import-module,jni)
$(call import-module,fb)
$(call import-module,jsc)

Просмотреть файл

@ -5,7 +5,7 @@ SUPPORTED_PLATFORMS = '^android-(armv7|x86)$'
DEPS = [
FBGLOGINIT_TARGET,
'//native/jni:jni',
'//native/fb:fb',
'//native/third-party/android-ndk:android',
'//xplat/folly:molly',
]

Просмотреть файл

@ -4,7 +4,7 @@
#include <mutex>
#include <jni/fbjni.h>
#include <fb/fbjni.h>
#include <react/ExecutorToken.h>

Просмотреть файл

@ -2,7 +2,7 @@
#pragma once
#include <jni/fbjni.h>
#include <fb/fbjni.h>
#include <react/ExecutorTokenFactory.h>
#include "JExecutorToken.h"

Просмотреть файл

@ -4,7 +4,7 @@
#include <fb/log.h>
#include <folly/Memory.h>
#include <jni/fbjni.h>
#include <fb/fbjni.h>
#include "JNativeRunnable.h"

Просмотреть файл

@ -6,7 +6,7 @@
#include <react/MessageQueueThread.h>
#include <jni/fbjni.h>
#include <fb/fbjni.h>
using namespace facebook::jni;

Просмотреть файл

@ -3,7 +3,7 @@
#include "JSCPerfLogging.h"
#include <fb/log.h>
#include <jni/fbjni.h>
#include <fb/fbjni.h>
#include <react/JSCHelpers.h>
using namespace facebook::jni;

Просмотреть файл

@ -3,7 +3,7 @@
#include "JSLoader.h"
#include <android/asset_manager_jni.h>
#include <jni/Environment.h>
#include <fb/Environment.h>
#include <fstream>
#include <sstream>
#include <streambuf>

Просмотреть файл

@ -2,7 +2,7 @@
#include "NativeArray.h"
#include <jni/fbjni.h>
#include <fb/fbjni.h>
#include <folly/json.h>
namespace facebook {

Просмотреть файл

@ -2,7 +2,7 @@
#pragma once
#include <jni/fbjni.h>
#include <fb/fbjni.h>
#include <folly/dynamic.h>
namespace facebook {

Просмотреть файл

@ -6,12 +6,12 @@
#include <fb/glog_init.h>
#include <folly/json.h>
#include <jni/Countable.h>
#include <jni/Environment.h>
#include <jni/fbjni.h>
#include <fb/Environment.h>
#include <fb/fbjni.h>
#include <jni/LocalReference.h>
#include <jni/LocalString.h>
#include <jni/WeakReference.h>
#include <jni/fbjni/Exceptions.h>
#include <fb/fbjni/Exceptions.h>
#include <react/Bridge.h>
#include <react/Executor.h>
#include <react/JSCExecutor.h>

Просмотреть файл

@ -3,7 +3,7 @@
#include "ProxyExecutor.h"
#include <fb/assert.h>
#include <jni/Environment.h>
#include <fb/Environment.h>
#include <jni/LocalReference.h>
#include <jni/LocalString.h>
#include <folly/json.h>

Просмотреть файл

@ -3,7 +3,7 @@
#pragma once
#include <react/Executor.h>
#include <jni/fbjni.h>
#include <fb/fbjni.h>
#include <jni.h>
#include <jni/GlobalReference.h>
#include "OnLoad.h"

Просмотреть файл

@ -9,7 +9,7 @@ cxx_library(
],
deps = [
'//native:base',
'//native/jni:jni',
'//native/fb:fb',
],
visibility = [
'//instrumentation_tests/com/facebook/react/...',

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#include <fb/log.h>
#include <jni/Environment.h>
#include <fb/Environment.h>
#include <jni/LocalString.h>
#include <jni/Registration.h>