From 76f6a54327837bd1d791528409b9b0704e37bb76 Mon Sep 17 00:00:00 2001 From: Emil Sjolander Date: Wed, 26 Apr 2017 07:29:50 -0700 Subject: [PATCH] Update fbjni Summary: Update yoga's copy of fbjni to include some missing java files. Reviewed By: IanChilds Differential Revision: D4953841 fbshipit-source-id: 74d5c617a6fcd11e82c86f03e61448b14a34b86b --- YOGA_DEFS | 1 + lib/fb/BUCK | 1 + lib/fb/src/main/java/com/facebook/jni/BUCK | 22 ++++++++ .../main/java/com/facebook/jni/Countable.java | 35 ++++++++++++ .../com/facebook/jni}/CppException.java | 0 .../jni}/CppSystemErrorException.java | 0 .../java/com/facebook/jni/HybridData.java | 49 ++++++++++++++++ .../java/com/facebook/jni/IteratorHelper.java | 56 +++++++++++++++++++ .../com/facebook/jni/MapIteratorHelper.java | 53 ++++++++++++++++++ .../java/com/facebook/jni/NativeRunnable.java | 28 ++++++++++ .../com/facebook/jni/ThreadScopeSupport.java | 22 ++++++++ .../facebook/jni}/UnknownCppException.java | 0 .../src/main/java/com/facebook/jni/fbjni.pro | 11 ++++ 13 files changed, 278 insertions(+) create mode 100644 lib/fb/src/main/java/com/facebook/jni/BUCK create mode 100644 lib/fb/src/main/java/com/facebook/jni/Countable.java rename lib/fb/src/main/{cpp/jni/java => java/com/facebook/jni}/CppException.java (100%) rename lib/fb/src/main/{cpp/jni/java => java/com/facebook/jni}/CppSystemErrorException.java (100%) create mode 100644 lib/fb/src/main/java/com/facebook/jni/HybridData.java create mode 100644 lib/fb/src/main/java/com/facebook/jni/IteratorHelper.java create mode 100644 lib/fb/src/main/java/com/facebook/jni/MapIteratorHelper.java create mode 100644 lib/fb/src/main/java/com/facebook/jni/NativeRunnable.java create mode 100644 lib/fb/src/main/java/com/facebook/jni/ThreadScopeSupport.java rename lib/fb/src/main/{cpp/jni/java => java/com/facebook/jni}/UnknownCppException.java (100%) create mode 100644 lib/fb/src/main/java/com/facebook/jni/fbjni.pro diff --git a/YOGA_DEFS b/YOGA_DEFS index c4242f5b..09faa1b7 100644 --- a/YOGA_DEFS +++ b/YOGA_DEFS @@ -9,6 +9,7 @@ SOLOADER_TARGET = '//lib/soloader:soloader' GTEST_TARGET = '//lib/gtest:gtest' JNI_TARGET = '//lib/jni:jni' FBJNI_TARGET = '//lib/fb:fbjni' +FBJNI_JAVA_TARGET = '//lib/fb/src/main/java/com/facebook/jni:jni' APPCOMPAT_TARGET = '//lib/appcompat:appcompat' ANDROID_SUPPORT_TARGET = '//lib/android-support:android-support' ANDROID_TARGET = '//android:android' diff --git a/lib/fb/BUCK b/lib/fb/BUCK index 5519091a..5e780dc7 100644 --- a/lib/fb/BUCK +++ b/lib/fb/BUCK @@ -40,6 +40,7 @@ cxx_library( visibility = ["PUBLIC"], deps = [ ":ndklog", + FBJNI_JAVA_TARGET, JNI_TARGET, ], ) diff --git a/lib/fb/src/main/java/com/facebook/jni/BUCK b/lib/fb/src/main/java/com/facebook/jni/BUCK new file mode 100644 index 00000000..280e6a33 --- /dev/null +++ b/lib/fb/src/main/java/com/facebook/jni/BUCK @@ -0,0 +1,22 @@ +# Copyright (c) 2014-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_defs("//YOGA_DEFS") + +android_library( + name = "jni", + srcs = glob(["**/*.java"]), + proguard_config = "fbjni.pro", + visibility = [ + "PUBLIC", + ], + deps = [ + PROGRUARD_ANNOTATIONS_TARGET, + SOLOADER_TARGET, + JSR_305_TARGET, + ], +) diff --git a/lib/fb/src/main/java/com/facebook/jni/Countable.java b/lib/fb/src/main/java/com/facebook/jni/Countable.java new file mode 100644 index 00000000..a319e187 --- /dev/null +++ b/lib/fb/src/main/java/com/facebook/jni/Countable.java @@ -0,0 +1,35 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.soloader.SoLoader; + +/** + * A Java Object that has native memory allocated corresponding to this instance. + * + * NB: THREAD SAFETY (this comment also exists at Countable.cpp) + * + * {@link #dispose} 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 + * will be deleted synchronously on that thread. + */ +@DoNotStrip +public class Countable { + + static { + SoLoader.loadLibrary("fb"); + } + + // Private C++ instance + @DoNotStrip + private long mInstance = 0; + + public native void dispose(); + + protected void finalize() throws Throwable { + dispose(); + super.finalize(); + } +} diff --git a/lib/fb/src/main/cpp/jni/java/CppException.java b/lib/fb/src/main/java/com/facebook/jni/CppException.java similarity index 100% rename from lib/fb/src/main/cpp/jni/java/CppException.java rename to lib/fb/src/main/java/com/facebook/jni/CppException.java diff --git a/lib/fb/src/main/cpp/jni/java/CppSystemErrorException.java b/lib/fb/src/main/java/com/facebook/jni/CppSystemErrorException.java similarity index 100% rename from lib/fb/src/main/cpp/jni/java/CppSystemErrorException.java rename to lib/fb/src/main/java/com/facebook/jni/CppSystemErrorException.java diff --git a/lib/fb/src/main/java/com/facebook/jni/HybridData.java b/lib/fb/src/main/java/com/facebook/jni/HybridData.java new file mode 100644 index 00000000..e0b864b0 --- /dev/null +++ b/lib/fb/src/main/java/com/facebook/jni/HybridData.java @@ -0,0 +1,49 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.soloader.SoLoader; + +/** + * This object holds a native C++ member for hybrid Java/C++ objects. + * + * NB: THREAD SAFETY + * + * {@link #dispose} deletes the corresponding native object on whatever thread + * the method is called on. In the common case when this is called by + * HybridData#finalize(), this will be called on the system finalizer + * thread. If you manually call resetNative() on the Java object, the C++ + * object will be deleted synchronously on that thread. + */ +@DoNotStrip +public class HybridData { + + static { + SoLoader.loadLibrary("fb"); + } + + // Private C++ instance + @DoNotStrip + private long mNativePointer = 0; + + /** + * To explicitly delete the instance, call resetNative(). If the C++ + * instance is referenced after this is called, a NullPointerException will + * be thrown. resetNative() may be called multiple times safely. Because + * {@link #finalize} calls resetNative, the instance will not leak if this is + * not called, but timing of deletion and the thread the C++ dtor is called + * on will be at the whim of the Java GC. If you want to control the thread + * and timing of the destructor, you should call resetNative() explicitly. + */ + public native void resetNative(); + + protected void finalize() throws Throwable { + resetNative(); + super.finalize(); + } + + public boolean isValid() { + return mNativePointer != 0; + } +} diff --git a/lib/fb/src/main/java/com/facebook/jni/IteratorHelper.java b/lib/fb/src/main/java/com/facebook/jni/IteratorHelper.java new file mode 100644 index 00000000..aca1cb50 --- /dev/null +++ b/lib/fb/src/main/java/com/facebook/jni/IteratorHelper.java @@ -0,0 +1,56 @@ +/** + * 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; + +import javax.annotation.Nullable; + +import java.util.Iterator; + +/** + * To iterate over an Iterator from C++ requires two calls per entry: hasNext() + * and next(). This helper reduces it to one call and one field get per entry. + * It does not use a generic argument, since in C++, the types will be erased, + * anyway. This is *not* a {@link java.util.Iterator}. + */ +@DoNotStrip +public class IteratorHelper { + private final Iterator mIterator; + + // This is private, but accessed via JNI. + @DoNotStrip + private @Nullable Object mElement; + + @DoNotStrip + public IteratorHelper(Iterator iterator) { + mIterator = iterator; + } + + @DoNotStrip + public IteratorHelper(Iterable iterable) { + mIterator = iterable.iterator(); + } + + /** + * Moves the helper to the next entry in the map, if any. Returns true iff + * there is an entry to read. + */ + @DoNotStrip + boolean hasNext() { + if (mIterator.hasNext()) { + mElement = mIterator.next(); + return true; + } else { + mElement = null; + return false; + } + } +} diff --git a/lib/fb/src/main/java/com/facebook/jni/MapIteratorHelper.java b/lib/fb/src/main/java/com/facebook/jni/MapIteratorHelper.java new file mode 100644 index 00000000..aa9283ed --- /dev/null +++ b/lib/fb/src/main/java/com/facebook/jni/MapIteratorHelper.java @@ -0,0 +1,53 @@ +/** + * 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 javax.annotation.Nullable; + +import java.util.Iterator; +import java.util.Map; + +import com.facebook.proguard.annotations.DoNotStrip; + +/** + * To iterate over a Map from C++ requires four calls per entry: hasNext(), + * next(), getKey(), getValue(). This helper reduces it to one call and two + * field gets per entry. It does not use a generic argument, since in C++, the + * types will be erased, anyway. This is *not* a {@link java.util.Iterator}. + */ +@DoNotStrip +public class MapIteratorHelper { + @DoNotStrip private final Iterator mIterator; + @DoNotStrip private @Nullable Object mKey; + @DoNotStrip private @Nullable Object mValue; + + @DoNotStrip + public MapIteratorHelper(Map map) { + mIterator = map.entrySet().iterator(); + } + + /** + * Moves the helper to the next entry in the map, if any. Returns true iff + * there is an entry to read. + */ + @DoNotStrip + boolean hasNext() { + if (mIterator.hasNext()) { + Map.Entry entry = mIterator.next(); + mKey = entry.getKey(); + mValue = entry.getValue(); + return true; + } else { + mKey = null; + mValue = null; + return false; + } + } +} diff --git a/lib/fb/src/main/java/com/facebook/jni/NativeRunnable.java b/lib/fb/src/main/java/com/facebook/jni/NativeRunnable.java new file mode 100644 index 00000000..151cc8ad --- /dev/null +++ b/lib/fb/src/main/java/com/facebook/jni/NativeRunnable.java @@ -0,0 +1,28 @@ +/** + * 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.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; + +/** + * A Runnable that has a native run implementation. + */ +@DoNotStrip +public class NativeRunnable implements Runnable { + + private final HybridData mHybridData; + + private NativeRunnable(HybridData hybridData) { + mHybridData = hybridData; + } + + public native void run(); +} diff --git a/lib/fb/src/main/java/com/facebook/jni/ThreadScopeSupport.java b/lib/fb/src/main/java/com/facebook/jni/ThreadScopeSupport.java new file mode 100644 index 00000000..89610c43 --- /dev/null +++ b/lib/fb/src/main/java/com/facebook/jni/ThreadScopeSupport.java @@ -0,0 +1,22 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.soloader.SoLoader; + +@DoNotStrip +public class ThreadScopeSupport { + static { + SoLoader.loadLibrary("fb"); + } + + // This is just used for ThreadScope::withClassLoader to have a java function + // in the stack so that jni has access to the correct classloader. + @DoNotStrip + private static void runStdFunction(long ptr) { + runStdFunctionImpl(ptr); + } + + private static native void runStdFunctionImpl(long ptr); +} diff --git a/lib/fb/src/main/cpp/jni/java/UnknownCppException.java b/lib/fb/src/main/java/com/facebook/jni/UnknownCppException.java similarity index 100% rename from lib/fb/src/main/cpp/jni/java/UnknownCppException.java rename to lib/fb/src/main/java/com/facebook/jni/UnknownCppException.java diff --git a/lib/fb/src/main/java/com/facebook/jni/fbjni.pro b/lib/fb/src/main/java/com/facebook/jni/fbjni.pro new file mode 100644 index 00000000..5b5b6454 --- /dev/null +++ b/lib/fb/src/main/java/com/facebook/jni/fbjni.pro @@ -0,0 +1,11 @@ +# For common use cases for the hybrid pattern, keep symbols which may +# be referenced only from C++. + +-keepclassmembers class * { + com.facebook.jni.HybridData *; + (com.facebook.jni.HybridData); +} + +-keepclasseswithmembers class * { + com.facebook.jni.HybridData *; +}