diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt
index c6f871141..456ee275b 100644
--- a/android/CMakeLists.txt
+++ b/android/CMakeLists.txt
@@ -31,7 +31,6 @@ add_library(${PACKAGE_NAME} SHARED ${SOURCES})
target_include_directories(${PACKAGE_NAME} PUBLIC "./")
set(libjnihack_DIR ${CMAKE_SOURCE_DIR}/../libs/jni-hack/)
-set(libfbjni_DIR ${CMAKE_SOURCE_DIR}/../libs/fbjni/)
set(libflipper_DIR ${CMAKE_SOURCE_DIR}/../xplat/)
set(external_DIR ${PROJECT_SOURCE_DIR}/third-party/external)
set(libfolly_DIR ${external_DIR}/folly/)
@@ -41,21 +40,22 @@ set(LIBEVENT_DIR ${external_DIR}/LibEvent/libevent-release-2.1.9/)
set(build_DIR ${CMAKE_SOURCE_DIR}/build)
-set(fbjni_build_DIR ${build_DIR}/fbjni/${ANDROID_ABI})
set(libflipper_build_DIR ${build_DIR}/libflipper/${ANDROID_ABI})
set(libfolly_build_DIR ${build_DIR}/libfolly/${ANDROID_ABI})
file(MAKE_DIRECTORY ${build_DIR})
+file(GLOB libfbjni_link_DIRS "${build_DIR}/fbjni*/jni/${ANDROID_ABI}")
+file(GLOB libfbjni_include_DIRS "${build_DIR}/fbjni-*-headers.jar/")
+
+# Without NO_CMAKE_FIND_ROOT_PATH, this will for some bizarre reason only look
+# in the NDK folder.
+find_library(FBJNI_LIBRARY fbjni PATHS ${libfbjni_link_DIRS} NO_CMAKE_FIND_ROOT_PATH)
add_subdirectory(${libflipper_DIR} ${libflipper_build_DIR})
-add_subdirectory(${libfbjni_DIR} ${fbjni_build_DIR})
target_include_directories(${PACKAGE_NAME} PRIVATE
${libjnihack_DIR}
- ${libfbjni_DIR}/cxx/
- ${libfbjni_DIR}/cxx/fbjni
- ${libfbjni_DIR}/cxx/fbjni/detail
- ${libfbjni_DIR}/cxx/lyra
+ ${libfbjni_include_DIRS}
${libflipper_DIR}
${libfolly_DIR}
${glog_DIR}
@@ -68,4 +68,4 @@ target_include_directories(${PACKAGE_NAME} PRIVATE
${LIBEVENT_DIR}/include/event2
)
-target_link_libraries(${PACKAGE_NAME} flipperfb flippercpp)
+target_link_libraries(${PACKAGE_NAME} ${FBJNI_LIBRARY} flippercpp)
diff --git a/android/build.gradle b/android/build.gradle
index 7e8416822..cdbaa9b27 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -35,6 +35,11 @@ android {
abortOnError false
}
+ configurations {
+ extractHeaders
+ extractJNI
+ }
+
sourceSets {
test {
java {
@@ -53,7 +58,9 @@ android {
dependencies {
compileOnly deps.lithoAnnotations
compileOnly deps.proguardAnnotations
- implementation project(':fbjni')
+ implementation 'com.facebook.fbjni:fbjni:0.0.1'
+ extractHeaders 'com.facebook.fbjni:fbjni:0.0.1:headers'
+ extractJNI 'com.facebook.fbjni:fbjni:0.0.1'
implementation deps.soloader
implementation deps.jsr305
implementation deps.supportAppCompat
@@ -87,3 +94,36 @@ task sourcesJar(type: Jar) {
}
artifacts.add('archives', sourcesJar)
+
+task extractAARHeaders {
+ doLast {
+ configurations.extractHeaders.files.each {
+ def file = it.absoluteFile
+ copy {
+ from zipTree(file)
+ into "$buildDir/$file.name"
+ include "**/*.h"
+ }
+ }
+ }
+}
+
+task extractJNIFiles {
+ doLast {
+ configurations.extractJNI.files.each {
+ def file = it.absoluteFile
+ copy {
+ from zipTree(file)
+ into "$buildDir/$file.name"
+ include "jni/**/*"
+ }
+ }
+ }
+}
+
+tasks.whenTaskAdded { task ->
+ if (task.name.contains('externalNativeBuild')) {
+ task.dependsOn(extractAARHeaders)
+ task.dependsOn(extractJNIFiles)
+ }
+}
diff --git a/build.gradle b/build.gradle
index 4b5dc061f..2d096ca94 100644
--- a/build.gradle
+++ b/build.gradle
@@ -31,6 +31,11 @@ subprojects {
mavenCentral()
jcenter()
+ maven {
+ // TODO: Remove once this is on official JCenter.
+ url 'https://dl.bintray.com/facebook/maven/'
+ }
+
if (isSnapshot()) {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
diff --git a/libs/fbjni/ApplicationManifest.xml b/libs/fbjni/ApplicationManifest.xml
deleted file mode 100644
index d09d5f057..000000000
--- a/libs/fbjni/ApplicationManifest.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
diff --git a/libs/fbjni/CMakeLists.txt b/libs/fbjni/CMakeLists.txt
deleted file mode 100644
index 41d8a5ea4..000000000
--- a/libs/fbjni/CMakeLists.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Copyright (c) 2014-present, Facebook, Inc.
-#
-# This source code is licensed under the MIT license found in the
-# LICENSE file in the root directory of this source tree.
-#
-
-cmake_minimum_required(VERSION 3.6.0)
-set(PACKAGE_NAME "flipperfb")
-project(${PACKAGE_NAME} CXX)
-
-set(CMAKE_VERBOSE_MAKEFILE on)
-
-add_compile_options(
- -fno-omit-frame-pointer
- -fexceptions
- -O3
- -Wall
- -std=c++11
- -frtti
- -ffunction-sections
- -DDISABLE_CPUCAP
- -DDISABLE_XPLAT)
-
-set(FBJNI_CXX ${PROJECT_SOURCE_DIR}/cxx)
-
-list(APPEND FBJNI_HDRS ${FBJNI_CXX})
-list(APPEND FBJNI_HDRS ${FBJNI_CXX}/fbjni/)
-list(APPEND FBJNI_HDRS ${FBJNI_CXX}/fbjni/detail)
-list(APPEND FBJNI_HDRS ${FBJNI_CXX}/lyra)
-list(APPEND FBJNI_HDRS ${FBJNI_CXX}/../../jni-hack)
-
-include_directories(${FBJNI_HDRS})
-
-file(GLOB FBJNI_SRC
- ${FBJNI_CXX}/fbjni/*.cpp
- ${FBJNI_CXX}/fbjni/detail/*.cpp
- ${FBJNI_CXX}/lyra/*.cpp
- )
-
-add_library(${PACKAGE_NAME} SHARED
- ${FBJNI_SRC})
-
-target_include_directories(${PACKAGE_NAME} PRIVATE ${FBJNI_HDRS})
-
-target_link_libraries(${PACKAGE_NAME} android log)
diff --git a/libs/fbjni/build.gradle b/libs/fbjni/build.gradle
deleted file mode 100644
index 3e596708c..000000000
--- a/libs/fbjni/build.gradle
+++ /dev/null
@@ -1,40 +0,0 @@
-apply plugin: 'com.android.library'
-apply plugin: 'maven'
-
-android {
- compileSdkVersion rootProject.compileSdkVersion
- buildToolsVersion rootProject.buildToolsVersion
-
- defaultConfig {
- minSdkVersion rootProject.minSdkVersion
- targetSdkVersion rootProject.targetSdkVersion
- sourceSets {
- main {
- manifest.srcFile './ApplicationManifest.xml'
- java {
- srcDir 'java'
- }
- }
- }
- }
-}
-
-dependencies {
- // compileOnly dependencies
- compileOnly deps.jsr305
- compileOnly deps.inferAnnotations
- compileOnly deps.lithoAnnotations
- implementation deps.soloader
-}
-
-apply from: rootProject.file('gradle/release.gradle')
-
-task sourcesJar(type: Jar) {
- from android.sourceSets.main.java.srcDirs
- classifier = 'sources'
-}
-artifacts.add('archives', sourcesJar)
-
-tasks.withType(Javadoc).all {
- enabled = false
-}
diff --git a/libs/fbjni/cxx/fbjni/ByteBuffer.cpp b/libs/fbjni/cxx/fbjni/ByteBuffer.cpp
deleted file mode 100644
index c0cd93eb0..000000000
--- a/libs/fbjni/cxx/fbjni/ByteBuffer.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#include
-
-#include
-
-namespace facebook {
-namespace jni {
-
-void JBuffer::rewind() const {
- static auto meth = javaClassStatic()->getMethod()>("rewind");
- meth(self());
-}
-
-void* JBuffer::getDirectAddress() const {
- if (!self()) {
- throwNewJavaException("java/lang/NullPointerException", "java.lang.NullPointerException");
- }
- void* addr = Environment::current()->GetDirectBufferAddress(self());
- FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
- if (!addr) {
- throw std::runtime_error(
- isDirect() ?
- "Attempt to get direct bytes of non-direct buffer." :
- "Error getting direct bytes of buffer.");
- }
- return addr;
-}
-
-size_t JBuffer::getDirectCapacity() const {
- if (!self()) {
- throwNewJavaException("java/lang/NullPointerException", "java.lang.NullPointerException");
- }
- int size = Environment::current()->GetDirectBufferCapacity(self());
- FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
- if (size < 0) {
- throw std::runtime_error(
- isDirect() ?
- "Attempt to get direct size of non-direct buffer." :
- "Error getting direct size of buffer.");
- }
- return static_cast(size);
-}
-
-bool JBuffer::isDirect() const {
- static auto meth = javaClassStatic()->getMethod("isDirect");
- return meth(self());
-}
-
-local_ref JByteBuffer::wrapBytes(uint8_t* data, size_t size) {
- // env->NewDirectByteBuffer requires that size is positive. Android's
- // dalvik returns an invalid result and Android's art aborts if size == 0.
- // Workaround this by using a slow path through Java in that case.
- if (!size) {
- return allocateDirect(0);
- }
- auto res = adopt_local(static_cast(Environment::current()->NewDirectByteBuffer(data, size)));
- FACEBOOK_JNI_THROW_PENDING_EXCEPTION();
- if (!res) {
- throw std::runtime_error("Direct byte buffers are unsupported.");
- }
- return res;
-}
-
-local_ref JByteBuffer::allocateDirect(jint size) {
- static auto cls = JByteBuffer::javaClassStatic();
- static auto meth = cls->getStaticMethod("allocateDirect");
- return meth(cls, size);
-}
-
-}}
diff --git a/libs/fbjni/cxx/fbjni/ByteBuffer.h b/libs/fbjni/cxx/fbjni/ByteBuffer.h
deleted file mode 100644
index 85c6177db..000000000
--- a/libs/fbjni/cxx/fbjni/ByteBuffer.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#pragma once
-
-#include
-
-namespace facebook {
-namespace jni {
-
-class JBuffer : public JavaClass {
-public:
- static constexpr const char* kJavaDescriptor = "Ljava/nio/Buffer;";
-
- void rewind() const;
- bool isDirect() const;
- void* getDirectAddress() const;
- size_t getDirectCapacity() const;
-};
-
-// JNI's NIO support has some awkward preconditions and error reporting. This
-// class provides much more user-friendly access.
-class JByteBuffer : public JavaClass {
- public:
- static constexpr const char* kJavaDescriptor = "Ljava/nio/ByteBuffer;";
-
- static local_ref wrapBytes(uint8_t* data, size_t size);
- static local_ref allocateDirect(jint size);
-
- uint8_t* getDirectBytes() const {
- return static_cast(getDirectAddress());
- }
-
- size_t getDirectSize() const {
- return getDirectCapacity();
- }
-};
-
-}}
diff --git a/libs/fbjni/cxx/fbjni/Context.h b/libs/fbjni/cxx/fbjni/Context.h
deleted file mode 100644
index 24427e8a3..000000000
--- a/libs/fbjni/cxx/fbjni/Context.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#pragma once
-
-#include
-#include
-
-namespace facebook {
-namespace jni {
-
-class AContext : public JavaClass {
- public:
- static constexpr const char* kJavaDescriptor = "Landroid/content/Context;";
-
- // Define a method that calls into the represented Java class
- local_ref getCacheDir() {
- static const auto method = getClass()->getMethod("getCacheDir");
- return method(self());
- }
-
- local_ref getFilesDir() {
- static const auto method = getClass()->getMethod("getFilesDir");
- return method(self());
- }
-};
-
-}
-}
diff --git a/libs/fbjni/cxx/fbjni/File.h b/libs/fbjni/cxx/fbjni/File.h
deleted file mode 100644
index 414deeef7..000000000
--- a/libs/fbjni/cxx/fbjni/File.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#pragma once
-
-#include
-
-namespace facebook {
-namespace jni {
-
-class JFile : public JavaClass {
- public:
- static constexpr const char* kJavaDescriptor = "Ljava/io/File;";
-
- // Define a method that calls into the represented Java class
- std::string getAbsolutePath() {
- static const auto method = getClass()->getMethod("getAbsolutePath");
- return method(self())->toStdString();
- }
-
-};
-
-}
-}
diff --git a/libs/fbjni/cxx/fbjni/JThread.h b/libs/fbjni/cxx/fbjni/JThread.h
deleted file mode 100644
index 671b247b6..000000000
--- a/libs/fbjni/cxx/fbjni/JThread.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#pragma once
-
-#include
-#include
-
-namespace facebook {
-namespace jni {
-
-class JThread : public JavaClass {
- public:
- static constexpr const char* kJavaDescriptor = "Ljava/lang/Thread;";
-
- void start() {
- static const auto method = javaClassStatic()->getMethod("start");
- method(self());
- }
-
- void join() {
- static const auto method = javaClassStatic()->getMethod("join");
- method(self());
- }
-
- static local_ref create(std::function&& runnable) {
- auto jrunnable = JNativeRunnable::newObjectCxxArgs(std::move(runnable));
- return newInstance(static_ref_cast(jrunnable));
- }
-
- static local_ref create(std::function&& runnable, std::string&& name) {
- auto jrunnable = JNativeRunnable::newObjectCxxArgs(std::move(runnable));
- return newInstance(static_ref_cast(jrunnable), make_jstring(std::move(name)));
- }
-
- static local_ref getCurrent() {
- static const auto method = javaClassStatic()->getStaticMethod()>("currentThread");
- return method(javaClassStatic());
- }
-
- int getPriority() {
- static const auto method = getClass()->getMethod("getPriority");
- return method(self());
- }
-
- void setPriority(int priority) {
- static const auto method = getClass()->getMethod("setPriority");
- method(self(), priority);
- }
-};
-
-}
-}
diff --git a/libs/fbjni/cxx/fbjni/NativeRunnable.h b/libs/fbjni/cxx/fbjni/NativeRunnable.h
deleted file mode 100644
index 054500d50..000000000
--- a/libs/fbjni/cxx/fbjni/NativeRunnable.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#pragma once
-
-#include
-
-#include
-
-namespace facebook {
-namespace jni {
-
-struct JRunnable : public JavaClass {
- static auto constexpr kJavaDescriptor = "Ljava/lang/Runnable;";
-};
-
-struct JNativeRunnable : public HybridClass {
- public:
- static auto constexpr kJavaDescriptor = "Lcom/facebook/jni/NativeRunnable;";
-
- JNativeRunnable(std::function&& runnable) : runnable_(std::move(runnable)) {}
-
- static void OnLoad() {
- registerHybrid({
- makeNativeMethod("run", JNativeRunnable::run),
- });
- }
-
- void run() {
- runnable_();
- }
-
- private:
- std::function runnable_;
-};
-
-
-} // namespace jni
-} // namespace facebook
diff --git a/libs/fbjni/cxx/fbjni/OnLoad.cpp b/libs/fbjni/cxx/fbjni/OnLoad.cpp
deleted file mode 100644
index 80b50622e..000000000
--- a/libs/fbjni/cxx/fbjni/OnLoad.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#include
-#include
-
-using namespace facebook::jni;
-
-JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
- return facebook::jni::initialize(vm, [] {
- HybridDataOnLoad();
- JNativeRunnable::OnLoad();
- ThreadScope::OnLoad();
- });
-}
diff --git a/libs/fbjni/cxx/fbjni/ReadableByteChannel.cpp b/libs/fbjni/cxx/fbjni/ReadableByteChannel.cpp
deleted file mode 100644
index 0c00601b5..000000000
--- a/libs/fbjni/cxx/fbjni/ReadableByteChannel.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#include
-
-namespace facebook {
-namespace jni {
-
-int JReadableByteChannel::read(alias_ref dest) const {
- if (!self()) {
- throwNewJavaException("java/lang/NullPointerException", "java.lang.NullPointerException");
- }
- static auto method = javaClassStatic()->getMethod)>("read");
- return method(self(), dest);
-}
-
-}}
-
diff --git a/libs/fbjni/cxx/fbjni/ReadableByteChannel.h b/libs/fbjni/cxx/fbjni/ReadableByteChannel.h
deleted file mode 100644
index 3ce0beda0..000000000
--- a/libs/fbjni/cxx/fbjni/ReadableByteChannel.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#pragma once
-
-#include
-#include
-
-namespace facebook {
-namespace jni {
-
-class JReadableByteChannel : public JavaClass {
-public:
- static constexpr const char* kJavaDescriptor = "Ljava/nio/channels/ReadableByteChannel;";
-
- int read(alias_ref dest) const;
-};
-
-}}
diff --git a/libs/fbjni/cxx/fbjni/detail/Boxed.h b/libs/fbjni/cxx/fbjni/detail/Boxed.h
deleted file mode 100644
index 87b79e51e..000000000
--- a/libs/fbjni/cxx/fbjni/detail/Boxed.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#pragma once
-
-#include "CoreClasses.h"
-
-namespace facebook {
-namespace jni {
-
-namespace detail {
-template
-struct JPrimitive : JavaClass {
- using typename JavaClass::javaobject;
- using JavaClass::javaClassStatic;
- static local_ref valueOf(jprim val) {
- static const auto cls = javaClassStatic();
- static const auto method =
- cls->template getStaticMethod("valueOf");
- return method(cls, val);
- }
- jprim value() const {
- static const auto method =
- javaClassStatic()->template getMethod(T::kValueMethod);
- return method(this->self());
- }
-};
-
-} // namespace detail
-
-
-#define DEFINE_BOXED_PRIMITIVE(LITTLE, BIG) \
- struct J ## BIG : detail::JPrimitive { \
- static auto constexpr kJavaDescriptor = "Ljava/lang/" #BIG ";"; \
- static auto constexpr kValueMethod = #LITTLE "Value"; \
- j ## LITTLE LITTLE ## Value() const { \
- return value(); \
- } \
- }; \
- inline local_ref 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
-
-template
-inline typename std::enable_if<
- (std::is_same::value || std::is_same::value) && !std::is_same::value,
- local_ref
->::type autobox(T val) {
- return JLong::valueOf(val);
-}
-
-struct JVoid : public jni::JavaClass {
- static auto constexpr kJavaDescriptor = "Ljava/lang/Void;";
-};
-
-inline local_ref autobox(alias_ref val) {
- return make_local(val);
-}
-
-}}
diff --git a/libs/fbjni/cxx/fbjni/detail/Common.h b/libs/fbjni/cxx/fbjni/detail/Common.h
deleted file mode 100644
index 1075cf19b..000000000
--- a/libs/fbjni/cxx/fbjni/detail/Common.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-/** @file Common.h
- *
- * Defining the stuff that don't deserve headers of their own...
- */
-
-#pragma once
-
-#include
-
-#include
-
-#ifdef FBJNI_DEBUG_REFS
-# ifdef __ANDROID__
-# include
-# else
-# include
-# endif
-#endif
-
-// If a pending JNI Java exception is found, wraps it in a JniException object and throws it as
-// a C++ exception.
-#define FACEBOOK_JNI_THROW_PENDING_EXCEPTION() \
- ::facebook::jni::throwPendingJniExceptionAsCppException()
-
-// If the condition is true, throws a JniException object, which wraps the pending JNI Java
-// exception if any. If no pending exception is found, throws a JniException object that wraps a
-// RuntimeException throwable.
-#define FACEBOOK_JNI_THROW_EXCEPTION_IF(CONDITION) \
- ::facebook::jni::throwCppExceptionIf(CONDITION)
-
-/// @cond INTERNAL
-
-namespace facebook {
-namespace jni {
-
-void throwPendingJniExceptionAsCppException();
-void throwCppExceptionIf(bool condition);
-
-[[noreturn]] void throwNewJavaException(jthrowable);
-[[noreturn]] void throwNewJavaException(const char* throwableName, const char* msg);
-template
-[[noreturn]] void throwNewJavaException(const char* throwableName, const char* fmt, Args... args);
-
-
-/**
- * This needs to be called at library load time, typically in your JNI_OnLoad method.
- *
- * The intended use is to return the result of initialize() directly
- * from JNI_OnLoad and to do nothing else there. Library specific
- * initialization code should go in the function passed to initialize
- * (which can be, and probably should be, a C++ lambda). This approach
- * provides correct error handling and translation errors during
- * initialization into Java exceptions when appropriate.
- *
- * Failure to call this will cause your code to crash in a remarkably
- * unhelpful way (typically a segfault) while trying to handle an exception
- * which occurs later.
- */
-jint initialize(JavaVM*, std::function&&) noexcept;
-
-namespace internal {
-
-// Define to get extremely verbose logging of references and to enable reference stats
-#ifdef FBJNI_DEBUG_REFS
-template
-inline void dbglog(const char* msg, Args... args) {
-# ifdef __ANDROID__
- __android_log_print(ANDROID_LOG_VERBOSE, "fbjni_dbg", msg, args...);
-# else
- std::fprintf(stderr, msg, args...);
-# endif
-}
-
-#else
-
-template
-inline void dbglog(const char*, Args...) {
-}
-
-#endif
-
-}}}
-
-/// @endcond
diff --git a/libs/fbjni/cxx/fbjni/detail/CoreClasses-inl.h b/libs/fbjni/cxx/fbjni/detail/CoreClasses-inl.h
deleted file mode 100644
index d4860aeee..000000000
--- a/libs/fbjni/cxx/fbjni/detail/CoreClasses-inl.h
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * Copyright (c) 2018-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the LICENSE
- * file in the root directory of this source tree.
- *
- */
-#pragma once
-
-#include
-#include
-#include
-
-#include "Common.h"
-#include "Exceptions.h"
-#include "Meta.h"
-#include "MetaConvert.h"
-
-namespace facebook {
-namespace jni {
-
-// jobject /////////////////////////////////////////////////////////////////////////////////////////
-
-inline bool isSameObject(alias_ref lhs, alias_ref rhs) noexcept {
- return Environment::current()->IsSameObject(lhs.get(), rhs.get()) != JNI_FALSE;
-}
-
-inline local_ref JObject::getClass() const noexcept {
- return adopt_local(Environment::current()->GetObjectClass(self()));
-}
-
-inline bool JObject::isInstanceOf(alias_ref cls) const noexcept {
- return Environment::current()->IsInstanceOf(self(), cls.get()) != JNI_FALSE;
-}
-
-template
-inline T JObject::getFieldValue(JField field) const noexcept {
- return field.get(self());
-}
-
-template
-inline local_ref JObject::getFieldValue(JField field) const noexcept {
- return adopt_local(field.get(self()));
-}
-
-template
-inline void JObject::setFieldValue(JField field, T value) noexcept {
- field.set(self(), value);
-}
-
-template
-inline void JObject::setFieldValue(JField field, alias_ref value) noexcept {
- setFieldValue(field, value.get());
-}
-
-inline std::string JObject::toString() const {
- static const auto method = findClassLocal("java/lang/Object")->getMethod("toString");
-
- return method(self())->toStdString();
-}
-
-
-// Class is here instead of CoreClasses.h because we need
-// alias_ref to be complete.
-class MonitorLock {
- public:
- inline MonitorLock() noexcept;
- inline MonitorLock(alias_ref object) noexcept;
- inline ~MonitorLock() noexcept;
-
- inline MonitorLock(MonitorLock&& other) noexcept;
- inline MonitorLock& operator=(MonitorLock&& other) noexcept;
-
- inline MonitorLock(const MonitorLock&) = delete;
- inline MonitorLock& operator=(const MonitorLock&) = delete;
-
- private:
- inline void reset() noexcept;
- alias_ref owned_;
-};
-
-MonitorLock::MonitorLock() noexcept : owned_(nullptr) {}
-
-MonitorLock::MonitorLock(alias_ref object) noexcept
- : owned_(object) {
- Environment::current()->MonitorEnter(object.get());
-}
-
-void MonitorLock::reset() noexcept {
- if (owned_) {
- Environment::current()->MonitorExit(owned_.get());
- if (Environment::current()->ExceptionCheck()) {
- abort(); // Lock mismatch
- }
- owned_ = nullptr;
- }
-}
-
-MonitorLock::~MonitorLock() noexcept {
- reset();
-}
-
-MonitorLock::MonitorLock(MonitorLock&& other) noexcept
- : owned_(other.owned_)
-{
- other.owned_ = nullptr;
-}
-
-MonitorLock& MonitorLock::operator=(MonitorLock&& other) noexcept {
- reset();
- owned_ = other.owned_;
- other.owned_ = nullptr;
- return *this;
-}
-
-inline MonitorLock JObject::lock() const noexcept {
- return MonitorLock(this_);
-}
-
-inline jobject JObject::self() const noexcept {
- return this_;
-}
-
-inline void swap(JObject& a, JObject& b) noexcept {
- using std::swap;
- swap(a.this_, b.this_);
-}
-
-// JavaClass ///////////////////////////////////////////////////////////////////////////////////////
-
-namespace detail {
-template
-static local_ref newInstance(Args... args) {
- static auto cls = JC::javaClassStatic();
- static const auto constructor = cls->template getConstructor();
- return cls->newObject(constructor, args...);
-}
-}
-
-
-template
-auto JavaClass::self() const noexcept -> javaobject {
- return static_cast(JObject::self());
-}
-
-// jclass //////////////////////////////////////////////////////////////////////////////////////////
-
-namespace detail {
-
-// This is not a real type. It is used so people won't accidentally
-// use a void* to initialize a NativeMethod.
-struct NativeMethodWrapper;
-
-}
-
-struct NativeMethod {
- const char* name;
- std::string descriptor;
- detail::NativeMethodWrapper* wrapper;
-};
-
-inline local_ref JClass::getSuperclass() const noexcept {
- return adopt_local(Environment::current()->GetSuperclass(self()));
-}
-
-inline void JClass::registerNatives(std::initializer_list methods) {
- const auto env = Environment::current();
-
- JNINativeMethod jnimethods[methods.size()];
- size_t i = 0;
- for (auto it = methods.begin(); it < methods.end(); ++it, ++i) {
- // The JNI struct members are unnecessarily non-const.
- jnimethods[i].name = const_cast(it->name);
- jnimethods[i].signature = const_cast(it->descriptor.c_str());
- jnimethods[i].fnPtr = reinterpret_cast(it->wrapper);
- }
-
- auto result = env->RegisterNatives(self(), jnimethods, methods.size());
- FACEBOOK_JNI_THROW_EXCEPTION_IF(result != JNI_OK);
-}
-
-inline bool JClass::isAssignableFrom(alias_ref other) const noexcept {
- const auto env = Environment::current();
- // Ths method has behavior compatible with the
- // java.lang.Class#isAssignableFrom method. The order of the
- // arguments to the JNI IsAssignableFrom C function is "opposite"
- // from what some might expect, which makes this code look a little
- // odd, but it is correct.
- const auto result = env->IsAssignableFrom(other.get(), self());
- return result;
-}
-
-template
-inline JConstructor JClass::getConstructor() const {
- return getConstructor(jmethod_traits_from_cxx::constructor_descriptor().c_str());
-}
-
-template
-inline JConstructor JClass::getConstructor(const char* descriptor) const {
- constexpr auto constructor_method_name = "";
- return getMethod(constructor_method_name, descriptor);
-}
-
-template
-inline JMethod JClass::getMethod(const char* name) const {
- return getMethod(name, jmethod_traits_from_cxx::descriptor().c_str());
-}
-
-template
-inline JMethod JClass::getMethod(
- const char* name,
- const char* descriptor) const {
- const auto env = Environment::current();
- const auto method = env->GetMethodID(self(), name, descriptor);
- FACEBOOK_JNI_THROW_EXCEPTION_IF(!method);
- return JMethod{method};
-}
-
-template
-inline JStaticMethod JClass::getStaticMethod(const char* name) const {
- return getStaticMethod(name, jmethod_traits_from_cxx::descriptor().c_str());
-}
-
-template
-inline JStaticMethod JClass::getStaticMethod(
- const char* name,
- const char* descriptor) const {
- const auto env = Environment::current();
- const auto method = env->GetStaticMethodID(self(), name, descriptor);
- FACEBOOK_JNI_THROW_EXCEPTION_IF(!method);
- return JStaticMethod{method};
-}
-
-template
-inline JNonvirtualMethod JClass::getNonvirtualMethod(const char* name) const {
- return getNonvirtualMethod(name, jmethod_traits_from_cxx::descriptor().c_str());
-}
-
-template
-inline JNonvirtualMethod JClass::getNonvirtualMethod(
- const char* name,
- const char* descriptor) const {
- const auto env = Environment::current();
- const auto method = env->GetMethodID(self(), name, descriptor);
- FACEBOOK_JNI_THROW_EXCEPTION_IF(!method);
- return JNonvirtualMethod{method};
-}
-
-template
-inline JField(), T>>
-JClass::getField(const char* name) const {
- return getField(name, jtype_traits::descriptor().c_str());
-}
-
-template
-inline JField(), T>> JClass::getField(
- const char* name,
- const char* descriptor) const {
- const auto env = Environment::current();
- auto field = env->GetFieldID(self(), name, descriptor);
- FACEBOOK_JNI_THROW_EXCEPTION_IF(!field);
- return JField{field};
-}
-
-template
-inline JStaticField(), T>> JClass::getStaticField(
- const char* name) const {
- return getStaticField(name, jtype_traits::descriptor().c_str());
-}
-
-template
-inline JStaticField(), T>> JClass::getStaticField(
- const char* name,
- const char* descriptor) const {
- const auto env = Environment::current();
- auto field = env->GetStaticFieldID(self(), name, descriptor);
- FACEBOOK_JNI_THROW_EXCEPTION_IF(!field);
- return JStaticField{field};
-}
-
-template
-inline T JClass::getStaticFieldValue(JStaticField field) const noexcept {
- return field.get(self());
-}
-
-template
-inline local_ref JClass::getStaticFieldValue(JStaticField field) noexcept {
- return adopt_local(field.get(self()));
-}
-
-template
-inline void JClass::setStaticFieldValue(JStaticField field, T value) noexcept {
- field.set(self(), value);
-}
-
-template
-inline void JClass::setStaticFieldValue(JStaticField field, alias_ref value) noexcept {
- setStaticFieldValue(field, value.get());
-}
-
-template
-inline local_ref JClass::newObject(
- JConstructor constructor,
- Args... args) const {
- const auto env = Environment::current();
- auto object = env->NewObject(self(), constructor.getId(),
- detail::callToJni(
- detail::Convert::type>::toCall(args))...);
- FACEBOOK_JNI_THROW_EXCEPTION_IF(!object);
- return adopt_local(static_cast(object));
-}
-
-inline jclass JClass::self() const noexcept {
- return static_cast(JObject::self());
-}
-
-inline void registerNatives(const char* name, std::initializer_list methods) {
- findClassLocal(name)->registerNatives(methods);
-}
-
-
-// jstring /////////////////////////////////////////////////////////////////////////////////////////
-
-inline local_ref make_jstring(const std::string& modifiedUtf8) {
- return make_jstring(modifiedUtf8.c_str());
-}
-
-namespace detail {
-// convert to std::string from jstring
-template <>
-struct Convert {
- typedef jstring jniType;
- static std::string fromJni(jniType t) {
- return wrap_alias(t)->toStdString();
- }
- static jniType toJniRet(const std::string& t) {
- return make_jstring(t).release();
- }
- static local_ref toCall(const std::string& t) {
- return make_jstring(t);
- }
-};
-
-// convert return from const char*
-template <>
-struct Convert {
- typedef jstring jniType;
- // no automatic synthesis of const char*. (It can't be freed.)
- static jniType toJniRet(const char* t) {
- return make_jstring(t).release();
- }
- static local_ref toCall(const char* t) {
- return make_jstring(t);
- }
-};
-}
-
-// jtypeArray //////////////////////////////////////////////////////////////////////////////////////
-
-namespace detail {
-inline size_t JArray::size() const noexcept {
- const auto env = Environment::current();
- return env->GetArrayLength(self());
-}
-}
-
-namespace detail {
-template
-inline ElementProxy::ElementProxy(
- Target* target,
- size_t idx)
- : target_{target}, idx_{idx} {}
-
-template
-inline ElementProxy& ElementProxy::operator=(const T& o) {
- target_->setElement(idx_, o);
- return *this;
-}
-
-template
-inline ElementProxy& ElementProxy::operator=(alias_ref& o) {
- target_->setElement(idx_, o.get());
- return *this;
-}
-
-template
-inline ElementProxy& ElementProxy::operator=(alias_ref&& o) {
- target_->setElement(idx_, o.get());
- return *this;
-}
-
-template
-inline ElementProxy& ElementProxy::operator=(const ElementProxy& o) {
- auto src = o.target_->getElement(o.idx_);
- target_->setElement(idx_, src.get());
- return *this;
-}
-
-template
-inline ElementProxy::ElementProxy::operator const local_ref () const {
- return target_->getElement(idx_);
-}
-
-template
-inline ElementProxy::ElementProxy::operator local_ref () {
- return target_->getElement(idx_);
-}
-}
-
-template
-std::string JArrayClass::get_instantiated_java_descriptor() {
- return "[" + jtype_traits::descriptor();
-};
-
-template
-std::string JArrayClass::get_instantiated_base_name() {
- return get_instantiated_java_descriptor();
-};
-
-template
-auto JArrayClass::newArray(size_t size) -> local_ref {
- static const auto elementClass = findClassStatic(jtype_traits::base_name().c_str());
- const auto env = Environment::current();
- auto rawArray = env->NewObjectArray(size, elementClass.get(), nullptr);
- FACEBOOK_JNI_THROW_EXCEPTION_IF(!rawArray);
- return adopt_local(static_cast(rawArray));
-}
-
-template
-inline void JArrayClass::setElement(size_t idx, const T& value) {
- const auto env = Environment::current();
- env->SetObjectArrayElement(this->self(), idx, value);
-}
-
-template
-inline local_ref JArrayClass::getElement(size_t idx) {
- const auto env = Environment::current();
- auto rawElement = env->GetObjectArrayElement(this->self(), idx);
- return adopt_local(static_cast(rawElement));
-}
-
-template
-inline detail::ElementProxy> JArrayClass::operator[](size_t index) {
- return detail::ElementProxy>(this, index);
-}
-
-template
-local_ref::javaobject> adopt_local_array(jobjectArray ref) {
- return adopt_local(static_cast::javaobject>(ref));
-}
-
-// jarray /////////////////////////////////////////////////////////////////////////////////////////
-
-template
-auto JPrimitiveArray::getRegion(jsize start, jsize length)
- -> std::unique_ptr {
- auto buf = std::unique_ptr{new T[length]};
- getRegion(start, length, buf.get());
- return buf;
-}
-
-template
-std::string JPrimitiveArray::get_instantiated_java_descriptor() {
- return jtype_traits::descriptor();
-}
-template
-std::string JPrimitiveArray::get_instantiated_base_name() {
- return JPrimitiveArray::get_instantiated_java_descriptor();
-}
-
-template
-auto JPrimitiveArray::pin() -> PinnedPrimitiveArray> {
- return PinnedPrimitiveArray>{this->self(), 0, 0};
-}
-
-template
-auto JPrimitiveArray::pinRegion(jsize start, jsize length)
- -> PinnedPrimitiveArray> {
- return PinnedPrimitiveArray>{this->self(), start, length};
-}
-
-template
-auto JPrimitiveArray::pinCritical()
- -> PinnedPrimitiveArray> {
- return PinnedPrimitiveArray>{this->self(), 0, 0};
-}
-
-template
-class PinnedArrayAlloc {
- public:
- static void allocate(
- alias_ref::array_type> array,
- jsize start,
- jsize length,
- T** elements,
- size_t* size,
- jboolean* isCopy) {
- (void) start;
- (void) length;
- *elements = array->getElements(isCopy);
- *size = array->size();
- }
- static void release(
- alias_ref::array_type> array,
- T* elements,
- jint start,
- jint size,
- jint mode) {
- (void) start;
- (void) size;
- array->releaseElements(elements, mode);
- }
-};
-
-template
-class PinnedCriticalAlloc {
- public:
- static void allocate(
- alias_ref::array_type> array,
- jsize start,
- jsize length,
- T** elements,
- size_t* size,
- jboolean* isCopy) {
- (void)start;
- (void)length;
- const auto env = Environment::current();
- *elements = static_cast(env->GetPrimitiveArrayCritical(array.get(), isCopy));
- FACEBOOK_JNI_THROW_EXCEPTION_IF(!elements);
- *size = array->size();
- }
- static void release(
- alias_ref::array_type> array,
- T* elements,
- jint start,
- jint size,
- jint mode) {
- (void)start;
- (void)size;
- const auto env = Environment::current();
- env->ReleasePrimitiveArrayCritical(array.get(), elements, mode);
- }
-};
-
-template
-class PinnedRegionAlloc {
- public:
- static void allocate(
- alias_ref::array_type> array,
- jsize start,
- jsize length,
- T** elements,
- size_t* size,
- jboolean* isCopy) {
- auto buf = array->getRegion(start, length);
- FACEBOOK_JNI_THROW_EXCEPTION_IF(!buf);
- *elements = buf.release();
- *size = length;
- *isCopy = true;
- }
- static void release(
- alias_ref