From e496d99ca0ec6a0acb5cefff2b94751058d634fe Mon Sep 17 00:00:00 2001
From: Kunal Farmah <kunal.farmah@airtel.com>
Date: Wed, 16 Feb 2022 15:46:23 +0530
Subject: [PATCH 1/3] added buildConfigField to decide weather to load jsc or
 hermes. | Incorporated changes and modified impl of
 getDefaultJSExecutorFactory

---
 ReactAndroid/build.gradle                     | 11 ++++
 .../react/ReactInstanceManagerBuilder.java    | 58 +++++++++----------
 2 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle
index d391da8576ce..90e80d0da48c 100644
--- a/ReactAndroid/build.gradle
+++ b/ReactAndroid/build.gradle
@@ -44,6 +44,10 @@ def boostPath = dependenciesPath ?: System.getenv("REACT_NATIVE_BOOST_PATH")
 // Setup build type for NDK, supported values: {debug, release}
 def nativeBuildType = System.getenv("NATIVE_BUILD_TYPE") ?: "release"
 
+def config = project.hasProperty("react") ? project.react : [:]
+
+def enableHermes = config.enableHermes ?: false
+
 task createNativeDepsDirectories {
     downloadsDir.mkdirs()
     thirdPartyNdkDir.mkdirs()
@@ -298,6 +302,13 @@ android {
         buildConfigField("boolean", "IS_INTERNAL_BUILD", "false")
         buildConfigField("int", "EXOPACKAGE_FLAGS", "0")
         buildConfigField("int", "HERMES_BYTECODE_VERSION", "0")
+        // setting buildConfigField to check for hermes or jsc
+        if(enableHermes){
+            buildConfigField("boolean", "HERMES_ENABLED", "true")
+        }
+        else{
+            buildConfigField("boolean", "HERMES_ENABLED", "false")
+        }
 
         resValue "integer", "react_native_dev_server_port", reactNativeDevServerPort()
         resValue "integer", "react_native_inspector_proxy_port", reactNativeInspectorProxyPort()
diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
index d7450a14ce5c..4be6bede5ea9 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
@@ -34,6 +34,7 @@
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
 import com.facebook.react.packagerconnection.RequestHandler;
 import com.facebook.react.uimanager.UIImplementationProvider;
+import com.facebook.react.BuildConfig;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -66,8 +67,11 @@ public class ReactInstanceManagerBuilder {
   private @Nullable Map<String, RequestHandler> mCustomPackagerCommandHandlers;
   private @Nullable ReactPackageTurboModuleManagerDelegate.Builder mTMMDelegateBuilder;
   private @Nullable SurfaceDelegateFactory mSurfaceDelegateFactory;
+  private boolean enableHermes = false;
 
-  /* package protected */ ReactInstanceManagerBuilder() {}
+  /* package protected */ ReactInstanceManagerBuilder() {
+    enableHermes = BuildConfig.HERMES_ENABLED;
+  }
 
   /** Sets a provider of {@link UIImplementation}. Uses default provider if null is passed. */
   public ReactInstanceManagerBuilder setUIImplementationProvider(
@@ -348,38 +352,32 @@ private JavaScriptExecutorFactory getDefaultJSExecutorFactory(
     try {
       // If JSC is included, use it as normal
       initializeSoLoaderIfNecessary(applicationContext);
-      JSCExecutor.loadLibrary();
-      return new JSCExecutorFactory(appName, deviceName);
-    } catch (UnsatisfiedLinkError jscE) {
-      // https://github.com/facebook/hermes/issues/78 shows that
-      // people who aren't trying to use Hermes are having issues.
-      // https://github.com/facebook/react-native/issues/25923#issuecomment-554295179
-      // includes the actual JSC error in at least one case.
-      //
-      // So, if "__cxa_bad_typeid" shows up in the jscE exception
-      // message, then we will assume that's the failure and just
-      // throw now.
-
-      if (jscE.getMessage().contains("__cxa_bad_typeid")) {
-        throw jscE;
-      }
-
-      // Otherwise use Hermes
-      try {
+      // Relying solely on try catch block and loading jsc even when
+      // project is suing hermes can lead to launchtime crashes expecially in
+      // monorepo architectures and hybrid apps using both native android
+      // and react native.
+      // So we use the value of enableHermes from build.gradle to decide which
+      // library to load at launch
+      if(enableHermes){
         HermesExecutor.loadLibrary();
         return new HermesExecutorFactory();
-      } catch (UnsatisfiedLinkError hermesE) {
-        // If we get here, either this is a JSC build, and of course
-        // Hermes failed (since it's not in the APK), or it's a Hermes
-        // build, and Hermes had a problem.
-
-        // We suspect this is a JSC issue (it's the default), so we
-        // will throw that exception, but we will print hermesE first,
-        // since it could be a Hermes issue and we don't want to
-        // swallow that.
-        hermesE.printStackTrace();
-        throw jscE;
       }
+      else{
+        JSCExecutor.loadLibrary();
+        return new JSCExecutorFactory(appName, deviceName);
+      }
+    } catch (UnsatisfiedLinkError e) {
+      // Any library failed to load, we
+      // will throw that exception, but we will print it first,
+      // since it could be a Hermes issue and we don't want to
+      // swallow that.
+      // The case  
+      // if (jscE.getMessage().contains("__cxa_bad_typeid")) {
+      //   throw jscE;
+      // }
+      // would be covered in this catch block only
+      e.printStackTrace();
+      throw e;
     }
   }
 }

From 5ca41c99364e089142bae2be68e70ff67116f852 Mon Sep 17 00:00:00 2001
From: Kunal Farmah <kunal.farmah@airtel.com>
Date: Wed, 16 Feb 2022 15:54:28 +0530
Subject: [PATCH 2/3] using convenience class ReactBuildConfig to get
 buildConfigField

---
 .../java/com/facebook/react/ReactInstanceManagerBuilder.java  | 4 ++--
 .../com/facebook/react/common/build/ReactBuildConfig.java     | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
index 4be6bede5ea9..df13f2ce96c1 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
@@ -24,6 +24,7 @@
 import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener;
 import com.facebook.react.common.LifecycleState;
 import com.facebook.react.common.SurfaceDelegateFactory;
+import com.facebook.react.common.build.ReactBuildConfig;
 import com.facebook.react.devsupport.DefaultDevSupportManagerFactory;
 import com.facebook.react.devsupport.DevSupportManagerFactory;
 import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
@@ -34,7 +35,6 @@
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
 import com.facebook.react.packagerconnection.RequestHandler;
 import com.facebook.react.uimanager.UIImplementationProvider;
-import com.facebook.react.BuildConfig;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -70,7 +70,7 @@ public class ReactInstanceManagerBuilder {
   private boolean enableHermes = false;
 
   /* package protected */ ReactInstanceManagerBuilder() {
-    enableHermes = BuildConfig.HERMES_ENABLED;
+    enableHermes = ReactBuildConfig.HERMES_ENABLED;
   }
 
   /** Sets a provider of {@link UIImplementation}. Uses default provider if null is passed. */
diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/build/ReactBuildConfig.java b/ReactAndroid/src/main/java/com/facebook/react/common/build/ReactBuildConfig.java
index 70273030bbe8..84011396702b 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/common/build/ReactBuildConfig.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/common/build/ReactBuildConfig.java
@@ -21,4 +21,5 @@ public class ReactBuildConfig {
   public static final boolean IS_INTERNAL_BUILD = BuildConfig.IS_INTERNAL_BUILD;
   public static final int EXOPACKAGE_FLAGS = BuildConfig.EXOPACKAGE_FLAGS;
   public static final int HERMES_BYTECODE_VERSION = BuildConfig.HERMES_BYTECODE_VERSION;
+  public static final boolean HERMES_ENABLED = BuildConfig.HERMES_ENABLED;
 }

From 9f132de26c4392b5ac36e3388cff0d42e1b99354 Mon Sep 17 00:00:00 2001
From: Kunal Farmah <kunal.farmah@airtel.com>
Date: Wed, 16 Feb 2022 17:32:43 +0530
Subject: [PATCH 3/3] refined comments

---
 .../java/com/facebook/react/ReactInstanceManagerBuilder.java  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
index df13f2ce96c1..d4897ff23bdc 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java
@@ -353,10 +353,10 @@ private JavaScriptExecutorFactory getDefaultJSExecutorFactory(
       // If JSC is included, use it as normal
       initializeSoLoaderIfNecessary(applicationContext);
       // Relying solely on try catch block and loading jsc even when
-      // project is suing hermes can lead to launchtime crashes expecially in
+      // project is using hermes can lead to launch-time crashes especially in
       // monorepo architectures and hybrid apps using both native android
       // and react native.
-      // So we use the value of enableHermes from build.gradle to decide which
+      // So we can use the value of enableHermes from build.gradle to decide which
       // library to load at launch
       if(enableHermes){
         HermesExecutor.loadLibrary();
