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
14 changes: 13 additions & 1 deletion 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 fun setDevMenuConfiguration (Lcom/facebook/react/devsupport/DevMenuConfiguration;)V
public abstract fun start ()Lcom/facebook/react/interfaces/TaskInterface;
}
Expand Down Expand Up @@ -1908,7 +1911,7 @@ public final class com/facebook/react/devsupport/DevMenuConfiguration {
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 Down Expand Up @@ -1943,6 +1946,7 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/
public fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
public final fun fetchSplitBundleAndCreateBundleLoader (Ljava/lang/String;Lcom/facebook/react/devsupport/DevSupportManagerBase$CallbackWithBundleLoader;)V
protected final fun getApplicationContext ()Landroid/content/Context;
public fun getBundleFilePath ()Ljava/lang/String;
public fun getCurrentActivity ()Landroid/app/Activity;
public final fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public final fun getDevLoadingViewManager ()Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;
Expand Down Expand Up @@ -1977,11 +1981,13 @@ 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 setBundleFilePath (Ljava/lang/String;)V
public final fun setDevLoadingViewManager (Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;)V
public fun setDevMenuEnabled (Z)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 fun setKeyboardShortcutsEnabled (Z)V
public final fun setLastErrorCookie (I)V
public final fun setLastErrorStack ([Lcom/facebook/react/devsupport/interfaces/StackFrame;)V
Expand Down Expand Up @@ -2151,6 +2157,7 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp
public abstract fun createSurfaceDelegate (Ljava/lang/String;)Lcom/facebook/react/common/SurfaceDelegate;
public abstract fun destroyRootView (Landroid/view/View;)V
public abstract fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
public fun getBundleFilePath ()Ljava/lang/String;
public abstract fun getCurrentActivity ()Landroid/app/Activity;
public abstract fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public fun getDevMenuEnabled ()Z
Expand Down Expand Up @@ -2180,6 +2187,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 setBundleFilePath (Ljava/lang/String;)V
public fun setDevMenuEnabled (Z)V
public abstract fun setDevSupportEnabled (Z)V
public abstract fun setFpsDebugEnabled (Z)V
Expand Down Expand Up @@ -3021,6 +3029,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 @@ -3099,6 +3109,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 setDevMenuConfiguration (Lcom/facebook/react/devsupport/DevMenuConfiguration;)V
public fun start ()Lcom/facebook/react/interfaces/TaskInterface;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,21 @@ public interface ReactHost {

/** Set the DevMenu configuration. */
public fun setDevMenuConfiguration(config: DevMenuConfiguration): Unit = Unit

/** 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 queryMapper a function that takes current packager options and returns updated options
*/
public fun setBundleSource(
debugServerHost: String,
moduleName: String,
queryMapper: (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 Down Expand Up @@ -148,6 +148,12 @@ public abstract class DevSupportManagerBase(
field = value
}

override var bundleFilePath: String? = null
get() = field
set(value) {
field = 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 @@ -48,6 +48,10 @@ public interface DevSupportManager : JSExceptionHandler {
get() = true
set(value) = Unit

public var bundleFilePath: 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(queryMapper: (Map<String, String>) -> Map<String, String>) {
_packagerOptionsUpdater = queryMapper
}

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 @@ -74,6 +74,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 @@ -650,6 +653,29 @@ public class ReactHostImpl(
}
}

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

@ThreadConfined(value = ThreadConfined.UI)
override fun setBundleSource(
debugServerHost: String,
moduleName: String,
queryMapper: (Map<String, String>) -> Map<String, String>,
) {
CoroutineScope(Dispatchers.Default).launch {
(devSupportManager as DevSupportManagerBase).devServerHelper.closePackagerConnection()
devSupportManager.devSettings.packagerConnectionSettings.let { it ->
it.setPackagerOptionsUpdater(queryMapper)
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 @@ -1064,6 +1090,16 @@ public class ReactHostImpl(
get() {
stateTracker.enterState("getJSBundleLoader()")

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

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