Bug 1370801: Add preference for controlling Opt-out Shield study enrollment. draft
authorMichael Kelly <mkelly@mozilla.com>
Thu, 15 Jun 2017 10:17:00 -0700
changeset 594874 75c9fc66e34268f587b6a3f9ff889cb8351e2a5d
parent 594149 da66c4a05fda49d457d9411a7092fed87cf9e53a
child 633566 048fb1457052bea7e0d7644bf5d9551daeef9c8b
push id64184
push userbmo:mkelly@mozilla.com
push dateThu, 15 Jun 2017 17:17:18 +0000
bugs1370801
milestone56.0a1
Bug 1370801: Add preference for controlling Opt-out Shield study enrollment. The checkbox for the preference is temporarily limited to en-US. MozReview-Commit-ID: MZb5m45q7v
browser/app/profile/firefox.js
browser/components/preferences/in-content/advanced.js
browser/components/preferences/in-content/advanced.xul
browser/components/preferences/in-content/tests/browser.ini
browser/components/preferences/in-content/tests/browser_optoutshieldstudies.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1694,8 +1694,12 @@ pref("browser.onboarding.enabled", true)
 // roll out the feature using SHIELD pref flipping.
 #ifdef NIGHTLY_BUILD
 pref("extensions.screenshots.system-disabled", false);
 #else
 pref("extensions.screenshots.system-disabled", true);
 #endif
 // Permanent pref that allows individual users to disable Screenshots.
 pref("extensions.screenshots.disabled", false);
+
+// Preferences for the Shield system extension
+pref("app.shield.optoutstudies.enabled", true);
+pref("app.shield.optoutstudies.infoURL", "https://www.mozilla.org/privacy/firefox/");
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -41,16 +41,17 @@ var gAdvancedPane = {
       window.addEventListener("unload", onUnload);
       Services.prefs.addObserver("app.update.", this);
       this.updateReadPrefs();
     }
     if (AppConstants.MOZ_CRASHREPORTER) {
       this.initSubmitCrashes();
     }
     this.initTelemetry();
+    this.initOptOutShieldStudies();
     if (AppConstants.MOZ_TELEMETRY_REPORTING) {
       this.initSubmitHealthReport();
     }
     this.updateOnScreenKeyboardVisibility();
     this.updateCacheSizeInputField();
     this.updateActualCacheSize();
 
     if (Services.prefs.getBoolPref("browser.storageManager.enabled")) {
@@ -311,42 +312,75 @@ var gAdvancedPane = {
         // If we disable FHR, untick the telemetry checkbox.
         Services.prefs.setBoolPref("toolkit.telemetry.enabled", false);
       }
       document.getElementById("telemetryDataDesc").disabled = disabled;
     }
   },
 
   /**
+   * The preference/checkbox is configured in XUL.
+   *
+   * In all cases, set up the Learn More link sanely.
+   */
+  initOptOutShieldStudies() {
+    // Hidden outside of en-* locales temporarily (bug 1370801)
+    const appLocale = Services.locale.getAppLocaleAsLangTag();
+    if (AppConstants.MOZ_TELEMETRY_REPORTING && appLocale.startsWith("en")) {
+      document.getElementById("optOutShieldStudiesContainer").hidden = false;
+      this._setupLearnMoreLink("app.shield.optoutstudies.infoURL", "optOutShieldStudiesLearnMore");
+    }
+  },
+
+  /**
+   * Set the status of the Shield study opt-out based on the input argument.
+   * @param {Boolean} aEnabled False disables the controls, true enables them.
+   */
+  setOptOutShieldStudiesEnabled(aEnabled) {
+    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
+      // If FHR is disabled, opt-out Shield studies should be disabled as well.
+      let disabled = !aEnabled;
+      document.getElementById("optOutShieldStudiesBox").disabled = disabled;
+      if (disabled) {
+        // If we disable FHR, modify the preference.
+        Services.prefs.setBoolPref("app.shield.optoutstudies.enabled", false);
+      }
+      document.getElementById("optOutShieldStudiesDesc").disabled = disabled;
+    }
+  },
+
+  /**
    * Initialize the health report service reference and checkbox.
    */
   initSubmitHealthReport() {
     if (AppConstants.MOZ_TELEMETRY_REPORTING) {
       this._setupLearnMoreLink("datareporting.healthreport.infoURL", "FHRLearnMore");
 
       let checkbox = document.getElementById("submitHealthReportBox");
 
       if (Services.prefs.prefIsLocked(PREF_UPLOAD_ENABLED)) {
         checkbox.setAttribute("disabled", "true");
         return;
       }
 
       checkbox.checked = Services.prefs.getBoolPref(PREF_UPLOAD_ENABLED);
       this.setTelemetrySectionEnabled(checkbox.checked);
+      this.setOptOutShieldStudiesEnabled(checkbox.checked);
     }
   },
 
   /**
    * Update the health report preference with state from checkbox.
    */
   updateSubmitHealthReport() {
     if (AppConstants.MOZ_TELEMETRY_REPORTING) {
       let checkbox = document.getElementById("submitHealthReportBox");
       Services.prefs.setBoolPref(PREF_UPLOAD_ENABLED, checkbox.checked);
       this.setTelemetrySectionEnabled(checkbox.checked);
+      this.setOptOutShieldStudiesEnabled(checkbox.checked);
     }
   },
 
   updateOnScreenKeyboardVisibility() {
     if (AppConstants.platform == "win") {
       let minVersion = Services.prefs.getBoolPref("ui.osk.require_win10") ? 10 : 6.2;
       if (Services.vc.compare(Services.sysinfo.getProperty("version"), minVersion) >= 0) {
         document.getElementById("useOnScreenKeyboard").hidden = false;
--- a/browser/components/preferences/in-content/advanced.xul
+++ b/browser/components/preferences/in-content/advanced.xul
@@ -37,16 +37,19 @@
   <preference id="layout.spellcheckDefault"
               name="layout.spellcheckDefault"
               type="int"/>
 
 #ifdef MOZ_TELEMETRY_REPORTING
   <preference id="toolkit.telemetry.enabled"
               name="toolkit.telemetry.enabled"
               type="bool"/>
+  <preference id="app.shield.optoutstudies.enabled"
+              name="app.shield.optoutstudies.enabled"
+              type="bool"/>
 #endif
 
   <!-- Data Choices tab -->
 #ifdef MOZ_CRASHREPORTER
   <preference id="browser.crashReports.unsubmittedCheck.autoSubmit"
               name="browser.crashReports.unsubmittedCheck.autoSubmit"
               type="bool"/>
 #endif
@@ -209,16 +212,32 @@
               </caption>
               <hbox class="indent" flex="1">
                 <label id="telemetryDataDesc" flex="1">&telemetryDesc.label;</label>
                 <label id="telemetryLearnMore" flex="1"
                        class="learnMore text-link">&telemetryLearnMore.label;</label>
               </hbox>
             </groupbox>
           </hbox>
+          <!-- Hidden outside of en-* locales temporarily (bug 1370801) -->
+          <hbox class="indent" id="optOutShieldStudiesContainer" hidden="true">
+            <groupbox flex="1">
+              <caption>
+                <checkbox id="optOutShieldStudiesBox" preference="app.shield.optoutstudies.enabled"
+                          label="Help make &brandShortName; better"
+                          accesskey="s"/>
+              </caption>
+              <hbox class="indent" flex="1" align="stretch">
+                <label id="optOutShieldStudiesDesc" flex="1"
+                       value="Let us study how you use new features and services" />
+                <label id="optOutShieldStudiesLearnMore"
+                       class="learnMore text-link" value="Learn more" />
+              </hbox>
+            </groupbox>
+          </hbox>
         </vbox>
       </groupbox>
 #endif
 #ifdef MOZ_CRASHREPORTER
       <groupbox>
         <caption>
           <checkbox id="automaticallySubmitCrashesBox"
                     preference="browser.crashReports.unsubmittedCheck.autoSubmit"
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -25,16 +25,19 @@ skip-if = os != "win" # This test tests 
 [browser_connection.js]
 [browser_connection_bug388287.js]
 [browser_cookies_exceptions.js]
 [browser_defaultbrowser_alwayscheck.js]
 [browser_healthreport.js]
 skip-if = true || !healthreport # Bug 1185403 for the "true"
 [browser_homepages_filter_aboutpreferences.js]
 [browser_notifications_do_not_disturb.js]
+[browser_optoutshieldstudies.js]
+# Skip this test when FHR/Telemetry aren't available, or when not building desktop Firefox.
+skip-if = !healthreport || !telemetry || !(buildapp == 'browser')
 [browser_performance.js]
 skip-if = !e10s
 [browser_performance_non_e10s.js]
 skip-if = e10s
 [browser_permissions_urlFieldHidden.js]
 [browser_proxy_backup.js]
 [browser_privacypane_1.js]
 [browser_privacypane_3.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser_optoutshieldstudies.js
@@ -0,0 +1,52 @@
+/* Any copyright is dedicated to the Public Domain.
+* http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const OPTOUT_STUDIES_ENABLED = "app.shield.optoutstudies.enabled";
+const FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
+
+function runPaneTest(fn) {
+  open_preferences((win) => {
+    let doc = win.document;
+    win.gotoPref("paneAdvanced");
+    let advancedPrefs = doc.getElementById("advancedPrefs");
+    let tab = doc.getElementById("dataChoicesTab");
+    advancedPrefs.selectedTab = tab;
+    fn(win, doc);
+  });
+}
+
+function test() {
+  waitForExplicitFinish();
+  resetPreferences();
+  registerCleanupFunction(resetPreferences);
+  runPaneTest(testOptOutStudyState);
+}
+
+function testOptOutStudyState(win, doc) {
+  let fhrCheckbox = doc.getElementById("submitHealthReportBox");
+  Assert.ok(fhrCheckbox.checked, "Health Report checkbox is checked on app first run.");
+
+  let optOutStudyCheckbox = doc.getElementById("optOutShieldStudiesBox");
+  Assert.ok(!optOutStudyCheckbox.disabled,
+            "Opt-out studies checkbox must be enabled if FHR is checked.");
+  Assert.ok(Services.prefs.getBoolPref(OPTOUT_STUDIES_ENABLED),
+            "Opt-out studies must be enabled if the checkbox is ticked.");
+
+  // Uncheck the FHR checkbox and make sure that Telemetry checkbox gets disabled.
+  fhrCheckbox.click();
+
+  Assert.ok(optOutStudyCheckbox.disabled,
+            "Opt-out studies checkbox must be disabled if FHR is unchecked.");
+  Assert.ok(!Services.prefs.getBoolPref(OPTOUT_STUDIES_ENABLED),
+            "Opt-out studies must be disabled if the checkbox is unticked.");
+
+  win.close();
+  finish();
+}
+
+function resetPreferences() {
+  Services.prefs.clearUserPref(OPTOUT_STUDIES_ENABLED);
+  Services.prefs.clearUserPref(FHR_UPLOAD_ENABLED);
+}