From 18165367b0347fc46cd52a6ac00afcf62d05cb30 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 15 Jun 2021 17:34:08 -0700 Subject: [PATCH] Move RuntimeScheduler initialisation to the start of the runtime Summary: Changelog: [internal] RuntimeScheduler needs to be created and registered in the runtime before any JS is allowed to run. This diff moves the registration right after the runtime is initialised. This diff removes funnelling of Fabric events through RuntimeScheduler. This will be added in subsequent diff to keep the complexity low. Reviewed By: JoshuaGross Differential Revision: D29131766 fbshipit-source-id: cbc650f6fbce95e4b9c2c9695e8e0aba5beac635 --- .../src/main/java/com/facebook/react/BUCK | 1 + .../facebook/react/ReactInstanceManager.java | 7 +++ .../react/config/ReactFeatureFlags.java | 2 + .../react/fabric/RuntimeSchedulerManager.java | 41 +++++++++++++++++ .../com/facebook/react/fabric/jni/OnLoad.cpp | 2 + .../fabric/jni/RuntimeSchedulerManager.cpp | 46 +++++++++++++++++++ .../fabric/jni/RuntimeSchedulerManager.h | 40 ++++++++++++++++ 7 files changed, 139 insertions(+) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/fabric/RuntimeSchedulerManager.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/fabric/jni/RuntimeSchedulerManager.cpp create mode 100644 ReactAndroid/src/main/java/com/facebook/react/fabric/jni/RuntimeSchedulerManager.h diff --git a/ReactAndroid/src/main/java/com/facebook/react/BUCK b/ReactAndroid/src/main/java/com/facebook/react/BUCK index eebb0432a68..669209d2e83 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/BUCK @@ -39,6 +39,7 @@ rn_android_library( react_native_target("java/com/facebook/react/modules/bundleloader:bundleloader"), react_native_target("java/com/facebook/react/modules/debug:debug"), react_native_target("java/com/facebook/react/modules/fabric:fabric"), + react_native_target("java/com/facebook/react/fabric:fabric"), react_native_target("java/com/facebook/react/modules/debug:interfaces"), react_native_target("java/com/facebook/react/modules/deviceinfo:deviceinfo"), react_native_target("java/com/facebook/react/modules/systeminfo:systeminfo"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index b46b1b71b2c..027cfc49f59 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -83,6 +83,7 @@ import com.facebook.react.devsupport.RedBoxHandler; import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.devsupport.interfaces.PackagerStatusCallback; +import com.facebook.react.fabric.RuntimeSchedulerManager; import com.facebook.react.modules.appearance.AppearanceModule; import com.facebook.react.modules.appregistry.AppRegistry; import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; @@ -162,6 +163,7 @@ public class ReactInstanceManager { private final DevSupportManager mDevSupportManager; private final boolean mUseDeveloperSupport; private @Nullable ComponentNameResolverManager mComponentNameResolverManager; + private @Nullable RuntimeSchedulerManager mRuntimeSchedulerManager; private final @Nullable NotThreadSafeBridgeIdleDebugListener mBridgeIdleDebugListener; private final Object mReactContextLock = new Object(); private @Nullable volatile ReactContext mCurrentReactContext; @@ -718,6 +720,7 @@ public class ReactInstanceManager { mViewManagerNames = null; } mComponentNameResolverManager = null; + mRuntimeSchedulerManager = null; FLog.d(ReactConstants.TAG, "ReactInstanceManager has been destroyed"); } @@ -1350,6 +1353,10 @@ public class ReactInstanceManager { }); catalystInstance.setGlobalVariable("__fbStaticViewConfig", "true"); } + if (ReactFeatureFlags.enableRuntimeScheduler) { + mRuntimeSchedulerManager = new RuntimeSchedulerManager(catalystInstance.getRuntimeExecutor()); + } + ReactMarker.logMarker(ReactMarkerConstants.PRE_RUN_JS_BUNDLE_START); Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "runJSBundle"); catalystInstance.runJSBundle(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index f5b43205099..b8a5d16069d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -44,6 +44,8 @@ public class ReactFeatureFlags { /** Enables Static ViewConfig in RN Android native code. */ public static boolean enableExperimentalStaticViewConfigs = false; + public static boolean enableRuntimeScheduler = false; + /** Enables a more aggressive cleanup during destruction of ReactContext */ public static boolean enableReactContextCleanupFix = false; diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/RuntimeSchedulerManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/RuntimeSchedulerManager.java new file mode 100644 index 00000000000..a188792fb3f --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/RuntimeSchedulerManager.java @@ -0,0 +1,41 @@ +// (c) Facebook, Inc. and its affiliates. Confidential and proprietary. + +/* + * 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.fabric; + +import com.facebook.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.proguard.annotations.DoNotStripAny; +import com.facebook.react.bridge.RuntimeExecutor; +import com.facebook.soloader.SoLoader; + +@DoNotStripAny +public class RuntimeSchedulerManager { + + static { + staticInit(); + } + + @DoNotStrip + @SuppressWarnings("unused") + private final HybridData mHybridData; + + public RuntimeSchedulerManager(RuntimeExecutor runtimeExecutor) { + mHybridData = initHybrid(runtimeExecutor); + installJSIBindings(); + } + + private native HybridData initHybrid(RuntimeExecutor runtimeExecutor); + + private native void installJSIBindings(); + + private static void staticInit() { + SoLoader.loadLibrary("fabricjni"); + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp index 61fcec3d1c9..bdf8ea52097 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp @@ -12,6 +12,7 @@ #include "CoreComponentsRegistry.h" #include "EventBeatManager.h" #include "EventEmitterWrapper.h" +#include "RuntimeSchedulerManager.h" #include "StateWrapperImpl.h" #include "SurfaceHandlerBinding.h" @@ -24,5 +25,6 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { facebook::react::ComponentFactory::registerNatives(); facebook::react::CoreComponentsRegistry::registerNatives(); facebook::react::SurfaceHandlerBinding::registerNatives(); + facebook::react::RuntimeSchedulerManager::registerNatives(); }); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/RuntimeSchedulerManager.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/RuntimeSchedulerManager.cpp new file mode 100644 index 00000000000..2b0d8933703 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/RuntimeSchedulerManager.cpp @@ -0,0 +1,46 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +#include "RuntimeSchedulerManager.h" + +namespace facebook { +namespace react { + +RuntimeSchedulerManager::RuntimeSchedulerManager( + RuntimeExecutor runtimeExecutor) + : runtimeExecutor_(runtimeExecutor) {} + +jni::local_ref +RuntimeSchedulerManager::initHybrid( + jni::alias_ref, + jni::alias_ref runtimeExecutor) { + return makeCxxInstance(runtimeExecutor->cthis()->get()); +} + +void RuntimeSchedulerManager::registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", RuntimeSchedulerManager::initHybrid), + makeNativeMethod( + "installJSIBindings", RuntimeSchedulerManager::installJSIBindings), + }); +} + +void RuntimeSchedulerManager::installJSIBindings() { + runtimeExecutor_([runtimeExecutor = runtimeExecutor_](jsi::Runtime &runtime) { + auto runtimeScheduler = std::make_shared(runtimeExecutor); + RuntimeSchedulerBinding::createAndInstallIfNeeded( + runtime, runtimeScheduler); + }); +} + +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/RuntimeSchedulerManager.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/RuntimeSchedulerManager.h new file mode 100644 index 00000000000..3c4112e0268 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/RuntimeSchedulerManager.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +namespace facebook { +namespace react { + +class RuntimeSchedulerManager + : public facebook::jni::HybridClass { + public: + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/fabric/RuntimeSchedulerManager;"; + + static facebook::jni::local_ref initHybrid( + jni::alias_ref, + facebook::jni::alias_ref runtimeExecutor); + + static void registerNatives(); + + private: + friend HybridBase; + RuntimeExecutor runtimeExecutor_; + + void installJSIBindings(); + + explicit RuntimeSchedulerManager(RuntimeExecutor runtimeExecutor); +}; + +} // namespace react +} // namespace facebook