Add inspector attach to RN Dev Menu (Android)
Reviewed By: Hypuk Differential Revision: D6405828 fbshipit-source-id: 9274c3e8748e6ce259357836dde7d53c4fce9fbf
This commit is contained in:
parent
de424cc291
commit
7c7108a1e8
|
@ -37,6 +37,11 @@ public class ReactSettingsForTests implements DeveloperSettings {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNuclideJSDebugEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRemoteJSDebugEnabled() {
|
public boolean isRemoteJSDebugEnabled() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -14,6 +14,7 @@ import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import com.facebook.react.common.annotations.VisibleForTesting;
|
import com.facebook.react.common.annotations.VisibleForTesting;
|
||||||
|
import com.facebook.react.common.build.ReactBuildConfig;
|
||||||
import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
|
import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
|
||||||
import com.facebook.react.packagerconnection.PackagerConnectionSettings;
|
import com.facebook.react.packagerconnection.PackagerConnectionSettings;
|
||||||
|
|
||||||
|
@ -124,6 +125,11 @@ public class DevInternalSettings implements
|
||||||
mPreferences.edit().putBoolean(PREFS_JS_BUNDLE_DELTAS_KEY, enabled).apply();
|
mPreferences.edit().putBoolean(PREFS_JS_BUNDLE_DELTAS_KEY, enabled).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNuclideJSDebugEnabled() {
|
||||||
|
return ReactBuildConfig.IS_INTERNAL_BUILD && ReactBuildConfig.DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRemoteJSDebugEnabled() {
|
public boolean isRemoteJSDebugEnabled() {
|
||||||
return mPreferences.getBoolean(PREFS_REMOTE_JS_DEBUG_KEY, false);
|
return mPreferences.getBoolean(PREFS_REMOTE_JS_DEBUG_KEY, false);
|
||||||
|
|
|
@ -12,8 +12,10 @@ package com.facebook.react.devsupport;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.widget.Toast;
|
||||||
import com.facebook.common.logging.FLog;
|
import com.facebook.common.logging.FLog;
|
||||||
import com.facebook.infer.annotation.Assertions;
|
import com.facebook.infer.annotation.Assertions;
|
||||||
|
import com.facebook.react.R;
|
||||||
import com.facebook.react.bridge.UiThreadUtil;
|
import com.facebook.react.bridge.UiThreadUtil;
|
||||||
import com.facebook.react.common.ReactConstants;
|
import com.facebook.react.common.ReactConstants;
|
||||||
import com.facebook.react.common.network.OkHttpCallUtil;
|
import com.facebook.react.common.network.OkHttpCallUtil;
|
||||||
|
@ -73,6 +75,7 @@ public class DevServerHelper {
|
||||||
private static final String PACKAGER_STATUS_URL_FORMAT = "http://%s/status";
|
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 HEAP_CAPTURE_UPLOAD_URL_FORMAT = "http://%s/jscheapcaptureupload";
|
||||||
private static final String INSPECTOR_DEVICE_URL_FORMAT = "http://%s/inspector/device?name=%s&app=%s";
|
private static final String INSPECTOR_DEVICE_URL_FORMAT = "http://%s/inspector/device?name=%s&app=%s";
|
||||||
|
private static final String INSPECTOR_ATTACH_URL_FORMAT = "http://%s/nuclide/attach-debugger-nuclide?title=%s&app=%s&device=%s";
|
||||||
private static final String SYMBOLICATE_URL_FORMAT = "http://%s/symbolicate";
|
private static final String SYMBOLICATE_URL_FORMAT = "http://%s/symbolicate";
|
||||||
private static final String OPEN_STACK_FRAME_URL_FORMAT = "http://%s/open-stack-frame";
|
private static final String OPEN_STACK_FRAME_URL_FORMAT = "http://%s/open-stack-frame";
|
||||||
|
|
||||||
|
@ -224,6 +227,36 @@ public class DevServerHelper {
|
||||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void attachDebugger(final Context context, final String title) {
|
||||||
|
new AsyncTask<Void, String, Boolean>() {
|
||||||
|
@Override
|
||||||
|
protected Boolean doInBackground(Void... ignore) {
|
||||||
|
return doSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean doSync() {
|
||||||
|
try {
|
||||||
|
String attachToNuclideUrl = getInspectorAttachUrl(title);
|
||||||
|
OkHttpClient client = new OkHttpClient();
|
||||||
|
Request request = new Request.Builder().url(attachToNuclideUrl).build();
|
||||||
|
client.newCall(request).execute();
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
FLog.e(ReactConstants.TAG, "Failed to send attach request to Inspector", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
if (!result) {
|
||||||
|
String message = context.getString(R.string.catalyst_debugjs_nuclide_failure);
|
||||||
|
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
public void symbolicateStackTrace(
|
public void symbolicateStackTrace(
|
||||||
Iterable<StackFrame> stackFrames,
|
Iterable<StackFrame> stackFrames,
|
||||||
final SymbolicationListener listener) {
|
final SymbolicationListener listener) {
|
||||||
|
@ -321,6 +354,16 @@ public class DevServerHelper {
|
||||||
mPackageName);
|
mPackageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getInspectorAttachUrl(String title) {
|
||||||
|
return String.format(
|
||||||
|
Locale.US,
|
||||||
|
INSPECTOR_ATTACH_URL_FORMAT,
|
||||||
|
AndroidInfoHelpers.getServerHost(),
|
||||||
|
title,
|
||||||
|
mPackageName,
|
||||||
|
AndroidInfoHelpers.getFriendlyDeviceName());
|
||||||
|
}
|
||||||
|
|
||||||
public BundleDownloader getBundleDownloader() {
|
public BundleDownloader getBundleDownloader() {
|
||||||
return mBundleDownloader;
|
return mBundleDownloader;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,9 @@ public class DevSupportManagerImpl implements
|
||||||
private static final String EXOPACKAGE_LOCATION_FORMAT
|
private static final String EXOPACKAGE_LOCATION_FORMAT
|
||||||
= "/data/local/tmp/exopackage/%s//secondary-dex";
|
= "/data/local/tmp/exopackage/%s//secondary-dex";
|
||||||
|
|
||||||
|
public static final String EMOJI_HUNDRED_POINTS_SYMBOL = " \uD83D\uDCAF";
|
||||||
|
public static final String EMOJI_FACE_WITH_NO_GOOD_GESTURE = " \uD83D\uDE45";
|
||||||
|
|
||||||
private final Context mApplicationContext;
|
private final Context mApplicationContext;
|
||||||
private final ShakeDetector mShakeDetector;
|
private final ShakeDetector mShakeDetector;
|
||||||
private final BroadcastReceiver mReloadAppBroadcastReceiver;
|
private final BroadcastReceiver mReloadAppBroadcastReceiver;
|
||||||
|
@ -395,16 +398,36 @@ public class DevSupportManagerImpl implements
|
||||||
LinkedHashMap<String, DevOptionHandler> options = new LinkedHashMap<>();
|
LinkedHashMap<String, DevOptionHandler> options = new LinkedHashMap<>();
|
||||||
/* register standard options */
|
/* register standard options */
|
||||||
options.put(
|
options.put(
|
||||||
mApplicationContext.getString(R.string.catalyst_reloadjs), new DevOptionHandler() {
|
mApplicationContext.getString(R.string.catalyst_reloadjs),
|
||||||
|
new DevOptionHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onOptionSelected() {
|
public void onOptionSelected() {
|
||||||
handleReloadJS();
|
handleReloadJS();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (mDevSettings.isNuclideJSDebugEnabled()) {
|
||||||
|
// The concatenation is applied directly here because XML isn't emoji-friendly
|
||||||
|
String nuclideJsDebugMenuItemTitle =
|
||||||
|
mApplicationContext.getString(R.string.catalyst_debugjs_nuclide)
|
||||||
|
+ EMOJI_HUNDRED_POINTS_SYMBOL;
|
||||||
|
options.put(
|
||||||
|
nuclideJsDebugMenuItemTitle,
|
||||||
|
new DevOptionHandler() {
|
||||||
|
@Override
|
||||||
|
public void onOptionSelected() {
|
||||||
|
mDevServerHelper.attachDebugger(mApplicationContext, "ReactNative");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
String remoteJsDebugMenuItemTitle =
|
||||||
|
mDevSettings.isRemoteJSDebugEnabled()
|
||||||
|
? mApplicationContext.getString(R.string.catalyst_debugjs_off)
|
||||||
|
: mApplicationContext.getString(R.string.catalyst_debugjs);
|
||||||
|
if (mDevSettings.isNuclideJSDebugEnabled()) {
|
||||||
|
remoteJsDebugMenuItemTitle += EMOJI_FACE_WITH_NO_GOOD_GESTURE;
|
||||||
|
}
|
||||||
options.put(
|
options.put(
|
||||||
mDevSettings.isRemoteJSDebugEnabled() ?
|
remoteJsDebugMenuItemTitle,
|
||||||
mApplicationContext.getString(R.string.catalyst_debugjs_off) :
|
|
||||||
mApplicationContext.getString(R.string.catalyst_debugjs),
|
|
||||||
new DevOptionHandler() {
|
new DevOptionHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onOptionSelected() {
|
public void onOptionSelected() {
|
||||||
|
|
|
@ -39,6 +39,11 @@ public interface DeveloperSettings {
|
||||||
*/
|
*/
|
||||||
boolean isElementInspectorEnabled();
|
boolean isElementInspectorEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Whether Nuclide JS debugging is enabled.
|
||||||
|
*/
|
||||||
|
boolean isNuclideJSDebugEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether remote JS debugging is enabled.
|
* @return Whether remote JS debugging is enabled.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="catalyst_reloadjs" project="catalyst" translatable="false">Reload</string>
|
<string name="catalyst_reloadjs" project="catalyst" translatable="false">Reload</string>
|
||||||
|
<string name="catalyst_debugjs_nuclide" project="catalyst" translatable="false">Debug JS in Nuclide</string>
|
||||||
|
<string name="catalyst_debugjs_nuclide_failure" project="catalyst" translatable="false">The request to attach Nuclide could not reach Metro Bundler!</string>
|
||||||
<string name="catalyst_debugjs" project="catalyst" translatable="false">Debug JS Remotely</string>
|
<string name="catalyst_debugjs" project="catalyst" translatable="false">Debug JS Remotely</string>
|
||||||
<string name="catalyst_debugjs_off" project="catalyst" translatable="false">Stop Remote JS Debugging</string>
|
<string name="catalyst_debugjs_off" project="catalyst" translatable="false">Stop Remote JS Debugging</string>
|
||||||
<string name="catalyst_hot_module_replacement" project="catalyst" translatable="false">Enable Hot Reloading</string>
|
<string name="catalyst_hot_module_replacement" project="catalyst" translatable="false">Enable Hot Reloading</string>
|
||||||
|
|
Loading…
Reference in New Issue