Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,11 @@ android {

!enableNewArchitecture
? "src/old-arch/java"
: reactNativeVersion >= v(0, 73, 0)
? "src/new-arch-0.73/java"
: "src/new-arch/java",
: reactNativeVersion >= v(0, 81, 0)
? "src/new-arch-0.81/java"
: reactNativeVersion >= v(0, 73, 0)
? "src/new-arch-0.73/java"
: "src/new-arch/java",

// TODO: Remove this block when we drop support for 0.74
// https://github.com/facebook/react-native/commit/3283202248a36dbda553745afc46a3e3e2ab41a6
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.facebook.react.ReactApplication
import com.facebook.react.ReactActivity
import com.facebook.react.ReactRootView
import com.facebook.react.interfaces.fabric.ReactSurface
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.microsoft.reacttestapp.BuildConfig

Expand All @@ -30,19 +31,33 @@ class ComponentBottomSheetDialogFragment : BottomSheetDialogFragment() {
}
}

private var surface: ReactSurface? = null

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val reactApplication = requireActivity().application as ReactApplication
return ReactRootView(context).apply {
setIsFabric(BuildConfig.REACTAPP_USE_FABRIC)
startReactApplication(
reactApplication.reactNativeHost.reactInstanceManager,
requireArguments().getString(NAME),
val activity = requireActivity() as ReactActivity
if (BuildConfig.REACTAPP_USE_BRIDGELESS) {
val surface = activity.reactActivityDelegate.reactHost?.createSurface(
activity,
requireNotNull(requireArguments().getString(NAME)),
requireArguments().getBundle(INITIAL_PROPERTIES)
)
this.surface = requireNotNull(surface)
surface.start()
return surface.view as View
} else {
return ReactRootView(context).apply {
setIsFabric(BuildConfig.REACTAPP_USE_FABRIC)
@Suppress("DEPRECATION")
startReactApplication(
activity.reactActivityDelegate.reactInstanceManager,
requireArguments().getString(NAME),
requireArguments().getBundle(INITIAL_PROPERTIES)
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.core.net.toUri
import com.facebook.hermes.reactexecutor.HermesExecutorFactory
import com.facebook.react.PackageList
import com.facebook.react.ReactInstanceEventListener
Expand All @@ -19,7 +19,6 @@ import com.facebook.react.packagerconnection.PackagerConnectionSettings
import com.microsoft.reacttestapp.BuildConfig
import com.microsoft.reacttestapp.MainActivity
import com.microsoft.reacttestapp.R
import com.microsoft.reacttestapp.compat.ReactNativeHostCompat
import java.lang.ref.WeakReference
import java.util.Collections.synchronizedList
import java.util.concurrent.CountDownLatch
Expand All @@ -44,10 +43,11 @@ sealed class BundleSource {
}
}

@Suppress("TYPEALIAS_EXPANSION_DEPRECATION")
class TestAppReactNativeHost(
application: Application,
private val reactBundleNameProvider: ReactBundleNameProvider
) : ReactNativeHostCompat(application) {
) : com.microsoft.reacttestapp.compat.ReactNativeHostCompat(application) {
val jsExecutorName: String
get() = javaScriptExecutorFactory.toString()

Expand Down Expand Up @@ -146,7 +146,7 @@ class TestAppReactNativeHost(
}

fun reloadJSFromServer(activity: Activity, bundleURL: String) {
val uri = Uri.parse(bundleURL)
val uri = bundleURL.toUri()
PackagerConnectionSettings(activity).debugServerHost =
if (uri.port > 0) {
"${uri.host}:${uri.port}"
Expand Down
12 changes: 12 additions & 0 deletions android/app/src/main/jni/AutolinkingCompat.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
#ifndef REACTAPP_JNI_AUTOLINKINGCOMPAT_H_
#define REACTAPP_JNI_AUTOLINKINGCOMPAT_H_

#if __has_include(<FBReactNativeSpec.h>) // >= 0.81

#include <FBReactNativeSpec.h>

#define rncore_ModuleProvider facebook::react::FBReactNativeSpec_ModuleProvider

#else // < 0.81

#include <rncore.h>

#endif // __has_include(<FBReactNativeSpec.h>) // >= 0.81
Comment on lines +4 to +14
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good, however we backported rncore.h to make this non breaking


#if __has_include(<autolinking.h>) // >= 0.75

#include <autolinking.h>
Expand Down
1 change: 0 additions & 1 deletion android/app/src/main/jni/OnLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include <DefaultComponentsRegistry.h>
#include <DefaultTurboModuleManagerDelegate.h>
#include <rncore.h>

#include <fbjni/fbjni.h>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.microsoft.reacttestapp.compat

import android.app.Application
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.soloader.SoLoader
import com.microsoft.reacttestapp.BuildConfig

abstract class ReactNativeHostCompat(application: Application) :
DefaultReactNativeHost(application) {

companion object {
init {
DefaultNewArchitectureEntryPoint.load()
SoLoader.loadLibrary("reacttestapp_appmodules")
}
}

override val isNewArchEnabled: Boolean = BuildConfig.REACTAPP_USE_FABRIC
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.microsoft.reacttestapp.fabric

import com.facebook.jni.HybridData
import com.facebook.proguard.annotations.DoNotStrip
import com.facebook.react.fabric.ComponentFactory
import com.facebook.soloader.SoLoader

/**
* The corresponding C++ implementation is in `android/app/src/main/jni/ComponentsRegistry.cpp`
*/
@DoNotStrip
class ComponentsRegistry @DoNotStrip private constructor(componentFactory: ComponentFactory) {

companion object {
@DoNotStrip
fun register(componentFactory: ComponentFactory): ComponentsRegistry =
ComponentsRegistry(componentFactory)

init {
SoLoader.loadLibrary("fabricjni")
SoLoader.loadLibrary("reacttestapp_appmodules")
}
}

@DoNotStrip
private val mHybridData: HybridData

@DoNotStrip
private external fun initHybrid(componentFactory: ComponentFactory): HybridData

init {
mHybridData = initHybrid(componentFactory)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.microsoft.reacttestapp.turbomodule

import com.facebook.jni.HybridData
import com.facebook.react.ReactPackage
import com.facebook.react.ReactPackageTurboModuleManagerDelegate
import com.facebook.react.bridge.ReactApplicationContext

/**
* These type aliases are here to prevent `@react-native-community/cli` from
* marking them as native modules to autolink.
*
* See also `matchClassName` in
* https://github.com/react-native-community/cli/blob/8.x/packages/platform-android/src/config/findPackageClassName.ts#L25
*/
typealias PackagesList = List<ReactPackage>
typealias ReactTurboModuleManagerDelegate = ReactPackageTurboModuleManagerDelegate
typealias ReactTurboModuleManagerDelegateBuilder = ReactPackageTurboModuleManagerDelegate.Builder

/**
* The corresponding C++ implementation is in `android/app/src/main/jni/TurboModuleManagerDelegate.cpp`
*/
class TurboModuleManagerDelegate protected constructor(
reactApplicationContext: ReactApplicationContext,
packages: PackagesList
) : ReactTurboModuleManagerDelegate(reactApplicationContext, packages) {

external override fun initHybrid(): HybridData

external fun canCreateTurboModule(moduleName: String?): Boolean

class Builder : ReactTurboModuleManagerDelegateBuilder() {
override fun build(
context: ReactApplicationContext,
packages: PackagesList
): TurboModuleManagerDelegate = TurboModuleManagerDelegate(context, packages)
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package com.microsoft.reacttestapp.compat

@Suppress("DEPRECATION")
typealias ReactNativeHostCompat = com.facebook.react.ReactNativeHost
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class TestApp :
override val reactHost: ReactHost
get() = getDefaultReactHost(this.applicationContext, reactNativeHost)

@Suppress("OVERRIDE_DEPRECATION")
override val reactNativeHost: TestAppReactNativeHost
get() = reactNativeHostInternal

Expand Down
44 changes: 32 additions & 12 deletions android/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,62 @@ def getDefaultGradlePluginVersion = { int reactNativeVersion ->
}
}

def getKotlinVersion = { File baseDir ->
def fallbackVersion = "1.7.21"
def getDependencyVersionFromCatalog = { String versionCatalog, String dependency, String fallback ->
if (versionCatalog == null) {
return fallback
}

def m = versionCatalog =~ /${dependency} = "([.0-9]+)"/
return m.size() > 0 ? m[0][1] : fallback
}

def getDependencyVersionNumberFromCatalog = { String versionCatalog, String dependency, int fallback ->
def version = getDependencyVersionFromCatalog(versionCatalog, dependency, null)
return version != null ? Integer.parseInt(version) : fallback
}

def getKotlinVersion = { String versionCatalog ->
def version = getDependencyVersionFromCatalog(versionCatalog, "kotlin", "1.7.21")
logger.info("Using Kotlin version ${version}")
return version
}

def getVersionCatalog = { File baseDir ->
def packagePath = findNodeModulesPath("react-native", baseDir)
def versionCatalog = file("${packagePath}/gradle/libs.versions.toml")
if (!versionCatalog.exists()) {
return fallbackVersion
return null
}

def m = versionCatalog.text =~ /kotlin = "([.0-9]+)"/
def version = m.size() > 0 ? m[0][1] : fallbackVersion
logger.info("Detected Kotlin version: ${version}")
return version
return versionCatalog.text
}

ext {
reactNativeVersion = getPackageVersionNumber("react-native", rootDir)

compileSdkVersion = rootProject.findProperty("react.compileSdkVersion") ?: 34
minSdkVersion = rootProject.findProperty("react.minSdkVersion") ?: 24
targetSdkVersion = rootProject.findProperty("react.targetSdkVersion") ?: 33
def versionCatalog = getVersionCatalog(rootDir)

compileSdkVersion = rootProject.findProperty("react.compileSdkVersion")
?: getDependencyVersionNumberFromCatalog(versionCatalog, "compileSdk", 34)
minSdkVersion = rootProject.findProperty("react.minSdkVersion")
?: getDependencyVersionNumberFromCatalog(versionCatalog, "minSdk", 24)
targetSdkVersion = rootProject.findProperty("react.targetSdkVersion")
?: getDependencyVersionNumberFromCatalog(versionCatalog, "targetSdk", 33)

autodetectReactNativeVersion = reactNativeVersion == 0 || reactNativeVersion >= v(0, 71, 0)
enableNewArchitecture = isNewArchitectureEnabled(project)
enableBridgeless = isBridgelessEnabled(project, enableNewArchitecture)
usePrefabs = reactNativeVersion == 0 || reactNativeVersion >= v(0, 71, 0)

androidPluginVersion = getDefaultGradlePluginVersion(reactNativeVersion)
kotlinVersion = rootProject.findProperty("KOTLIN_VERSION") ?: getKotlinVersion(rootDir)
kotlinVersion = rootProject.findProperty("KOTLIN_VERSION") ?: getKotlinVersion(versionCatalog)

// We need only set `ndkVersion` when building react-native from source.
if (rootProject.hasProperty("ANDROID_NDK_VERSION")) {
ndkVersion = rootProject.properties["ANDROID_NDK_VERSION"]
} else if (reactNativeVersion >= v(0, 74, 0)) {
// https://github.com/facebook/react-native/commit/9ce7b564131c5b2075489c09ff05325ddc28014a
ndkVersion = "26.1.10909125"
ndkVersion = getDependencyVersionFromCatalog(versionCatalog, "ndkVersion", "26.1.10909125")
} else if (System.properties["os.arch"] == "aarch64" && androidPluginVersion == "7.2.2") {
// NDK r23c has been patched to support Apple M1 and is default in AGP
// 7.3.0. Prior to 0.71, we still need to set `ndkVersion` because we'll
Expand Down
3 changes: 3 additions & 0 deletions test/pack.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ describe("npm pack", () => {
"android/app/src/new-arch-0.73/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt",
"android/app/src/new-arch-0.73/java/com/microsoft/reacttestapp/fabric/ComponentsRegistry.kt",
"android/app/src/new-arch-0.73/java/com/microsoft/reacttestapp/turbomodule/TurboModuleManagerDelegate.kt",
"android/app/src/new-arch-0.81/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt",
"android/app/src/new-arch-0.81/java/com/microsoft/reacttestapp/fabric/ComponentsRegistry.kt",
"android/app/src/new-arch-0.81/java/com/microsoft/reacttestapp/turbomodule/TurboModuleManagerDelegate.kt",
"android/app/src/new-arch/java/com/microsoft/reacttestapp/compat/ReactNativeHostCompat.kt",
"android/app/src/new-arch/java/com/microsoft/reacttestapp/fabric/ComponentsRegistry.kt",
"android/app/src/new-arch/java/com/microsoft/reacttestapp/turbomodule/TurboModuleManagerDelegate.kt",
Expand Down