Bug 1640897 - Update UI for Data Collection and Use to match Firefox's. r=Paenglab
authorMagnus Melin <mkmelin+mozilla@iki.fi>
Mon, 01 Jun 2020 12:51:51 +0300
changeset 39300 907599e03dc45bb2a96edeb058dea5e2a6d52fd6
parent 39299 71fc60874af7a9238732362a4ebb3b11bdcceeb1
child 39301 47aa8304f805f5f3d5603b59a2be899c2927c79a
push id402
push userclokep@gmail.com
push dateMon, 29 Jun 2020 20:48:04 +0000
reviewersPaenglab
bugs1640897
Bug 1640897 - Update UI for Data Collection and Use to match Firefox's. r=Paenglab
mail/app/profile/all-thunderbird.js
mail/components/preferences/privacy.inc.xhtml
mail/components/preferences/privacy.js
mail/locales/en-US/messenger/preferences/preferences.ftl
mail/moz.configure
mail/themes/shared/mail/preferences/preferences.css
python/l10n/tb_fluent_migrations/bug_1615501_preferences.py
--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -79,20 +79,27 @@ pref("app.update.service.enabled", true)
 #ifdef XP_WIN
 // This pref prevents BITS from being used by Thunderbird to download updates.
 pref("app.update.BITS.enabled", false);
 #endif
 
 // Release notes URL
 pref("app.releaseNotesURL", "https://live.thunderbird.net/%APP%/releasenotes?locale=%LOCALE%&version=%VERSION%&channel=%CHANNEL%&os=%OS%&buildid=%APPBUILDID%");
 
+// URL for "Learn More" for DataCollection
+pref("toolkit.datacollection.infoURL",
+     "https://www.mozilla.org/thunderbird/legal/privacy/#telemetry");
+
 // URL for "Learn More" for Crash Reporter.
 pref("toolkit.crashreporter.infoURL",
      "https://www.mozilla.org/thunderbird/legal/privacy/#crash-reporter");
 
+pref("datareporting.healthreport.uploadEnabled", true); // Required to enable telemetry pings.
+pref("datareporting.healthreport.infoURL", "https://www.mozilla.org/thunderbird/legal/privacy/#health-report");
+
 // Base URL for web-based support pages.
 pref("app.support.baseURL", "https://support.thunderbird.net/%LOCALE%/%APP%/%APPBUILDID%/");
 
 // Base url for web-based feedback pages.
 pref("app.feedback.baseURL", "https://input.mozilla.org/%LOCALE%/feedback/%APP%/%VERSION%/");
 
 // Show error messages in error console.
 pref("javascript.options.showInConsole", true);
@@ -1231,20 +1238,13 @@ pref("toolkit.telemetry.updatePing.enabl
 pref("toolkit.telemetry.bhrPing.enabled", true);
 // Whether to enable Ecosystem Telemetry, requires a restart.
 #ifdef NIGHTLY_BUILD
   pref("toolkit.telemetry.ecosystemtelemetry.enabled", true);
 #else
   pref("toolkit.telemetry.ecosystemtelemetry.enabled", false);
 #endif
 
-// Required to enable telemetry pings (defaults to true if
-// MOZ_SERVICES_HEALTHREPORT is defined, but we're not yet sure we want
-// that...)
-pref("datareporting.healthreport.uploadEnabled", true);
-
-pref("toolkit.telemetry.infoURL", "https://www.mozilla.org/thunderbird/legal/privacy/#telemetry");
-
 #ifdef XP_WIN
 pref("mail.minimizeToTray", false);
 #endif
 
 pref("prompts.defaultModalType", 3);
--- a/mail/components/preferences/privacy.inc.xhtml
+++ b/mail/components/preferences/privacy.inc.xhtml
@@ -181,47 +181,74 @@
                 oncommand="gPrivacyPane.resetTrainingData()"/>
       </hbox>
     </html:fieldset>
 
 #ifdef MOZ_DATA_REPORTING
     <hbox id="privacyDataCollectionCategory"
           class="subcategory"
           data-category="panePrivacy">
-      <html:h1 data-l10n-id="privacy-data-collection-header"/>
+      <html:h1 data-l10n-id="collection-header"/>
     </hbox>
 
-#ifdef MOZ_TELEMETRY_REPORTING
     <html:fieldset data-category="panePrivacy">
-      <html:legend data-l10n-id="telemetry-legend"></html:legend>
-      <description data-l10n-id="telemetry-description"/>
+      <description>
+        <label class="tail-with-learn-more" data-l10n-id="collection-description"/>
+        <label id="dataCollectionPrivacyNotice"
+               class="learnMore" is="text-link"
+               data-l10n-id="collection-privacy-notice"/>
+      </description>
+      <description>
+        <hbox id="telemetry-container" align="stretch" flex="1" hidden="true">
+          <hbox align="top">
+            <image class="info-icon-telemetry" flex="1"></image>
+          </hbox>
+          <hbox align="center" id="dataDescriptionBox" flex="1">
+            <html:span id="telemetryDisabledDescription" class="tail-with-learn-more" data-l10n-id="collection-health-report-telemetry-disabled"/>
+          </hbox>
+          <hbox>
+              <button id="telemetryDataDeletionLearnMore"
+                     class="learnMore" is="text-link"
+                     data-l10n-id="collection-health-report-telemetry-disabled-link"/>
+          </hbox>
+        </hbox>
+      </description>
+      <vbox data-subcategory="reports">
+        <description flex="1">
+          <checkbox id="submitHealthReportBox"
+                    data-l10n-id="collection-health-report"
+                    class="tail-with-learn-more"/>
+          <label id="FHRLearnMore"
+                 class="learnMore" is="text-link"
+                 data-l10n-id="collection-health-report-link"/>
+        </description>
+#ifndef MOZ_TELEMETRY_REPORTING
+        <description id="TelemetryDisabledDesc"
+          class="indent tip-caption" control="telemetryGroup"
+          data-l10n-id="collection-health-report-disabled"/>
+#endif
+
+#ifdef MOZ_CRASHREPORTER
       <hbox align="center">
-        <checkbox id="submitTelemetryBox"
+        <checkbox id="automaticallySubmitCrashesBox"
                   class="tail-with-learn-more"
-                  preference="toolkit.telemetry.enabled"
-                  data-l10n-id="telemetry-label"/>
-        <label is="text-link" id="telemetryLearnMore"
-               data-l10n-id="learn-label"/>
+                  preference="browser.crashReports.unsubmittedCheck.autoSubmit2"
+                  data-l10n-id="collection-backlogged-crash-reports"
+                  flex="1"/>
+        <label id="crashReporterLearnMore"
+               class="learnMore" is="text-link" data-l10n-id="collection-backlogged-crash-reports-link"/>
+      </hbox>
+#endif
+      </vbox>
+
+      <hbox align="start" style="padding-bottom:2em;">
+        <spacer flex="1"/>
       </hbox>
     </html:fieldset>
 #endif
-#ifdef MOZ_CRASHREPORTER
-    <html:fieldset data-category="panePrivacy">
-      <html:legend data-l10n-id="crash-legend"></html:legend>
-      <description data-l10n-id="crash-description"/>
-      <hbox align="center">
-        <checkbox id="submitCrashesBox" class="tail-with-learn-more"
-                  oncommand="gPrivacyPane.updateSubmitCrashes();"
-                  data-l10n-id="crash-label"/>
-        <label is="text-link" id="crashReporterLearnMore"
-               data-l10n-id="learn-label"/>
-      </hbox>
-    </html:fieldset>
-#endif
-#endif
 
     <hbox id="privacySecurityCategory"
           class="subcategory"
           data-category="panePrivacy">
       <html:h1 data-l10n-id="privacy-security-header"/>
     </hbox>
 
     <html:fieldset data-category="panePrivacy">
--- a/mail/components/preferences/privacy.js
+++ b/mail/components/preferences/privacy.js
@@ -24,16 +24,18 @@ ChromeUtils.defineModuleGetter(
 );
 XPCOMUtils.defineLazyGetter(this, "L10n", () => {
   return new Localization([
     "branding/brand.ftl",
     "messenger/preferences/preferences.ftl",
   ]);
 });
 
+const PREF_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
+
 Preferences.addAll([
   { id: "mail.spam.manualMark", type: "bool" },
   { id: "mail.spam.manualMarkMode", type: "int" },
   { id: "mail.spam.markAsReadOnSpam", type: "bool" },
   { id: "mail.spam.logging.enabled", type: "bool" },
   { id: "mail.phishing.detection.enabled", type: "bool" },
   { id: "browser.safebrowsing.enabled", type: "bool" },
   { id: "mailnews.downloadToTempFile", type: "bool" },
@@ -51,33 +53,63 @@ Preferences.addAll([
   { id: "network.cookie.blockFutureCookies", type: "bool" },
   { id: "privacy.donottrackheader.enabled", type: "bool" },
   { id: "security.default_personal_cert", type: "string" },
   { id: "security.disable_button.openCertManager", type: "bool" },
   { id: "security.disable_button.openDeviceManager", type: "bool" },
   { id: "security.OCSP.enabled", type: "int" },
 ]);
 
-if (AppConstants.MOZ_TELEMETRY_REPORTING) {
-  Preferences.add({ id: "toolkit.telemetry.enabled", type: "bool" });
+if (AppConstants.MOZ_DATA_REPORTING) {
+  Preferences.addAll([
+    // Preference instances for prefs that we need to monitor while the page is open.
+    { id: PREF_UPLOAD_ENABLED, type: "bool" },
+  ]);
+}
+
+// Data Choices tab
+if (AppConstants.MOZ_CRASHREPORTER) {
+  Preferences.add({
+    id: "browser.crashReports.unsubmittedCheck.autoSubmit2",
+    type: "bool",
+  });
+}
+
+function setEventListener(aId, aEventType, aCallback) {
+  document
+    .getElementById(aId)
+    .addEventListener(aEventType, aCallback.bind(gPrivacyPane));
 }
 
 var gPrivacyPane = {
   init() {
     this.updateManualMarkMode(Preferences.get("mail.spam.manualMark").value);
     this.updateJunkLogButton(
       Preferences.get("mail.spam.logging.enabled").value
     );
 
     this._initMasterPasswordUI();
 
-    if (AppConstants.MOZ_CRASHREPORTER) {
-      this.initSubmitCrashes();
+    if (AppConstants.MOZ_DATA_REPORTING) {
+      this.initDataCollection();
+      if (AppConstants.MOZ_CRASHREPORTER) {
+        this.initSubmitCrashes();
+      }
+      this.initSubmitHealthReport();
+      setEventListener(
+        "submitHealthReportBox",
+        "command",
+        gPrivacyPane.updateSubmitHealthReport
+      );
+      setEventListener(
+        "telemetryDataDeletionLearnMore",
+        "command",
+        gPrivacyPane.showDataDeletion
+      );
     }
-    this.initTelemetry();
 
     this.readAcceptCookies();
     let element = document.getElementById("acceptCookies");
     Preferences.addSyncFromPrefListener(element, () =>
       this.readAcceptCookies()
     );
     Preferences.addSyncToPrefListener(element, () => this.writeAcceptCookies());
 
@@ -386,77 +418,16 @@ var gPrivacyPane = {
 
   updateDownloadedPhishingListState() {
     document.getElementById(
       "useDownloadedList"
     ).disabled = !document.getElementById("enablePhishingDetector").checked;
   },
 
   /**
-   * Set up or hide the Learn More links for various data collection options
-   */
-  _setupLearnMoreLink(pref, element) {
-    // set up the Learn More link with the correct URL
-    let url = Services.prefs.getCharPref(pref);
-    let el = document.getElementById(element);
-
-    if (url) {
-      el.setAttribute("href", url);
-    } else {
-      el.setAttribute("hidden", "true");
-    }
-  },
-
-  initSubmitCrashes() {
-    var checkbox = document.getElementById("submitCrashesBox");
-    try {
-      var cr = Cc["@mozilla.org/toolkit/crash-reporter;1"].getService(
-        Ci.nsICrashReporter
-      );
-      checkbox.checked = cr.submitReports;
-    } catch (e) {
-      checkbox.style.display = "none";
-    }
-    this._setupLearnMoreLink(
-      "toolkit.crashreporter.infoURL",
-      "crashReporterLearnMore"
-    );
-  },
-
-  updateSubmitCrashReports(aChecked) {
-    Cc["@mozilla.org/toolkit/crash-reporter;1"].getService(
-      Ci.nsICrashReporter
-    ).submitReports = aChecked;
-  },
-
-  updateSubmitCrashes() {
-    var checkbox = document.getElementById("submitCrashesBox");
-    try {
-      var cr = Cc["@mozilla.org/toolkit/crash-reporter;1"].getService(
-        Ci.nsICrashReporter
-      );
-      cr.submitReports = checkbox.checked;
-    } catch (e) {}
-  },
-
-  /**
-   * The preference/checkbox is configured in XUL.
-   *
-   * In all cases, set up the Learn More link sanely
-   */
-  initTelemetry() {
-    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
-      this._setupLearnMoreLink(
-        "toolkit.telemetry.infoURL",
-        "telemetryLearnMore"
-      );
-    }
-  },
-
-  /**
    * Display the user's certificates and associated options.
    */
   showCertificates() {
     gSubDialog.open("chrome://pippki/content/certManager.xhtml");
   },
 
   /**
    * security.OCSP.enabled is an integer value for legacy reasons.
@@ -480,16 +451,95 @@ var gPrivacyPane = {
   },
 
   /**
    * Display a dialog from which the user can manage his security devices.
    */
   showSecurityDevices() {
     gSubDialog.open("chrome://pippki/content/device_manager.xhtml");
   },
+
+  /**
+   * Displays the learn more health report page when a user opts out of data collection.
+   */
+  showDataDeletion() {
+    let url =
+      Services.urlFormatter.formatURLPref("app.support.baseURL") +
+      "telemetry-clientid";
+    window.open(url, "_blank");
+  },
+
+  initDataCollection() {
+    this._setupLearnMoreLink(
+      "toolkit.datacollection.infoURL",
+      "dataCollectionPrivacyNotice"
+    );
+  },
+
+  initSubmitCrashes() {
+    this._setupLearnMoreLink(
+      "toolkit.crashreporter.infoURL",
+      "crashReporterLearnMore"
+    );
+  },
+
+  /**
+   * Set up or hide the Learn More links for various data collection options
+   */
+  _setupLearnMoreLink(pref, element) {
+    // set up the Learn More link with the correct URL
+    let url = Services.urlFormatter.formatURLPref(pref);
+    let el = document.getElementById(element);
+
+    if (url) {
+      el.setAttribute("href", url);
+    } else {
+      el.setAttribute("hidden", "true");
+    }
+  },
+
+  /**
+   * Initialize the health report service reference and checkbox.
+   */
+  initSubmitHealthReport() {
+    this._setupLearnMoreLink(
+      "datareporting.healthreport.infoURL",
+      "FHRLearnMore"
+    );
+
+    let checkbox = document.getElementById("submitHealthReportBox");
+
+    // Telemetry is only sending data if MOZ_TELEMETRY_REPORTING is defined.
+    // We still want to display the preferences panel if that's not the case, but
+    // we want it to be disabled and unchecked.
+    if (
+      Services.prefs.prefIsLocked(PREF_UPLOAD_ENABLED) ||
+      !AppConstants.MOZ_TELEMETRY_REPORTING
+    ) {
+      checkbox.setAttribute("disabled", "true");
+      return;
+    }
+
+    checkbox.checked =
+      Services.prefs.getBoolPref(PREF_UPLOAD_ENABLED) &&
+      AppConstants.MOZ_TELEMETRY_REPORTING;
+  },
+
+  /**
+   * Update the health report preference with state from checkbox.
+   */
+  updateSubmitHealthReport() {
+    let checkbox = document.getElementById("submitHealthReportBox");
+
+    Services.prefs.setBoolPref(PREF_UPLOAD_ENABLED, checkbox.checked);
+
+    // If allow telemetry is checked, hide the box saying you're no longer
+    // allowing it.
+    document.getElementById("telemetry-container").hidden = checkbox.checked;
+  },
 };
 
 Preferences.get("mailnews.message_display.disable_remote_image").on(
   "change",
   gPrivacyPane.reloadMessageInOpener
 );
 Preferences.get("mail.phishing.detection.enabled").on(
   "change",
--- a/mail/locales/en-US/messenger/preferences/preferences.ftl
+++ b/mail/locales/en-US/messenger/preferences/preferences.ftl
@@ -58,17 +58,37 @@ compose-html-style-title = HTML Style
 composition-addressing-header = Addressing
 
 privacy-main-header = Privacy
 
 privacy-passwords-header = Passwords
 
 privacy-junk-header = Junk
 
-privacy-data-collection-header = Data Collection and Use
+collection-header = { -brand-short-name } Data Collection and Use
+
+collection-description = We strive to provide you with choices and collect only what we need to provide and improve { -brand-short-name } for everyone. We always ask permission before receiving personal information.
+collection-privacy-notice = Privacy Notice
+
+collection-health-report-telemetry-disabled = You’re no longer allowing { -vendor-short-name } to capture technical and interaction data. All past data will be deleted within 30 days.
+collection-health-report-telemetry-disabled-link = Learn more
+
+collection-health-report =
+    .label = Allow { -brand-short-name } to send technical and interaction data to { -vendor-short-name }
+    .accesskey = r
+collection-health-report-link = Learn more
+
+# This message is displayed above disabled data sharing options in developer builds
+# or builds with no Telemetry support available.
+collection-health-report-disabled = Data reporting is disabled for this build configuration
+
+collection-backlogged-crash-reports =
+    .label = Allow { -brand-short-name } to send backlogged crash reports on your behalf
+    .accesskey = c
+collection-backlogged-crash-reports-link = Learn more
 
 privacy-security-header = Security
 
 privacy-scam-detection-title = Scam Detection
 
 privacy-anti-virus-title = Antivirus
 
 privacy-certificates-title = Certificates
@@ -694,33 +714,16 @@ junk-log-label =
 junk-log-button =
     .label = Show log
     .accesskey = S
 
 reset-junk-button =
     .label = Reset Training Data
     .accesskey = R
 
-telemetry-legend = Telemetry
-telemetry-description = Shares performance, usage, hardware and customization data about your e-mail client with { -vendor-short-name } to help us make { -brand-short-name } better
-
-telemetry-label =
-    .label = Enable Telemetry
-    .accesskey = T
-
-learn-label =
-    .value = Learn More
-
-crash-legend = Crash Reporter
-crash-description = { -brand-short-name } submits crash reports to help { -vendor-short-name } make your e-mail client more stable and secure
-
-crash-label =
-    .label = Enable Crash Reporter
-    .accesskey = C
-
 phishing-description = { -brand-short-name } can analyze messages for suspected email scams by looking for common techniques used to deceive you.
 
 phishing-label =
     .label = Tell me if the message I'm reading is a suspected email scam
     .accesskey = T
 
 antivirus-description = { -brand-short-name } can make it easy for antivirus software to analyze incoming mail messages for viruses before they are stored locally.
 
--- a/mail/moz.configure
+++ b/mail/moz.configure
@@ -67,16 +67,17 @@ def thunderbird_version(build_env, app_p
                      version_display=rv[1])
 
 set_defconf('THUNDERBIRD_VERSION', thunderbird_version.version)
 set_defconf('THUNDERBIRD_VERSION_DISPLAY', thunderbird_version.version_display)
 
 set_define('MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES', True)
 
 imply_option('MOZ_PLACES', True)
+imply_option('MOZ_SERVICES_HEALTHREPORT', True)
 imply_option('MOZ_DEDICATED_PROFILES', True)
 imply_option('MOZ_BLOCK_PROFILE_DOWNGRADE', True)
 
 with only_when(target_is_linux & compile_environment):
     option(env='MOZ_NO_PIE_COMPAT',
            help='Enable non-PIE wrapper')
 
     set_config('MOZ_NO_PIE_COMPAT',
--- a/mail/themes/shared/mail/preferences/preferences.css
+++ b/mail/themes/shared/mail/preferences/preferences.css
@@ -345,16 +345,22 @@ html|input.indent {
 .align-no-label {
   margin-inline-start: 4px;
 }
 
 .tail-with-learn-more {
   margin-inline-end: 10px;
 }
 
+.learnMore {
+  margin-inline-start: 0;
+  font-weight: normal;
+  white-space: nowrap;
+}
+
 .update-throbber {
   width: 16px;
   min-height: 16px;
   margin-inline: 6px 4px;
   list-style-image: url("chrome://global/skin/icons/loading.png");
 }
 
 @media (min-resolution: 1.1dppx) {
@@ -386,19 +392,31 @@ html|input.indent {
 #updateSettingCrossUserWarning:-moz-locale-dir(rtl) {
   background-position-x: right 2px;
 }
 
 #releasenotes {
   margin-inline-start: 6px !important;
 }
 
-#telemetryLearnMore,
-#crashReporterLearnMore {
-  margin-inline-end: 4px !important;
+#telemetry-container {
+  border-radius: 4px;
+  background-color: rgba(12, 12, 13, 0.2);
+  font-size: 85%;
+  padding: 3px;
+  margin-block: 4px;
+  width: 100%;
+}
+
+#dataDescriptionBox {
+  line-height: 1.3em;
+}
+
+#submitHealthReportBox {
+  display: -moz-inline-box;
 }
 
 /* Remove the start margin to align these elements */
 #addCloudFileAccount,
 #chatStartupAction,
 #defaults-itemtype-menulist,
 #manageCertificatesButton {
   margin-inline-start: 0;
--- a/python/l10n/tb_fluent_migrations/bug_1615501_preferences.py
+++ b/python/l10n/tb_fluent_migrations/bug_1615501_preferences.py
@@ -898,31 +898,16 @@ antivirus-label =
         ]
     )
 
     ctx.add_transforms(
         "mail/messenger/preferences/preferences.ftl",
         "mail/messenger/preferences/preferences.ftl",
         transforms_from(
 """
-telemetry-legend = { COPY(from_path, "telemetrySection.label") }
-
-telemetry-label =
-    .label = { COPY(from_path, "enableTelemetry.label") }
-    .accesskey = { COPY(from_path, "enableTelemetry.accesskey") }
-
-learn-label =
-    .value = { COPY(from_path, "telemetryLearnMore.label") }
-
-crash-legend = { COPY(from_path, "crashReporterSection.label") }
-
-crash-label =
-    .label = { COPY(from_path, "enableCrashReporter.label") }
-    .accesskey = { COPY(from_path, "enableCrashReporter.accesskey") }
-
 certificate-description = { COPY(from_path, "certSelection.description") }
 
 certificate-auto =
     .label = { COPY(from_path, "certs.auto") }
     .accesskey = { COPY(from_path, "certs.auto.accesskey") }
 
 certificate-ask =
     .label = { COPY(from_path, "certs.ask") }
@@ -941,45 +926,16 @@ security-devices-button =
     .accesskey = { COPY(from_path, "viewSecurityDevices2.accesskey") }
 """, from_path="mail/chrome/messenger/preferences/advanced.dtd"
         )
     )
 
     ctx.add_transforms(
         "mail/messenger/preferences/preferences.ftl",
         "mail/messenger/preferences/preferences.ftl",
-        [
-            FTL.Message(
-                id = FTL.Identifier("telemetry-description"),
-                value = REPLACE(
-                    "mail/chrome/messenger/preferences/advanced.dtd",
-                    "telemetryDesc.label",
-                    {
-                        "&brandShortName;": TERM_REFERENCE("brand-short-name"),
-                        "&vendorShortName;": TERM_REFERENCE("vendor-short-name")
-                    },
-                )
-            ),
-            FTL.Message(
-                id = FTL.Identifier("crash-description"),
-                value = REPLACE(
-                    "mail/chrome/messenger/preferences/advanced.dtd",
-                    "crashReporterDesc.label",
-                    {
-                        "&brandShortName;": TERM_REFERENCE("brand-short-name"),
-                        "&vendorShortName;": TERM_REFERENCE("vendor-short-name")
-                    },
-                )
-            ),
-        ]
-    )
-
-    ctx.add_transforms(
-        "mail/messenger/preferences/preferences.ftl",
-        "mail/messenger/preferences/preferences.ftl",
         transforms_from(
 """
 offline-label =
     .label = { COPY(from_path, "startupOffline.label") }
 
 auto-connect-label =
     .label = { COPY(from_path, "startupConnectAuto.label") }