diff --git a/ReactCommon/react/nativemodule/samples/platform/android/Android.mk b/ReactCommon/react/nativemodule/samples/platform/android/Android.mk new file mode 100644 index 0000000000..46dfd7623a --- /dev/null +++ b/ReactCommon/react/nativemodule/samples/platform/android/Android.mk @@ -0,0 +1,18 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := sampleturbomodule +LOCAL_C_INCLUDES := $(LOCAL_PATH) +LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/ReactCommon/*.cpp) +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) +LOCAL_SHARED_LIBRARIES := libfbjni libreact_nativemodule_core +LOCAL_CFLAGS := \ + -DLOG_TAG=\"ReactNative\" +LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall + +include $(BUILD_STATIC_LIBRARY) diff --git a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp index b1c6922e3b..676a79ee5e 100644 --- a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp +++ b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp @@ -196,5 +196,14 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI( 0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; } +std::shared_ptr SampleTurboModuleSpec_ModuleProvider( + const std::string moduleName, + const JavaTurboModule::InitParams ¶ms) { + if (moduleName == "SampleTurboModule") { + return std::make_shared(params); + } + return nullptr; +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h index fd8f6c3c87..6baefae6d8 100644 --- a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h +++ b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h @@ -19,11 +19,14 @@ namespace react { /** * C++ class for module 'SampleTurboModule' */ - class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public JavaTurboModule { public: NativeSampleTurboModuleSpecJSI(const JavaTurboModule::InitParams ¶ms); }; +std::shared_ptr SampleTurboModuleSpec_ModuleProvider( + const std::string moduleName, + const JavaTurboModule::InitParams ¶ms); + } // namespace react } // namespace facebook diff --git a/packages/rn-tester/android/app/build.gradle b/packages/rn-tester/android/app/build.gradle index fe95b03be0..186a325259 100644 --- a/packages/rn-tester/android/app/build.gradle +++ b/packages/rn-tester/android/app/build.gradle @@ -184,6 +184,14 @@ android { proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro" } } + sourceSets.main { + java { + // SampleTurboModule. + srcDirs += [ + "$rootDir/ReactCommon/react/nativemodule/samples/platform/android", + ] + } + } } configurations { diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java index c191ecaec9..710d8e0c72 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java @@ -10,16 +10,19 @@ package com.facebook.react.uiapp; import android.app.Application; import android.content.Context; import androidx.annotation.Nullable; +import com.facebook.fbreact.specs.SampleTurboModule; import com.facebook.react.ReactApplication; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; +import com.facebook.react.TurboReactPackage; import com.facebook.react.bridge.JSIModule; import com.facebook.react.bridge.JSIModulePackage; import com.facebook.react.bridge.JSIModuleProvider; import com.facebook.react.bridge.JSIModuleSpec; import com.facebook.react.bridge.JSIModuleType; import com.facebook.react.bridge.JavaScriptContextHolder; +import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.UIManager; import com.facebook.react.config.ReactFeatureFlags; @@ -27,6 +30,8 @@ import com.facebook.react.fabric.ComponentFactory; import com.facebook.react.fabric.CoreComponentsRegistry; import com.facebook.react.fabric.FabricJSIModuleProvider; import com.facebook.react.fabric.ReactNativeConfig; +import com.facebook.react.module.model.ReactModuleInfo; +import com.facebook.react.module.model.ReactModuleInfoProvider; import com.facebook.react.shell.MainReactPackage; import com.facebook.react.turbomodule.core.TurboModuleManager; import com.facebook.react.views.text.ReactFontManager; @@ -34,7 +39,9 @@ import com.facebook.soloader.SoLoader; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class RNTesterApplication extends Application implements ReactApplication { @@ -57,7 +64,47 @@ public class RNTesterApplication extends Application implements ReactApplication @Override public List getPackages() { - return Arrays.asList(new MainReactPackage()); + return Arrays.asList( + new MainReactPackage(), + new TurboReactPackage() { + public NativeModule getModule( + final String name, final ReactApplicationContext reactContext) { + if (!ReactFeatureFlags.useTurboModules) { + return null; + } + + if (SampleTurboModule.NAME.equals(name)) { + return new SampleTurboModule(reactContext); + } + + return null; + } + + // Note: Specialized annotation processor for @ReactModule isn't configured in OSS + // yet. For now, hardcode this information, though it's not necessary for most + // modules. + public ReactModuleInfoProvider getReactModuleInfoProvider() { + return new ReactModuleInfoProvider() { + public Map getReactModuleInfos() { + final Map moduleInfos = new HashMap<>(); + if (ReactFeatureFlags.useTurboModules) { + moduleInfos.put( + SampleTurboModule.NAME, + new ReactModuleInfo( + SampleTurboModule.NAME, + "SampleTurboModule", + false, // canOverrideExistingModule + false, // needsEagerInit + true, // hasConstants + false, // isCxxModule + true // isTurboModule + )); + } + return moduleInfos; + } + }; + } + }); } @Nullable @@ -72,7 +119,7 @@ public class RNTesterApplication extends Application implements ReactApplication public List getJSIModules( final ReactApplicationContext reactApplicationContext, final JavaScriptContextHolder jsContext) { - List specs = new ArrayList<>(); + final List specs = new ArrayList<>(); // Install the new native module system. if (ReactFeatureFlags.useTurboModules) { @@ -88,8 +135,9 @@ public class RNTesterApplication extends Application implements ReactApplication return new JSIModuleProvider() { @Override public JSIModule get() { - ReactInstanceManager reactInstanceManager = getReactInstanceManager(); - List packages = reactInstanceManager.getPackages(); + final ReactInstanceManager reactInstanceManager = + getReactInstanceManager(); + final List packages = reactInstanceManager.getPackages(); return new TurboModuleManager( jsContext, @@ -118,7 +166,7 @@ public class RNTesterApplication extends Application implements ReactApplication @Override public JSIModuleProvider getJSIModuleProvider() { - ComponentFactory ComponentFactory = new ComponentFactory(); + final ComponentFactory ComponentFactory = new ComponentFactory(); CoreComponentsRegistry.register(ComponentFactory); return new FabricJSIModuleProvider( reactApplicationContext, @@ -126,22 +174,22 @@ public class RNTesterApplication extends Application implements ReactApplication // TODO: T71362667 add ReactNativeConfig's support in RNTester new ReactNativeConfig() { @Override - public boolean getBool(String s) { + public boolean getBool(final String s) { return false; } @Override - public int getInt64(String s) { + public int getInt64(final String s) { return 0; } @Override - public String getString(String s) { + public String getString(final String s) { return ""; } @Override - public double getDouble(String s) { + public double getDouble(final String s) { return 0; } }); @@ -178,24 +226,24 @@ public class RNTesterApplication extends Application implements ReactApplication * @param reactInstanceManager */ private static void initializeFlipper( - Context context, ReactInstanceManager reactInstanceManager) { + final Context context, final ReactInstanceManager reactInstanceManager) { if (BuildConfig.DEBUG) { try { /* We use reflection here to pick up the class that initializes Flipper, since Flipper library is not available in release mode */ - Class aClass = Class.forName("com.facebook.react.uiapp.ReactNativeFlipper"); + final Class aClass = Class.forName("com.facebook.react.uiapp.ReactNativeFlipper"); aClass .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) .invoke(null, context, reactInstanceManager); - } catch (ClassNotFoundException e) { + } catch (final ClassNotFoundException e) { e.printStackTrace(); - } catch (NoSuchMethodException e) { + } catch (final NoSuchMethodException e) { e.printStackTrace(); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { e.printStackTrace(); - } catch (InvocationTargetException e) { + } catch (final InvocationTargetException e) { e.printStackTrace(); } } diff --git a/packages/rn-tester/android/app/src/main/jni/Android.mk b/packages/rn-tester/android/app/src/main/jni/Android.mk index 2029b87348..6e003cdb95 100644 --- a/packages/rn-tester/android/app/src/main/jni/Android.mk +++ b/packages/rn-tester/android/app/src/main/jni/Android.mk @@ -7,6 +7,9 @@ THIS_DIR := $(call my-dir) include $(REACT_ANDROID_DIR)/Android-prebuilt.mk +# SampleNativeModule +include $(REACT_COMMON_DIR)/react/nativemodule/samples/platform/android/Android.mk + LOCAL_PATH := $(THIS_DIR) include $(CLEAR_VARS) @@ -16,6 +19,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) $(GENERATED_SRC_DIR)/codegen/jni LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(GENERATED_SRC_DIR)/codegen/jni LOCAL_SHARED_LIBRARIES := libfbjni libreact_nativemodule_core libturbomodulejsijni libreact_codegen_reactandroidspec +LOCAL_STATIC_LIBRARIES := libsampleturbomodule LOCAL_CFLAGS := \ -DLOG_TAG=\"ReactNative\" LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall diff --git a/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp b/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp index 493d8267e3..60d8c7fba8 100644 --- a/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp +++ b/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp @@ -9,6 +9,8 @@ #include #include +// TODO: Remove SampleTurboModule from ReactAndroidSpec, then uncomment. +// #include namespace facebook { namespace react { @@ -19,6 +21,12 @@ std::shared_ptr RNTesterAppModuleProvider(const std::string moduleN return module; } + // TODO: Remove SampleTurboModule from ReactAndroidSpec, then uncomment. + // module = SampleTurboModuleSpec_ModuleProvider(moduleName, params); + // if (module != nullptr) { + // return module; + // } + // TODO: fix up the ReactAndroidSpec_ModuleProvider() to avoid the Android prefix. if (moduleName == "DatePicker") { return std::make_shared(params); diff --git a/packages/rn-tester/js/utils/RNTesterList.android.js b/packages/rn-tester/js/utils/RNTesterList.android.js index bb509d0f3b..5971a0facf 100644 --- a/packages/rn-tester/js/utils/RNTesterList.android.js +++ b/packages/rn-tester/js/utils/RNTesterList.android.js @@ -264,6 +264,14 @@ const APIExamples: Array = [ }, ]; +if (global.__turboModuleProxy) { + APIExamples.push({ + key: 'TurboModuleExample', + category: 'Basic', + module: require('../examples/TurboModule/TurboModuleExample'), + }); +} + const Modules: any = {}; APIExamples.concat(ComponentExamples).forEach(Example => {