Collapse native/{fb,jni,xplatinit} into one DSO
Reviewed By: dcolascione Differential Revision: D3201488 fbshipit-source-id: 0cf965ee16e360329285d834a4c575d8f1061f15
This commit is contained in:
Родитель
c779e233b6
Коммит
ee77e50c4a
|
@ -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>
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче