Drop support for webworkers

Reviewed By: AaaChiuuu

Differential Revision: D4916449

fbshipit-source-id: a447233d3b7cfee98db2ce00f1c0505d513e2429
This commit is contained in:
Pieter De Baets
2017-04-25 05:29:45 -07:00
committed by Facebook Github Bot
parent a20882f62e
commit 34bc6bd2ae
64 changed files with 266 additions and 1639 deletions

View File

@@ -42,7 +42,6 @@ import com.facebook.react.bridge.ReactMarker;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.bridge.queue.ReactQueueConfigurationSpec;
import com.facebook.react.common.ApplicationHolder;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.annotations.VisibleForTesting;
@@ -229,8 +228,6 @@ public class ReactInstanceManager {
initializeSoLoaderIfNecessary(applicationContext);
// TODO(9577825): remove this
ApplicationHolder.setApplication((Application) applicationContext.getApplicationContext());
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(applicationContext);
mApplicationContext = applicationContext;

View File

@@ -66,11 +66,6 @@ public abstract class BaseJavaModule implements NativeModule {
// do nothing
}
@Override
public boolean supportsWebWorkers() {
return false;
}
public boolean hasConstants() {
return false;
}

View File

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

View File

@@ -37,12 +37,10 @@ public interface CatalystInstance
// which this prevents.
@Override @DoNotStrip
void invokeCallback(
ExecutorToken executorToken,
int callbackID,
NativeArray arguments);
@DoNotStrip
void callFunction(
ExecutorToken executorToken,
String module,
String method,
NativeArray arguments);
@@ -63,7 +61,6 @@ public interface CatalystInstance
ReactQueueConfiguration getReactQueueConfiguration();
<T extends JavaScriptModule> T getJSModule(Class<T> jsInterface);
<T extends JavaScriptModule> T getJSModule(ExecutorToken executorToken, Class<T> jsInterface);
<T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface);
<T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface);
Collection<NativeModule> getNativeModules();

View File

@@ -1,24 +0,0 @@
package com.facebook.react.bridge;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
/**
* Class corresponding to a JS VM that can call into native modules. In Java, this should
* just be treated as a black box to be used to help the framework route native->JS calls back to
* the proper JS VM. See {@link ReactContext#getJSModule(ExecutorToken, Class)} and
* {@link BaseJavaModule#supportsWebWorkers()}.
*
* Note: If your application doesn't use web workers, it will only have a single ExecutorToken
* per instance of React Native.
*/
@DoNotStrip
public class ExecutorToken {
private final HybridData mHybridData;
@DoNotStrip
private ExecutorToken(HybridData hybridData) {
mHybridData = hybridData;
}
}

View File

@@ -16,7 +16,6 @@ package com.facebook.react.bridge;
*/
public interface JSInstance {
void invokeCallback(
ExecutorToken executorToken,
int callbackID,
NativeArray arguments);
// TODO if this interface survives refactoring, think about adding

View File

@@ -31,11 +31,11 @@ import com.facebook.react.common.ReactConstants;
* JavaScript.
*/
public class JavaScriptModuleRegistry {
private final WeakHashMap<ExecutorToken, HashMap<Class<? extends JavaScriptModule>, JavaScriptModule>> mModuleInstances;
private final HashMap<Class<? extends JavaScriptModule>, JavaScriptModule> mModuleInstances;
private final HashMap<Class<? extends JavaScriptModule>, JavaScriptModuleRegistration> mModuleRegistrations;
public JavaScriptModuleRegistry(List<JavaScriptModuleRegistration> config) {
mModuleInstances = new WeakHashMap<>();
mModuleInstances = new HashMap<>();
mModuleRegistrations = new HashMap<>();
for (JavaScriptModuleRegistration registration : config) {
mModuleRegistrations.put(registration.getModuleInterface(), registration);
@@ -43,17 +43,9 @@ public class JavaScriptModuleRegistry {
}
public synchronized <T extends JavaScriptModule> T getJavaScriptModule(
CatalystInstance instance,
ExecutorToken executorToken,
Class<T> moduleInterface) {
HashMap<Class<? extends JavaScriptModule>, JavaScriptModule> instancesForContext =
mModuleInstances.get(executorToken);
if (instancesForContext == null) {
instancesForContext = new HashMap<>();
mModuleInstances.put(executorToken, instancesForContext);
}
JavaScriptModule module = instancesForContext.get(moduleInterface);
CatalystInstance instance,
Class<T> moduleInterface) {
JavaScriptModule module = mModuleInstances.get(moduleInterface);
if (module != null) {
return (T) module;
}
@@ -65,8 +57,8 @@ public class JavaScriptModuleRegistry {
JavaScriptModule interfaceProxy = (JavaScriptModule) Proxy.newProxyInstance(
moduleInterface.getClassLoader(),
new Class[]{moduleInterface},
new JavaScriptModuleInvocationHandler(executorToken, instance, registration));
instancesForContext.put(moduleInterface, interfaceProxy);
new JavaScriptModuleInvocationHandler(instance, registration));
mModuleInstances.put(moduleInterface, interfaceProxy);
return (T) interfaceProxy;
}
@@ -85,30 +77,20 @@ public class JavaScriptModuleRegistry {
}
private static class JavaScriptModuleInvocationHandler implements InvocationHandler {
private final WeakReference<ExecutorToken> mExecutorToken;
private final CatalystInstance mCatalystInstance;
private final JavaScriptModuleRegistration mModuleRegistration;
public JavaScriptModuleInvocationHandler(
ExecutorToken executorToken,
CatalystInstance catalystInstance,
JavaScriptModuleRegistration moduleRegistration) {
mExecutorToken = new WeakReference<>(executorToken);
mCatalystInstance = catalystInstance;
mModuleRegistration = moduleRegistration;
}
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
ExecutorToken executorToken = mExecutorToken.get();
if (executorToken == null) {
FLog.w(ReactConstants.TAG, "Dropping JS call, ExecutorToken went away...");
return null;
}
NativeArray jsArgs = args != null ? Arguments.fromJavaArgs(args) : new WritableNativeArray();
mCatalystInstance.callFunction(
executorToken,
mModuleRegistration.getName(),
method.getName(),
jsArgs

View File

@@ -9,10 +9,7 @@
package com.facebook.react.bridge;
import javax.annotation.Nullable;
import java.lang.reflect.Method;
import java.util.Map;
/**
* A native module whose API can be provided to JS catalyst instances. {@link NativeModule}s whose
@@ -23,7 +20,7 @@ import java.util.Map;
*/
public interface NativeModule {
interface NativeMethod {
void invoke(JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray parameters);
void invoke(JSInstance jsInstance, ReadableNativeArray parameters);
String getType();
}
@@ -52,27 +49,4 @@ public interface NativeModule {
* Called before {CatalystInstance#onHostDestroy}
*/
void onCatalystInstanceDestroy();
/**
* In order to support web workers, a module must be aware that it can be invoked from multiple
* different JS VMs. Supporting web workers means recognizing things like:
*
* 1) ids (e.g. timer ids, request ids, etc.) may only unique on a per-VM basis
* 2) the module needs to make sure to enqueue callbacks and JS module calls to the correct VM
*
* In order to facilitate this, modules that support web workers will have all their @ReactMethod-
* annotated methods passed a {@link ExecutorToken} as the first parameter before any arguments
* from JS. This ExecutorToken internally maps to a specific JS VM and can be used by the
* framework to route calls appropriately. In order to make JS module calls correctly, start using
* the version of {@link ReactContext#getJSModule(ExecutorToken, Class)} that takes an
* ExecutorToken. It will ensure that any calls you dispatch to the returned object will go to
* the right VM. For Callbacks, you don't have to do anything special -- the framework
* automatically tags them with the correct ExecutorToken when the are created.
*
* Note: even though calls can come from multiple JS VMs on multiple threads, calls to this module
* will still only occur on a single thread.
*
* @return whether this module supports web workers.
*/
boolean supportsWebWorkers();
}

View File

@@ -1,22 +0,0 @@
/**
* 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;
/**
* Interface for a module that will be notified when JS executors have been unregistered from the bridge.
* Note that this will NOT notify listeners about the main executor being destroyed: use
* {@link NativeModule#onCatalystInstanceDestroy()} for that. Once a module has received a
* {@link NativeModule#onCatalystInstanceDestroy()} call, it will not receive any onExecutorUnregistered
* calls.
*/
public interface OnExecutorUnregisteredListener {
void onExecutorDestroyed(ExecutorToken executorToken);
}

View File

@@ -107,15 +107,6 @@ public class ReactContext extends ContextWrapper {
return mCatalystInstance.getJSModule(jsInterface);
}
public <T extends JavaScriptModule> T getJSModule(
ExecutorToken executorToken,
Class<T> jsInterface) {
if (mCatalystInstance == null) {
throw new RuntimeException(EARLY_JS_ACCESS_EXCEPTION_MESSAGE);
}
return mCatalystInstance.getJSModule(executorToken, jsInterface);
}
public <T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface) {
if (mCatalystInstance == null) {
throw new RuntimeException(

View File

@@ -1,15 +0,0 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.react.bridge;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Annotation indicating that a JS module should be made available to web
* workers spawned by the main JS executor.
*/
@Retention(RUNTIME)
public @interface SupportsWebWorkers {
}

View File

@@ -1,37 +0,0 @@
/**
* 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.common;
import android.app.Application;
import com.facebook.infer.annotation.Assertions;
import com.facebook.proguard.annotations.DoNotStrip;
/**
* Holds the current Application Object.
*
* TODO(9577825): This is a bad pattern, we should thread through an Environment object instead.
* Remove once bridge is unforked.
*/
@DoNotStrip
@Deprecated
public class ApplicationHolder {
private static Application sApplication;
public static void setApplication(Application application) {
sApplication = application;
}
@DoNotStrip
public static Application getApplication() {
return Assertions.assertNotNull(sApplication);
}
}

View File

@@ -24,7 +24,6 @@ import com.facebook.infer.annotation.Assertions;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.ExecutorToken;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.JavaScriptModuleRegistry;
import com.facebook.react.bridge.MemoryPressure;
@@ -60,17 +59,14 @@ public class CatalystInstanceImpl implements CatalystInstance {
private static class PendingJSCall {
public ExecutorToken mExecutorToken;
public String mModule;
public String mMethod;
public NativeArray mArguments;
public PendingJSCall(
ExecutorToken executorToken,
String module,
String method,
NativeArray arguments) {
mExecutorToken = executorToken;
mModule = module;
mMethod = method;
mArguments = arguments;
@@ -89,7 +85,6 @@ public class CatalystInstanceImpl implements CatalystInstance {
private final JSBundleLoader mJSBundleLoader;
private final ArrayList<PendingJSCall> mJSCallsPendingInit = new ArrayList<PendingJSCall>();
private final Object mJSCallsPendingInitLock = new Object();
private ExecutorToken mMainExecutorToken;
private final NativeModuleRegistry mJavaRegistry;
private final NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
@@ -134,7 +129,6 @@ public class CatalystInstanceImpl implements CatalystInstance {
mJavaRegistry.getJavaModules(this),
mJavaRegistry.getCxxModules());
FLog.d(ReactConstants.TAG, "Initializing React Xplat Bridge after initializeBridge");
mMainExecutorToken = getMainExecutorToken();
}
private static class BridgeCallback implements ReactCallback {
@@ -224,7 +218,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
mAcceptCalls = true;
for (PendingJSCall call : mJSCallsPendingInit) {
jniCallJSFunction(call.mExecutorToken, call.mModule, call.mMethod, call.mArguments);
jniCallJSFunction(call.mModule, call.mMethod, call.mArguments);
}
mJSCallsPendingInit.clear();
}
@@ -239,14 +233,12 @@ public class CatalystInstanceImpl implements CatalystInstance {
}
private native void jniCallJSFunction(
ExecutorToken token,
String module,
String method,
NativeArray arguments);
@Override
public void callFunction(
ExecutorToken executorToken,
final String module,
final String method,
final NativeArray arguments) {
@@ -258,25 +250,25 @@ public class CatalystInstanceImpl implements CatalystInstance {
// Most of the time the instance is initialized and we don't need to acquire the lock
synchronized (mJSCallsPendingInitLock) {
if (!mAcceptCalls) {
mJSCallsPendingInit.add(new PendingJSCall(executorToken, module, method, arguments));
mJSCallsPendingInit.add(new PendingJSCall(module, method, arguments));
return;
}
}
}
jniCallJSFunction(executorToken, module, method, arguments);
jniCallJSFunction(module, method, arguments);
}
private native void jniCallJSCallback(ExecutorToken executorToken, int callbackID, NativeArray arguments);
private native void jniCallJSCallback(int callbackID, NativeArray arguments);
@Override
public void invokeCallback(ExecutorToken executorToken, final int callbackID, final NativeArray arguments) {
public void invokeCallback(final int callbackID, final NativeArray arguments) {
if (mDestroyed) {
FLog.w(ReactConstants.TAG, "Invoking JS callback after bridge has been destroyed.");
return;
}
jniCallJSCallback(executorToken, callbackID, arguments);
jniCallJSCallback(callbackID, arguments);
}
/**
@@ -348,17 +340,9 @@ public class CatalystInstanceImpl implements CatalystInstance {
@Override
public <T extends JavaScriptModule> T getJSModule(Class<T> jsInterface) {
return getJSModule(mMainExecutorToken, jsInterface);
return mJSModuleRegistry.getJavaScriptModule(this, jsInterface);
}
@Override
public <T extends JavaScriptModule> T getJSModule(ExecutorToken executorToken, Class<T> jsInterface) {
return Assertions.assertNotNull(mJSModuleRegistry)
.getJavaScriptModule(this, executorToken, jsInterface);
}
private native ExecutorToken getMainExecutorToken();
@Override
public <T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface) {
return mJavaRegistry.hasModule(nativeModuleInterface);

View File

@@ -2,7 +2,6 @@
package com.facebook.react.cxxbridge;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.NativeModule;
@@ -37,11 +36,6 @@ public class CxxModuleWrapperBase implements NativeModule
return false;
}
@Override
public boolean supportsWebWorkers() {
return false;
}
@Override
public void onCatalystInstanceDestroy() {
mHybridData.resetNative();

View File

@@ -14,11 +14,22 @@ import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.facebook.react.bridge.*;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.cxxbridge.JavaModuleWrapper;
import com.facebook.systrace.Systrace;
import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.DynamicFromArray;
import com.facebook.react.bridge.JSInstance;
import com.facebook.react.bridge.NativeArgumentsParseException;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.PromiseImpl;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeArray;
import com.facebook.react.bridge.UnexpectedNativeTypeException;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.systrace.SystraceMessage;
import static com.facebook.infer.annotation.Assertions.assertNotNull;
@@ -32,14 +43,14 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
}
public abstract @Nullable T extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex);
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex);
}
static final private ArgumentExtractor<Boolean> ARGUMENT_EXTRACTOR_BOOLEAN =
new ArgumentExtractor<Boolean>() {
@Override
public Boolean extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getBoolean(atIndex);
}
};
@@ -48,7 +59,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
new ArgumentExtractor<Double>() {
@Override
public Double extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getDouble(atIndex);
}
};
@@ -57,7 +68,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
new ArgumentExtractor<Float>() {
@Override
public Float extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
return (float) jsArguments.getDouble(atIndex);
}
};
@@ -66,7 +77,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
new ArgumentExtractor<Integer>() {
@Override
public Integer extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
return (int) jsArguments.getDouble(atIndex);
}
};
@@ -75,7 +86,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
new ArgumentExtractor<String>() {
@Override
public String extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getString(atIndex);
}
};
@@ -84,7 +95,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
new ArgumentExtractor<ReadableNativeArray>() {
@Override
public ReadableNativeArray extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getArray(atIndex);
}
};
@@ -93,7 +104,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
new ArgumentExtractor<Dynamic>() {
@Override
public Dynamic extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
return DynamicFromArray.create(jsArguments, atIndex);
}
};
@@ -102,7 +113,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
new ArgumentExtractor<ReadableMap>() {
@Override
public ReadableMap extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
return jsArguments.getMap(atIndex);
}
};
@@ -111,12 +122,12 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
new ArgumentExtractor<Callback>() {
@Override
public @Nullable Callback extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
if (jsArguments.isNull(atIndex)) {
return null;
} else {
int id = (int) jsArguments.getDouble(atIndex);
return new com.facebook.react.bridge.CallbackImpl(jsInstance, executorToken, id);
return new com.facebook.react.bridge.CallbackImpl(jsInstance, id);
}
}
};
@@ -130,11 +141,11 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
@Override
public Promise extractArgument(
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
Callback resolve = ARGUMENT_EXTRACTOR_CALLBACK
.extractArgument(jsInstance, executorToken, jsArguments, atIndex);
.extractArgument(jsInstance, jsArguments, atIndex);
Callback reject = ARGUMENT_EXTRACTOR_CALLBACK
.extractArgument(jsInstance, executorToken, jsArguments, atIndex + 1);
.extractArgument(jsInstance, jsArguments, atIndex + 1);
return new PromiseImpl(resolve, reject);
}
};
@@ -144,9 +155,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
if (tryCommon != '\0') {
return tryCommon;
}
if (paramClass == ExecutorToken.class) {
return 'T';
} else if (paramClass == Callback.class) {
if (paramClass == Callback.class) {
return 'X';
} else if (paramClass == Promise.class) {
return 'P';
@@ -269,50 +278,20 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
for (int i = 0; i < paramTypes.length; i++) {
Class paramClass = paramTypes[i];
if (paramClass == ExecutorToken.class) {
if (!mModuleWrapper.supportsWebWorkers()) {
throw new RuntimeException(
"Module " + mModuleWrapper.getName() + " doesn't support web workers, but " +
mMethod.getName() +
" takes an ExecutorToken.");
}
} else if (paramClass == Promise.class) {
if (paramClass == Promise.class) {
Assertions.assertCondition(
i == paramTypes.length - 1, "Promise must be used as last parameter only");
}
builder.append(paramTypeToChar(paramClass));
}
// Modules that support web workers are expected to take an ExecutorToken as the first
// parameter to all their @ReactMethod-annotated methods.
if (mModuleWrapper.supportsWebWorkers()) {
if (builder.charAt(2) != 'T') {
throw new RuntimeException(
"Module " + mModuleWrapper.getName() + " supports web workers, but " + mMethod.getName() +
"does not take an ExecutorToken as its first parameter.");
}
}
return builder.toString();
}
private ArgumentExtractor[] buildArgumentExtractors(Class[] paramTypes) {
// Modules that support web workers are expected to take an ExecutorToken as the first
// parameter to all their @ReactMethod-annotated methods. We compensate for that here.
int executorTokenOffset = 0;
if (mModuleWrapper.supportsWebWorkers()) {
if (paramTypes[0] != ExecutorToken.class) {
throw new RuntimeException(
"Module " + mModuleWrapper.getName() + " supports web workers, but " + mMethod.getName() +
"does not take an ExecutorToken as its first parameter.");
}
executorTokenOffset = 1;
}
ArgumentExtractor[] argumentExtractors = new ArgumentExtractor[paramTypes.length - executorTokenOffset];
for (int i = 0; i < paramTypes.length - executorTokenOffset; i += argumentExtractors[i].getJSArgumentsNeeded()) {
int paramIndex = i + executorTokenOffset;
Class argumentClass = paramTypes[paramIndex];
ArgumentExtractor[] argumentExtractors = new ArgumentExtractor[paramTypes.length];
for (int i = 0; i < paramTypes.length; i += argumentExtractors[i].getJSArgumentsNeeded()) {
Class argumentClass = paramTypes[i];
if (argumentClass == Boolean.class || argumentClass == boolean.class) {
argumentExtractors[i] = ARGUMENT_EXTRACTOR_BOOLEAN;
} else if (argumentClass == Integer.class || argumentClass == int.class) {
@@ -328,7 +307,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
} else if (argumentClass == Promise.class) {
argumentExtractors[i] = ARGUMENT_EXTRACTOR_PROMISE;
Assertions.assertCondition(
paramIndex == paramTypes.length - 1, "Promise must be used as last parameter only");
i == paramTypes.length - 1, "Promise must be used as last parameter only");
} else if (argumentClass == ReadableMap.class) {
argumentExtractors[i] = ARGUMENT_EXTRACTOR_MAP;
} else if (argumentClass == ReadableArray.class) {
@@ -357,7 +336,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
}
@Override
public void invoke(JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray parameters) {
public void invoke(JSInstance jsInstance, ReadableNativeArray parameters) {
String traceName = mModuleWrapper.getName() + "." + mMethod.getName();
SystraceMessage.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "callJavaModuleMethod")
.arg("method", traceName)
@@ -374,18 +353,11 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
traceName + " got " + parameters.size() + " arguments, expected " + mJSArgumentsNeeded);
}
// Modules that support web workers are expected to take an ExecutorToken as the first
// parameter to all their @ReactMethod-annotated methods. We compensate for that here.
int i = 0, jsArgumentsConsumed = 0;
int executorTokenOffset = 0;
if (mModuleWrapper.supportsWebWorkers()) {
mArguments[0] = executorToken;
executorTokenOffset = 1;
}
try {
for (; i < mArgumentExtractors.length; i++) {
mArguments[i + executorTokenOffset] = mArgumentExtractors[i].extractArgument(
jsInstance, executorToken, parameters, jsArgumentsConsumed);
mArguments[i] = mArgumentExtractors[i].extractArgument(
jsInstance, parameters, jsArgumentsConsumed);
jsArgumentsConsumed += mArgumentExtractors[i].getJSArgumentsNeeded();
}
} catch (UnexpectedNativeTypeException e) {

View File

@@ -20,7 +20,6 @@ import java.util.Set;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.ExecutorToken;
import com.facebook.react.bridge.JSInstance;
import com.facebook.react.bridge.NativeArray;
import com.facebook.react.bridge.NativeModule;
@@ -155,16 +154,11 @@ public class JavaModuleWrapper {
}
@DoNotStrip
public boolean supportsWebWorkers() {
return mModuleHolder.getSupportsWebWorkers();
}
@DoNotStrip
public void invoke(ExecutorToken token, int methodId, ReadableNativeArray parameters) {
public void invoke(int methodId, ReadableNativeArray parameters) {
if (mMethods == null || methodId >= mMethods.size()) {
return;
}
mMethods.get(methodId).invoke(mJSInstance, token, parameters);
mMethods.get(methodId).invoke(mJSInstance, parameters);
}
}

View File

@@ -32,7 +32,6 @@ public class ModuleHolder {
private final String mName;
private final boolean mCanOverrideExistingModule;
private final boolean mSupportsWebWorkers;
private final boolean mHasConstants;
private @Nullable Provider<? extends NativeModule> mProvider;
@@ -42,7 +41,6 @@ public class ModuleHolder {
public ModuleHolder(ReactModuleInfo moduleInfo, Provider<? extends NativeModule> provider) {
mName = moduleInfo.name();
mCanOverrideExistingModule = moduleInfo.canOverrideExistingModule();
mSupportsWebWorkers = moduleInfo.supportsWebWorkers();
mHasConstants = moduleInfo.hasConstants();
mProvider = provider;
if (moduleInfo.needsEagerInit()) {
@@ -53,7 +51,6 @@ public class ModuleHolder {
public ModuleHolder(NativeModule nativeModule) {
mName = nativeModule.getName();
mCanOverrideExistingModule = nativeModule.canOverrideExistingModule();
mSupportsWebWorkers = nativeModule.supportsWebWorkers();
mHasConstants = true;
mModule = nativeModule;
}
@@ -85,10 +82,6 @@ public class ModuleHolder {
return mCanOverrideExistingModule;
}
public boolean getSupportsWebWorkers() {
return mSupportsWebWorkers;
}
public boolean getHasConstants() {
return mHasConstants;
}

View File

@@ -13,8 +13,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.ExecutorToken;
import com.facebook.react.bridge.ReactContext;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -38,29 +36,6 @@ public @interface ReactModule {
*/
boolean canOverrideExistingModule() default false;
/**
* In order to support web workers, a module must be aware that it can be invoked from multiple
* different JS VMs. Supporting web workers means recognizing things like:
*
* 1) ids (e.g. timer ids, request ids, etc.) may only unique on a per-VM basis
* 2) the module needs to make sure to enqueue callbacks and JS module calls to the correct VM
*
* In order to facilitate this, modules that support web workers will have all their @ReactMethod-
* annotated methods passed a {@link ExecutorToken} as the first parameter before any arguments
* from JS. This ExecutorToken internally maps to a specific JS VM and can be used by the
* framework to route calls appropriately. In order to make JS module calls correctly, start using
* the version of {@link ReactContext#getJSModule(ExecutorToken, Class)} that takes an
* ExecutorToken. It will ensure that any calls you dispatch to the returned object will go to
* the right VM. For Callbacks, you don't have to do anything special -- the framework
* automatically tags them with the correct ExecutorToken when the are created.
*
* Note: even though calls can come from multiple JS VMs on multiple threads, calls to this module
* will still only occur on a single thread.
*
* @return whether this module supports web workers.
*/
boolean supportsWebWorkers() default false;
/**
* Whether this module needs to be loaded immediately.
*/

View File

@@ -10,19 +10,16 @@ public class ReactModuleInfo {
private final String mName;
private final boolean mCanOverrideExistingModule;
private final boolean mSupportsWebWorkers;
private final boolean mNeedsEagerInit;
private final boolean mHasConstants;
public ReactModuleInfo(
String name,
boolean canOverrideExistingModule,
boolean supportsWebWorkers,
boolean needsEagerInit,
boolean hasConstants) {
mName = name;
mCanOverrideExistingModule = canOverrideExistingModule;
mSupportsWebWorkers = supportsWebWorkers;
mNeedsEagerInit = needsEagerInit;
mHasConstants = hasConstants;
}
@@ -35,10 +32,6 @@ public class ReactModuleInfo {
return mCanOverrideExistingModule;
}
public boolean supportsWebWorkers() {
return mSupportsWebWorkers;
}
public boolean needsEagerInit() {
return mNeedsEagerInit;
}

View File

@@ -175,7 +175,6 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
.append("new ReactModuleInfo(")
.append("\"").append(reactModule.name()).append("\"").append(", ")
.append(reactModule.canOverrideExistingModule()).append(", ")
.append(reactModule.supportsWebWorkers()).append(", ")
.append(reactModule.needsEagerInit()).append(", ")
.append(hasConstants)
.append(")")

View File

@@ -18,7 +18,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.SupportsWebWorkers;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule;
@@ -29,7 +28,6 @@ import com.facebook.react.module.annotations.ReactModule;
@ReactModule(name = "DeviceEventManager")
public class DeviceEventManagerModule extends ReactContextBaseJavaModule {
@SupportsWebWorkers
public interface RCTDeviceEventEmitter extends JavaScriptModule {
void emit(String eventName, @Nullable Object data);
}