diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleLegacyModule.java b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleLegacyModule.java deleted file mode 100644 index 92e75ee27d2465..00000000000000 --- a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleLegacyModule.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * 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.Dynamic; -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.ReadableType; -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", "", ""); - 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; - } - - @SuppressWarnings("unused") - @ReactMethod(isBlockingSynchronousMethod = true) - public WritableMap getDynamic(Dynamic dynamic) { - WritableNativeMap resultMap = new WritableNativeMap(); - ReadableType type = dynamic.getType(); - if (type == ReadableType.Null) { - log("getDynamic as Null", dynamic, dynamic); - resultMap.putString("type", "Null"); - resultMap.putNull("value"); - } else if (type == ReadableType.Boolean) { - boolean result = dynamic.asBoolean(); - log("getDynamic as Boolean", dynamic, result); - resultMap.putString("type", "Boolean"); - resultMap.putBoolean("value", result); - } else if (type == ReadableType.Number) { - int result = dynamic.asInt(); - log("getDynamic as Number", dynamic, result); - resultMap.putString("type", "Number"); - resultMap.putInt("value", result); - } else if (type == ReadableType.String) { - String result = dynamic.asString(); - log("getDynamic as String", dynamic, result); - resultMap.putString("type", "String"); - resultMap.putString("value", result); - } else if (type == ReadableType.Array) { - ReadableArray result = dynamic.asArray(); - log("getDynamic as Array", dynamic, result); - resultMap.putString("type", "Array"); - resultMap.putArray("value", result); - } else if (type == ReadableType.Map) { - ReadableMap result = dynamic.asMap(); - log("getDynamic as Map", dynamic, result); - resultMap.putString("type", "Map"); - resultMap.putMap("value", result); - } - return resultMap; - } - - @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 getConstants() { - Map 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; - } -} diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleLegacyModule.kt b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleLegacyModule.kt new file mode 100644 index 00000000000000..690125d77b5272 --- /dev/null +++ b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleLegacyModule.kt @@ -0,0 +1,277 @@ +/* + * 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.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.Dynamic +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.ReadableType +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.module.annotations.ReactModule + +@ReactModule(name = SampleLegacyModule.NAME) +public class SampleLegacyModule(private val context: ReactApplicationContext) : + ReactContextBaseJavaModule(context) { + private var toast: Toast? = null + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getBool(arg: Boolean?): Boolean? { + log("getBool", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getEnum(arg: Double?): Double? { + log("getEnum", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getDouble(arg: Double?): Double? { + log("getDouble", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getInt(arg: Int?): Int? { + log("getInt", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getFloat(arg: Float?): Float? { + log("getFloat", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getObjectDouble(arg: Double?): Double? { + log("getObjectDouble", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getObjectInteger(arg: Int?): Int? { + log("getObjectInteger", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getObjectFloat(arg: Float?): Float? { + log("getObjectFloat", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getString(arg: String?): String? { + log("getString", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getRootTag(arg: Double?): Double? { + log("getRootTag", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod + public fun voidFunc() { + log("voidFunc", "", "") + 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 + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getObject(arg: ReadableMap?): WritableMap { + val map = WritableNativeMap() + arg?.let { map.merge(it) } + log("getObject", arg, map) + return map + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getUnsafeObject(arg: ReadableMap?): WritableMap { + val map = WritableNativeMap() + arg?.let { map.merge(it) } + log("getUnsafeObject", arg, map) + return map + } + + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getDynamic(dynamic: Dynamic?): WritableMap { + val resultMap = WritableNativeMap() + when (dynamic?.type) { + ReadableType.Null -> { + log("getDynamic as Null", dynamic, dynamic) + resultMap.putString("type", "Null") + resultMap.putNull("value") + } + ReadableType.Boolean -> { + val result = dynamic.asBoolean() + log("getDynamic as Boolean", dynamic, result) + resultMap.putString("type", "Boolean") + resultMap.putBoolean("value", result) + } + ReadableType.Number -> { + val result = dynamic.asInt() + log("getDynamic as Number", dynamic, result) + resultMap.putString("type", "Number") + resultMap.putInt("value", result) + } + ReadableType.String -> { + val result = dynamic.asString() + log("getDynamic as String", dynamic, result) + resultMap.putString("type", "String") + resultMap.putString("value", result) + } + ReadableType.Array -> { + val result = dynamic.asArray() + log("getDynamic as Array", dynamic, result) + resultMap.putString("type", "Array") + resultMap.putArray("value", result) + } + ReadableType.Map -> { + val result = dynamic.asMap() + log("getDynamic as Map", dynamic, result) + resultMap.putString("type", "Map") + resultMap.putMap("value", result) + } + else -> error("Unsupported dynamic type") + } + return resultMap + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getValue(numberArg: Double?, stringArg: String?, mapArg: ReadableMap?): WritableMap { + val map: WritableMap = + WritableNativeMap().apply { + putDouble("x", numberArg ?: 0.0) + putString("y", stringArg) + } + val zMap: WritableMap = WritableNativeMap() + mapArg?.let { zMap.merge(it) } + map.putMap("z", zMap) + log( + "getValue", + mapOf("1-numberArg" to numberArg, "2-stringArg" to stringArg, "3-mapArg" to mapArg), + map) + return map + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod + public fun getValueWithCallback(callback: Callback?) { + val result = "Value From Callback" + log("Callback", "Return Time", result) + callback?.invoke(result) + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod(isBlockingSynchronousMethod = true) + public fun getArray(arg: ReadableArray?): WritableArray { + if (arg == null || Arguments.toList(arg) == null) { + // Returning an empty array, since the super class always returns non-null + return WritableNativeArray() + } + val result: WritableArray = Arguments.makeNativeArray(Arguments.toList(arg)) + log("getArray", arg, result) + return result + } + + @DoNotStrip + @Suppress("unused") + @ReactMethod + public fun getValueWithPromise(error: Boolean, promise: Promise?) { + if (error) { + promise?.reject( + "code 1", "intentional promise rejection", Throwable("promise intentionally rejected")) + } else { + promise?.resolve("result") + } + } + + override fun getConstants(): Map { + val result: MutableMap = mutableMapOf() + val activity = context.currentActivity + if (activity != null) { + result["const2"] = 390 + } + result["const1"] = true + result["const3"] = "something" + log("constantsToExport", "", result) + return result + } + + private fun log(method: String, input: Any?, output: Any?) { + toast?.cancel() + val message = StringBuilder("Method :") + message + .append(method) + .append("\nInputs: ") + .append(input.toString()) + .append("\nOutputs: ") + .append(output.toString()) + toast = Toast.makeText(context, message.toString(), Toast.LENGTH_LONG) + toast?.show() + } + + override fun invalidate(): Unit = Unit + + override fun getName(): String { + return NAME + } + + public companion object { + public const val NAME: String = "SampleLegacyModule" + } +} diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.java b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.java deleted file mode 100644 index f74faf4b4dd1e9..00000000000000 --- a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * 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.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 com.facebook.react.turbomodule.core.interfaces.BindingsInstallerHolder; -import com.facebook.react.turbomodule.core.interfaces.TurboModuleWithJSIBindings; -import java.util.HashMap; -import java.util.Map; - -@DoNotStrip -@ReactModule(name = SampleTurboModule.NAME) -public class SampleTurboModule extends NativeSampleTurboModuleSpec - implements TurboModuleWithJSIBindings { - - public static final String NAME = "SampleTurboModule"; - - private static final String TAG = SampleTurboModule.class.getName(); - private final ReactApplicationContext mContext; - private Toast mToast; - - public SampleTurboModule(ReactApplicationContext context) { - super(context); - mContext = context; - } - - @DoNotStrip - @SuppressWarnings("unused") - @Override - public boolean getBool(boolean arg) { - log("getBool", arg, arg); - return arg; - } - - @DoNotStrip - @SuppressWarnings("unused") - @Override - public double getEnum(double arg) { - log("getEnum", arg, arg); - return arg; - } - - @Override - protected Map getTypedExportedConstants() { - Map result = new HashMap<>(); - DisplayMetrics displayMetrics = new DisplayMetrics(); - Activity activity = mContext.getCurrentActivity(); - if (activity != null) { - activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - result.put("const2", displayMetrics.widthPixels); - } - result.put("const1", true); - result.put("const3", "something"); - log("constantsToExport", "", result); - return result; - } - - @DoNotStrip - @SuppressWarnings("unused") - @Override - public double getNumber(double arg) { - log("getNumber", arg, arg); - return arg; - } - - @DoNotStrip - @SuppressWarnings("unused") - @Override - public String getString(String arg) { - log("getString", arg, arg); - return arg; - } - - @DoNotStrip - @SuppressWarnings("unused") - @Override - public double getRootTag(double arg) { - log("getRootTag", arg, arg); - return arg; - } - - @DoNotStrip - @SuppressWarnings("unused") - @Override - public void voidFunc() { - log("voidFunc", "", ""); - emitOnPress(); - emitOnClick("click"); - { - WritableNativeMap map = new WritableNativeMap(); - map.putInt("a", 1); - map.putString("b", "two"); - emitOnChange(map); - } - { - WritableNativeArray array = new WritableNativeArray(); - WritableNativeMap map = new WritableNativeMap(); - map.putInt("a", 1); - map.putString("b", "two"); - array.pushMap(map); - WritableNativeMap map1 = new WritableNativeMap(); - map1.putInt("a", 3); - map1.putString("b", "four"); - array.pushMap(map1); - emitOnSubmit(array); - } - } - - // 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 - @Override - @SuppressWarnings("unused") - public WritableMap getObject(ReadableMap arg) { - WritableNativeMap map = new WritableNativeMap(); - map.merge(arg); - log("getObject", arg, map); - return map; - } - - @DoNotStrip - @Override - @SuppressWarnings("unused") - public WritableMap getUnsafeObject(ReadableMap arg) { - WritableNativeMap map = new WritableNativeMap(); - map.merge(arg); - log("getUnsafeObject", arg, map); - return map; - } - - @DoNotStrip - @SuppressWarnings("unused") - @Override - 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") - @Override - public void getValueWithCallback(final Callback callback) { - String result = "Value From Callback"; - log("Callback", "Return Time", result); - callback.invoke(result); - } - - @DoNotStrip - @SuppressWarnings("unused") - @Override - 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; - } - - @Override - @DoNotStrip - @SuppressWarnings("unused") - 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 - @DoNotStrip - @SuppressWarnings("unused") - public void voidFuncThrows() { - throw new RuntimeException("Intentional exception from JVM voidFuncThrows"); - } - ; - - @Override - @DoNotStrip - @SuppressWarnings("unused") - public WritableMap getObjectThrows(ReadableMap arg) { - throw new RuntimeException( - "Intentional exception from JVM getObjectThrows with " + arg.toString()); - } - ; - - @Override - @DoNotStrip - @SuppressWarnings("unused") - public void promiseThrows(Promise promise) { - throw new RuntimeException("Intentional exception from JVM promiseThrows"); - } - ; - - @Override - @DoNotStrip - @SuppressWarnings("unused") - public void voidFuncAssert() { - assert false : "Intentional assert from JVM voidFuncAssert"; - } - ; - - @Override - @DoNotStrip - @SuppressWarnings("unused") - public WritableMap getObjectAssert(ReadableMap arg) { - assert false : "Intentional assert from JVM getObjectAssert with " + arg.toString(); - return null; - } - ; - - @Override - @DoNotStrip - @SuppressWarnings("unused") - public void promiseAssert(Promise promise) { - assert false : "Intentional assert from JVM promiseAssert"; - } - ; - - 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; - } - - @Override - @DoNotStrip - public native BindingsInstallerHolder getBindingsInstaller(); -} diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.kt b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.kt new file mode 100644 index 00000000000000..7a17bc941f9505 --- /dev/null +++ b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.kt @@ -0,0 +1,245 @@ +/* + * 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.os.Build +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.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.module.annotations.ReactModule +import com.facebook.react.turbomodule.core.interfaces.BindingsInstallerHolder +import com.facebook.react.turbomodule.core.interfaces.TurboModuleWithJSIBindings + +@DoNotStrip +@ReactModule(name = SampleTurboModule.NAME) +public class SampleTurboModule(private val context: ReactApplicationContext) : + NativeSampleTurboModuleSpec(context), TurboModuleWithJSIBindings { + + private var toast: Toast? = null + + @DoNotStrip + override fun getBool(arg: Boolean): Boolean { + log("getBool", arg, arg) + return arg + } + + @DoNotStrip + override fun getEnum(arg: Double): Double { + log("getEnum", arg, arg) + return arg + } + + override fun getTypedExportedConstants(): MutableMap { + val result: MutableMap = mutableMapOf() + val activity = context.currentActivity + if (activity != null) { + @Suppress("DEPRECATION") + val widthPixels = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + activity.windowManager.currentWindowMetrics.bounds.width() + } else { + val displayMetrics = DisplayMetrics() + activity.windowManager.defaultDisplay.getMetrics(displayMetrics) + displayMetrics.widthPixels + } + result["const2"] = widthPixels + } + result["const1"] = true + result["const3"] = "something" + log("constantsToExport", "", result) + return result + } + + @DoNotStrip + override fun getNumber(arg: Double): Double { + log("getNumber", arg, arg) + return arg + } + + @DoNotStrip + override fun getString(arg: String?): String? { + log("getString", arg, arg) + return arg + } + + @DoNotStrip + @Suppress("unused") + override fun getRootTag(arg: Double): Double { + log("getRootTag", arg, arg) + return arg + } + + @DoNotStrip + override fun voidFunc() { + log("voidFunc", "", "") + emitOnPress() + emitOnClick("click") + run { + val map = + WritableNativeMap().apply { + putInt("a", 1) + putString("b", "two") + } + emitOnChange(map) + } + run { + val array = WritableNativeArray() + val map1 = + WritableNativeMap().apply { + putInt("a", 1) + putString("b", "two") + } + val map2 = + WritableNativeMap().apply { + putInt("a", 3) + putString("b", "four") + } + array.pushMap(map1) + array.pushMap(map2) + emitOnSubmit(array) + } + } + + // 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 + @Suppress("unused") + override fun getObject(arg: ReadableMap?): WritableMap { + val map = WritableNativeMap() + arg?.let { map.merge(it) } + log("getObject", arg, map) + return map + } + + @DoNotStrip + @Suppress("unused") + override fun getUnsafeObject(arg: ReadableMap?): WritableMap { + val map = WritableNativeMap() + arg?.let { map.merge(it) } + log("getUnsafeObject", arg, map) + return map + } + + @DoNotStrip + @Suppress("unused") + override fun getValue(x: Double, y: String?, z: ReadableMap?): WritableMap { + val map: WritableMap = WritableNativeMap() + map.putDouble("x", x) + map.putString("y", y) + val zMap: WritableMap = WritableNativeMap() + z?.let { zMap.merge(it) } + map.putMap("z", zMap) + log("getValue", mapOf("1-numberArg" to x, "2-stringArg" to y, "3-mapArg" to z), map) + return map + } + + @DoNotStrip + @Suppress("unused") + override fun getValueWithCallback(callback: Callback?) { + val result = "Value From Callback" + log("Callback", "Return Time", result) + callback?.invoke(result) + } + + @DoNotStrip + @Suppress("unused") + override fun getArray(arg: ReadableArray?): WritableArray { + if (arg == null || Arguments.toList(arg) == null) { + // Returning an empty array, since the super class always returns non-null + return WritableNativeArray() + } + val result: WritableArray = Arguments.makeNativeArray(Arguments.toList(arg)) + log("getArray", arg, result) + return result + } + + @DoNotStrip + @Suppress("unused") + override fun getValueWithPromise(error: Boolean, promise: Promise?) { + if (error) { + promise?.reject( + "code 1", "intentional promise rejection", Throwable("promise intentionally rejected")) + } else { + promise?.resolve("result") + } + } + + @DoNotStrip + @Suppress("unused") + override fun voidFuncThrows() { + error("Intentional exception from JVM voidFuncThrows") + } + + @DoNotStrip + @Suppress("unused") + override fun getObjectThrows(arg: ReadableMap?): WritableMap? { + error("Intentional exception from JVM getObjectThrows with $arg") + } + + @DoNotStrip + @Suppress("unused") + override fun promiseThrows(promise: Promise?) { + error("Intentional exception from JVM promiseThrows") + } + + @DoNotStrip + @Suppress("unused") + override fun voidFuncAssert() { + assert(false) { "Intentional assert from JVM voidFuncAssert" } + } + + @DoNotStrip + @Suppress("unused") + override fun getObjectAssert(arg: ReadableMap?): WritableMap? { + assert(false) { "Intentional assert from JVM getObjectAssert with $arg" } + return null + } + + @DoNotStrip + @Suppress("unused") + override fun promiseAssert(promise: Promise?) { + assert(false) { "Intentional assert from JVM promiseAssert" } + } + + private fun log(method: String, input: Any?, output: Any?) { + toast?.cancel() + val message = StringBuilder("Method :") + message + .append(method) + .append("\nInputs: ") + .append(input.toString()) + .append("\nOutputs: ") + .append(output.toString()) + toast = Toast.makeText(context, message.toString(), Toast.LENGTH_LONG) + toast?.show() + } + + override fun invalidate(): Unit = Unit + + override fun getName(): String { + return NAME + } + + @DoNotStrip external override fun getBindingsInstaller(): BindingsInstallerHolder + + public companion object { + public const val NAME: String = "SampleTurboModule" + } +} diff --git a/packages/rn-tester/android/app/build.gradle.kts b/packages/rn-tester/android/app/build.gradle.kts index 6bea209c0e8938..463552fee0647a 100644 --- a/packages/rn-tester/android/app/build.gradle.kts +++ b/packages/rn-tester/android/app/build.gradle.kts @@ -184,6 +184,8 @@ android { } } +kotlin { explicitApi() } + afterEvaluate { if (project.findProperty("react.internal.useHermesNightly") == null || project.findProperty("react.internal.useHermesNightly").toString() == "false") { diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/FBRNTesterEndToEndHelper.kt b/packages/rn-tester/android/app/src/main/java/com/facebook/react/FBRNTesterEndToEndHelper.kt index 59abbe221566c9..2b4e2e3463ea57 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/FBRNTesterEndToEndHelper.kt +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/FBRNTesterEndToEndHelper.kt @@ -11,7 +11,7 @@ import android.app.Application import java.io.PrintWriter @Suppress("UNUSED_PARAMETER") -object FBRNTesterEndToEndHelper { +internal object FBRNTesterEndToEndHelper { fun onCreate(application: Application) { // no-op This is an empty implementation to stub out Meta's internal test coverage // instrumentation. diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.kt b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.kt index ceb499fd44e94d..e1394a77e0fbe5 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.kt +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.kt @@ -21,7 +21,7 @@ import com.facebook.react.defaults.DefaultReactActivityDelegate import java.io.FileDescriptor import java.io.PrintWriter -class RNTesterActivity : ReactActivity() { +internal class RNTesterActivity : ReactActivity() { class RNTesterActivityDelegate(val activity: ReactActivity, mainComponentName: String) : DefaultReactActivityDelegate(activity, mainComponentName, fabricEnabled) { private val PARAM_ROUTE = "route" diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.kt b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.kt index 18d03973eaf1a4..aadae931fe00e0 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.kt +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.kt @@ -34,7 +34,7 @@ import com.facebook.react.uimanager.ReactShadowNode import com.facebook.react.uimanager.ViewManager import com.facebook.soloader.SoLoader -class RNTesterApplication : Application(), ReactApplication { +internal class RNTesterApplication : Application(), ReactApplication { override val reactNativeHost: ReactNativeHost by lazy { object : DefaultReactNativeHost(this) { public override fun getJSMainModuleName(): String = BuildConfig.JS_MAIN_MODULE_NAME diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeView.kt b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeView.kt index 59d3509e528f54..4fb12443c2c365 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeView.kt +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/component/MyNativeView.kt @@ -23,7 +23,7 @@ import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.uimanager.events.Event import com.facebook.react.uimanager.events.RCTEventEmitter -class MyNativeView(context: ThemedReactContext) : View(context) { +internal class MyNativeView(context: ThemedReactContext) : View(context) { private var currentColor = 0 private var background: GradientDrawable = GradientDrawable() private var reactContext: ReactContext = context.reactApplicationContext