From f93d95e0791e41688a161f046393bf26c742f646 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Fri, 13 Aug 2021 13:52:11 -0700 Subject: [PATCH] Log SoftExceptions when the legacy NativeModule system is used Summary: When ReactFeatureFlags.warnOnLegacyNativeModuleSystemUse is true, we will log a SoftException, whenever: 1. A Java/Cxx NativeModule is created by the legacy system. 2. Any method on the Java NativeModule is executed, including getConstants(). NOTE: Logs to CXXModule use incoming. Changelog: [Internal] Reviewed By: JoshuaGross Differential Revision: D30252953 fbshipit-source-id: 570929624d0114bb298c593ba909e5cdbd54bd6c --- .../react/bridge/JavaModuleWrapper.java | 37 +++++++++++++++++++ .../react/bridge/NativeModuleRegistry.java | 22 +++++++++++ 2 files changed, 59 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaModuleWrapper.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaModuleWrapper.java index 2267300ec2f..c113c6b056b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaModuleWrapper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaModuleWrapper.java @@ -15,6 +15,7 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE; import androidx.annotation.Nullable; import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.config.ReactFeatureFlags; import com.facebook.systrace.Systrace; import com.facebook.systrace.SystraceMessage; import java.lang.reflect.Method; @@ -43,6 +44,7 @@ public class JavaModuleWrapper { private final ModuleHolder mModuleHolder; private final ArrayList mMethods; private final ArrayList mDescs; + private static final String TAG = JavaModuleWrapper.class.getSimpleName(); public JavaModuleWrapper(JSInstance jsInstance, ModuleHolder moduleHolder) { mJSInstance = jsInstance; @@ -113,6 +115,17 @@ public class JavaModuleWrapper { @DoNotStrip public @Nullable NativeMap getConstants() { + if (ReactFeatureFlags.warnOnLegacyNativeModuleSystemUse) { + ReactSoftExceptionLogger.logSoftException( + TAG, + new ReactNoCrashSoftException( + "Calling getConstants() on Java NativeModule (name = \"" + + mModuleHolder.getName() + + "\", className = " + + mModuleHolder.getClassName() + + ").")); + } + if (!mModuleHolder.getHasConstants()) { return null; } @@ -144,10 +157,34 @@ public class JavaModuleWrapper { @DoNotStrip public void invoke(int methodId, ReadableNativeArray parameters) { + if (ReactFeatureFlags.warnOnLegacyNativeModuleSystemUse) { + ReactSoftExceptionLogger.logSoftException( + TAG, + new ReactNoCrashSoftException( + "Calling method on Java NativeModule (name = \"" + + mModuleHolder.getName() + + "\", className = " + + mModuleHolder.getClassName() + + ").")); + } + if (mMethods == null || methodId >= mMethods.size()) { return; } + if (ReactFeatureFlags.warnOnLegacyNativeModuleSystemUse) { + ReactSoftExceptionLogger.logSoftException( + TAG, + new ReactNoCrashSoftException( + "Calling " + + mDescs.get(methodId).name + + "() on Java NativeModule (name = \"" + + mModuleHolder.getName() + + "\", className = " + + mModuleHolder.getClassName() + + ").")); + } + mMethods.get(methodId).invoke(mJSInstance, parameters); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java index 26bd8b050be..809d915c014 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java @@ -21,6 +21,7 @@ public class NativeModuleRegistry { private final ReactApplicationContext mReactApplicationContext; private final Map mModules; + private final String TAG = NativeModuleRegistry.class.getSimpleName(); public NativeModuleRegistry( ReactApplicationContext reactApplicationContext, Map modules) { @@ -41,6 +42,17 @@ public class NativeModuleRegistry { ArrayList javaModules = new ArrayList<>(); for (Map.Entry entry : mModules.entrySet()) { if (!entry.getValue().isCxxModule()) { + if (ReactFeatureFlags.warnOnLegacyNativeModuleSystemUse) { + ReactSoftExceptionLogger.logSoftException( + TAG, + new ReactNoCrashSoftException( + "Registering legacy NativeModule: Java NativeModule (name = \"" + + entry.getValue().getName() + + "\", className = " + + entry.getValue().getClassName() + + ").")); + } + javaModules.add(new JavaModuleWrapper(jsInstance, entry.getValue())); } } @@ -51,6 +63,16 @@ public class NativeModuleRegistry { ArrayList cxxModules = new ArrayList<>(); for (Map.Entry entry : mModules.entrySet()) { if (entry.getValue().isCxxModule()) { + if (ReactFeatureFlags.warnOnLegacyNativeModuleSystemUse) { + ReactSoftExceptionLogger.logSoftException( + TAG, + new ReactNoCrashSoftException( + "Registering legacy NativeModule: Cxx NativeModule (name = \"" + + entry.getValue().getName() + + "\", className = " + + entry.getValue().getClassName() + + ").")); + } cxxModules.add(entry.getValue()); } }