mirror of
https://github.com/status-im/react-native.git
synced 2025-01-13 19:15:05 +00:00
Extract PackagerConnectionSettings to ensure easier reusability of PackagerConnection module
Reviewed By: cwdick Differential Revision: D4689535 fbshipit-source-id: f698837f407a03bf91521cc5e921c66f5755e6e0
This commit is contained in:
parent
50ff7167cb
commit
60142adc72
@ -17,6 +17,7 @@ import android.preference.PreferenceManager;
|
||||
|
||||
import com.facebook.react.common.annotations.VisibleForTesting;
|
||||
import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
|
||||
import com.facebook.react.packagerconnection.PackagerConnectionSettings;
|
||||
|
||||
/**
|
||||
* Helper class for accessing developers settings that should not be accessed outside of the package
|
||||
@ -31,7 +32,6 @@ public class DevInternalSettings implements
|
||||
private static final String PREFS_FPS_DEBUG_KEY = "fps_debug";
|
||||
private static final String PREFS_JS_DEV_MODE_DEBUG_KEY = "js_dev_mode_debug";
|
||||
private static final String PREFS_JS_MINIFY_DEBUG_KEY = "js_minify_debug";
|
||||
private static final String PREFS_DEBUG_SERVER_HOST_KEY = "debug_http_host";
|
||||
private static final String PREFS_ANIMATIONS_DEBUG_KEY = "animations_debug";
|
||||
private static final String PREFS_RELOAD_ON_JS_CHANGE_KEY = "reload_on_js_change";
|
||||
private static final String PREFS_INSPECTOR_DEBUG_KEY = "inspector_debug";
|
||||
@ -40,6 +40,7 @@ public class DevInternalSettings implements
|
||||
|
||||
private final SharedPreferences mPreferences;
|
||||
private final Listener mListener;
|
||||
private final PackagerConnectionSettings mPackagerConnectionSettings;
|
||||
|
||||
public DevInternalSettings(
|
||||
Context applicationContext,
|
||||
@ -47,6 +48,11 @@ public class DevInternalSettings implements
|
||||
mListener = listener;
|
||||
mPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext);
|
||||
mPreferences.registerOnSharedPreferenceChangeListener(this);
|
||||
mPackagerConnectionSettings = new PackagerConnectionSettings(applicationContext);
|
||||
}
|
||||
|
||||
public PackagerConnectionSettings getPackagerConnectionSettings() {
|
||||
return mPackagerConnectionSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,10 +79,6 @@ public class DevInternalSettings implements
|
||||
return mPreferences.getBoolean(PREFS_JS_MINIFY_DEBUG_KEY, false);
|
||||
}
|
||||
|
||||
public @Nullable String getDebugServerHost() {
|
||||
return mPreferences.getString(PREFS_DEBUG_SERVER_HOST_KEY, null);
|
||||
}
|
||||
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (mListener != null) {
|
||||
if (PREFS_FPS_DEBUG_KEY.equals(key) ||
|
||||
|
@ -73,7 +73,6 @@ public class DevServerHelper {
|
||||
private static final String ONCHANGE_ENDPOINT_URL_FORMAT =
|
||||
"http://%s/onchange";
|
||||
private static final String WEBSOCKET_PROXY_URL_FORMAT = "ws://%s/debugger-proxy?role=client";
|
||||
private static final String PACKAGER_CONNECTION_URL_FORMAT = "ws://%s/message?role=android-rn-devserverhelper";
|
||||
private static final String PACKAGER_STATUS_URL_FORMAT = "http://%s/status";
|
||||
private static final String HEAP_CAPTURE_UPLOAD_URL_FORMAT = "http://%s/jscheapcaptureupload";
|
||||
private static final String INSPECTOR_DEVICE_URL_FORMAT = "http://%s/inspector/device?name=%s";
|
||||
@ -152,7 +151,7 @@ public class DevServerHelper {
|
||||
});
|
||||
handlers.putAll(new FileIoHandler().handlers());
|
||||
|
||||
mPackagerClient = new JSPackagerClient(getPackagerConnectionURL(), handlers);
|
||||
mPackagerClient = new JSPackagerClient("devserverhelper", mSettings.getPackagerConnectionSettings(), handlers);
|
||||
mPackagerClient.init();
|
||||
|
||||
return null;
|
||||
@ -213,22 +212,18 @@ public class DevServerHelper {
|
||||
}
|
||||
|
||||
public String getWebsocketProxyURL() {
|
||||
return String.format(Locale.US, WEBSOCKET_PROXY_URL_FORMAT, getDebugServerHost());
|
||||
}
|
||||
|
||||
private String getPackagerConnectionURL() {
|
||||
return String.format(Locale.US, PACKAGER_CONNECTION_URL_FORMAT, getDebugServerHost());
|
||||
return String.format(Locale.US, WEBSOCKET_PROXY_URL_FORMAT, mSettings.getPackagerConnectionSettings().getDebugServerHost());
|
||||
}
|
||||
|
||||
public String getHeapCaptureUploadUrl() {
|
||||
return String.format(Locale.US, HEAP_CAPTURE_UPLOAD_URL_FORMAT, getDebugServerHost());
|
||||
return String.format(Locale.US, HEAP_CAPTURE_UPLOAD_URL_FORMAT, mSettings.getPackagerConnectionSettings().getDebugServerHost());
|
||||
}
|
||||
|
||||
public String getInspectorDeviceUrl() {
|
||||
return String.format(
|
||||
Locale.US,
|
||||
INSPECTOR_DEVICE_URL_FORMAT,
|
||||
getDebugServerHost(),
|
||||
mSettings.getPackagerConnectionSettings().getDebugServerHost(),
|
||||
AndroidInfoHelpers.getFriendlyDeviceName());
|
||||
}
|
||||
|
||||
@ -260,30 +255,6 @@ public class DevServerHelper {
|
||||
return mSettings.isHotModuleReplacementEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the host to use when connecting to the bundle server.
|
||||
*/
|
||||
private String getDebugServerHost() {
|
||||
// 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);
|
||||
}
|
||||
|
||||
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 host;
|
||||
}
|
||||
|
||||
private static String createBundleURL(String host, String jsModulePath, boolean devMode, boolean hmr, boolean jsMinify) {
|
||||
return String.format(Locale.US, BUNDLE_URL_FORMAT, host, jsModulePath, devMode, hmr, jsMinify);
|
||||
}
|
||||
@ -294,7 +265,7 @@ public class DevServerHelper {
|
||||
|
||||
public String getDevServerBundleURL(final String jsModulePath) {
|
||||
return createBundleURL(
|
||||
getDebugServerHost(),
|
||||
mSettings.getPackagerConnectionSettings().getDebugServerHost(),
|
||||
jsModulePath,
|
||||
getDevMode(),
|
||||
getHMR(),
|
||||
@ -438,7 +409,7 @@ public class DevServerHelper {
|
||||
}
|
||||
|
||||
public void isPackagerRunning(final PackagerStatusCallback callback) {
|
||||
String statusURL = createPackagerStatusURL(getDebugServerHost());
|
||||
String statusURL = createPackagerStatusURL(mSettings.getPackagerConnectionSettings().getDebugServerHost());
|
||||
Request request = new Request.Builder()
|
||||
.url(statusURL)
|
||||
.build();
|
||||
@ -558,11 +529,11 @@ public class DevServerHelper {
|
||||
}
|
||||
|
||||
private String createOnChangeEndpointUrl() {
|
||||
return String.format(Locale.US, ONCHANGE_ENDPOINT_URL_FORMAT, getDebugServerHost());
|
||||
return String.format(Locale.US, ONCHANGE_ENDPOINT_URL_FORMAT, mSettings.getPackagerConnectionSettings().getDebugServerHost());
|
||||
}
|
||||
|
||||
private String createLaunchJSDevtoolsCommandUrl() {
|
||||
return String.format(Locale.US, LAUNCH_JS_DEVTOOLS_COMMAND_URL_FORMAT, getDebugServerHost());
|
||||
return String.format(Locale.US, LAUNCH_JS_DEVTOOLS_COMMAND_URL_FORMAT, mSettings.getPackagerConnectionSettings().getDebugServerHost());
|
||||
}
|
||||
|
||||
public void launchJSDevtools() {
|
||||
@ -584,11 +555,11 @@ public class DevServerHelper {
|
||||
}
|
||||
|
||||
public String getSourceMapUrl(String mainModuleName) {
|
||||
return String.format(Locale.US, SOURCE_MAP_URL_FORMAT, getDebugServerHost(), mainModuleName, getDevMode(), getHMR(), getJSMinifyMode());
|
||||
return String.format(Locale.US, SOURCE_MAP_URL_FORMAT, mSettings.getPackagerConnectionSettings().getDebugServerHost(), mainModuleName, getDevMode(), getHMR(), getJSMinifyMode());
|
||||
}
|
||||
|
||||
public String getSourceUrl(String mainModuleName) {
|
||||
return String.format(Locale.US, BUNDLE_URL_FORMAT, getDebugServerHost(), mainModuleName, getDevMode(), getHMR(), getJSMinifyMode());
|
||||
return String.format(Locale.US, BUNDLE_URL_FORMAT, mSettings.getPackagerConnectionSettings().getDebugServerHost(), mainModuleName, getDevMode(), getHMR(), getJSMinifyMode());
|
||||
}
|
||||
|
||||
public String getJSBundleURLForRemoteDebugging(String mainModuleName) {
|
||||
@ -607,7 +578,7 @@ public class DevServerHelper {
|
||||
public @Nullable File downloadBundleResourceFromUrlSync(
|
||||
final String resourcePath,
|
||||
final File outputFile) {
|
||||
final String resourceURL = createResourceURL(getDebugServerHost(), resourcePath);
|
||||
final String resourceURL = createResourceURL(mSettings.getPackagerConnectionSettings().getDebugServerHost(), resourcePath);
|
||||
final Request request = new Request.Builder()
|
||||
.url(resourceURL)
|
||||
.build();
|
||||
|
@ -2,15 +2,33 @@ include_defs("//ReactAndroid/DEFS")
|
||||
|
||||
android_library(
|
||||
name = "systeminfo",
|
||||
srcs = glob(["**/*.java"]),
|
||||
srcs = [
|
||||
"AndroidInfoModule.java",
|
||||
],
|
||||
exported_deps = [
|
||||
":systeminfo-moduleless",
|
||||
],
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
deps = [
|
||||
react_native_dep("third-party/java/infer-annotations:infer-annotations"),
|
||||
react_native_dep("third-party/java/jsr-305:jsr-305"),
|
||||
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/module/annotations:annotations"),
|
||||
],
|
||||
)
|
||||
|
||||
android_library(
|
||||
name = "systeminfo-moduleless",
|
||||
srcs = [
|
||||
"AndroidInfoHelpers.java",
|
||||
],
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
deps = [
|
||||
react_native_dep("third-party/java/infer-annotations:infer-annotations"),
|
||||
react_native_dep("third-party/java/jsr-305:jsr-305"),
|
||||
],
|
||||
)
|
||||
|
@ -13,5 +13,6 @@ android_library(
|
||||
react_native_dep("third-party/java/okhttp:okhttp3"),
|
||||
react_native_dep("third-party/java/okhttp:okhttp3-ws"),
|
||||
react_native_dep("third-party/java/okio:okio"),
|
||||
react_native_target("java/com/facebook/react/modules/systeminfo:systeminfo-moduleless"),
|
||||
],
|
||||
)
|
||||
|
@ -13,7 +13,10 @@ import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.react.modules.systeminfo.AndroidInfoHelpers;
|
||||
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.ResponseBody;
|
||||
@ -26,6 +29,7 @@ import org.json.JSONObject;
|
||||
*/
|
||||
final public class JSPackagerClient implements ReconnectingWebSocket.MessageCallback {
|
||||
private static final String TAG = JSPackagerClient.class.getSimpleName();
|
||||
private static final String PACKAGER_CONNECTION_URL_FORMAT = "ws://%s/message?device=%s&app=%s&context=%s";
|
||||
private static final int PROTOCOL_VERSION = 2;
|
||||
|
||||
public class Responder {
|
||||
@ -83,8 +87,18 @@ final public class JSPackagerClient implements ReconnectingWebSocket.MessageCall
|
||||
private ReconnectingWebSocket mWebSocket;
|
||||
private Map<String, RequestHandler> mRequestHandlers;
|
||||
|
||||
public JSPackagerClient(String url, Map<String, RequestHandler> requestHandlers) {
|
||||
public JSPackagerClient(String clientId, PackagerConnectionSettings settings, Map<String, RequestHandler> requestHandlers) {
|
||||
super();
|
||||
|
||||
Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme("ws")
|
||||
.encodedAuthority(settings.getDebugServerHost())
|
||||
.appendPath("message")
|
||||
.appendQueryParameter("device", AndroidInfoHelpers.getFriendlyDeviceName())
|
||||
.appendQueryParameter("app", settings.getPackageName())
|
||||
.appendQueryParameter("clientid", clientId);
|
||||
String url = builder.build().toString();
|
||||
|
||||
mWebSocket = new ReconnectingWebSocket(url, this);
|
||||
mRequestHandlers = requestHandlers;
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.packagerconnection;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.modules.systeminfo.AndroidInfoHelpers;
|
||||
|
||||
public class PackagerConnectionSettings {
|
||||
private static final String TAG = PackagerConnectionSettings.class.getSimpleName();
|
||||
private static final String PREFS_DEBUG_SERVER_HOST_KEY = "debug_http_host";
|
||||
|
||||
private final SharedPreferences mPreferences;
|
||||
private final String mPackageName;
|
||||
|
||||
public PackagerConnectionSettings(Context applicationContext) {
|
||||
mPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext);
|
||||
mPackageName = applicationContext.getPackageName();
|
||||
}
|
||||
|
||||
public String getDebugServerHost() {
|
||||
// Check host setting first. If empty try to detect emulator type and use default
|
||||
// hostname for those
|
||||
String hostFromSettings = mPreferences.getString(PREFS_DEBUG_SERVER_HOST_KEY, null);
|
||||
|
||||
if (!TextUtils.isEmpty(hostFromSettings)) {
|
||||
return Assertions.assertNotNull(hostFromSettings);
|
||||
}
|
||||
|
||||
String host = AndroidInfoHelpers.getServerHost();
|
||||
|
||||
if (host.equals(AndroidInfoHelpers.DEVICE_LOCALHOST)) {
|
||||
FLog.w(
|
||||
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 host;
|
||||
}
|
||||
|
||||
public @Nullable String getPackageName() {
|
||||
return mPackageName;
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
|
||||
package com.facebook.react.packagerconnection;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@ -32,11 +33,19 @@ public class JSPackagerClientTest {
|
||||
return m;
|
||||
}
|
||||
|
||||
private PackagerConnectionSettings mSettings;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mSettings = mock(PackagerConnectionSettings.class);
|
||||
when(mSettings.getDebugServerHost()).thenReturn("ws://not_needed");
|
||||
when(mSettings.getPackageName()).thenReturn("my_test_package");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_onMessage_ShouldTriggerNotification() throws IOException {
|
||||
JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("ws://not_needed", createRH("methodValue", handler));
|
||||
WebSocket webSocket = mock(WebSocket.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler));
|
||||
|
||||
client.onMessage(
|
||||
ResponseBody.create(
|
||||
@ -49,8 +58,7 @@ public class JSPackagerClientTest {
|
||||
@Test
|
||||
public void test_onMessage_ShouldTriggerRequest() throws IOException {
|
||||
JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("ws://not_needed", createRH("methodValue", handler));
|
||||
WebSocket webSocket = mock(WebSocket.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler));
|
||||
|
||||
client.onMessage(
|
||||
ResponseBody.create(
|
||||
@ -63,8 +71,7 @@ public class JSPackagerClientTest {
|
||||
@Test
|
||||
public void test_onMessage_WithoutParams_ShouldTriggerNotification() throws IOException {
|
||||
JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("ws://not_needed", createRH("methodValue", handler));
|
||||
WebSocket webSocket = mock(WebSocket.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler));
|
||||
|
||||
client.onMessage(
|
||||
ResponseBody.create(
|
||||
@ -77,8 +84,7 @@ public class JSPackagerClientTest {
|
||||
@Test
|
||||
public void test_onMessage_WithInvalidContentType_ShouldNotTriggerCallback() throws IOException {
|
||||
JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("ws://not_needed", createRH("methodValue", handler));
|
||||
WebSocket webSocket = mock(WebSocket.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler));
|
||||
|
||||
client.onMessage(
|
||||
ResponseBody.create(
|
||||
@ -91,8 +97,7 @@ public class JSPackagerClientTest {
|
||||
@Test
|
||||
public void test_onMessage_WithoutMethod_ShouldNotTriggerCallback() throws IOException {
|
||||
JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("ws://not_needed", createRH("methodValue", handler));
|
||||
WebSocket webSocket = mock(WebSocket.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler));
|
||||
|
||||
client.onMessage(
|
||||
ResponseBody.create(
|
||||
@ -105,8 +110,7 @@ public class JSPackagerClientTest {
|
||||
@Test
|
||||
public void test_onMessage_With_Null_Action_ShouldNotTriggerCallback() throws IOException {
|
||||
JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("ws://not_needed", createRH("methodValue", handler));
|
||||
WebSocket webSocket = mock(WebSocket.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler));
|
||||
|
||||
client.onMessage(
|
||||
ResponseBody.create(
|
||||
@ -119,8 +123,7 @@ public class JSPackagerClientTest {
|
||||
@Test
|
||||
public void test_onMessage_WithInvalidMethod_ShouldNotTriggerCallback() throws IOException {
|
||||
JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("ws://not_needed", createRH("methodValue", handler));
|
||||
WebSocket webSocket = mock(WebSocket.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler));
|
||||
|
||||
client.onMessage(
|
||||
ResponseBody.create(
|
||||
@ -133,8 +136,7 @@ public class JSPackagerClientTest {
|
||||
@Test
|
||||
public void test_onMessage_WrongVersion_ShouldNotTriggerCallback() throws IOException {
|
||||
JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("ws://not_needed", createRH("methodValue", handler));
|
||||
WebSocket webSocket = mock(WebSocket.class);
|
||||
final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler));
|
||||
|
||||
client.onMessage(
|
||||
ResponseBody.create(
|
||||
|
@ -130,7 +130,7 @@ function attachToServer(server, path) {
|
||||
result = {};
|
||||
clients.forEach((otherWs, otherId) => {
|
||||
if (clientId !== otherId) {
|
||||
result[otherId] = url.parse(otherWs.upgradeReq.url).query;
|
||||
result[otherId] = url.parse(otherWs.upgradeReq.url, true).query;
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user