diff --git a/Libraries/Utilities/HMRClient.js b/Libraries/Utilities/HMRClient.js index cb901e86e..c8d685973 100644 --- a/Libraries/Utilities/HMRClient.js +++ b/Libraries/Utilities/HMRClient.js @@ -98,12 +98,20 @@ Error: ${e.message}` RCTExceptionsManager && RCTExceptionsManager.dismissRedbox && RCTExceptionsManager.dismissRedbox(); } + let serverHost; + + if (Platform.OS === 'android') { + serverHost = require('NativeModules').AndroidConstants.ServerHost; + } else { + serverHost = port ? `${host}:${port}` : host; + } + modules.forEach(({id, code}, i) => { code = code + '\n\n' + sourceMappingURLs[i]; require('SourceMapsCache').fetch({ text: code, - url: sourceURLs[i], + url: `http://${serverHost}${sourceURLs[i]}`, sourceMappingURL: sourceMappingURLs[i], }); diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK index 5f81485ca..8bd558248 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK @@ -9,6 +9,7 @@ android_library( react_native_target('java/com/facebook/react/bridge:bridge'), react_native_target('java/com/facebook/react/common:common'), react_native_target('java/com/facebook/react/modules/debug:debug'), + react_native_target('java/com/facebook/react/modules/systeminfo:systeminfo'), react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'), react_native_dep('third-party/java/infer-annotations:infer-annotations'), react_native_dep('third-party/java/jsr-305:jsr-305'), diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java index e99c7a9b0..b48d8f632 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java @@ -9,16 +9,7 @@ package com.facebook.react.devsupport; -import javax.annotation.Nullable; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.Locale; -import java.util.concurrent.TimeUnit; - import android.content.Context; -import android.os.Build; import android.os.Handler; import android.text.TextUtils; @@ -26,6 +17,7 @@ import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.common.ReactConstants; +import com.facebook.react.modules.systeminfo.AndroidInfoHelpers; import com.squareup.okhttp.Call; import com.squareup.okhttp.Callback; import com.squareup.okhttp.ConnectionPool; @@ -34,6 +26,13 @@ import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import com.squareup.okhttp.ResponseBody; +import java.io.File; +import java.io.IOException; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nullable; + import okio.Okio; import okio.Sink; @@ -51,10 +50,6 @@ public class DevServerHelper { public static final String RELOAD_APP_EXTRA_JS_PROXY = "jsproxy"; private static final String RELOAD_APP_ACTION_SUFFIX = ".RELOAD_APP_ACTION"; - private static final String EMULATOR_LOCALHOST = "10.0.2.2:8081"; - private static final String GENYMOTION_LOCALHOST = "10.0.3.2:8081"; - private static final String DEVICE_LOCALHOST = "localhost:8081"; - private static final String BUNDLE_URL_FORMAT = "http://%s/%s.bundle?platform=android&dev=%s&hot=%s&minify=%s"; private static final String SOURCE_MAP_URL_FORMAT = @@ -118,7 +113,7 @@ public class DevServerHelper { * @return the host to use when connecting to the bundle server from the host itself. */ private static String getHostForJSProxy() { - return DEVICE_LOCALHOST; + return AndroidInfoHelpers.DEVICE_LOCALHOST; } /** @@ -149,31 +144,21 @@ public class DevServerHelper { // Check debug server host setting first. If empty try to detect emulator type and use default // hostname for those String hostFromSettings = mSettings.getDebugServerHost(); + if (!TextUtils.isEmpty(hostFromSettings)) { return Assertions.assertNotNull(hostFromSettings); } - // Since genymotion runs in vbox it use different hostname to refer to adb host. - // We detect whether app runs on genymotion and replace js bundle server hostname accordingly - if (isRunningOnGenymotion()) { - return GENYMOTION_LOCALHOST; - } - if (isRunningOnStockEmulator()) { - return EMULATOR_LOCALHOST; - } - FLog.w( + String host = AndroidInfoHelpers.getServerHost(); + + if (host.equals(AndroidInfoHelpers.DEVICE_LOCALHOST)) { + FLog.w( ReactConstants.TAG, "You seem to be running on device. Run 'adb reverse tcp:8081 tcp:8081' " + - "to forward the debug server's port to the device."); - return DEVICE_LOCALHOST; - } + "to forward the debug server's port to the device."); + } - private boolean isRunningOnGenymotion() { - return Build.FINGERPRINT.contains("vbox"); - } - - private boolean isRunningOnStockEmulator() { - return Build.FINGERPRINT.contains("generic"); + return host; } private static String createBundleURL(String host, String jsModulePath, boolean devMode, boolean hmr, boolean jsMinify) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoHelpers.java b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoHelpers.java new file mode 100644 index 000000000..9f61648e3 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoHelpers.java @@ -0,0 +1,33 @@ +package com.facebook.react.modules.systeminfo; + +import android.os.Build; + +public class AndroidInfoHelpers { + + public static final String EMULATOR_LOCALHOST = "10.0.2.2:8081"; + public static final String GENYMOTION_LOCALHOST = "10.0.3.2:8081"; + public static final String DEVICE_LOCALHOST = "localhost:8081"; + + private static boolean isRunningOnGenymotion() { + return Build.FINGERPRINT.contains("vbox"); + } + + private static boolean isRunningOnStockEmulator() { + return Build.FINGERPRINT.contains("generic"); + } + + public static String getServerHost() { + // Since genymotion runs in vbox it use different hostname to refer to adb host. + // We detect whether app runs on genymotion and replace js bundle server hostname accordingly + + if (isRunningOnGenymotion()) { + return GENYMOTION_LOCALHOST; + } + + if (isRunningOnStockEmulator()) { + return EMULATOR_LOCALHOST; + } + + return DEVICE_LOCALHOST; + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java index d07eb4a5f..7ef7dee01 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java @@ -9,14 +9,14 @@ package com.facebook.react.modules.systeminfo; -import javax.annotation.Nullable; +import android.os.Build; + +import com.facebook.react.bridge.BaseJavaModule; import java.util.HashMap; import java.util.Map; -import android.os.Build; - -import com.facebook.react.bridge.BaseJavaModule; +import javax.annotation.Nullable; /** * Module that exposes Android Constants to JS. @@ -32,6 +32,7 @@ public class AndroidInfoModule extends BaseJavaModule { public @Nullable Map getConstants() { HashMap constants = new HashMap(); constants.put("Version", Build.VERSION.SDK_INT); + constants.put("ServerHost", AndroidInfoHelpers.getServerHost()); return constants; } } diff --git a/packager/react-packager/src/Bundler/index.js b/packager/react-packager/src/Bundler/index.js index 8d630528b..52bb3ad27 100644 --- a/packager/react-packager/src/Bundler/index.js +++ b/packager/react-packager/src/Bundler/index.js @@ -170,9 +170,9 @@ class Bundler { }); } - _sourceHMRURL(platform, host, port, path) { + _sourceHMRURL(platform, path) { return this._hmrURL( - `http://${host}:${port}`, + '', platform, 'bundle', path, @@ -217,7 +217,7 @@ class Bundler { return this._bundle({ ...options, bundle: new HMRBundle({ - sourceURLFn: this._sourceHMRURL.bind(this, options.platform, host, port), + sourceURLFn: this._sourceHMRURL.bind(this, options.platform), sourceMappingURLFn: this._sourceMappingHMRURL.bind( this, options.platform,