diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 4fe7fc8edb4708..e9f3254c9efb19 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2091,7 +2091,7 @@ public abstract interface class com/facebook/react/devsupport/DevServerHelper$Pa public abstract fun onPackagerReloadCommand ()V } -public class com/facebook/react/devsupport/DevSettingsActivity : android/preference/PreferenceActivity { +public final class com/facebook/react/devsupport/DevSettingsActivity : android/preference/PreferenceActivity { public fun ()V public fun onCreate (Landroid/os/Bundle;)V } @@ -3165,7 +3165,7 @@ public final class com/facebook/react/modules/core/TimingModule : com/facebook/f public fun setSendIdleEvents (Z)V } -public class com/facebook/react/modules/debug/DevSettingsModule : com/facebook/fbreact/specs/NativeDevSettingsSpec { +public final class com/facebook/react/modules/debug/DevSettingsModule : com/facebook/fbreact/specs/NativeDevSettingsSpec { public fun (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/react/devsupport/interfaces/DevSupportManager;)V public fun addListener (Ljava/lang/String;)V public fun addMenuItem (Ljava/lang/String;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.java deleted file mode 100644 index 32ff198161f11d..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.devsupport; - -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.common.build.ReactBuildConfig; -import com.facebook.react.modules.debug.interfaces.DeveloperSettings; -import com.facebook.react.packagerconnection.PackagerConnectionSettings; - -/** - * Helper class for accessing developers settings that can not be accessed outside of the package - * {@link com.facebook.react.devsupport}. For accessing some of the settings by external modules - * this class implements an external interface {@link DeveloperSettings}. - */ -@Nullsafe(Nullsafe.Mode.LOCAL) -class DevInternalSettings - implements DeveloperSettings, SharedPreferences.OnSharedPreferenceChangeListener { - - private static final String PREFS_FPS_DEBUG_KEY = "fps_debug"; - private static final String PREFS_JS_DEV_MODE_DEBUG_KEY = "js_dev_mode_debug"; - private static final String PREFS_JS_MINIFY_DEBUG_KEY = "js_minify_debug"; - private static final String PREFS_ANIMATIONS_DEBUG_KEY = "animations_debug"; - private static final String PREFS_INSPECTOR_DEBUG_KEY = "inspector_debug"; - private static final String PREFS_HOT_MODULE_REPLACEMENT_KEY = "hot_module_replacement"; - private static final String PREFS_REMOTE_JS_DEBUG_KEY = "remote_js_debug"; - private static final String PREFS_START_SAMPLING_PROFILER_ON_INIT = - "start_sampling_profiler_on_init"; - - private final SharedPreferences mPreferences; - private final Listener mListener; - private final PackagerConnectionSettings mPackagerConnectionSettings; - - public DevInternalSettings(Context applicationContext, Listener listener) { - mListener = listener; - mPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext); - mPreferences.registerOnSharedPreferenceChangeListener(this); - mPackagerConnectionSettings = new PackagerConnectionSettings(applicationContext); - } - - @Override - public boolean isFpsDebugEnabled() { - return mPreferences.getBoolean(PREFS_FPS_DEBUG_KEY, false); - } - - @Override - public boolean isAnimationFpsDebugEnabled() { - return mPreferences.getBoolean(PREFS_ANIMATIONS_DEBUG_KEY, false); - } - - @Override - public boolean isJSDevModeEnabled() { - return mPreferences.getBoolean(PREFS_JS_DEV_MODE_DEBUG_KEY, true); - } - - @Override - public boolean isJSMinifyEnabled() { - return mPreferences.getBoolean(PREFS_JS_MINIFY_DEBUG_KEY, false); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (mListener != null) { - if (PREFS_FPS_DEBUG_KEY.equals(key) - || PREFS_JS_DEV_MODE_DEBUG_KEY.equals(key) - || PREFS_START_SAMPLING_PROFILER_ON_INIT.equals(key) - || PREFS_JS_MINIFY_DEBUG_KEY.equals(key)) { - mListener.onInternalSettingsChanged(); - } - } - } - - @Override - public boolean isElementInspectorEnabled() { - return mPreferences.getBoolean(PREFS_INSPECTOR_DEBUG_KEY, false); - } - - @Override - public boolean isDeviceDebugEnabled() { - return ReactBuildConfig.DEBUG; - } - - @Override - public boolean isRemoteJSDebugEnabled() { - return mPreferences.getBoolean(PREFS_REMOTE_JS_DEBUG_KEY, false); - } - - @Override - public void setRemoteJSDebugEnabled(boolean remoteJSDebugEnabled) { - mPreferences.edit().putBoolean(PREFS_REMOTE_JS_DEBUG_KEY, remoteJSDebugEnabled).apply(); - } - - @Override - public boolean isStartSamplingProfilerOnInit() { - return mPreferences.getBoolean(PREFS_START_SAMPLING_PROFILER_ON_INIT, false); - } - - @Override - public void addMenuItem(String title) { - // Not supported. - } - - void setElementInspectorEnabled(boolean enabled) { - mPreferences.edit().putBoolean(PREFS_INSPECTOR_DEBUG_KEY, enabled).apply(); - } - - boolean isHotModuleReplacementEnabled() { - return mPreferences.getBoolean(PREFS_HOT_MODULE_REPLACEMENT_KEY, true); - } - - void setHotModuleReplacementEnabled(boolean enabled) { - mPreferences.edit().putBoolean(PREFS_HOT_MODULE_REPLACEMENT_KEY, enabled).apply(); - } - - void setJSDevModeEnabled(boolean value) { - mPreferences.edit().putBoolean(PREFS_JS_DEV_MODE_DEBUG_KEY, value).apply(); - } - - void setFpsDebugEnabled(boolean enabled) { - mPreferences.edit().putBoolean(PREFS_FPS_DEBUG_KEY, enabled).apply(); - } - - PackagerConnectionSettings getPackagerConnectionSettings() { - return mPackagerConnectionSettings; - } - - public interface Listener { - void onInternalSettingsChanged(); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.kt new file mode 100644 index 00000000000000..e2cfecf5a81fbc --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.kt @@ -0,0 +1,108 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +@file:Suppress("DEPRECATION") + +package com.facebook.react.devsupport + +import android.content.Context +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import android.preference.PreferenceManager +import com.facebook.react.common.build.ReactBuildConfig +import com.facebook.react.modules.debug.interfaces.DeveloperSettings +import com.facebook.react.packagerconnection.PackagerConnectionSettings + +/** + * Helper class for accessing developers settings that can not be accessed outside of the package + * [com.facebook.react.devsupport]. For accessing some of the settings by external modules this + * class implements an external interface [DeveloperSettings]. + */ +internal class DevInternalSettings(applicationContext: Context, private val listener: Listener?) : + DeveloperSettings, OnSharedPreferenceChangeListener { + private val preferences: SharedPreferences = + PreferenceManager.getDefaultSharedPreferences(applicationContext) + val packagerConnectionSettings: PackagerConnectionSettings + + init { + preferences.registerOnSharedPreferenceChangeListener(this) + packagerConnectionSettings = PackagerConnectionSettings(applicationContext) + } + + override fun isFpsDebugEnabled(): Boolean = preferences.getBoolean(PREFS_FPS_DEBUG_KEY, false) + + override fun isAnimationFpsDebugEnabled(): Boolean = + preferences.getBoolean(PREFS_ANIMATIONS_DEBUG_KEY, false) + + override fun isJSDevModeEnabled(): Boolean = + preferences.getBoolean(PREFS_JS_DEV_MODE_DEBUG_KEY, true) + + override fun isJSMinifyEnabled(): Boolean = + preferences.getBoolean(PREFS_JS_MINIFY_DEBUG_KEY, false) + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) { + if (listener != null) { + if (PREFS_FPS_DEBUG_KEY == key || + PREFS_JS_DEV_MODE_DEBUG_KEY == key || + PREFS_START_SAMPLING_PROFILER_ON_INIT == key || + PREFS_JS_MINIFY_DEBUG_KEY == key) { + listener.onInternalSettingsChanged() + } + } + } + + override fun isElementInspectorEnabled(): Boolean = + preferences.getBoolean(PREFS_INSPECTOR_DEBUG_KEY, false) + + override fun isDeviceDebugEnabled(): Boolean = ReactBuildConfig.DEBUG + + override fun isRemoteJSDebugEnabled(): Boolean = + preferences.getBoolean(PREFS_REMOTE_JS_DEBUG_KEY, false) + + override fun setRemoteJSDebugEnabled(remoteJSDebugEnabled: Boolean) { + preferences.edit().putBoolean(PREFS_REMOTE_JS_DEBUG_KEY, remoteJSDebugEnabled).apply() + } + + override fun isStartSamplingProfilerOnInit(): Boolean = + preferences.getBoolean(PREFS_START_SAMPLING_PROFILER_ON_INIT, false) + + // Not supported. + override fun addMenuItem(title: String) = Unit + + fun setElementInspectorEnabled(enabled: Boolean) { + preferences.edit().putBoolean(PREFS_INSPECTOR_DEBUG_KEY, enabled).apply() + } + + var isHotModuleReplacementEnabled: Boolean + get() = preferences.getBoolean(PREFS_HOT_MODULE_REPLACEMENT_KEY, true) + set(enabled) { + preferences.edit().putBoolean(PREFS_HOT_MODULE_REPLACEMENT_KEY, enabled).apply() + } + + fun setJSDevModeEnabled(value: Boolean) { + preferences.edit().putBoolean(PREFS_JS_DEV_MODE_DEBUG_KEY, value).apply() + } + + fun setFpsDebugEnabled(enabled: Boolean) { + preferences.edit().putBoolean(PREFS_FPS_DEBUG_KEY, enabled).apply() + } + + interface Listener { + fun onInternalSettingsChanged() + } + + companion object { + private const val PREFS_FPS_DEBUG_KEY = "fps_debug" + private const val PREFS_JS_DEV_MODE_DEBUG_KEY = "js_dev_mode_debug" + private const val PREFS_JS_MINIFY_DEBUG_KEY = "js_minify_debug" + private const val PREFS_ANIMATIONS_DEBUG_KEY = "animations_debug" + private const val PREFS_INSPECTOR_DEBUG_KEY = "inspector_debug" + private const val PREFS_HOT_MODULE_REPLACEMENT_KEY = "hot_module_replacement" + private const val PREFS_REMOTE_JS_DEBUG_KEY = "remote_js_debug" + private const val PREFS_START_SAMPLING_PROFILER_ON_INIT = "start_sampling_profiler_on_init" + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSettingsActivity.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSettingsActivity.java deleted file mode 100644 index d6a5b314c54d50..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSettingsActivity.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.devsupport; - -import android.os.Bundle; -import android.preference.PreferenceActivity; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.R; - -/** - * Activity that display developers settings. Should be added to the debug manifest of the app. Can - * be triggered through the developers option menu displayed by {@link DevSupportManager}. - */ -@Nullsafe(Nullsafe.Mode.LOCAL) -public class DevSettingsActivity extends PreferenceActivity { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setTitle(getApplication().getResources().getString(R.string.catalyst_settings_title)); - addPreferencesFromResource(R.xml.rn_dev_preferences); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSettingsActivity.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSettingsActivity.kt new file mode 100644 index 00000000000000..f19f7b52d439e0 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSettingsActivity.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +@file:Suppress("DEPRECATION") + +package com.facebook.react.devsupport + +import android.os.Bundle +import android.preference.PreferenceActivity +import com.facebook.react.R + +/** + * Activity that display developers settings. Should be added to the debug manifest of the app. Can + * be triggered through the developers option menu displayed by [DevSupportManager]. + */ +public class DevSettingsActivity : PreferenceActivity() { + public override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + title = application.resources.getString(R.string.catalyst_settings_title) + addPreferencesFromResource(R.xml.rn_dev_preferences) + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.java deleted file mode 100644 index ede03d57abe124..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.modules.debug; - -import com.facebook.fbreact.specs.NativeDevSettingsSpec; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.UiThreadUtil; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.devsupport.interfaces.DevOptionHandler; -import com.facebook.react.devsupport.interfaces.DevSupportManager; -import com.facebook.react.module.annotations.ReactModule; - -/** - * Module that exposes the URL to the source code map (used for exception stack trace parsing) to JS - */ -@ReactModule(name = NativeDevSettingsSpec.NAME) -public class DevSettingsModule extends NativeDevSettingsSpec { - - private final DevSupportManager mDevSupportManager; - - public DevSettingsModule( - ReactApplicationContext reactContext, DevSupportManager devSupportManager) { - super(reactContext); - - mDevSupportManager = devSupportManager; - } - - @Override - public void reload() { - if (mDevSupportManager.getDevSupportEnabled()) { - UiThreadUtil.runOnUiThread( - new Runnable() { - @Override - public void run() { - mDevSupportManager.handleReloadJS(); - } - }); - } - } - - @Override - public void reloadWithReason(String reason) { - this.reload(); - } - - @Override - public void onFastRefresh() { - // noop - } - - @Override - public void setHotLoadingEnabled(boolean isHotLoadingEnabled) { - mDevSupportManager.setHotModuleReplacementEnabled(isHotLoadingEnabled); - } - - @Override - public void setIsDebuggingRemotely(boolean isDebugginRemotelyEnabled) { - mDevSupportManager.setRemoteJSDebugEnabled(isDebugginRemotelyEnabled); - } - - @Override - public void setProfilingEnabled(boolean isProfilingEnabled) { - mDevSupportManager.setFpsDebugEnabled(isProfilingEnabled); - } - - @Override - public void toggleElementInspector() { - mDevSupportManager.toggleElementInspector(); - } - - @Override - public void addMenuItem(final String title) { - mDevSupportManager.addCustomDevOption( - title, - new DevOptionHandler() { - @Override - public void onOptionSelected() { - WritableMap data = Arguments.createMap(); - data.putString("title", title); - - ReactApplicationContext reactApplicationContext = - getReactApplicationContextIfActiveOrWarn(); - - if (reactApplicationContext != null) { - reactApplicationContext.emitDeviceEvent("didPressMenuItem", data); - } - } - }); - } - - @Override - public void setIsShakeToShowDevMenuEnabled(boolean enabled) { - // iOS only - } - - @Override - public void addListener(String eventName) { - // iOS only - } - - @Override - public void removeListeners(double count) { - // iOS only - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.kt new file mode 100644 index 00000000000000..258f8042c5fec1 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DevSettingsModule.kt @@ -0,0 +1,75 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.modules.debug + +import com.facebook.fbreact.specs.NativeDevSettingsSpec +import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.UiThreadUtil +import com.facebook.react.devsupport.interfaces.DevSupportManager +import com.facebook.react.module.annotations.ReactModule + +/** + * Module that exposes the URL to the source code map (used for exception stack trace parsing) to JS + */ +@ReactModule(name = NativeDevSettingsSpec.NAME) +public class DevSettingsModule( + reactContext: ReactApplicationContext?, + private val devSupportManager: DevSupportManager +) : NativeDevSettingsSpec(reactContext) { + override fun reload() { + if (devSupportManager.devSupportEnabled) { + UiThreadUtil.runOnUiThread { devSupportManager.handleReloadJS() } + } + } + + override fun reloadWithReason(reason: String) { + reload() + } + + override fun onFastRefresh() { + // noop + } + + override fun setHotLoadingEnabled(isHotLoadingEnabled: Boolean) { + devSupportManager.setHotModuleReplacementEnabled(isHotLoadingEnabled) + } + + override fun setIsDebuggingRemotely(isDebugginRemotelyEnabled: Boolean) { + devSupportManager.setRemoteJSDebugEnabled(isDebugginRemotelyEnabled) + } + + override fun setProfilingEnabled(isProfilingEnabled: Boolean) { + devSupportManager.setFpsDebugEnabled(isProfilingEnabled) + } + + override fun toggleElementInspector() { + devSupportManager.toggleElementInspector() + } + + override fun addMenuItem(title: String) { + devSupportManager.addCustomDevOption(title) { + val data = Arguments.createMap() + data.putString("title", title) + val reactApplicationContext = reactApplicationContextIfActiveOrWarn + reactApplicationContext?.emitDeviceEvent("didPressMenuItem", data) + } + } + + override fun setIsShakeToShowDevMenuEnabled(enabled: Boolean) { + // iOS only + } + + override fun addListener(eventName: String) { + // iOS only + } + + override fun removeListeners(count: Double) { + // iOS only + } +}