Bug 1418266 - add devtools onboarding preferences and probes (beta-only);r=ochameau a=gchang
The devtools.onboarding.experiment pref now supports 3 states:
- off (default)
- on
- force
When set to "on" or "force" the preference will flip devtools
enabled to false.
When set to "force" the devtools.enabled pref can no longer be
flipped to true by looking at devtools.selfxss.count, users
have to go through the onboarding flow.
To make sure the devtools.enabled pref is only flipped once, we
use a supporting pref devtools.onboarding.experiment.flipped
MozReview-Commit-ID: B5fPKuGxPW2
--- a/devtools/shim/devtools-startup-prefs.js
+++ b/devtools/shim/devtools-startup-prefs.js
@@ -15,8 +15,23 @@ pref("devtools.jsonview.enabled", true);
#ifdef MOZ_DEV_EDITION
sticky_pref("devtools.theme", "dark");
#else
sticky_pref("devtools.theme", "light");
#endif
// Should the devtools toolbar be opened on startup
pref("devtools.toolbar.visible", false);
+
+// Pref to drive the devtools onboarding flow experiment. States:
+// - off: forces devtools.enabled to true
+// - on: devtools.enabled is not forced to true.
+// - force: devtools.enabled is not forced to true and cannot be set to true by checking
+// devtools.selfxss.count. User will have to go through onboarding to use DevTools.
+pref("devtools.onboarding.experiment", "off");
+
+// If devtools.onboarding.experiment is set to "on" or "force", we will flip the
+// devtools.enabled preference to false once. The flag is used to make sure it is only
+// flipped once.
+pref("devtools.onboarding.experiment.flipped", false);
+
+// Flag to check if we already logged the devtools onboarding related probe.
+pref("devtools.onboarding.telemetry.logged", false);
--- a/devtools/shim/devtools-startup.js
+++ b/devtools/shim/devtools-startup.js
@@ -243,26 +243,52 @@ DevToolsStartup.prototype = {
this.hookWindow(window);
if (Services.prefs.getBoolPref(TOOLBAR_VISIBLE_PREF, false)) {
// Loading devtools-browser will open the developer toolbar by also checking this
// pref.
this.initDevTools();
}
- if (this.devtoolsFlag) {
- this.handleDevToolsFlag(window);
- // This listener is called for all Firefox windows, but we want to execute
- // that command only once.
- this.devtoolsFlag = false;
+ // This listener is called for all Firefox windows, but we want to execute some code
+ // only once.
+ if (!this._firstWindowReadyReceived) {
+ this.onFirstWindowReady(window);
+ this._firstWindowReadyReceived = true;
}
JsonView.initialize();
},
+ onFirstWindowReady(window) {
+ if (this.devtoolsFlag) {
+ this.handleDevToolsFlag(window);
+ }
+
+ // Wait until we get a window before sending a ping to telemetry to avoid slowing down
+ // the startup phase.
+ this.pingOnboardingTelemetry();
+ },
+
+ /**
+ * Check if the user is being flagged as DevTools users or not. This probe should only
+ * be logged once per profile.
+ */
+ pingOnboardingTelemetry() {
+ // Only ping telemetry once per profile.
+ let alreadyLoggedPref = "devtools.onboarding.telemetry.logged";
+ if (Services.prefs.getBoolPref(alreadyLoggedPref)) {
+ return;
+ }
+
+ let scalarId = "devtools.onboarding.is_devtools_user";
+ Services.telemetry.scalarSet(scalarId, this.isDevToolsUser());
+ Services.prefs.setBoolPref(alreadyLoggedPref, true);
+ },
+
/**
* Register listeners to all possible entry points for Developer Tools.
* But instead of implementing the actual actions, defer to DevTools codebase.
* In most cases, it only needs to call this.initDevTools which handles the rest.
* We do that to prevent loading any DevTools module until the user intent to use them.
*/
hookWindow(window) {
// Key Shortcuts need to be added on all the created windows.
@@ -442,24 +468,45 @@ DevToolsStartup.prototype = {
/**
* Depending on some runtime parameters (command line arguments as well as existing
* preferences), the DEVTOOLS_ENABLED_PREF might be forced to true.
*
* @param {Boolean} hasDevToolsFlag
* true if any DevTools command line argument was passed when starting Firefox.
*/
setupEnabledPref(hasDevToolsFlag) {
+ // Read the current experiment state.
+ let experimentState = Services.prefs.getCharPref("devtools.onboarding.experiment");
+ let isRegularExperiment = experimentState == "on";
+ let isForcedExperiment = experimentState == "force";
+ let isInExperiment = isRegularExperiment || isForcedExperiment;
+
+ // Force devtools.enabled to true for users that are not part of the experiment.
+ if (!isInExperiment) {
+ Services.prefs.setBoolPref(DEVTOOLS_ENABLED_PREF, true);
+ return;
+ }
+
+ // Force devtools.enabled to false once for each experiment user.
+ if (!Services.prefs.getBoolPref("devtools.onboarding.experiment.flipped")) {
+ Services.prefs.setBoolPref(DEVTOOLS_ENABLED_PREF, false);
+ Services.prefs.setBoolPref("devtools.onboarding.experiment.flipped", true);
+ }
+
if (Services.prefs.getBoolPref(DEVTOOLS_ENABLED_PREF)) {
// Nothing to do if DevTools are already enabled.
return;
}
- let hasToolbarPref = Services.prefs.getBoolPref(TOOLBAR_VISIBLE_PREF, false);
+ // We only consider checking the actual isDevToolsUser() if the user is in the
+ // "regular" experiment group.
+ let isDevToolsUser = isRegularExperiment && this.isDevToolsUser();
- if (hasDevToolsFlag || hasToolbarPref || this.isDevToolsUser()) {
+ let hasToolbarPref = Services.prefs.getBoolPref(TOOLBAR_VISIBLE_PREF, false);
+ if (hasDevToolsFlag || hasToolbarPref || isDevToolsUser) {
Services.prefs.setBoolPref(DEVTOOLS_ENABLED_PREF, true);
}
},
hookKeyShortcuts(window) {
let doc = window.document;
let keyset = doc.createElement("keyset");
keyset.setAttribute("id", "devtoolsKeyset");
--- a/toolkit/components/telemetry/Scalars.yaml
+++ b/toolkit/components/telemetry/Scalars.yaml
@@ -951,16 +951,29 @@ devtools.aboutdevtools:
Number of times the user left about:devtools without enabling devtools.
expires: "60"
kind: uint
notification_emails:
- dev-developer-tools@lists.mozilla.org, jdescottes@mozilla.com
record_in_processes:
- 'main'
+devtools.onboarding:
+ is_devtools_user:
+ bug_numbers:
+ - 1408339
+ description: >
+ How many users are flagged as existing devtools users.
+ expires: "60"
+ kind: boolean
+ notification_emails:
+ - dev-developer-tools@lists.mozilla.org, jdescottes@mozilla.com
+ record_in_processes:
+ - 'main'
+
navigator.storage:
estimate_count:
bug_numbers:
- 1359708
description: >
Number of times navigator.storage.estimate has been used.
expires: "60"
kind: uint