public void showDevOptionsDialog()

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);
    }
  }