diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarker.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarker.java index 73aa6922b9f..fa82230f2a9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarker.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarker.java @@ -8,9 +8,12 @@ package com.facebook.react.bridge; import android.os.SystemClock; +import androidx.annotation.AnyThread; import androidx.annotation.Nullable; import com.facebook.proguard.annotations.DoNotStrip; import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -20,6 +23,26 @@ import java.util.concurrent.CopyOnWriteArrayList; @DoNotStrip public class ReactMarker { + private static Queue sNativeReactMarkerQueue = new ConcurrentLinkedQueue<>(); + + private static class ReactMarkerRecord { + private final String mMarkerName; + private final long mMarkerTime; + + public ReactMarkerRecord(String markerName, long markerTime) { + mMarkerName = markerName; + mMarkerTime = markerTime; + } + + public String getMarkerName() { + return mMarkerName; + } + + public long getMarkerTime() { + return mMarkerTime; + } + } + public interface MarkerListener { void logMarker(ReactMarkerConstants name, @Nullable String tag, int instanceKey); }; @@ -135,14 +158,36 @@ public class ReactMarker { } @DoNotStrip + @AnyThread public static void logMarker(ReactMarkerConstants name, @Nullable String tag, int instanceKey) { logFabricMarker(name, tag, instanceKey); for (MarkerListener listener : sListeners) { listener.logMarker(name, tag, instanceKey); } + notifyNativeMarker(name); + } + + @DoNotStrip + private static void notifyNativeMarker(ReactMarkerConstants name) { + if (!name.hasMatchingNameMarker()) { + return; + } + + long now = SystemClock.uptimeMillis(); + if (ReactBridge.isInitialized()) { - nativeLogMarker(name.name(), SystemClock.uptimeMillis()); + // First send the current marker + nativeLogMarker(name.name(), now); + + // Then send all cached native ReactMarkers + while (!sNativeReactMarkerQueue.isEmpty()) { + ReactMarkerRecord record = sNativeReactMarkerQueue.poll(); + nativeLogMarker(record.getMarkerName(), record.getMarkerTime()); + } + } else { + // The native JNI method is not loaded at this point. + sNativeReactMarkerQueue.add(new ReactMarkerRecord(name.name(), now)); } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java index b90a03600bd..af8fcb804d0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactMarkerConstants.java @@ -10,7 +10,7 @@ package com.facebook.react.bridge; /** Constants used by ReactMarker. */ public enum ReactMarkerConstants { CREATE_REACT_CONTEXT_START, - CREATE_REACT_CONTEXT_END, + CREATE_REACT_CONTEXT_END(true), PROCESS_PACKAGES_START, PROCESS_PACKAGES_END, BUILD_NATIVE_MODULE_REGISTRY_START, @@ -19,8 +19,8 @@ public enum ReactMarkerConstants { CREATE_CATALYST_INSTANCE_END, DESTROY_CATALYST_INSTANCE_START, DESTROY_CATALYST_INSTANCE_END, - RUN_JS_BUNDLE_START, - RUN_JS_BUNDLE_END, + RUN_JS_BUNDLE_START(true), + RUN_JS_BUNDLE_END(true), NATIVE_MODULE_INITIALIZE_START, NATIVE_MODULE_INITIALIZE_END, SETUP_REACT_CONTEXT_START, @@ -32,8 +32,8 @@ public enum ReactMarkerConstants { CREATE_VIEW_MANAGERS_END, CREATE_UI_MANAGER_MODULE_CONSTANTS_START, CREATE_UI_MANAGER_MODULE_CONSTANTS_END, - NATIVE_MODULE_SETUP_START, - NATIVE_MODULE_SETUP_END, + NATIVE_MODULE_SETUP_START(true), + NATIVE_MODULE_SETUP_END(true), CREATE_MODULE_START, CREATE_MODULE_END, PROCESS_CORE_REACT_PACKAGE_START, @@ -59,8 +59,8 @@ public enum ReactMarkerConstants { UNPACKING_JS_BUNDLE_LOADER_CHECK_END, UNPACKING_JS_BUNDLE_LOADER_EXTRACTED, UNPACKING_JS_BUNDLE_LOADER_BLOCKED, - loadApplicationScript_startStringConvert, - loadApplicationScript_endStringConvert, + loadApplicationScript_startStringConvert(true), + loadApplicationScript_endStringConvert(true), PRE_SETUP_REACT_CONTEXT_START, PRE_SETUP_REACT_CONTEXT_END, PRE_RUN_JS_BUNDLE_START, @@ -86,8 +86,8 @@ public enum ReactMarkerConstants { CREATE_MC_MODULE_END, CREATE_MC_MODULE_GET_METADATA_START, CREATE_MC_MODULE_GET_METADATA_END, - REGISTER_JS_SEGMENT_START, - REGISTER_JS_SEGMENT_STOP, + REGISTER_JS_SEGMENT_START(true), + REGISTER_JS_SEGMENT_STOP(true), VM_INIT, ON_FRAGMENT_CREATE, JAVASCRIPT_EXECUTOR_FACTORY_INJECT_START, @@ -121,5 +121,19 @@ public enum ReactMarkerConstants { REACT_BRIDGELESS_LOADING_START, REACT_BRIDGELESS_LOADING_END, LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_START, - LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_END, + LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_END; + + private boolean mHasMatchingNameMarker; + + ReactMarkerConstants() { + this(false); + } + + ReactMarkerConstants(boolean hasMatchingNameMarker) { + mHasMatchingNameMarker = hasMatchingNameMarker; + } + + public boolean hasMatchingNameMarker() { + return mHasMatchingNameMarker; + } }