Add Java JNI bindings

Reviewed By: mhorowitz

Differential Revision: D4021520

fbshipit-source-id: dbaf2ebb7fa48f4efe6cf47a97c39bb079dda8d0
This commit is contained in:
Alexander Blom 2016-11-02 12:18:20 -07:00 committed by Facebook Github Bot
parent fbc8410d86
commit 788e2775f6
5 changed files with 241 additions and 0 deletions

View File

@ -0,0 +1,81 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.react.bridge;
import java.util.Arrays;
import java.util.List;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public class Inspector {
static {
ReactBridge.staticInit();
}
private final HybridData mHybridData;
public static List<Page> getPages() {
return Arrays.asList(instance().getPagesNative());
}
public static LocalConnection connect(int pageId, RemoteConnection remote) {
return instance().connectNative(pageId, remote);
}
private static native Inspector instance();
private native Page[] getPagesNative();
private native LocalConnection connectNative(int pageId, RemoteConnection remote);
private Inspector(HybridData hybridData) {
mHybridData = hybridData;
}
@DoNotStrip
public static class Page {
private final int mId;
private final String mTitle;
public int getId() {
return mId;
}
public String getTitle() {
return mTitle;
}
@Override
public String toString() {
return "Page{" +
"mId=" + mId +
", mTitle='" + mTitle + '\'' +
'}';
}
private Page(int id, String title) {
mId = id;
mTitle = title;
}
}
@DoNotStrip
public interface RemoteConnection {
void onMessage(String message);
void onDisconnect();
}
@DoNotStrip
public static class LocalConnection {
private final HybridData mHybridData;
public native void sendMessage(String message);
public native void disconnect();
private LocalConnection(HybridData hybridData) {
mHybridData = hybridData;
}
}
}

View File

@ -27,6 +27,7 @@ cxx_library(
'//xplat/fbsystrace:fbsystrace',
react_native_xplat_target('cxxreact:bridge'),
react_native_xplat_target('cxxreact:module'),
react_native_xplat_target('inspector:inspector'),
],
srcs = glob(['*.cpp']),
xcode_public_headers_symlinks = True,
@ -35,6 +36,7 @@ cxx_library(
preprocessor_flags = [
'-DLOG_TAG="ReactNativeJNI"',
'-DWITH_FBSYSTRACE=1',
'-DWITH_INSPECTOR=1',
],
compiler_flags = [
'-Wall',

View File

@ -0,0 +1,90 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#include "JInspector.h"
namespace facebook {
namespace react {
namespace {
class RemoteConnection : public Inspector::RemoteConnection {
public:
RemoteConnection(jni::alias_ref<JRemoteConnection::javaobject> connection)
: connection_(jni::make_global(connection)) {}
void onMessage(std::string message) override {
connection_->onMessage(message);
}
void onDisconnect() override {
connection_->onDisconnect();
}
private:
jni::global_ref<JRemoteConnection::javaobject> connection_;
};
}
jni::local_ref<JPage::javaobject> JPage::create(int id, const std::string& title) {
static auto constructor = javaClassStatic()->getConstructor<JPage::javaobject(jint, jni::local_ref<jni::JString>)>();
return javaClassStatic()->newObject(constructor, id, jni::make_jstring(title));
}
void JRemoteConnection::onMessage(const std::string& message) const {
static auto method = javaClassStatic()->getMethod<void(jni::local_ref<jstring>)>("onMessage");
method(self(), jni::make_jstring(message));
}
void JRemoteConnection::onDisconnect() const {
static auto method = javaClassStatic()->getMethod<void()>("onDisconnect");
method(self());
}
JLocalConnection::JLocalConnection(std::unique_ptr<Inspector::LocalConnection> connection)
: connection_(std::move(connection)) {}
void JLocalConnection::sendMessage(std::string message) {
connection_->sendMessage(std::move(message));
}
void JLocalConnection::disconnect() {
connection_->disconnect();
}
void JLocalConnection::registerNatives() {
javaClassStatic()->registerNatives({
makeNativeMethod("sendMessage", JLocalConnection::sendMessage),
makeNativeMethod("disconnect", JLocalConnection::disconnect),
});
}
jni::global_ref<JInspector::javaobject> JInspector::instance(jni::alias_ref<jclass>) {
static auto instance = jni::make_global(newObjectCxxArgs(&Inspector::instance()));
return instance;
}
jni::local_ref<jni::JArrayClass<JPage::javaobject>> JInspector::getPages() {
std::vector<Inspector::Page> pages = inspector_->getPages();
auto array = jni::JArrayClass<JPage::javaobject>::newArray(pages.size());
for (size_t i = 0; i < pages.size(); i++) {
(*array)[i] = JPage::create(pages[i].id, pages[i].title);
}
return array;
}
jni::local_ref<JLocalConnection::javaobject> JInspector::connect(int pageId, jni::alias_ref<JRemoteConnection::javaobject> remote) {
auto localConnection = inspector_->connect(pageId, folly::make_unique<RemoteConnection>(std::move(remote)));
return JLocalConnection::newObjectCxxArgs(std::move(localConnection));
}
void JInspector::registerNatives() {
JLocalConnection::registerNatives();
javaClassStatic()->registerNatives({
makeNativeMethod("instance", JInspector::instance),
makeNativeMethod("getPagesNative", JInspector::getPages),
makeNativeMethod("connectNative", JInspector::connect),
});
}
}
}

View File

@ -0,0 +1,61 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#pragma once
#include <inspector/Inspector.h>
#include <fb/fbjni.h>
#include <folly/Memory.h>
namespace facebook {
namespace react {
class JPage : public jni::JavaClass<JPage> {
public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$Page;";
static jni::local_ref<JPage::javaobject> create(int id, const std::string& title);
};
class JRemoteConnection : public jni::JavaClass<JRemoteConnection> {
public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$RemoteConnection;";
void onMessage(const std::string& message) const;
void onDisconnect() const;
};
class JLocalConnection : public jni::HybridClass<JLocalConnection> {
public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$LocalConnection;";
JLocalConnection(std::unique_ptr<Inspector::LocalConnection> connection);
void sendMessage(std::string message);
void disconnect();
static void registerNatives();
private:
std::unique_ptr<Inspector::LocalConnection> connection_;
};
class JInspector : public jni::HybridClass<JInspector> {
public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector;";
static jni::global_ref<JInspector::javaobject> instance(jni::alias_ref<jclass>);
jni::local_ref<jni::JArrayClass<JPage::javaobject>> getPages();
jni::local_ref<JLocalConnection::javaobject> connect(int pageId, jni::alias_ref<JRemoteConnection::javaobject> remote);
static void registerNatives();
private:
friend HybridBase;
JInspector(Inspector* inspector) : inspector_(inspector) {}
Inspector* inspector_;
};
}
}

View File

@ -16,6 +16,10 @@
#include "WebWorkers.h"
#include "JCallback.h"
#ifdef WITH_INSPECTOR
#include "JInspector.h"
#endif
#include "WritableNativeMap.h"
#include "WritableNativeArray.h"
@ -181,6 +185,9 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
ModuleRegistryHolder::registerNatives();
CxxModuleWrapper::registerNatives();
JCallbackImpl::registerNatives();
#ifdef WITH_INSPECTOR
JInspector::registerNatives();
#endif
registerJSLoaderNatives();
NativeArray::registerNatives();