diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactSettingsForTests.java b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactSettingsForTests.java index 511c7f97620..7bc6c231147 100644 --- a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactSettingsForTests.java +++ b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactSettingsForTests.java @@ -47,4 +47,9 @@ public class ReactSettingsForTests implements DeveloperSettings { @Override public void setRemoteJSDebugEnabled(boolean remoteJSDebugEnabled) {} + + @Override + public boolean isStartSamplingProfilerOnInit() { + return false; + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.java index 59b9837e573..c4a48a4281b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevInternalSettings.java @@ -36,7 +36,8 @@ public class DevInternalSettings 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_SAMPLING_PROFILER_ENABLED = "sampling_profiler_enabled"; + private static final String PREFS_START_SAMPLING_PROFILER_ON_INIT = + "start_sampling_profiler_on_init"; private final SharedPreferences mPreferences; private final Listener mListener; @@ -100,6 +101,7 @@ public class DevInternalSettings || PREFS_JS_DEV_MODE_DEBUG_KEY.equals(key) || PREFS_JS_BUNDLE_DELTAS_KEY.equals(key) || PREFS_JS_BUNDLE_DELTAS_CPP_KEY.equals(key) + || PREFS_START_SAMPLING_PROFILER_ON_INIT.equals(key) || PREFS_JS_MINIFY_DEBUG_KEY.equals(key)) { mListener.onInternalSettingsChanged(); } @@ -166,6 +168,11 @@ public class DevInternalSettings mPreferences.edit().putBoolean(PREFS_REMOTE_JS_DEBUG_KEY, remoteJSDebugEnabled).apply(); } + @Override + public boolean isStartSamplingProfilerOnInit() { + return mPreferences.getBoolean(PREFS_START_SAMPLING_PROFILER_ON_INIT, false); + } + public interface Listener { void onInternalSettingsChanged(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java index 07d88559218..70b3eb954d0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java @@ -96,8 +96,6 @@ public class DevSupportManagerImpl private static final int JSEXCEPTION_ERROR_COOKIE = -1; private static final String JS_BUNDLE_FILE_NAME = "ReactNativeDevBundle.js"; private static final String RELOAD_APP_ACTION_SUFFIX = ".RELOAD_APP_ACTION"; - private static final String ENABLE_SAMPLING_PROFILER = ".ENABLE_SAMPLING_PROFILER"; - private static final String DISABLE_SAMPLING_PROFILER = ".DISABLE_SAMPLING_PROFILER"; private boolean mIsSamplingProfilerEnabled = false; private enum ErrorType { @@ -236,6 +234,19 @@ public class DevSupportManagerImpl new DevLoadingViewController(applicationContext, reactInstanceManagerHelper); mExceptionLoggers.add(new JSExceptionLogger()); + + if (mDevSettings.isStartSamplingProfilerOnInit()) { + // Only start the profiler. If its already running, there is an error + if (!mIsSamplingProfilerEnabled) { + toggleJSSamplingProfiler(); + } else { + Toast.makeText( + mApplicationContext, + "JS Sampling Profiler was already running, so did not start the sampling profiler", + Toast.LENGTH_LONG) + .show(); + } + } } @Override @@ -537,6 +548,7 @@ public class DevSupportManagerImpl } } }); + options.put( mIsSamplingProfilerEnabled ? mApplicationContext.getString(R.string.catalyst_sample_profiler_disable) @@ -544,49 +556,7 @@ public class DevSupportManagerImpl new DevOptionHandler() { @Override public void onOptionSelected() { - JavaScriptExecutorFactory javaScriptExecutorFactory = - mReactInstanceManagerHelper.getJavaScriptExecutorFactory(); - if (!mIsSamplingProfilerEnabled) { - try { - javaScriptExecutorFactory.startSamplingProfiler(); - Toast.makeText( - mApplicationContext, "Starting Sampling Profiler", Toast.LENGTH_SHORT) - .show(); - } catch (UnsupportedOperationException e) { - Toast.makeText( - mApplicationContext, - javaScriptExecutorFactory.toString() - + " does not support Sampling Profiler", - Toast.LENGTH_LONG) - .show(); - } - } else { - try { - final String outputPath = - File.createTempFile( - "sampling-profiler-trace", - ".cpuprofile", - mApplicationContext.getCacheDir()) - .getPath(); - javaScriptExecutorFactory.stopSamplingProfiler(outputPath); - Toast.makeText( - mApplicationContext, - "Saved results from Profiler to " + outputPath, - Toast.LENGTH_LONG) - .show(); - } catch (IOException e) { - FLog.e( - ReactConstants.TAG, - "Could not create temporary file for saving results from Sampling Profiler"); - } catch (UnsupportedOperationException e) { - Toast.makeText( - mApplicationContext, - javaScriptExecutorFactory.toString() + "does not support Sampling Profiler", - Toast.LENGTH_LONG) - .show(); - } - } - mIsSamplingProfilerEnabled = !mIsSamplingProfilerEnabled; + toggleJSSamplingProfiler(); } }); @@ -655,6 +625,52 @@ public class DevSupportManagerImpl mDevOptionsDialog.show(); } + /** Starts of stops the sampling profiler */ + private void toggleJSSamplingProfiler() { + JavaScriptExecutorFactory javaScriptExecutorFactory = + mReactInstanceManagerHelper.getJavaScriptExecutorFactory(); + if (!mIsSamplingProfilerEnabled) { + try { + javaScriptExecutorFactory.startSamplingProfiler(); + Toast.makeText(mApplicationContext, "Starting Sampling Profiler", Toast.LENGTH_SHORT) + .show(); + } catch (UnsupportedOperationException e) { + Toast.makeText( + mApplicationContext, + javaScriptExecutorFactory.toString() + " does not support Sampling Profiler", + Toast.LENGTH_LONG) + .show(); + } finally { + mIsSamplingProfilerEnabled = true; + } + } else { + try { + final String outputPath = + File.createTempFile( + "sampling-profiler-trace", ".cpuprofile", mApplicationContext.getCacheDir()) + .getPath(); + javaScriptExecutorFactory.stopSamplingProfiler(outputPath); + Toast.makeText( + mApplicationContext, + "Saved results from Profiler to " + outputPath, + Toast.LENGTH_LONG) + .show(); + } catch (IOException e) { + FLog.e( + ReactConstants.TAG, + "Could not create temporary file for saving results from Sampling Profiler"); + } catch (UnsupportedOperationException e) { + Toast.makeText( + mApplicationContext, + javaScriptExecutorFactory.toString() + "does not support Sampling Profiler", + Toast.LENGTH_LONG) + .show(); + } finally { + mIsSamplingProfilerEnabled = false; + } + } + } + /** * {@link ReactInstanceDevCommandsHandler} is responsible for enabling/disabling dev support when * a React view is attached/detached or when application state changes (e.g. the application is diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/debug/interfaces/DeveloperSettings.java b/ReactAndroid/src/main/java/com/facebook/react/modules/debug/interfaces/DeveloperSettings.java index faa91e4f79a..934e5dad60f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/debug/interfaces/DeveloperSettings.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/debug/interfaces/DeveloperSettings.java @@ -32,4 +32,7 @@ public interface DeveloperSettings { /** Enable/Disable remote JS debugging. */ void setRemoteJSDebugEnabled(boolean remoteJSDebugEnabled); + + /** @return Whether Start Sampling Profiler on App Start is enabled. */ + boolean isStartSamplingProfilerOnInit(); } diff --git a/ReactAndroid/src/main/res/devsupport/xml/rn_dev_preferences.xml b/ReactAndroid/src/main/res/devsupport/xml/rn_dev_preferences.xml index 6208e4e8802..1c03b0ca9d3 100644 --- a/ReactAndroid/src/main/res/devsupport/xml/rn_dev_preferences.xml +++ b/ReactAndroid/src/main/res/devsupport/xml/rn_dev_preferences.xml @@ -52,15 +52,8 @@ -