Skip to content

Commit

Permalink
Add inspector attach to RN Dev Menu (Android)
Browse files Browse the repository at this point in the history
Reviewed By: Hypuk

Differential Revision: D6405828

fbshipit-source-id: 9274c3e8748e6ce259357836dde7d53c4fce9fbf
  • Loading branch information
pakoito authored and facebook-github-bot committed Dec 5, 2017
1 parent de424cc commit 7c7108a
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public boolean isElementInspectorEnabled() {
return false;
}

@Override
public boolean isNuclideJSDebugEnabled() {
return false;
}

@Override
public boolean isRemoteJSDebugEnabled() {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
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.packagerconnection.PackagerConnectionSettings;

Expand Down Expand Up @@ -124,6 +125,11 @@ public void setBundleDeltasEnabled(boolean enabled) {
mPreferences.edit().putBoolean(PREFS_JS_BUNDLE_DELTAS_KEY, enabled).apply();
}

@Override
public boolean isNuclideJSDebugEnabled() {
return ReactBuildConfig.IS_INTERNAL_BUILD && ReactBuildConfig.DEBUG;
}

@Override
public boolean isRemoteJSDebugEnabled() {
return mPreferences.getBoolean(PREFS_REMOTE_JS_DEBUG_KEY, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.widget.Toast;
import com.facebook.common.logging.FLog;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.R;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.network.OkHttpCallUtil;
Expand Down Expand Up @@ -73,6 +75,7 @@ public class 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&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 OPEN_STACK_FRAME_URL_FORMAT = "http://%s/open-stack-frame";

Expand Down Expand Up @@ -224,6 +227,36 @@ protected Void doInBackground(Void... params) {
}.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(
Iterable<StackFrame> stackFrames,
final SymbolicationListener listener) {
Expand Down Expand Up @@ -321,6 +354,16 @@ public String getInspectorDeviceUrl() {
mPackageName);
}

public String getInspectorAttachUrl(String title) {
return String.format(
Locale.US,
INSPECTOR_ATTACH_URL_FORMAT,
AndroidInfoHelpers.getServerHost(),
title,
mPackageName,
AndroidInfoHelpers.getFriendlyDeviceName());
}

public BundleDownloader getBundleDownloader() {
return mBundleDownloader;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ private static enum ErrorType {
private static final String EXOPACKAGE_LOCATION_FORMAT
= "/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 ShakeDetector mShakeDetector;
private final BroadcastReceiver mReloadAppBroadcastReceiver;
Expand Down Expand Up @@ -395,16 +398,36 @@ public void showDevOptionsDialog() {
LinkedHashMap<String, DevOptionHandler> options = new LinkedHashMap<>();
/* register standard options */
options.put(
mApplicationContext.getString(R.string.catalyst_reloadjs), new DevOptionHandler() {
mApplicationContext.getString(R.string.catalyst_reloadjs),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
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(
mDevSettings.isRemoteJSDebugEnabled() ?
mApplicationContext.getString(R.string.catalyst_debugjs_off) :
mApplicationContext.getString(R.string.catalyst_debugjs),
remoteJsDebugMenuItemTitle,
new DevOptionHandler() {
@Override
public void onOptionSelected() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public interface DeveloperSettings {
*/
boolean isElementInspectorEnabled();

/**
* @return Whether Nuclide JS debugging is enabled.
*/
boolean isNuclideJSDebugEnabled();

/**
* @return Whether remote JS debugging is enabled.
*/
Expand Down
2 changes: 2 additions & 0 deletions ReactAndroid/src/main/res/devsupport/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<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_off" project="catalyst" translatable="false">Stop Remote JS Debugging</string>
<string name="catalyst_hot_module_replacement" project="catalyst" translatable="false">Enable Hot Reloading</string>
Expand Down

0 comments on commit 7c7108a

Please sign in to comment.