Skip to content
Open
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
17 changes: 15 additions & 2 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ public abstract interface class com/facebook/react/ReactHost {
public abstract fun reload (Ljava/lang/String;)Lcom/facebook/react/interfaces/TaskInterface;
public abstract fun removeBeforeDestroyListener (Lkotlin/jvm/functions/Function0;)V
public abstract fun removeReactInstanceEventListener (Lcom/facebook/react/ReactInstanceEventListener;)V
public fun setBundleSource (Ljava/lang/String;)V
public fun setBundleSource (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun setBundleSource$default (Lcom/facebook/react/ReactHost;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public abstract fun start ()Lcom/facebook/react/interfaces/TaskInterface;
}

Expand Down Expand Up @@ -1898,7 +1901,7 @@ public final class com/facebook/react/devsupport/DefaultDevLoadingViewImplementa
public class com/facebook/react/devsupport/DevServerHelper {
public fun <init> (Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;Landroid/content/Context;Lcom/facebook/react/packagerconnection/PackagerConnectionSettings;)V
public final fun closeInspectorConnection ()V
public final fun closePackagerConnection ()V
public final fun closePackagerConnection ()Landroid/os/AsyncTask;
public final fun disableDebugger ()V
public final fun downloadBundleFromURL (Lcom/facebook/react/devsupport/interfaces/DevBundleDownloadListener;Ljava/io/File;Ljava/lang/String;Lcom/facebook/react/devsupport/BundleDownloader$BundleInfo;)V
public final fun downloadBundleFromURL (Lcom/facebook/react/devsupport/interfaces/DevBundleDownloadListener;Ljava/io/File;Ljava/lang/String;Lcom/facebook/react/devsupport/BundleDownloader$BundleInfo;Lokhttp3/Request$Builder;)V
Expand All @@ -1925,7 +1928,8 @@ public abstract interface class com/facebook/react/devsupport/DevServerHelper$Pa

public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/facebook/react/devsupport/interfaces/DevSupportManager {
public static final field Companion Lcom/facebook/react/devsupport/DevSupportManagerBase$Companion;
public fun <init> (Landroid/content/Context;Lcom/facebook/react/devsupport/ReactInstanceDevHelper;Ljava/lang/String;ZLcom/facebook/react/devsupport/interfaces/RedBoxHandler;Lcom/facebook/react/devsupport/interfaces/DevBundleDownloadListener;ILjava/util/Map;Lcom/facebook/react/common/SurfaceDelegateFactory;Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;Lcom/facebook/react/devsupport/interfaces/PausedInDebuggerOverlayManager;)V
public fun <init> (Landroid/content/Context;Lcom/facebook/react/devsupport/ReactInstanceDevHelper;Ljava/lang/String;ZLcom/facebook/react/devsupport/interfaces/RedBoxHandler;Lcom/facebook/react/devsupport/interfaces/DevBundleDownloadListener;ILjava/util/Map;Lcom/facebook/react/common/SurfaceDelegateFactory;Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;Lcom/facebook/react/devsupport/interfaces/PausedInDebuggerOverlayManager;Ljava/lang/String;)V
public synthetic fun <init> (Landroid/content/Context;Lcom/facebook/react/devsupport/ReactInstanceDevHelper;Ljava/lang/String;ZLcom/facebook/react/devsupport/interfaces/RedBoxHandler;Lcom/facebook/react/devsupport/interfaces/DevBundleDownloadListener;ILjava/util/Map;Lcom/facebook/react/common/SurfaceDelegateFactory;Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;Lcom/facebook/react/devsupport/interfaces/PausedInDebuggerOverlayManager;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun addCustomDevOption (Ljava/lang/String;Lcom/facebook/react/devsupport/interfaces/DevOptionHandler;)V
public fun createRootView (Ljava/lang/String;)Landroid/view/View;
public fun createSurfaceDelegate (Ljava/lang/String;)Lcom/facebook/react/common/SurfaceDelegate;
Expand All @@ -1935,6 +1939,7 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/
protected final fun getApplicationContext ()Landroid/content/Context;
public fun getCurrentActivity ()Landroid/app/Activity;
public final fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public fun getCustomBundleFilePath ()Ljava/lang/String;
public final fun getDevLoadingViewManager ()Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;
public final fun getDevServerHelper ()Lcom/facebook/react/devsupport/DevServerHelper;
public final fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
Expand Down Expand Up @@ -1964,10 +1969,12 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/
public fun reloadJSFromServer (Ljava/lang/String;Lcom/facebook/react/devsupport/interfaces/BundleLoadCallback;)V
public fun reloadSettings ()V
public fun setAdditionalOptionForPackager (Ljava/lang/String;Ljava/lang/String;)V
public fun setCustomBundleFilePath (Ljava/lang/String;)V
public final fun setDevLoadingViewManager (Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;)V
public final fun setDevSupportEnabled (Z)V
public fun setFpsDebugEnabled (Z)V
public fun setHotModuleReplacementEnabled (Z)V
public final fun setJsAppBundleName (Ljava/lang/String;)V
public final fun setLastErrorCookie (I)V
public final fun setLastErrorStack ([Lcom/facebook/react/devsupport/interfaces/StackFrame;)V
public final fun setLastErrorTitle (Ljava/lang/String;)V
Expand Down Expand Up @@ -2131,6 +2138,7 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp
public abstract fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
public abstract fun getCurrentActivity ()Landroid/app/Activity;
public abstract fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public fun getCustomBundleFilePath ()Ljava/lang/String;
public abstract fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
public abstract fun getDevSupportEnabled ()Z
public abstract fun getDownloadedJSBundleFile ()Ljava/lang/String;
Expand All @@ -2155,6 +2163,7 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp
public abstract fun reloadJSFromServer (Ljava/lang/String;Lcom/facebook/react/devsupport/interfaces/BundleLoadCallback;)V
public abstract fun reloadSettings ()V
public abstract fun setAdditionalOptionForPackager (Ljava/lang/String;Ljava/lang/String;)V
public fun setCustomBundleFilePath (Ljava/lang/String;)V
public abstract fun setDevSupportEnabled (Z)V
public abstract fun setFpsDebugEnabled (Z)V
public abstract fun setHotModuleReplacementEnabled (Z)V
Expand Down Expand Up @@ -2993,6 +3002,8 @@ public class com/facebook/react/packagerconnection/PackagerConnectionSettings {
public fun resetDebugServerHost ()V
public final fun setAdditionalOptionForPackager (Ljava/lang/String;Ljava/lang/String;)V
public fun setDebugServerHost (Ljava/lang/String;)V
public final fun setPackagerOptionsUpdater (Lkotlin/jvm/functions/Function1;)V
public final fun updatePackagerOptions (Ljava/util/Map;)Ljava/util/Map;
}

public final class com/facebook/react/packagerconnection/ReconnectingWebSocket : okhttp3/WebSocketListener {
Expand Down Expand Up @@ -3071,6 +3082,8 @@ public final class com/facebook/react/runtime/ReactHostImpl : com/facebook/react
public fun reload (Ljava/lang/String;)Lcom/facebook/react/interfaces/TaskInterface;
public fun removeBeforeDestroyListener (Lkotlin/jvm/functions/Function0;)V
public fun removeReactInstanceEventListener (Lcom/facebook/react/ReactInstanceEventListener;)V
public fun setBundleSource (Ljava/lang/String;)V
public fun setBundleSource (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public fun start ()Lcom/facebook/react/interfaces/TaskInterface;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,21 @@ public interface ReactHost {

/** Remove a listener previously added with [addReactInstanceEventListener]. */
public fun removeReactInstanceEventListener(listener: ReactInstanceEventListener)

/** Sets the source of the bundle to be loaded from the file system. */
public fun setBundleSource(filePath: String): Unit = Unit

/**
* Sets the source of the bundle to be loaded from the packager server and updates the packager
* connection.
*
* @param debugServerHost host and port of the server, for example "localhost:8081"
* @param moduleName the module name to load, for example "js/RNTesterApp.android"
* @param queryBuilder a function that takes current packager options and returns updated options
*/
public fun setBundleSource(
debugServerHost: String,
moduleName: String,
queryBuilder: (Map<String, String>) -> Map<String, String> = { it },
): Unit = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,18 @@ public open class DevServerHelper(
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
}

public fun closePackagerConnection() {
object : AsyncTask<Void, Void, Void>() {
public fun closePackagerConnection(): AsyncTask<Void, Void, Void> {
val task =
object : AsyncTask<Void, Void, Void>() {
@Deprecated("This class needs to be rewritten to don't use AsyncTasks")
override fun doInBackground(vararg params: Void): Void? {
packagerClient?.close()
packagerClient = null
return null
}
}
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
return task
}

public fun openInspectorConnection() {
Expand Down Expand Up @@ -280,7 +282,11 @@ public open class DevServerHelper(
): String {
val dev = devMode
val additionalOptionsBuilder = StringBuilder()
for ((key, value) in packagerConnectionSettings.additionalOptionsForPackager) {
val packagerOptions =
packagerConnectionSettings.updatePackagerOptions(
packagerConnectionSettings.additionalOptionsForPackager
)
for ((key, value) in packagerOptions) {
if (value.isEmpty()) {
continue
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ import java.util.Locale
public abstract class DevSupportManagerBase(
protected val applicationContext: Context,
public val reactInstanceDevHelper: ReactInstanceDevHelper,
@get:JvmName("getJSAppBundleName") public val jsAppBundleName: String?,
@get:JvmName("getJSAppBundleName") public var jsAppBundleName: String?,
enableOnCreate: Boolean,
public override val redBoxHandler: RedBoxHandler?,
private val devBundleDownloadListener: DevBundleDownloadListener?,
Expand All @@ -94,6 +94,7 @@ public abstract class DevSupportManagerBase(
private val surfaceDelegateFactory: SurfaceDelegateFactory?,
public var devLoadingViewManager: DevLoadingViewManager?,
private var pausedInDebuggerOverlayManager: PausedInDebuggerOverlayManager?,
private var customBundleFilePathField: String? = null,
) : DevSupportManager {

public interface CallbackWithBundleLoader {
Expand Down Expand Up @@ -132,6 +133,12 @@ public abstract class DevSupportManagerBase(
reloadSettings()
}

override var customBundleFilePath: String?
get() = customBundleFilePathField
set(value) {
customBundleFilePathField = value
}

override val sourceMapUrl: String
get() = jsAppBundleName?.let { devServerHelper.getSourceMapUrl(it) } ?: ""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public interface DevSupportManager : JSExceptionHandler {
public val currentActivity: Activity?
public val currentReactContext: ReactContext?

public var customBundleFilePath: String?
get() = null
set(value) = Unit

public var devSupportEnabled: Boolean

public fun showNewJavaError(message: String?, e: Throwable)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,24 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

@file:Suppress("DEPRECATION") // PreferenceManager should be migrated to androidx

package com.facebook.react.packagerconnection

import android.content.Context
import android.content.SharedPreferences
import android.preference.PreferenceManager
import com.facebook.common.logging.FLog
import com.facebook.react.modules.systeminfo.AndroidInfoHelpers

public open class PackagerConnectionSettings(private val appContext: Context) {
private val preferences: SharedPreferences =
PreferenceManager.getDefaultSharedPreferences(appContext)
public val packageName: String = appContext.packageName
private val _additionalOptionsForPackager: MutableMap<String, String> = mutableMapOf()
private var _packagerOptionsUpdater: (Map<String, String>) -> Map<String, String> = { it }
private var cachedHost: String? = null

public open var debugServerHost: String
get() {
// Check host setting first. If empty try to detect emulator type and use default
// Check cached host first. If empty try to detect emulator type and use default
// hostname for those
val hostFromSettings = preferences.getString(PREFS_DEBUG_SERVER_HOST_KEY, null)
if (!hostFromSettings.isNullOrEmpty()) {
return hostFromSettings
cachedHost?.let {
return it
}
val host = AndroidInfoHelpers.getServerHost(appContext)
if (host == AndroidInfoHelpers.DEVICE_LOCALHOST) {
Expand All @@ -36,20 +30,29 @@ public open class PackagerConnectionSettings(private val appContext: Context) {
"You seem to be running on device. Run '${AndroidInfoHelpers.getAdbReverseTcpCommand(appContext)}' to forward the debug server's port to the device.",
)
}

cachedHost = host
return host
}
set(host) {
if (host.isEmpty()) {
preferences.edit().remove(PREFS_DEBUG_SERVER_HOST_KEY).apply()
cachedHost = null
} else {
preferences.edit().putString(PREFS_DEBUG_SERVER_HOST_KEY, host).apply()
cachedHost = host
}
}

public open fun resetDebugServerHost() {
preferences.edit().remove(PREFS_DEBUG_SERVER_HOST_KEY).apply()
cachedHost = null
}

public fun setPackagerOptionsUpdater(updater: (Map<String, String>) -> Map<String, String>) {
_packagerOptionsUpdater = updater
}

public fun updatePackagerOptions(options: Map<String, String>): Map<String, String> =
_packagerOptionsUpdater(options)

public fun setAdditionalOptionForPackager(key: String, value: String) {
_additionalOptionsForPackager[key] = value
}
Expand All @@ -59,6 +62,5 @@ public open class PackagerConnectionSettings(private val appContext: Context) {

private companion object {
private val TAG = PackagerConnectionSettings::class.java.simpleName
private const val PREFS_DEBUG_SERVER_HOST_KEY = "debug_http_host"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicReference
import kotlin.Unit
import kotlin.concurrent.Volatile
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

/**
* A ReactHost is an object that manages a single [ReactInstance]. A ReactHost can be constructed
Expand Down Expand Up @@ -643,6 +646,29 @@ public class ReactHostImpl(
}
}

@ThreadConfined(value = ThreadConfined.UI)
override fun setBundleSource(filePath: String) {
devSupportManager.customBundleFilePath = filePath
reload("Change bundle source")
}

@ThreadConfined(value = ThreadConfined.UI)
override fun setBundleSource(
debugServerHost: String,
moduleName: String,
queryBuilder: (Map<String, String>) -> Map<String, String>,
) {
CoroutineScope(Dispatchers.Default).launch {
(devSupportManager as DevSupportManagerBase).devServerHelper.closePackagerConnection()
devSupportManager.devSettings.packagerConnectionSettings.let { it ->
it.setPackagerOptionsUpdater(queryBuilder)
it.debugServerHost = debugServerHost
}
devSupportManager.jsAppBundleName = moduleName
reload("Changed bundle source")
}
}

@ThreadConfined(ThreadConfined.UI)
override fun onConfigurationChanged(context: Context) {
val currentReactContext = this.currentReactContext
Expand Down Expand Up @@ -1057,6 +1083,14 @@ public class ReactHostImpl(
get() {
stateTracker.enterState("getJSBundleLoader()")

if (devSupportManager.customBundleFilePath != null) {
return try {
Task.forResult(JSBundleLoader.createFileLoader(devSupportManager.customBundleFilePath!!))
} catch (e: Exception) {
Task.forError(e)
}
}

if (useDevSupport && allowPackagerServerAccess) {
return isMetroRunning.onSuccessTask(
{ task ->
Expand Down
Loading