mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Introduce SampleLegacyModule example in RNTester (#38539)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38539 We will use this example to: - Showcase legacy module support in the TurboModule system in RNTester - E2E test legacy module support in the TurboModule system Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D47529295 fbshipit-source-id: b98e315741bed7740c36997d706f48e375b0c815
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a384e076e0
commit
145659241a
+246
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* 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.fbreact.specs;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.widget.Toast;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeArray;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ReactModule(name = SampleLegacyModule.NAME)
|
||||
public class SampleLegacyModule extends ReactContextBaseJavaModule {
|
||||
|
||||
public static final String NAME = "SampleLegacyModule";
|
||||
|
||||
private static final String TAG = SampleLegacyModule.class.getName();
|
||||
private final ReactApplicationContext mContext;
|
||||
private Toast mToast;
|
||||
|
||||
public SampleLegacyModule(ReactApplicationContext context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public boolean getBool(boolean arg) {
|
||||
log("getBool", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public double getEnum(double arg) {
|
||||
log("getEnum", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public double getDouble(double arg) {
|
||||
log("getDouble", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public int getInt(int arg) {
|
||||
log("getInt", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public float getFloat(float arg) {
|
||||
log("getFloat", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public double getObjectDouble(Double arg) {
|
||||
log("getObjectDouble", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public Integer getObjectInteger(Integer arg) {
|
||||
log("getObjectInteger", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public Float getObjectFloat(Float arg) {
|
||||
log("getObjectFloat", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String getString(String arg) {
|
||||
log("getString", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public double getRootTag(double arg) {
|
||||
log("getRootTag", arg, arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod
|
||||
public void voidFunc() {
|
||||
log("voidFunc", "<void>", "<void>");
|
||||
return;
|
||||
}
|
||||
|
||||
// This function returns {@link WritableMap} instead of {@link Map} for backward compat with
|
||||
// existing native modules that use this Writable* as return types or in events. {@link
|
||||
// WritableMap} is modified in the Java side, and read (or consumed) on the C++ side.
|
||||
// In the future, all native modules should ideally return an immutable Map
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public WritableMap getObject(ReadableMap arg) {
|
||||
WritableNativeMap map = new WritableNativeMap();
|
||||
map.merge(arg);
|
||||
log("getObject", arg, map);
|
||||
return map;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public WritableMap getUnsafeObject(ReadableMap arg) {
|
||||
WritableNativeMap map = new WritableNativeMap();
|
||||
map.merge(arg);
|
||||
log("getUnsafeObject", arg, map);
|
||||
return map;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public WritableMap getValue(double numberArg, String stringArg, ReadableMap mapArg) {
|
||||
WritableMap map = new WritableNativeMap();
|
||||
map.putDouble("x", numberArg);
|
||||
map.putString("y", stringArg);
|
||||
WritableMap zMap = new WritableNativeMap();
|
||||
zMap.merge(mapArg);
|
||||
map.putMap("z", zMap);
|
||||
log(
|
||||
"getValue",
|
||||
MapBuilder.of("1-numberArg", numberArg, "2-stringArg", stringArg, "3-mapArg", mapArg),
|
||||
map);
|
||||
return map;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod
|
||||
public void getValueWithCallback(final Callback callback) {
|
||||
String result = "Value From Callback";
|
||||
log("Callback", "Return Time", result);
|
||||
callback.invoke(result);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public WritableArray getArray(ReadableArray arg) {
|
||||
if (arg == null || Arguments.toList(arg) == null) {
|
||||
// Returning an empty array, since the super class always returns non-null
|
||||
return new WritableNativeArray();
|
||||
}
|
||||
WritableArray result = Arguments.makeNativeArray(Arguments.toList(arg));
|
||||
log("getArray", arg, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
@ReactMethod
|
||||
public void getValueWithPromise(boolean error, Promise promise) {
|
||||
if (error) {
|
||||
promise.reject(
|
||||
"code 1",
|
||||
"intentional promise rejection",
|
||||
new Throwable("promise intentionally rejected"));
|
||||
} else {
|
||||
promise.resolve("result");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @Nullable Map<String, Object> getConstants() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
Activity activity = mContext.getCurrentActivity();
|
||||
if (activity != null) {
|
||||
result.put("const2", 390);
|
||||
}
|
||||
result.put("const1", true);
|
||||
result.put("const3", "something");
|
||||
log("constantsToExport", "", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void log(String method, Object input, Object output) {
|
||||
if (mToast != null) {
|
||||
mToast.cancel();
|
||||
}
|
||||
StringBuilder message = new StringBuilder("Method :");
|
||||
message
|
||||
.append(method)
|
||||
.append("\nInputs: ")
|
||||
.append(input.toString())
|
||||
.append("\nOutputs: ")
|
||||
.append(output.toString());
|
||||
mToast = Toast.makeText(mContext, message.toString(), Toast.LENGTH_LONG);
|
||||
mToast.show();
|
||||
}
|
||||
|
||||
public void invalidate() {}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
+17
@@ -9,6 +9,7 @@ package com.facebook.react.uiapp;
|
||||
|
||||
import android.app.Application;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.facebook.fbreact.specs.SampleLegacyModule;
|
||||
import com.facebook.fbreact.specs.SampleTurboModule;
|
||||
import com.facebook.react.JSEngineResolutionAlgorithm;
|
||||
import com.facebook.react.ReactApplication;
|
||||
@@ -79,6 +80,10 @@ public class RNTesterApplication extends Application implements ReactApplication
|
||||
return new SampleTurboModule(reactContext);
|
||||
}
|
||||
|
||||
if (SampleLegacyModule.NAME.equals(name)) {
|
||||
return new SampleLegacyModule(reactContext);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -101,6 +106,18 @@ public class RNTesterApplication extends Application implements ReactApplication
|
||||
false, // isCxxModule
|
||||
true // isTurboModule
|
||||
));
|
||||
|
||||
moduleInfos.put(
|
||||
SampleLegacyModule.NAME,
|
||||
new ReactModuleInfo(
|
||||
SampleLegacyModule.NAME,
|
||||
"SampleLegacyModule",
|
||||
false, // canOverrideExistingModule
|
||||
false, // needsEagerInit
|
||||
true, // hasConstants
|
||||
false, // isCxxModule
|
||||
false // isTurboModule
|
||||
));
|
||||
}
|
||||
return moduleInfos;
|
||||
}
|
||||
|
||||
+17
@@ -10,6 +10,7 @@ package com.facebook.react.uiapp;
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.fbreact.specs.SampleLegacyModule;
|
||||
import com.facebook.fbreact.specs.SampleTurboModule;
|
||||
import com.facebook.react.JSEngineResolutionAlgorithm;
|
||||
import com.facebook.react.ReactPackage;
|
||||
@@ -111,6 +112,10 @@ public class RNTesterReactHostDelegate implements ReactHostDelegate {
|
||||
return new SampleTurboModule(reactContext);
|
||||
}
|
||||
|
||||
if (SampleLegacyModule.NAME.equals(name)) {
|
||||
return new SampleLegacyModule(reactContext);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -133,6 +138,18 @@ public class RNTesterReactHostDelegate implements ReactHostDelegate {
|
||||
false, // isCxxModule
|
||||
true // isTurboModule
|
||||
));
|
||||
|
||||
moduleInfos.put(
|
||||
SampleLegacyModule.NAME,
|
||||
new ReactModuleInfo(
|
||||
SampleLegacyModule.NAME,
|
||||
"SampleLegacyModule",
|
||||
false, // canOverrideExistingModule
|
||||
false, // needsEagerInit
|
||||
true, // hasConstants
|
||||
false, // isCxxModule
|
||||
false // isTurboModule
|
||||
));
|
||||
}
|
||||
return moduleInfos;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
|
||||
import styles from './TurboModuleExampleCommon';
|
||||
@@ -58,57 +59,97 @@ class SampleLegacyModuleExample extends React.Component<{||}, State> {
|
||||
|
||||
// Add calls to methods in TurboModule here
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
_tests = {
|
||||
voidFunc: () => getSampleLegacyModule()?.voidFunc(),
|
||||
getBool: () => getSampleLegacyModule()?.getBool(true),
|
||||
getEnum: () => getSampleLegacyModule()?.getEnum(1.0),
|
||||
getNumber: () => getSampleLegacyModule()?.getNumber(99.95),
|
||||
getFloat: () => getSampleLegacyModule()?.getNumber(99.95),
|
||||
getInt: () => getSampleLegacyModule()?.getInt(99),
|
||||
getLongLong: () => getSampleLegacyModule()?.getLongLong(99),
|
||||
getUnsignedLongLong: () => getSampleLegacyModule()?.getUnsignedLongLong(99),
|
||||
getNSInteger: () => getSampleLegacyModule()?.getNSInteger(99),
|
||||
getNSUInteger: () => getSampleLegacyModule()?.getNSUInteger(99),
|
||||
getArray: () =>
|
||||
getSampleLegacyModule()?.getArray([
|
||||
{a: 1, b: 'foo'},
|
||||
{a: 2, b: 'bar'},
|
||||
null,
|
||||
]),
|
||||
getObject: () =>
|
||||
getSampleLegacyModule()?.getObject({a: 1, b: 'foo', c: null}),
|
||||
getString: () => getSampleLegacyModule()?.getString('Hello'),
|
||||
getNullString: () => getSampleLegacyModule()?.getString(null),
|
||||
getNSNumber: () => getSampleLegacyModule()?.getNSNumber(20.0),
|
||||
getUnsafeObject: () =>
|
||||
getSampleLegacyModule()?.getObject({a: 1, b: 'foo', c: null}),
|
||||
getRootTag: () => getSampleLegacyModule()?.getRootTag(this.context),
|
||||
getValue: () =>
|
||||
getSampleLegacyModule()?.getValue(5, 'test', {a: 1, b: 'foo'}),
|
||||
callback: () =>
|
||||
getSampleLegacyModule()?.getValueWithCallback(callbackValue =>
|
||||
this._setResult('callback', callbackValue),
|
||||
),
|
||||
promise: () =>
|
||||
getSampleLegacyModule()
|
||||
?.getValueWithPromise(false)
|
||||
.then(valuePromise => this._setResult('promise', valuePromise)),
|
||||
rejectPromise: () =>
|
||||
getSampleLegacyModule()
|
||||
?.getValueWithPromise(true)
|
||||
.then(() => {})
|
||||
.catch(e => this._setResult('rejectPromise', e.message)),
|
||||
// voidFuncThrows: () => getSampleLegacyModule()?.voidFuncThrows(),
|
||||
// getObjectThrows: () => getSampleLegacyModule()?.getObjectThrows({}),
|
||||
// promiseThrows: () => getSampleLegacyModule()?.promiseThrows(true),
|
||||
// voidFuncAssert: () => getSampleLegacyModule()?.voidFuncAssert(),
|
||||
// getObjectAssert: () => getSampleLegacyModule()?.getObjectAssert({}),
|
||||
// promiseAssert: () => getSampleLegacyModule()?.promiseAssert(true),
|
||||
getConstants: () => getSampleLegacyModule()?.getConstants(),
|
||||
getConst1: () => getSampleLegacyModule()?.const1,
|
||||
getConst2: () => getSampleLegacyModule()?.const2,
|
||||
getConst3: () => getSampleLegacyModule()?.const3,
|
||||
};
|
||||
_tests =
|
||||
Platform.OS === 'ios'
|
||||
? {
|
||||
voidFunc: () => getSampleLegacyModule()?.voidFunc(),
|
||||
getBool: () => getSampleLegacyModule()?.getBool(true),
|
||||
getEnum: () => getSampleLegacyModule()?.getEnum(1.0),
|
||||
getNumber: () => getSampleLegacyModule()?.getNumber(99.95),
|
||||
getFloat: () => getSampleLegacyModule()?.getNumber(99.95),
|
||||
getInt: () => getSampleLegacyModule()?.getInt(99),
|
||||
getLongLong: () => getSampleLegacyModule()?.getLongLong(99),
|
||||
getUnsignedLongLong: () =>
|
||||
getSampleLegacyModule()?.getUnsignedLongLong(99),
|
||||
getNSInteger: () => getSampleLegacyModule()?.getNSInteger(99),
|
||||
getNSUInteger: () => getSampleLegacyModule()?.getNSUInteger(99),
|
||||
getArray: () =>
|
||||
getSampleLegacyModule()?.getArray([
|
||||
{a: 1, b: 'foo'},
|
||||
{a: 2, b: 'bar'},
|
||||
null,
|
||||
]),
|
||||
getObject: () =>
|
||||
getSampleLegacyModule()?.getObject({a: 1, b: 'foo', c: null}),
|
||||
getString: () => getSampleLegacyModule()?.getString('Hello'),
|
||||
getNullString: () => getSampleLegacyModule()?.getString(null),
|
||||
getNSNumber: () => getSampleLegacyModule()?.getNSNumber(20.0),
|
||||
getUnsafeObject: () =>
|
||||
getSampleLegacyModule()?.getObject({a: 1, b: 'foo', c: null}),
|
||||
getRootTag: () => getSampleLegacyModule()?.getRootTag(this.context),
|
||||
getValue: () =>
|
||||
getSampleLegacyModule()?.getValue(5, 'test', {a: 1, b: 'foo'}),
|
||||
callback: () =>
|
||||
getSampleLegacyModule()?.getValueWithCallback(callbackValue =>
|
||||
this._setResult('callback', callbackValue),
|
||||
),
|
||||
promise: () =>
|
||||
getSampleLegacyModule()
|
||||
?.getValueWithPromise(false)
|
||||
.then(valuePromise => this._setResult('promise', valuePromise)),
|
||||
rejectPromise: () =>
|
||||
getSampleLegacyModule()
|
||||
?.getValueWithPromise(true)
|
||||
.then(() => {})
|
||||
.catch(e => this._setResult('rejectPromise', e.message)),
|
||||
getConstants: () => getSampleLegacyModule()?.getConstants(),
|
||||
getConst1: () => getSampleLegacyModule()?.const1,
|
||||
getConst2: () => getSampleLegacyModule()?.const2,
|
||||
getConst3: () => getSampleLegacyModule()?.const3,
|
||||
}
|
||||
: {
|
||||
voidFunc: () => getSampleLegacyModule()?.voidFunc(),
|
||||
getBool: () => getSampleLegacyModule()?.getBool(true),
|
||||
getEnum: () => getSampleLegacyModule()?.getEnum(1.0),
|
||||
getDouble: () => getSampleLegacyModule()?.getDouble(99.95),
|
||||
getInt: () => getSampleLegacyModule()?.getInt(99),
|
||||
getFloat: () => getSampleLegacyModule()?.getFloat(99.95),
|
||||
getObjectDouble: () =>
|
||||
getSampleLegacyModule()?.getObjectDouble(99.95),
|
||||
getObjectInteger: () => getSampleLegacyModule()?.getObjectInteger(99),
|
||||
getObjectFloat: () => getSampleLegacyModule()?.getObjectFloat(99.95),
|
||||
getString: () => getSampleLegacyModule()?.getString('Hello'),
|
||||
getRootTag: () => getSampleLegacyModule()?.getRootTag(this.context),
|
||||
getObject: () =>
|
||||
getSampleLegacyModule()?.getObject({a: 1, b: 'foo', c: null}),
|
||||
getUnsafeObject: () =>
|
||||
getSampleLegacyModule()?.getObject({a: 1, b: 'foo', c: null}),
|
||||
getValue: () =>
|
||||
getSampleLegacyModule()?.getValue(5, 'test', {a: 1, b: 'foo'}),
|
||||
callback: () =>
|
||||
getSampleLegacyModule()?.getValueWithCallback(callbackValue =>
|
||||
this._setResult('callback', callbackValue),
|
||||
),
|
||||
getArray: () =>
|
||||
getSampleLegacyModule()?.getArray([
|
||||
{a: 1, b: 'foo'},
|
||||
{a: 2, b: 'bar'},
|
||||
null,
|
||||
]),
|
||||
promise: () =>
|
||||
getSampleLegacyModule()
|
||||
?.getValueWithPromise(false)
|
||||
.then(valuePromise => this._setResult('promise', valuePromise)),
|
||||
rejectPromise: () =>
|
||||
getSampleLegacyModule()
|
||||
?.getValueWithPromise(true)
|
||||
.then(() => {})
|
||||
.catch(e => this._setResult('rejectPromise', e.message)),
|
||||
getConstants: () => getSampleLegacyModule()?.getConstants(),
|
||||
getConst1: () => getSampleLegacyModule()?.const1,
|
||||
getConst2: () => getSampleLegacyModule()?.const2,
|
||||
getConst3: () => getSampleLegacyModule()?.const3,
|
||||
};
|
||||
|
||||
_setResult(name: string, result: mixed) {
|
||||
this.setState(({testResults}) => ({
|
||||
|
||||
@@ -312,6 +312,10 @@ const APIs: Array<RNTesterModuleInfo> = ([
|
||||
category: 'Basic',
|
||||
module: require('../examples/TurboModule/TurboModuleExample'),
|
||||
},
|
||||
{
|
||||
key: 'LegacyModuleExample',
|
||||
module: require('../examples/TurboModule/LegacyModuleExample'),
|
||||
},
|
||||
{
|
||||
key: 'TurboCxxModuleExample',
|
||||
category: 'Basic',
|
||||
|
||||
Reference in New Issue
Block a user