Add hybrid class to hold native delta client

Summary:
Adds hybrid JNI wrapper class that can hold a native delta client.

This class allows Java code in the `devsupport` package to hold onto a native delta client across reloads.
It also takes care of passing `okhttp` response objects to native code, where we build a `std::string` to hold JSON messages coming from Metro, and parse them with `folly::parseJson`.

In a follow-up, we will switch to a streaming-friendly binary format that will make allocating memory for the whole message unnecessary.

Reviewed By: fromcelticpark

Differential Revision: D7845138

fbshipit-source-id: 7a29b30645331addf843097dd0d05c03b3143991
This commit is contained in:
David Aurelio 2018-05-03 08:38:03 -07:00 коммит произвёл Facebook Github Bot
Родитель 4d931d529e
Коммит 82b8a9221a
5 изменённых файлов: 120 добавлений и 0 удалений

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

@ -0,0 +1,25 @@
/**
* 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.
*/
package com.facebook.react.bridge;
import java.nio.channels.ReadableByteChannel;
import com.facebook.jni.HybridData;
public class NativeDeltaClient {
static {
ReactBridge.staticInit();
}
// C++ parts
private final HybridData mHybridData = initHybrid();
private native static HybridData initHybrid();
public native void reset();
public native void processDelta(ReadableByteChannel deltaMessage);
}

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

@ -18,6 +18,7 @@ LOCAL_SRC_FILES := \
ModuleRegistryBuilder.cpp \
NativeArray.cpp \
NativeCommon.cpp \
NativeDeltaClient.cpp \
NativeMap.cpp \
OnLoad.cpp \
ProxyExecutor.cpp \

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

@ -0,0 +1,54 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#include "NativeDeltaClient.h"
#include <sstream>
#include <fb/fbjni/ByteBuffer.h>
#include <folly/json.h>
namespace facebook {
namespace react {
jni::local_ref<NativeDeltaClient::jhybriddata> NativeDeltaClient::initHybrid(
jni::alias_ref<jclass>) {
return makeCxxInstance();
}
void NativeDeltaClient::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", NativeDeltaClient::initHybrid),
makeNativeMethod("processDelta", NativeDeltaClient::jniProcessDelta),
makeNativeMethod("reset", NativeDeltaClient::jniReset),
});
}
void NativeDeltaClient::jniProcessDelta(
jni::alias_ref<jni::JReadableByteChannel> delta) {
std::ostringstream deltaMessage;
std::vector<uint8_t> buffer(8192);
auto byteBuffer = jni::JByteBuffer::wrapBytes(buffer.data(), buffer.size());
size_t pos = 0;
int read = 0;
do {
read = delta->read(byteBuffer);
if (read < 1) {
deltaMessage.write(reinterpret_cast<const char *>(buffer.data()), pos);
byteBuffer->rewind();
pos = 0;
} else {
pos += read;
}
} while (read != -1);
deltaClient_->patch(folly::parseJson(deltaMessage.str()));
}
void NativeDeltaClient::jniReset() {
deltaClient_->clear();
}
} // namespace react
} // namespace facebook

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

@ -0,0 +1,38 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#pragma once
#include <memory>
#include <cxxreact/JSDeltaBundleClient.h>
#include <fb/fbjni.h>
#include <fb/fbjni/Hybrid.h>
#include <fb/fbjni/ReadableByteChannel.h>
namespace facebook {
namespace react {
class NativeDeltaClient : public jni::HybridClass<NativeDeltaClient> {
public:
static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/NativeDeltaClient;";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
static void registerNatives();
~NativeDeltaClient() override = default;
std::shared_ptr<const JSDeltaBundleClient> getDeltaClient() {
return deltaClient_;
}
private:
friend HybridBase;
void jniProcessDelta(jni::alias_ref<jni::JReadableByteChannel> delta);
void jniReset();
const std::shared_ptr<JSDeltaBundleClient> deltaClient_ =
std::make_shared<JSDeltaBundleClient>();
};
} // namespace react
} // namespace facebook

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

@ -16,6 +16,7 @@
#include "CxxModuleWrapper.h"
#include "JavaScriptExecutorHolder.h"
#include "JCallback.h"
#include "NativeDeltaClient.h"
#include "ProxyExecutor.h"
#include "WritableNativeArray.h"
#include "WritableNativeMap.h"
@ -91,6 +92,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
CxxModuleWrapper::registerNatives();
JCxxCallbackImpl::registerNatives();
NativeArray::registerNatives();
NativeDeltaClient::registerNatives();
ReadableNativeArray::registerNatives();
WritableNativeArray::registerNatives();
NativeMap::registerNatives();