From 1bedcd1f1a08cd930d1fc6ea19cd05ecf1eb8af8 Mon Sep 17 00:00:00 2001 From: Edmond Chui Date: Mon, 5 Feb 2024 14:17:20 -0800 Subject: [PATCH] disable "Open Debugger" menu item if the bundler is disconnected (#42876) Summary: Changelog: [Android][Fixed] Disable the "Open Debugger" item from dev menu if the bundler is disconnected # Existing In our dev menu, the "Open Debugger" menu item is shown even if the packager isn't connected. {F1451833462} # In this PR The "Open Debugger" menu item is disabled when the packager is disconnected with the message "Connect to the bundler to debug JavaScript" {F1451834019} # Reference * Also on iOS: D53354110 Differential Revision: D53428914 --- .../devsupport/DevSupportManagerBase.java | 48 +++++++++++++++++-- .../main/res/devsupport/values/strings.xml | 1 + 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java index 05bd027eaa10fc..1e1c38fd6f2355 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java @@ -23,10 +23,14 @@ import android.util.Pair; import android.view.Gravity; import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.LinearLayout; +import android.widget.ListAdapter; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; import com.facebook.common.logging.FLog; @@ -63,10 +67,12 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; public abstract class DevSupportManagerBase implements DevSupportManager { @@ -104,6 +110,7 @@ public interface CallbackWithBundleLoader { private boolean mIsReceiverRegistered = false; private boolean mIsShakeDetectorStarted = false; private boolean mIsDevSupportEnabled = false; + private boolean mIsPackagerConnected; private @Nullable final RedBoxHandler mRedBoxHandler; private @Nullable String mLastErrorTitle; private @Nullable StackFrame[] mLastErrorStack; @@ -340,6 +347,7 @@ public void showDevOptionsDialog() { return; } LinkedHashMap options = new LinkedHashMap<>(); + Set disabledItemKeys = new HashSet<>(); /* register standard options */ options.put( mApplicationContext.getString(R.string.catalyst_reload), @@ -369,8 +377,15 @@ public void onOptionSelected() { if (mDevSettings.isDeviceDebugEnabled() && !mDevSettings.isRemoteJSDebugEnabled()) { // On-device JS debugging (CDP). Render action to open debugger frontend. + boolean isConnected = mIsPackagerConnected; + String debuggerItemString = + mApplicationContext.getString( + isConnected ? R.string.catalyst_debug_open : R.string.catalyst_debug_open_disabled); + if (!isConnected) { + disabledItemKeys.add(debuggerItemString); + } options.put( - mApplicationContext.getString(R.string.catalyst_debug_open), + debuggerItemString, () -> mDevServerHelper.openDebugger( mCurrentContext, @@ -505,11 +520,34 @@ public void onOptionSelected() { header.addView(jsExecutorLabel); } + ListAdapter adapter = + new ArrayAdapter( + context, android.R.layout.simple_list_item_1, options.keySet().toArray(new String[0])) { + @Override + public boolean areAllItemsEnabled() { + return false; + } + + @Override + public boolean isEnabled(int position) { + return !disabledItemKeys.contains(getItem(position)); + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + View view = super.getView(position, convertView, parent); + view.setEnabled(isEnabled(position)); + + return view; + } + }; + mDevOptionsDialog = new AlertDialog.Builder(context) .setCustomTitle(header) - .setItems( - options.keySet().toArray(new String[0]), + .setAdapter( + adapter, (dialog, which) -> { optionHandlers[which].onOptionSelected(); mDevOptionsDialog = null; @@ -1022,12 +1060,12 @@ private void reload() { new PackagerCommandListener() { @Override public void onPackagerConnected() { - // No-op + mIsPackagerConnected = true; } @Override public void onPackagerDisconnected() { - // No-op + mIsPackagerConnected = false; } @Override diff --git a/packages/react-native/ReactAndroid/src/main/res/devsupport/values/strings.xml b/packages/react-native/ReactAndroid/src/main/res/devsupport/values/strings.xml index bc89201b956550..7065f16c0b19f8 100644 --- a/packages/react-native/ReactAndroid/src/main/res/devsupport/values/strings.xml +++ b/packages/react-native/ReactAndroid/src/main/res/devsupport/values/strings.xml @@ -5,6 +5,7 @@ Change Bundle Location Failed to open debugger. Please check that the dev server is running and reload the app. Open Debugger + Connect to the bundler to debug JavaScript Connecting to debugger... Failed to connect to debugger! Enable Fast Refresh