Decouple module callback mechanism from CatalystInstance

Summary:
Create a JSInstance superinterface which doesn't include all
the lifecycle stuff.

Reviewed By: AaaChiuuu

Differential Revision: D4614410

fbshipit-source-id: 16047bbcb1bb69bf36a0a13ef68f3a6aa396a991
This commit is contained in:
Marc Horowitz 2017-03-14 15:28:52 -07:00 committed by Facebook Github Bot
parent 7e4b8ff000
commit 6410e256c5
8 changed files with 74 additions and 45 deletions

View File

@ -59,14 +59,14 @@ public abstract class BaseJavaModule implements NativeModule {
} }
public abstract @Nullable T extractArgument( public abstract @Nullable T extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex); JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex);
} }
static final private ArgumentExtractor<Boolean> ARGUMENT_EXTRACTOR_BOOLEAN = static final private ArgumentExtractor<Boolean> ARGUMENT_EXTRACTOR_BOOLEAN =
new ArgumentExtractor<Boolean>() { new ArgumentExtractor<Boolean>() {
@Override @Override
public Boolean extractArgument( public Boolean extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getBoolean(atIndex); return jsArguments.getBoolean(atIndex);
} }
}; };
@ -75,7 +75,7 @@ public abstract class BaseJavaModule implements NativeModule {
new ArgumentExtractor<Double>() { new ArgumentExtractor<Double>() {
@Override @Override
public Double extractArgument( public Double extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getDouble(atIndex); return jsArguments.getDouble(atIndex);
} }
}; };
@ -84,7 +84,7 @@ public abstract class BaseJavaModule implements NativeModule {
new ArgumentExtractor<Float>() { new ArgumentExtractor<Float>() {
@Override @Override
public Float extractArgument( public Float extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
return (float) jsArguments.getDouble(atIndex); return (float) jsArguments.getDouble(atIndex);
} }
}; };
@ -93,7 +93,7 @@ public abstract class BaseJavaModule implements NativeModule {
new ArgumentExtractor<Integer>() { new ArgumentExtractor<Integer>() {
@Override @Override
public Integer extractArgument( public Integer extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
return (int) jsArguments.getDouble(atIndex); return (int) jsArguments.getDouble(atIndex);
} }
}; };
@ -102,7 +102,7 @@ public abstract class BaseJavaModule implements NativeModule {
new ArgumentExtractor<String>() { new ArgumentExtractor<String>() {
@Override @Override
public String extractArgument( public String extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getString(atIndex); return jsArguments.getString(atIndex);
} }
}; };
@ -111,7 +111,7 @@ public abstract class BaseJavaModule implements NativeModule {
new ArgumentExtractor<ReadableNativeArray>() { new ArgumentExtractor<ReadableNativeArray>() {
@Override @Override
public ReadableNativeArray extractArgument( public ReadableNativeArray extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getArray(atIndex); return jsArguments.getArray(atIndex);
} }
}; };
@ -120,7 +120,7 @@ public abstract class BaseJavaModule implements NativeModule {
new ArgumentExtractor<Dynamic>() { new ArgumentExtractor<Dynamic>() {
@Override @Override
public Dynamic extractArgument( public Dynamic extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
return DynamicFromArray.create(jsArguments, atIndex); return DynamicFromArray.create(jsArguments, atIndex);
} }
}; };
@ -129,7 +129,7 @@ public abstract class BaseJavaModule implements NativeModule {
new ArgumentExtractor<ReadableMap>() { new ArgumentExtractor<ReadableMap>() {
@Override @Override
public ReadableMap extractArgument( public ReadableMap extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getMap(atIndex); return jsArguments.getMap(atIndex);
} }
}; };
@ -138,12 +138,12 @@ public abstract class BaseJavaModule implements NativeModule {
new ArgumentExtractor<Callback>() { new ArgumentExtractor<Callback>() {
@Override @Override
public @Nullable Callback extractArgument( public @Nullable Callback extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
if (jsArguments.isNull(atIndex)) { if (jsArguments.isNull(atIndex)) {
return null; return null;
} else { } else {
int id = (int) jsArguments.getDouble(atIndex); int id = (int) jsArguments.getDouble(atIndex);
return new CallbackImpl(catalystInstance, executorToken, id); return new CallbackImpl(jsInstance, executorToken, id);
} }
} }
}; };
@ -157,11 +157,11 @@ public abstract class BaseJavaModule implements NativeModule {
@Override @Override
public Promise extractArgument( public Promise extractArgument(
CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
Callback resolve = ARGUMENT_EXTRACTOR_CALLBACK Callback resolve = ARGUMENT_EXTRACTOR_CALLBACK
.extractArgument(catalystInstance, executorToken, jsArguments, atIndex); .extractArgument(jsInstance, executorToken, jsArguments, atIndex);
Callback reject = ARGUMENT_EXTRACTOR_CALLBACK Callback reject = ARGUMENT_EXTRACTOR_CALLBACK
.extractArgument(catalystInstance, executorToken, jsArguments, atIndex + 1); .extractArgument(jsInstance, executorToken, jsArguments, atIndex + 1);
return new PromiseImpl(resolve, reject); return new PromiseImpl(resolve, reject);
} }
}; };
@ -307,7 +307,7 @@ public abstract class BaseJavaModule implements NativeModule {
} }
@Override @Override
public void invoke(CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray parameters) { public void invoke(JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray parameters) {
SystraceMessage.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "callJavaModuleMethod") SystraceMessage.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "callJavaModuleMethod")
.arg("method", mTraceName) .arg("method", mTraceName)
.flush(); .flush();
@ -329,7 +329,7 @@ public abstract class BaseJavaModule implements NativeModule {
try { try {
for (; i < mArgumentExtractors.length; i++) { for (; i < mArgumentExtractors.length; i++) {
mArguments[i + executorTokenOffset] = mArgumentExtractors[i].extractArgument( mArguments[i + executorTokenOffset] = mArgumentExtractors[i].extractArgument(
catalystInstance, executorToken, parameters, jsArgumentsConsumed); jsInstance, executorToken, parameters, jsArgumentsConsumed);
jsArgumentsConsumed += mArgumentExtractors[i].getJSArgumentsNeeded(); jsArgumentsConsumed += mArgumentExtractors[i].getJSArgumentsNeeded();
} }
} catch (UnexpectedNativeTypeException e) { } catch (UnexpectedNativeTypeException e) {

View File

@ -14,13 +14,13 @@ package com.facebook.react.bridge;
*/ */
public final class CallbackImpl implements Callback { public final class CallbackImpl implements Callback {
private final CatalystInstance mCatalystInstance; private final JSInstance mJSInstance;
private final ExecutorToken mExecutorToken; private final ExecutorToken mExecutorToken;
private final int mCallbackId; private final int mCallbackId;
private boolean mInvoked; private boolean mInvoked;
public CallbackImpl(CatalystInstance bridge, ExecutorToken executorToken, int callbackId) { public CallbackImpl(JSInstance jsInstance, ExecutorToken executorToken, int callbackId) {
mCatalystInstance = bridge; mJSInstance = jsInstance;
mExecutorToken = executorToken; mExecutorToken = executorToken;
mCallbackId = callbackId; mCallbackId = callbackId;
mInvoked = false; mInvoked = false;
@ -33,7 +33,7 @@ public final class CallbackImpl implements Callback {
"module. This callback type only permits a single invocation from "+ "module. This callback type only permits a single invocation from "+
"native code."); "native code.");
} }
mCatalystInstance.invokeCallback(mExecutorToken, mCallbackId, Arguments.fromJavaArgs(args)); mJSInstance.invokeCallback(mExecutorToken, mCallbackId, Arguments.fromJavaArgs(args));
mInvoked = true; mInvoked = true;
} }
} }

View File

@ -23,7 +23,8 @@ import com.facebook.react.common.annotations.VisibleForTesting;
* Java APIs be invokable from JavaScript as well. * Java APIs be invokable from JavaScript as well.
*/ */
@DoNotStrip @DoNotStrip
public interface CatalystInstance extends MemoryPressureListener { public interface CatalystInstance
extends MemoryPressureListener, JSInstance {
void runJSBundle(); void runJSBundle();
/** /**
@ -34,8 +35,11 @@ public interface CatalystInstance extends MemoryPressureListener {
// This is called from java code, so it won't be stripped anyway, but proguard will rename it, // This is called from java code, so it won't be stripped anyway, but proguard will rename it,
// which this prevents. // which this prevents.
@DoNotStrip @Override @DoNotStrip
void invokeCallback(ExecutorToken executorToken, final int callbackID, final NativeArray arguments); void invokeCallback(
ExecutorToken executorToken,
int callbackID,
NativeArray arguments);
@DoNotStrip @DoNotStrip
void callFunction( void callFunction(
ExecutorToken executorToken, ExecutorToken executorToken,

View File

@ -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.
*/
package com.facebook.react.bridge;
/**
* This interface includes the methods needed to use a running JS
* instance, without specifying any of the bridge-specific
* initialization or lifecycle management.
*/
public interface JSInstance {
void invokeCallback(
ExecutorToken executorToken,
int callbackID,
NativeArray arguments);
// TODO if this interface survives refactoring, think about adding
// callFunction.
}

View File

@ -20,7 +20,7 @@ import java.util.Map;
*/ */
public interface NativeModule { public interface NativeModule {
interface NativeMethod { interface NativeMethod {
void invoke(CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray parameters); void invoke(JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray parameters);
String getType(); String getType();
} }

View File

@ -176,12 +176,13 @@ public class CatalystInstanceImpl implements CatalystInstance {
} }
} }
private native void initializeBridge(ReactCallback callback, private native void initializeBridge(
JavaScriptExecutor jsExecutor, ReactCallback callback,
MessageQueueThread jsQueue, JavaScriptExecutor jsExecutor,
MessageQueueThread moduleQueue, MessageQueueThread jsQueue,
Collection<JavaModuleWrapper> javaModules, MessageQueueThread moduleQueue,
Collection<CxxModuleWrapper> cxxModules); Collection<JavaModuleWrapper> javaModules,
Collection<CxxModuleWrapper> cxxModules);
/** /**
* This API is used in situations where the JS bundle is being executed not on * This API is used in situations where the JS bundle is being executed not on
@ -232,7 +233,6 @@ public class CatalystInstanceImpl implements CatalystInstance {
mJSCallsPendingInit.clear(); mJSCallsPendingInit.clear();
} }
// This is registered after JS starts since it makes a JS call // This is registered after JS starts since it makes a JS call
Systrace.registerListener(mTraceListener); Systrace.registerListener(mTraceListener);
} }
@ -302,7 +302,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
mReactQueueConfiguration.getNativeModulesQueueThread().runOnQueue(new Runnable() { mReactQueueConfiguration.getNativeModulesQueueThread().runOnQueue(new Runnable() {
@Override @Override
public void run() { public void run() {
mJavaRegistry.notifyCatalystInstanceDestroy(); mJavaRegistry.notifyJSInstanceDestroy();
} }
}); });
boolean wasIdle = (mPendingJSCalls.getAndSet(0) == 0); boolean wasIdle = (mPendingJSCalls.getAndSet(0) == 0);
@ -341,7 +341,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
mReactQueueConfiguration.getNativeModulesQueueThread().runOnQueue(new Runnable() { mReactQueueConfiguration.getNativeModulesQueueThread().runOnQueue(new Runnable() {
@Override @Override
public void run() { public void run() {
mJavaRegistry.notifyCatalystInstanceInitialized(); mJavaRegistry.notifyJSInstanceInitialized();
} }
}); });
} }
@ -390,7 +390,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
if (mDestroyed) { if (mDestroyed) {
return; return;
} }
switch(level) { switch (level) {
case UI_HIDDEN: case UI_HIDDEN:
handleMemoryPressureUiHidden(); handleMemoryPressureUiHidden();
break; break;

View File

@ -16,8 +16,8 @@ import java.util.Map;
import com.facebook.proguard.annotations.DoNotStrip; import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.BaseJavaModule; import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.ExecutorToken; import com.facebook.react.bridge.ExecutorToken;
import com.facebook.react.bridge.JSInstance;
import com.facebook.react.bridge.NativeArray; import com.facebook.react.bridge.NativeArray;
import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactMarker; import com.facebook.react.bridge.ReactMarker;
@ -54,12 +54,12 @@ public class JavaModuleWrapper {
String type; String type;
} }
private final CatalystInstance mCatalystInstance; private final JSInstance mJSInstance;
private final ModuleHolder mModuleHolder; private final ModuleHolder mModuleHolder;
private final ArrayList<NativeModule.NativeMethod> mMethods; private final ArrayList<NativeModule.NativeMethod> mMethods;
public JavaModuleWrapper(CatalystInstance catalystinstance, ModuleHolder moduleHolder) { public JavaModuleWrapper(JSInstance jsInstance, ModuleHolder moduleHolder) {
mCatalystInstance = catalystinstance; mJSInstance = jsInstance;
mModuleHolder = moduleHolder; mModuleHolder = moduleHolder;
mMethods = new ArrayList<>(); mMethods = new ArrayList<>();
} }
@ -135,6 +135,6 @@ public class JavaModuleWrapper {
return; return;
} }
mMethods.get(methodId).invoke(mCatalystInstance, token, parameters); mMethods.get(methodId).invoke(mJSInstance, token, parameters);
} }
} }

View File

@ -15,6 +15,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.JSInstance;
import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.OnBatchCompleteListener; import com.facebook.react.bridge.OnBatchCompleteListener;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
@ -41,12 +42,12 @@ public class NativeModuleRegistry {
} }
/* package */ Collection<JavaModuleWrapper> getJavaModules( /* package */ Collection<JavaModuleWrapper> getJavaModules(
CatalystInstanceImpl catalystInstanceImpl) { JSInstance jsInstance) {
ArrayList<JavaModuleWrapper> javaModules = new ArrayList<>(); ArrayList<JavaModuleWrapper> javaModules = new ArrayList<>();
for (Map.Entry<Class<? extends NativeModule>, ModuleHolder> entry : mModules.entrySet()) { for (Map.Entry<Class<? extends NativeModule>, ModuleHolder> entry : mModules.entrySet()) {
Class<?> type = entry.getKey(); Class<?> type = entry.getKey();
if (!CxxModuleWrapper.class.isAssignableFrom(type)) { if (!CxxModuleWrapper.class.isAssignableFrom(type)) {
javaModules.add(new JavaModuleWrapper(catalystInstanceImpl, entry.getValue())); javaModules.add(new JavaModuleWrapper(jsInstance, entry.getValue()));
} }
} }
return javaModules; return javaModules;
@ -63,11 +64,11 @@ public class NativeModuleRegistry {
return cxxModules; return cxxModules;
} }
/* package */ void notifyCatalystInstanceDestroy() { /* package */ void notifyJSInstanceDestroy() {
mReactApplicationContext.assertOnNativeModulesQueueThread(); mReactApplicationContext.assertOnNativeModulesQueueThread();
Systrace.beginSection( Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
"NativeModuleRegistry_notifyCatalystInstanceDestroy"); "NativeModuleRegistry_notifyJSInstanceDestroy");
try { try {
for (ModuleHolder module : mModules.values()) { for (ModuleHolder module : mModules.values()) {
module.destroy(); module.destroy();
@ -77,7 +78,7 @@ public class NativeModuleRegistry {
} }
} }
/* package */ void notifyCatalystInstanceInitialized() { /* package */ void notifyJSInstanceInitialized() {
mReactApplicationContext.assertOnNativeModulesQueueThread("From version React Native v0.44, " + mReactApplicationContext.assertOnNativeModulesQueueThread("From version React Native v0.44, " +
"native modules are explicitly not initialized on the UI thread. See " + "native modules are explicitly not initialized on the UI thread. See " +
"https://github.com/facebook/react-native/wiki/Breaking-Changes#d4611211-reactnativeandroidbreaking-move-nativemodule-initialization-off-ui-thread---aaachiuuu " + "https://github.com/facebook/react-native/wiki/Breaking-Changes#d4611211-reactnativeandroidbreaking-move-nativemodule-initialization-off-ui-thread---aaachiuuu " +
@ -85,7 +86,7 @@ public class NativeModuleRegistry {
ReactMarker.logMarker(ReactMarkerConstants.NATIVE_MODULE_INITIALIZE_START); ReactMarker.logMarker(ReactMarkerConstants.NATIVE_MODULE_INITIALIZE_START);
Systrace.beginSection( Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
"NativeModuleRegistry_notifyCatalystInstanceInitialized"); "NativeModuleRegistry_notifyJSInstanceInitialized");
try { try {
for (ModuleHolder module : mModules.values()) { for (ModuleHolder module : mModules.values()) {
module.initialize(); module.initialize();