chore(Android): Migrate Hermes Executor to Kotlin (#48617)

Summary:
Migrating HermesExecutor and it's factory to Kotlin. Not sure if the TAG in HermesExecutorFactory is needed anymore or not, but the rest of the changes are pretty bog standard

## Changelog:

[INTERNAL] [FIXED] - Migrate HermesExecutor and HermesExecutorFactory to Kotlin

Pull Request resolved: https://github.com/facebook/react-native/pull/48617

Test Plan:
`./gradlew test`:
<img width="1266" alt="Screenshot 2025-01-11 at 04 01 12" src="https://github.com/user-attachments/assets/c0f1402c-796b-45fa-9ee3-41c5a5ffc356" />

Reviewed By: tdn120

Differential Revision: D68094681

Pulled By: cortinico

fbshipit-source-id: 16eae5c7c24886421cbd2cbf213295134a9c01cf
This commit is contained in:
Parsa Nasirimehr
2025-01-13 08:44:05 -08:00
committed by Facebook GitHub Bot
parent c7785e7ead
commit 12e321daf0
4 changed files with 95 additions and 107 deletions
@@ -1,50 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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.hermes.reactexecutor;
import com.facebook.jni.HybridData;
import com.facebook.react.bridge.JavaScriptExecutor;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.soloader.SoLoader;
import javax.annotation.Nullable;
public class HermesExecutor extends JavaScriptExecutor {
private static String mode_;
static {
loadLibrary();
}
public static void loadLibrary() throws UnsatisfiedLinkError {
if (mode_ == null) {
// libhermes must be loaded explicitly to invoke its JNI_OnLoad.
SoLoader.loadLibrary("hermes");
SoLoader.loadLibrary("hermes_executor");
// libhermes_executor is built differently for Debug & Release so we load the proper mode.
mode_ = ReactBuildConfig.DEBUG ? "Debug" : "Release";
}
}
HermesExecutor(@Nullable RuntimeConfig config, boolean enableDebugger, String debuggerName) {
super(
config == null
? initHybridDefaultConfig(enableDebugger, debuggerName)
: initHybrid(enableDebugger, debuggerName, config.getHeapSizeMB()));
}
@Override
public String getName() {
return "HermesExecutor" + mode_;
}
private static native HybridData initHybridDefaultConfig(
boolean enableDebugger, String debuggerName);
private static native HybridData initHybrid(
boolean enableDebugger, String debuggerName, long heapSizeMB);
}
@@ -0,0 +1,53 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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.hermes.reactexecutor
import com.facebook.jni.HybridData
import com.facebook.react.bridge.JavaScriptExecutor
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.soloader.SoLoader
public class HermesExecutor
internal constructor(config: RuntimeConfig?, enableDebugger: Boolean, debuggerName: String) :
JavaScriptExecutor(
config?.let { initHybrid(enableDebugger, debuggerName, it.heapSizeMB) }
?: initHybridDefaultConfig(enableDebugger, debuggerName)) {
override fun getName(): String = "HermesExecutor$mode"
public companion object {
private var mode: String? = null
init {
loadLibrary()
}
@JvmStatic
@Throws(UnsatisfiedLinkError::class)
public fun loadLibrary() {
if (mode == null) {
// libhermes must be loaded explicitly to invoke its JNI_OnLoad.
SoLoader.loadLibrary("hermes")
SoLoader.loadLibrary("hermes_executor")
// libhermes_executor is built differently for Debug & Release so we load the proper mode.
mode = if (ReactBuildConfig.DEBUG) "Debug" else "Release"
}
}
private external fun initHybridDefaultConfig(
enableDebugger: Boolean,
debuggerName: String
): HybridData?
private external fun initHybrid(
enableDebugger: Boolean,
debuggerName: String,
heapSizeMB: Long
): HybridData?
}
}
@@ -1,57 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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.hermes.reactexecutor;
import com.facebook.hermes.instrumentation.HermesSamplingProfiler;
import com.facebook.react.bridge.JavaScriptExecutor;
import com.facebook.react.bridge.JavaScriptExecutorFactory;
public class HermesExecutorFactory implements JavaScriptExecutorFactory {
private static final String TAG = "Hermes";
private final RuntimeConfig mConfig;
private boolean mEnableDebugger = true;
private String mDebuggerName = "";
public HermesExecutorFactory() {
this(null);
}
public HermesExecutorFactory(RuntimeConfig config) {
mConfig = config;
}
public void setEnableDebugger(boolean enableDebugger) {
mEnableDebugger = enableDebugger;
}
public void setDebuggerName(String debuggerName) {
mDebuggerName = debuggerName;
}
@Override
public JavaScriptExecutor create() {
return new HermesExecutor(mConfig, mEnableDebugger, mDebuggerName);
}
@Override
public void startSamplingProfiler() {
HermesSamplingProfiler.enable();
}
@Override
public void stopSamplingProfiler(String filename) {
HermesSamplingProfiler.dumpSampledTraceToFile(filename);
HermesSamplingProfiler.disable();
}
@Override
public String toString() {
return "JSIExecutor+HermesRuntime";
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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.hermes.reactexecutor
import com.facebook.hermes.instrumentation.HermesSamplingProfiler.disable
import com.facebook.hermes.instrumentation.HermesSamplingProfiler.dumpSampledTraceToFile
import com.facebook.hermes.instrumentation.HermesSamplingProfiler.enable
import com.facebook.react.bridge.JavaScriptExecutor
import com.facebook.react.bridge.JavaScriptExecutorFactory
public class HermesExecutorFactory
@JvmOverloads
public constructor(private val config: RuntimeConfig? = null) : JavaScriptExecutorFactory {
private var enableDebugger = true
private var debuggerName = ""
public fun setEnableDebugger(enableDebugger: Boolean) {
this.enableDebugger = enableDebugger
}
public fun setDebuggerName(debuggerName: String) {
this.debuggerName = debuggerName
}
override fun create(): JavaScriptExecutor = HermesExecutor(config, enableDebugger, debuggerName)
override fun startSamplingProfiler() {
enable()
}
override fun stopSamplingProfiler(filename: String) {
dumpSampledTraceToFile(filename)
disable()
}
override fun toString(): String = "JSIExecutor+HermesRuntime"
}