diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK index ba1e76099c..a5c503d2f7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK @@ -26,6 +26,7 @@ rn_android_library( react_native_target("java/com/facebook/debug/tags:tags"), react_native_target("java/com/facebook/react/bridge:bridge"), react_native_target("java/com/facebook/react/common:common"), + react_native_target("java/com/facebook/react/util:util"), react_native_target("java/com/facebook/react/common/network:network"), react_native_target("java/com/facebook/react/devsupport:interfaces"), react_native_target("java/com/facebook/react/module/annotations:annotations"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java index 2c4e4eae53..201ee96f95 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java @@ -11,13 +11,12 @@ import android.app.Activity; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; -import com.facebook.common.logging.FLog; import com.facebook.fbreact.specs.NativeLogBoxSpec; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.UiThreadUtil; -import com.facebook.react.common.ReactConstants; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.module.annotations.ReactModule; +import com.facebook.react.util.RNLog; @ReactModule(name = LogBoxModule.NAME) public class LogBoxModule extends NativeLogBoxSpec { @@ -40,9 +39,7 @@ public class LogBoxModule extends NativeLogBoxSpec { if (mReactRootView == null && mDevSupportManager != null) { mReactRootView = mDevSupportManager.createRootView("LogBox"); if (mReactRootView == null) { - FLog.e( - ReactConstants.TAG, - "Unable to launch logbox because react was unable to create the root view"); + RNLog.e("Unable to launch logbox because react was unable to create the root view"); } } } @@ -64,8 +61,7 @@ public class LogBoxModule extends NativeLogBoxSpec { if (mLogBoxDialog == null && mReactRootView != null) { Activity context = getCurrentActivity(); if (context == null || context.isFinishing()) { - FLog.e( - ReactConstants.TAG, + RNLog.e( "Unable to launch logbox because react activity " + "is not available, here is the error that logbox would've displayed: "); return; diff --git a/ReactAndroid/src/main/java/com/facebook/react/util/BUCK b/ReactAndroid/src/main/java/com/facebook/react/util/BUCK index 93288f7267..b78a3fd8e3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/util/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/util/BUCK @@ -7,7 +7,9 @@ rn_android_library( "PUBLIC", ], deps = [ + react_native_dep("libraries/fbcore/src/main/java/com/facebook/common/logging:logging"), react_native_dep("third-party/java/jsr-305:jsr-305"), + react_native_target("java/com/facebook/react/common:common"), react_native_target("java/com/facebook/react/bridge:bridge"), ], ) diff --git a/ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.java b/ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.java new file mode 100644 index 0000000000..511190ebac --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.java @@ -0,0 +1,26 @@ +/* + * 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. + */ + +package com.facebook.react.util; + +import com.facebook.react.bridge.JavaScriptModule; + +/** + * JS module interface for RCTLog + * + *

The RCTLog module allows for showing native logs in JavaScript. + */ +public interface RCTLog extends JavaScriptModule { + + /** + * Send a log to JavaScript. + * + * @param level The level of the log. + * @param message The message to log. + */ + void logIfNoNativeHook(String level, String message); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/util/RNLog.java b/ReactAndroid/src/main/java/com/facebook/react/util/RNLog.java new file mode 100644 index 0000000000..6355251cb5 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/util/RNLog.java @@ -0,0 +1,125 @@ +/* + * 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. + */ + +package com.facebook.react.util; + +import android.util.Log; +import com.facebook.common.logging.FLog; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.common.ReactConstants; + +/** Logging wrapper for FLog with LogBox support. */ +public class RNLog { + public static final int MINIMUM_LEVEL_FOR_UI = Log.WARN; + + public static final int LOG = Log.VERBOSE; + + public static final int TRACE = Log.DEBUG; + + public static final int ADVICE = Log.INFO; + + public static final int WARN = Log.WARN; + + public static final int ERROR = Log.ERROR; + + /** + * Log a log level message tagged as React Native to the console. + * + * @param message The message to log. + */ + public static void l(String message) { + FLog.i(ReactConstants.TAG, message); + } + + /** + * Log a trace level message tagged as React Native to the console. + * + * @param message The message to log. + */ + public static void t(String message) { + FLog.i(ReactConstants.TAG, message); + } + + /** + * Log a warning level message tagged as React Native to the console. This warning will not be + * shown in LogBox. + * + * @param message The message to log. + */ + public static void a(String message) { + FLog.w(ReactConstants.TAG, "(ADVICE)" + message); + } + + /** + * Log a warning level message tagged as React Native to the console and display in the app. + * + * @param context The React context of the application use to display the warning. + * @param message The message to log. + */ + public static void w(ReactContext context, String message) { + RNLog.logInternal(context, message, WARN); + FLog.w(ReactConstants.TAG, message); + } + + /** + * Log an error level message tagged as React Native to the console and display in the app. + * + * @param context The React context of the application use to display the error. + * @param message The message to log. + */ + public static void e(ReactContext context, String message) { + RNLog.logInternal(context, message, ERROR); + FLog.e(ReactConstants.TAG, message); + } + + /** + * Log an error level message tagged as React Native to the console. This error will not be shown + * in LogBox. + * + * @param message The message to log. + */ + public static void e(String message) { + FLog.e(ReactConstants.TAG, message); + } + + private static void logInternal(ReactContext context, String message, int level) { + if (level >= MINIMUM_LEVEL_FOR_UI) { + if (context != null && message != null) { + context.getJSModule(RCTLog.class).logIfNoNativeHook(levelToString(level), message); + } + } + } + + private static String levelToString(int level) { + switch (level) { + case LOG: + { + return "log"; + } + case TRACE: + { + return "log"; + } + case ADVICE: + { + return "warn"; + } + case WARN: + { + return "warn"; + } + case ERROR: + { + return "error"; + } + default: + { + return "none"; + } + } + } +}