in ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java [373:583]
public void showDevOptionsDialog() {
if (mDevOptionsDialog != null || !mIsDevSupportEnabled || ActivityManager.isUserAMonkey()) {
return;
}
LinkedHashMap<String, DevOptionHandler> options = new LinkedHashMap<>();
/* register standard options */
options.put(
mApplicationContext.getString(R.string.catalyst_reload),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
if (!mDevSettings.isJSDevModeEnabled()
&& mDevSettings.isHotModuleReplacementEnabled()) {
Toast.makeText(
mApplicationContext,
mApplicationContext.getString(R.string.catalyst_hot_reloading_auto_disable),
Toast.LENGTH_LONG)
.show();
mDevSettings.setHotModuleReplacementEnabled(false);
}
handleReloadJS();
}
});
if (mDevSettings.isDeviceDebugEnabled()) {
// For on-device debugging we link out to Flipper.
// Since we're assuming Flipper is available, also include the DevTools.
// Reset the old debugger setting so no one gets stuck.
// TODO: Remove in a few weeks.
if (mDevSettings.isRemoteJSDebugEnabled()) {
mDevSettings.setRemoteJSDebugEnabled(false);
handleReloadJS();
}
options.put(
mApplicationContext.getString(R.string.catalyst_debug_open),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
mDevServerHelper.openUrl(
mCurrentContext,
FLIPPER_DEBUGGER_URL,
mApplicationContext.getString(R.string.catalyst_open_flipper_error));
}
});
options.put(
mApplicationContext.getString(R.string.catalyst_devtools_open),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
mDevServerHelper.openUrl(
mCurrentContext,
FLIPPER_DEVTOOLS_URL,
mApplicationContext.getString(R.string.catalyst_open_flipper_error));
}
});
}
options.put(
mApplicationContext.getString(R.string.catalyst_change_bundle_location),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
Activity context = mReactInstanceDevHelper.getCurrentActivity();
if (context == null || context.isFinishing()) {
FLog.e(
ReactConstants.TAG,
"Unable to launch change bundle location because react activity is not available");
return;
}
final EditText input = new EditText(context);
input.setHint("localhost:8081");
AlertDialog bundleLocationDialog =
new AlertDialog.Builder(context)
.setTitle(
mApplicationContext.getString(R.string.catalyst_change_bundle_location))
.setView(input)
.setPositiveButton(
android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String host = input.getText().toString();
mDevSettings.getPackagerConnectionSettings().setDebugServerHost(host);
handleReloadJS();
}
})
.create();
bundleLocationDialog.show();
}
});
options.put(
mDevSettings.isElementInspectorEnabled()
? mApplicationContext.getString(R.string.catalyst_inspector_stop)
: mApplicationContext.getString(R.string.catalyst_inspector),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
mDevSettings.setElementInspectorEnabled(!mDevSettings.isElementInspectorEnabled());
mReactInstanceDevHelper.toggleElementInspector();
}
});
options.put(
mDevSettings.isHotModuleReplacementEnabled()
? mApplicationContext.getString(R.string.catalyst_hot_reloading_stop)
: mApplicationContext.getString(R.string.catalyst_hot_reloading),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
boolean nextEnabled = !mDevSettings.isHotModuleReplacementEnabled();
mDevSettings.setHotModuleReplacementEnabled(nextEnabled);
if (mCurrentContext != null) {
if (nextEnabled) {
mCurrentContext.getJSModule(HMRClient.class).enable();
} else {
mCurrentContext.getJSModule(HMRClient.class).disable();
}
}
if (nextEnabled && !mDevSettings.isJSDevModeEnabled()) {
Toast.makeText(
mApplicationContext,
mApplicationContext.getString(R.string.catalyst_hot_reloading_auto_enable),
Toast.LENGTH_LONG)
.show();
mDevSettings.setJSDevModeEnabled(true);
handleReloadJS();
}
}
});
options.put(
mDevSettings.isFpsDebugEnabled()
? mApplicationContext.getString(R.string.catalyst_perf_monitor_stop)
: mApplicationContext.getString(R.string.catalyst_perf_monitor),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
if (!mDevSettings.isFpsDebugEnabled()) {
// Request overlay permission if needed when "Show Perf Monitor" option is selected
Context context = mReactInstanceDevHelper.getCurrentActivity();
if (context == null) {
FLog.e(ReactConstants.TAG, "Unable to get reference to react activity");
} else {
DebugOverlayController.requestPermission(context);
}
}
mDevSettings.setFpsDebugEnabled(!mDevSettings.isFpsDebugEnabled());
}
});
options.put(
mApplicationContext.getString(R.string.catalyst_settings),
new DevOptionHandler() {
@Override
public void onOptionSelected() {
Intent intent = new Intent(mApplicationContext, DevSettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mApplicationContext.startActivity(intent);
}
});
if (mCustomDevOptions.size() > 0) {
options.putAll(mCustomDevOptions);
}
final DevOptionHandler[] optionHandlers = options.values().toArray(new DevOptionHandler[0]);
Activity context = mReactInstanceDevHelper.getCurrentActivity();
if (context == null || context.isFinishing()) {
FLog.e(
ReactConstants.TAG,
"Unable to launch dev options menu because react activity " + "isn't available");
return;
}
final TextView textView = new TextView(getApplicationContext());
textView.setText("React Native DevMenu (" + getUniqueTag() + ")");
textView.setPadding(0, 50, 0, 0);
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Color.BLACK);
textView.setTextSize(17);
textView.setTypeface(textView.getTypeface(), Typeface.BOLD);
mDevOptionsDialog =
new AlertDialog.Builder(context)
.setCustomTitle(textView)
.setItems(
options.keySet().toArray(new String[0]),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
optionHandlers[which].onOptionSelected();
mDevOptionsDialog = null;
}
})
.setOnCancelListener(
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
mDevOptionsDialog = null;
}
})
.create();
mDevOptionsDialog.show();
if (mCurrentContext != null) {
mCurrentContext.getJSModule(RCTNativeAppEventEmitter.class).emit("RCTDevMenuShown", null);
}
}