Skip to content
Draft
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
222 changes: 222 additions & 0 deletions .yarn/patches/expo-updates-npm-29.0.16-1c5c89eb83.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
diff --git a/android/src/main/java/expo/modules/updates/UpdatesController.kt b/android/src/main/java/expo/modules/updates/UpdatesController.kt
index 6ff694ccecafac0da2ffa2538500341e07e858d8..a670c0b833f33cf00981bc95daf44afa879cc69d 100644
--- a/android/src/main/java/expo/modules/updates/UpdatesController.kt
+++ b/android/src/main/java/expo/modules/updates/UpdatesController.kt
@@ -2,6 +2,7 @@ package expo.modules.updates

import android.content.Context
import com.facebook.react.ReactApplication
+import com.facebook.react.ReactHost
import expo.modules.updates.events.IUpdatesEventManagerObserver
import expo.modules.updates.loader.LoaderTask
import expo.modules.updates.logging.UpdatesErrorCode
@@ -25,6 +26,19 @@ object UpdatesController {
@Volatile
private var overrideConfiguration: UpdatesConfiguration? = null

+ @Volatile
+ private var reactHost: ReactHost? = null
+
+ @JvmStatic
+ fun setReactHost(reactHost: ReactHost) {
+ this.reactHost = reactHost
+ }
+
+ @JvmStatic
+ fun getReactHost(): ReactHost? {
+ return reactHost
+ }
+
@JvmStatic
val instance: IUpdatesController
get() {
diff --git a/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt b/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt
index 3bf9f207ae7d3c46151103d8f809821a9df20d56..1ccb4877c2fcefd2c63d43dcc59664c83932805f 100644
--- a/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt
+++ b/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt
@@ -2,7 +2,6 @@ package expo.modules.updates.procedures

import android.app.Activity
import android.content.Context
-import com.facebook.react.ReactApplication
import expo.modules.updates.launcher.Launcher
import expo.modules.updates.statemachine.UpdatesStateEvent
import kotlinx.coroutines.CoroutineScope
@@ -20,16 +19,11 @@ class RecreateReactContextProcedure(
override val loggerTimerLabel = "timer-recreate-react-context"

override suspend fun run(procedureContext: ProcedureContext) {
- val reactApplication = context.applicationContext as? ReactApplication ?: run inner@{
- callback.onFailure(Exception("Could not reload application. Ensure you have passed the correct instance of ReactApplication into UpdatesController.initialize()."))
- return
- }
-
procedureContext.processStateEvent(UpdatesStateEvent.Restart())
callback.onSuccess()
procedureScope.launch {
withContext(Dispatchers.Main) {
- reactApplication.restart(weakActivity?.get(), "Restart from RecreateReactContextProcedure")
+ RestartReactAppExtensions.restart(weakActivity?.get(), "Restart from RecreateReactContextProcedure")
}
}
procedureContext.resetStateAfterRestart()
diff --git a/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt b/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt
index 64cc2870d28557c07217e1f78ad86e0fabe70bee..f2cf6a958d4da3f0a29040a6e101ce819c0696b7 100644
--- a/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt
+++ b/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt
@@ -43,11 +43,6 @@ class RelaunchProcedure(
override val loggerTimerLabel = "timer-relaunch"

override suspend fun run(procedureContext: ProcedureContext) {
- val reactApplication = context as? ReactApplication ?: run inner@{
- callback.onFailure(Exception("Could not reload application. Ensure you have passed the correct instance of ReactApplication into UpdatesController.initialize()."))
- return
- }
-
procedureContext.processStateEvent(UpdatesStateEvent.Restart())

val oldLaunchAssetFile = getCurrentLauncher().launchAssetFile
@@ -74,7 +69,7 @@ class RelaunchProcedure(
val newLaunchAssetFile = getCurrentLauncher().launchAssetFile
if (newLaunchAssetFile != null && newLaunchAssetFile != oldLaunchAssetFile) {
try {
- replaceLaunchAssetFileIfNeeded(reactApplication, newLaunchAssetFile)
+ replaceLaunchAssetFileIfNeeded(newLaunchAssetFile)
} catch (e: Exception) {
logger.error("Could not reset launchAssetFile for the ReactApplication", e, UpdatesErrorCode.Unknown)
}
@@ -84,7 +79,7 @@ class RelaunchProcedure(
procedureScope.launch {
withContext(Dispatchers.Main) {
reloadScreenManager?.show(weakActivity?.get())
- reactApplication.restart(weakActivity?.get(), "Restart from RelaunchProcedure")
+ RestartReactAppExtensions.restart(weakActivity?.get(), "Restart from RelaunchProcedure")
}
}

@@ -127,13 +122,16 @@ class RelaunchProcedure(
* [com.facebook.react.ReactInstanceManager].
*/
private fun replaceLaunchAssetFileIfNeeded(
- reactApplication: ReactApplication,
launchAssetFile: String
) {
if (ReactNativeFeatureFlags.enableBridgelessArchitecture) {
return
}

+ val reactApplication = context as? ReactApplication ?: run inner@{
+ callback.onFailure(Exception("Could not reload application. Ensure you have passed the correct instance of ReactApplication into UpdatesController.initialize()."))
+ return
+ }
val instanceManager = reactApplication.reactNativeHost.reactInstanceManager
val jsBundleLoaderField = instanceManager.javaClass.getDeclaredField("mBundleLoader")
jsBundleLoaderField.isAccessible = true
diff --git a/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt b/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt
index 25c6e804d31f9ee915acdf5f363af07e7b7bf424..3a90db88ac3e70fae3c6d909c955210093f306f9 100644
--- a/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt
+++ b/android/src/main/java/expo/modules/updates/procedures/RestartReactAppExtensions.kt
@@ -2,25 +2,42 @@ package expo.modules.updates.procedures

import android.app.Activity
import com.facebook.react.ReactApplication
+import com.facebook.react.ReactHost
+import com.facebook.react.ReactNativeHost
import com.facebook.react.common.LifecycleState
import expo.modules.rncompatibility.ReactNativeFeatureFlags
+import expo.modules.updates.UpdatesController

-/**
- * An extension for [ReactApplication] to restart the app
- *
- * @param activity For bridgeless mode if the ReactHost is destroyed, we need an Activity to resume it.
- * @param reason The restart reason. Only used on bridgeless mode.
- */
-internal fun ReactApplication.restart(activity: Activity?, reason: String) {
- if (ReactNativeFeatureFlags.enableBridgelessArchitecture) {
- val reactHost = this.reactHost
- check(reactHost != null)
- if (reactHost.lifecycleState != LifecycleState.RESUMED && activity != null) {
- reactHost.onHostResume(activity)
+private fun getReactHostReflectively(app: ReactApplication): ReactHost? {
+ return runCatching {
+ app.javaClass.getMethod("getReactHost").invoke(app) as? ReactHost
+ }.getOrNull()
+}
+
+private fun getReactNativeHostReflectively(app: ReactApplication): ReactNativeHost? {
+ return runCatching {
+ app.javaClass.getMethod("getReactNativeHost").invoke(app) as? ReactNativeHost
+ }.getOrNull()
+}
+
+object RestartReactAppExtensions {
+ /**
+ * A function to restart the app
+ *
+ * @param activity For bridgeless mode if the ReactHost is destroyed, we need an Activity to resume it.
+ * @param reason The restart reason. Only used on bridgeless mode.
+ */
+ fun restart(activity: Activity?, reason: String) {
+ if (ReactNativeFeatureFlags.enableBridgelessArchitecture) {
+ val reactHost = UpdatesController.getReactHost() ?: getReactHostReflectively(activity?.application as ReactApplication)
+ check(reactHost != null)
+ if (reactHost.lifecycleState != LifecycleState.RESUMED && activity != null) {
+ reactHost.onHostResume(activity)
+ }
+ reactHost.reload(reason)
+ return
}
- reactHost.reload(reason)
- return
- }

- reactNativeHost.reactInstanceManager.recreateReactContextInBackground()
+ getReactNativeHostReflectively(activity?.application as ReactApplication)?.reactInstanceManager?.recreateReactContextInBackground()
+ }
}
diff --git a/ios/EXUpdates/UpdatesConfig.swift b/ios/EXUpdates/UpdatesConfig.swift
index 09a1e145a9f5a938e10dd3c59eedfd213ad54346..787c1a8f7ae6a010fff4200ffebe31742e9a25eb 100644
--- a/ios/EXUpdates/UpdatesConfig.swift
+++ b/ios/EXUpdates/UpdatesConfig.swift
@@ -141,7 +141,8 @@ public final class UpdatesConfig: NSObject {
}

private static func configDictionaryWithExpoPlist(mergingOtherDictionary: [String: Any]?) throws -> [String: Any] {
- guard let configPlistPath = Bundle.main.path(forResource: PlistName, ofType: "plist") else {
+ let bundle = Bundle(for: UpdatesConfig.self)
+ guard let configPlistPath = bundle.path(forResource: PlistName, ofType: "plist") else {
throw UpdatesConfigError.ExpoUpdatesConfigPlistError
}

diff --git a/ios/EXUpdates/UpdatesUtils.swift b/ios/EXUpdates/UpdatesUtils.swift
index a1e2c9af4ebaf9e50db2acaabfa876fc46d22454..0b96a7062dbcd021339a9daeb4397b3c7715b96d 100644
--- a/ios/EXUpdates/UpdatesUtils.swift
+++ b/ios/EXUpdates/UpdatesUtils.swift
@@ -108,18 +108,22 @@ public final class UpdatesUtils: NSObject {
return assetFilesMap
}

+ private static func getBundle() -> Bundle {
+ return Bundle(for: UpdatesUtils.self)
+ }
+
internal static func url(forBundledAsset asset: UpdateAsset) -> URL? {
guard let mainBundleDir = asset.mainBundleDir else {
- return Bundle.main.url(forResource: asset.mainBundleFilename, withExtension: asset.type)
+ return getBundle().url(forResource: asset.mainBundleFilename, withExtension: asset.type)
}
- return Bundle.main.url(forResource: asset.mainBundleFilename, withExtension: asset.type, subdirectory: mainBundleDir)
+ return getBundle().url(forResource: asset.mainBundleFilename, withExtension: asset.type, subdirectory: mainBundleDir)
}

internal static func path(forBundledAsset asset: UpdateAsset) -> String? {
guard let mainBundleDir = asset.mainBundleDir else {
- return Bundle.main.path(forResource: asset.mainBundleFilename, ofType: asset.type)
+ return getBundle().path(forResource: asset.mainBundleFilename, ofType: asset.type)
}
- return Bundle.main.path(forResource: asset.mainBundleFilename, ofType: asset.type, inDirectory: mainBundleDir)
+ return getBundle().path(forResource: asset.mainBundleFilename, ofType: asset.type, inDirectory: mainBundleDir)
}

/**
Loading
Loading