Bug 1602800 - Backout some of the preferences handling to make sure we have defaults for older firefox versions r=gregtatum
authorNazım Can Altınova <canaltinova@gmail.com>
Thu, 12 Dec 2019 13:54:40 +0000
changeset 506680 3263f5baebf08bfb52ea2c0b444a14f1a42b3459
parent 506679 0694837833fecabb4faae5d12045191ed3ef1fd0
child 506681 75643c678e24f1adfb91f674123db257fa94069b
push id36910
push usercsabou@mozilla.com
push dateThu, 12 Dec 2019 21:50:40 +0000
treeherdermozilla-central@0f6958f49842 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgregtatum
bugs1602800
milestone73.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1602800 - Backout some of the preferences handling to make sure we have defaults for older firefox versions r=gregtatum Differential Revision: https://phabricator.services.mozilla.com/D56721
devtools/client/performance-new/browser.js
devtools/client/performance-new/initializer.js
devtools/client/performance-new/popup/background.jsm.js
--- a/devtools/client/performance-new/browser.js
+++ b/devtools/client/performance-new/browser.js
@@ -154,62 +154,112 @@ function receiveProfile(profile, getSymb
 }
 
 /**
  * Don't trust that the user has stored the correct value in preferences, or that it
  * even exists. Gracefully handle malformed data or missing data. Ensure that this
  * function always returns a valid array of strings.
  * @param {PreferenceFront} preferenceFront
  * @param {string} prefName
+ * @param {string[]} defaultValue Default value of the preference. We don't need
+ *   this value since Firefox 72, but we keep it to support older Firefox versions.
  */
-async function _getArrayOfStringsPref(preferenceFront, prefName) {
-  const text = await preferenceFront.getCharPref(prefName);
-  return JSON.parse(text);
+async function _getArrayOfStringsPref(preferenceFront, prefName, defaultValue) {
+  let array;
+  try {
+    const text = await preferenceFront.getCharPref(prefName);
+    array = JSON.parse(text);
+  } catch (error) {
+    return defaultValue;
+  }
+
+  if (
+    Array.isArray(array) &&
+    array.every(feature => typeof feature === "string")
+  ) {
+    return array;
+  }
+
+  return defaultValue;
 }
 
 /**
  * Similar to _getArrayOfStringsPref, but gets the pref from the host browser
  * instance, *not* from the debuggee.
  * Don't trust that the user has stored the correct value in preferences, or that it
  * even exists. Gracefully handle malformed data or missing data. Ensure that this
  * function always returns a valid array of strings.
  * @param {string} prefName
+ * @param {string[]} defaultValue Default value of the preference. We don't need
+ *   this value since Firefox 72, but we keep it to support older Firefox versions.
  */
-async function _getArrayOfStringsHostPref(prefName) {
+async function _getArrayOfStringsHostPref(prefName, defaultValue) {
   const { Services } = lazyServices();
-  const text = Services.prefs.getStringPref(prefName);
+  let array;
+  try {
+    const text = Services.prefs.getStringPref(
+      prefName,
+      JSON.stringify(defaultValue)
+    );
+    array = JSON.parse(text);
+  } catch (error) {
+    return defaultValue;
+  }
 
-  return JSON.parse(text);
+  if (
+    Array.isArray(array) &&
+    array.every(feature => typeof feature === "string")
+  ) {
+    return array;
+  }
+
+  return defaultValue;
 }
 
 /**
  * Attempt to get a int preference value from the debuggee.
  *
  * @param {PreferenceFront} preferenceFront
  * @param {string} prefName
+ * @param {number} defaultValue Default value of the preference. We don't need
+ *   this value since Firefox 72, but we keep it to support older Firefox versions.
  */
-async function _getIntPref(preferenceFront, prefName) {
-  return preferenceFront.getIntPref(prefName);
+async function _getIntPref(preferenceFront, prefName, defaultValue) {
+  try {
+    return await preferenceFront.getIntPref(prefName);
+  } catch (error) {
+    return defaultValue;
+  }
 }
 
 /**
  * Get the recording settings from the preferences. These settings are stored once
  * for local debug targets, and another set of settings for remote targets. This
  * is helpful for configuring for remote targets like Android phones that may require
  * different features or configurations.
  *
  * @param {PreferenceFront} preferenceFront
+ * @param {RecordingStateFromPreferences} defaultPrefs Default preference values.
+ *   We don't need this value since Firefox 72, but we keep it to support older
+ *   Firefox versions.
  */
-async function getRecordingPreferencesFromDebuggee(preferenceFront) {
+async function getRecordingPreferencesFromDebuggee(
+  preferenceFront,
+  defaultPrefs
+) {
   const [entries, interval, features, threads, objdirs] = await Promise.all([
-    _getIntPref(preferenceFront, ENTRIES_PREF),
-    _getIntPref(preferenceFront, INTERVAL_PREF),
-    _getArrayOfStringsPref(preferenceFront, FEATURES_PREF),
-    _getArrayOfStringsPref(preferenceFront, THREADS_PREF),
-    _getArrayOfStringsHostPref(OBJDIRS_PREF),
+    _getIntPref(preferenceFront, ENTRIES_PREF, defaultPrefs.entries),
+    _getIntPref(preferenceFront, INTERVAL_PREF, defaultPrefs.interval),
+    _getArrayOfStringsPref(
+      preferenceFront,
+      FEATURES_PREF,
+      defaultPrefs.features
+    ),
+    _getArrayOfStringsPref(preferenceFront, THREADS_PREF, defaultPrefs.threads),
+    _getArrayOfStringsHostPref(OBJDIRS_PREF, defaultPrefs.objdirs),
   ]);
 
   return { entries, interval, features, threads, objdirs };
 }
 
 /**
  * Take the recording preferences, as defined by the getRecordingSettings
  * selector, and translated using translatePreferencesFromState, and then
--- a/devtools/client/performance-new/initializer.js
+++ b/devtools/client/performance-new/initializer.js
@@ -48,16 +48,20 @@ const actions = require("devtools/client
 const { Provider } = require("devtools/client/shared/vendor/react-redux");
 const {
   receiveProfile,
   getRecordingPreferencesFromDebuggee,
   setRecordingPreferencesOnDebuggee,
   createMultiModalGetSymbolTableFn,
 } = require("devtools/client/performance-new/browser");
 
+const { getDefaultRecordingPreferencesForOlderFirefox } = ChromeUtils.import(
+  "resource://devtools/client/performance-new/popup/background.jsm.js"
+);
+
 /**
  * This file initializes the DevTools Panel UI. It is in charge of initializing
  * the DevTools specific environment, and then passing those requirements into
  * the UI.
  */
 
 /**
  * Initialize the panel by creating a redux store, and render the root component.
@@ -69,17 +73,20 @@ async function gInit(perfFront, preferen
   const store = createStore(reducers);
 
   // Send the initial requests in parallel.
   const [recordingPreferences, supportedFeatures] = await Promise.all([
     // Pull the default recording settings from the background.jsm module. Update them
     // according to what's in the target's preferences. This way the preferences are
     // stored on the target. This could be useful for something like Android where you
     // might want to tweak the settings.
-    getRecordingPreferencesFromDebuggee(preferenceFront),
+    getRecordingPreferencesFromDebuggee(
+      preferenceFront,
+      getDefaultRecordingPreferencesForOlderFirefox()
+    ),
     // Get the supported features from the debuggee. If the debuggee is before
     // Firefox 72, then return null, as the actor does not support that feature.
     // We can't use `target.actorHasMethod`, because the target is not provided
     // when remote debugging. Unfortunately, this approach means that if this
     // function throws a real error, it will get swallowed here.
     Promise.resolve(perfFront.getSupportedFeatures()).catch(() => null),
   ]);
 
--- a/devtools/client/performance-new/popup/background.jsm.js
+++ b/devtools/client/performance-new/popup/background.jsm.js
@@ -303,20 +303,57 @@ function revertRecordingPreferences() {
   Services.prefs.clearUserPref(ENTRIES_PREF);
   Services.prefs.clearUserPref(INTERVAL_PREF);
   Services.prefs.clearUserPref(FEATURES_PREF);
   Services.prefs.clearUserPref(THREADS_PREF);
   Services.prefs.clearUserPref(OBJDIRS_PREF);
   Services.prefs.clearUserPref(DURATION_PREF);
 }
 
+/**
+ * A simple cache for the default recording preferences.
+ * @type {RecordingStateFromPreferences}
+ */
+let _defaultPrefsForOlderFirefox;
+
+/**
+ * This function contains the canonical defaults for the data store in the
+ * preferences in the user profile. They represent the default values for both
+ * the popup and panel's recording settings.
+ *
+ * NOTE: We don't need that function anymore, because have recording default
+ * values in the all.js file since Firefox 72. But we still keep this to support
+ * older Firefox versions. See Bug 1603415.
+ */
+function getDefaultRecordingPreferencesForOlderFirefox() {
+  if (!_defaultPrefsForOlderFirefox) {
+    _defaultPrefsForOlderFirefox = {
+      entries: 10000000, // ~80mb,
+      // Do not expire markers, let them roll off naturally from the circular buffer.
+      duration: 0,
+      interval: 1000, // 1000┬Ás = 1ms
+      features: ["js", "leaf", "stackwalk"],
+      threads: ["GeckoMain", "Compositor"],
+      objdirs: [],
+    };
+
+    if (AppConstants.platform === "android") {
+      // Java profiling is only meaningful on android.
+      _defaultPrefsForOlderFirefox.features.push("java");
+    }
+  }
+
+  return _defaultPrefsForOlderFirefox;
+}
+
 var EXPORTED_SYMBOLS = [
   "captureProfile",
   "startProfiler",
   "stopProfiler",
   "restartProfiler",
   "toggleProfiler",
   "platform",
   "getSymbolsFromThisBrowser",
   "getRecordingPreferencesFromBrowser",
   "setRecordingPreferencesOnBrowser",
   "revertRecordingPreferences",
+  "getDefaultRecordingPreferencesForOlderFirefox",
 ];