Bug 765398 - Add a "yes, I allow tracking" option to DNT. (r=dolske)
authorSid Stamm <sstamm@mozilla.com>
Thu, 14 Jun 2012 14:19:27 -0700
changeset 120083 a26f703d6be8
parent 120082 68e0432939c9
child 120084 d9a0933dfe2a
child 120087 d5d406f27a7d
push id24237
push userryanvm@gmail.com
push date2013-01-29 00:01 +0000
treeherdermozilla-central@0c45e6378f1f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdolske
bugs765398
milestone21.0a1
Bug 765398 - Add a "yes, I allow tracking" option to DNT. (r=dolske)
browser/app/profile/firefox.js
browser/components/preferences/in-content/privacy.js
browser/components/preferences/in-content/privacy.xul
browser/components/preferences/privacy.js
browser/components/preferences/privacy.xul
browser/locales/en-US/chrome/browser/preferences/privacy.dtd
mobile/xul/app/mobile.js
modules/libpref/src/init/all.js
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -996,16 +996,17 @@ pref("services.sync.prefs.sync.privacy.c
 pref("services.sync.prefs.sync.privacy.clearOnShutdown.downloads", true);
 pref("services.sync.prefs.sync.privacy.clearOnShutdown.formdata", true);
 pref("services.sync.prefs.sync.privacy.clearOnShutdown.history", true);
 pref("services.sync.prefs.sync.privacy.clearOnShutdown.offlineApps", true);
 pref("services.sync.prefs.sync.privacy.clearOnShutdown.passwords", true);
 pref("services.sync.prefs.sync.privacy.clearOnShutdown.sessions", true);
 pref("services.sync.prefs.sync.privacy.clearOnShutdown.siteSettings", true);
 pref("services.sync.prefs.sync.privacy.donottrackheader.enabled", true);
+pref("services.sync.prefs.sync.privacy.donottrackheader.value", true);
 pref("services.sync.prefs.sync.privacy.sanitize.sanitizeOnShutdown", true);
 pref("services.sync.prefs.sync.security.OCSP.disable_button.managecrl", true);
 pref("services.sync.prefs.sync.security.OCSP.enabled", true);
 pref("services.sync.prefs.sync.security.OCSP.require", true);
 pref("services.sync.prefs.sync.security.default_personal_cert", true);
 pref("services.sync.prefs.sync.security.enable_ssl3", true);
 pref("services.sync.prefs.sync.security.enable_tls", true);
 pref("services.sync.prefs.sync.signon.rememberSignons", true);
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -119,16 +119,66 @@ var gPrivacyPane = {
     case "custom":
       selectedIndex = 2;
       break;
     }
     document.getElementById("historyPane").selectedIndex = selectedIndex;
   },
 
   /**
+   * Open up the DNT "learn more" link.
+   */
+  openTrackingInfoSite: function PPP_openTrackingInfoSite()
+  {
+    let thisDocEl = document.documentElement,
+        openerDocEl = window.opener && window.opener.document.documentElement,
+        url = "https://www.mozilla.org/dnt";
+    if (thisDocEl.id == "BrowserPreferences" && !thisDocEl.instantApply)
+      openUILinkIn(url, "window");
+    else
+      openUILinkIn(url, "tab");
+  },
+
+  /**
+   * Update the Tracking preferences based on controls.
+   */
+  setTrackingPrefs: function PPP_setTrackingPrefs()
+  {
+    let dntRadioGroup = document.getElementById("doNotTrackSelection"),
+        dntValuePref = document.getElementById("privacy.donottrackheader.value"),
+        dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled");
+
+    // if the selected radio button says "no preference", set on/off pref to
+    // false and don't change the value pref.
+    if (dntRadioGroup.selectedItem.value == -1) {
+      dntEnabledPref.value = false;
+      return dntValuePref.value;
+    }
+
+    dntEnabledPref.value = true;
+    return dntRadioGroup.selectedItem.value;
+  },
+
+  /**
+   * Obtain the tracking preference value and reflect it in the UI.
+   */
+  getTrackingPrefs: function PPP_getTrackingPrefs()
+  {
+    let dntValuePref = document.getElementById("privacy.donottrackheader.value"),
+        dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled");
+
+    // if DNT is enbaled, select the value from the selected radio
+    // button, otherwise choose the "no preference" radio button
+    if (dntEnabledPref.value)
+      return dntValuePref.value;
+
+    return document.getElementById("dntnopref").value;
+  },
+
+  /**
    * Update the private browsing auto-start pref and the history mode
    * micro-management prefs based on the history mode menulist
    */
   updateHistoryModePrefs: function PPP_updateHistoryModePrefs()
   {
     let pref = document.getElementById("browser.privatebrowsing.autostart");
     switch (document.getElementById("historyMode").value) {
     case "remember":
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -6,16 +6,19 @@
         src="chrome://browser/content/preferences/in-content/privacy.js"/>
 
 <preferences id="privacyPreferences">
 
   <!-- Tracking -->
   <preference id="privacy.donottrackheader.enabled"
               name="privacy.donottrackheader.enabled"
               type="bool"/>
+  <preference id="privacy.donottrackheader.value"
+              name="privacy.donottrackheader.value"
+              type="int"/>
 
   <!-- XXX button prefs -->
   <preference id="pref.privacy.disable_button.cookie_exceptions"
               name="pref.privacy.disable_button.cookie_exceptions"
               type="bool"/>
   <preference id="pref.privacy.disable_button.view_cookies"
               name="pref.privacy.disable_button.view_cookies"
               type="bool"/>
@@ -74,21 +77,30 @@
 <hbox class="heading" data-category="panePrivacy" hidden="true">
   <image class="preference-icon" type="privacy"/>
   <html:h1>&panePrivacy.title;</html:h1>
 </hbox>
 
 <!-- Tracking -->
 <groupbox id="trackingGroup" data-category="panePrivacy" hidden="true">
   <caption label="&tracking.label;"/>
-
-  <checkbox id="privacyDoNotTrackPrefs"
-            label="&doNotTrack.label;"
-            accesskey="&doNotTrack.accesskey;"
-            preference="privacy.donottrackheader.enabled"/>
+  <radiogroup id="doNotTrackSelection" orient="vertical"
+              preference="privacy.donottrackheader.value"
+              onsynctopreference="return gPrivacyPane.setTrackingPrefs()"
+              onsyncfrompreference="return gPrivacyPane.getTrackingPrefs()">
+    <radio id="dntnotrack" value="1" label="&dntTrackingNotOkay.label;"
+            accesskey="&dntTrackingNotOkay.accesskey;" />
+    <radio id="dntdotrack" value="0" label="&dntTrackingOkay.label;"
+            accesskey="&dntTrackingOkay.accesskey;" />
+    <radio id="dntnopref" value="-1" label="&dntTrackingNopref.label;"
+            accesskey="&dntTrackingNopref.accesskey;" />
+  </radiogroup>
+  <label class="text-link" id="doNotTrackInfo"
+          onclick="event.stopPropagation();gPrivacyPane.openTrackingInfoSite();"
+          value="&doNotTrackInfo.label;"/>
 </groupbox>
 
 <!-- History -->
 <groupbox id="historyGroup" data-category="panePrivacy" hidden="true">
   <caption label="&history.label;"/>
   <hbox align="center">
     <label id="historyModeLabel"
            control="historyMode"
--- a/browser/components/preferences/privacy.js
+++ b/browser/components/preferences/privacy.js
@@ -122,16 +122,66 @@ var gPrivacyPane = {
     case "custom":
       selectedIndex = 2;
       break;
     }
     document.getElementById("historyPane").selectedIndex = selectedIndex;
   },
 
   /**
+   * Open up the DNT "learn more" link.
+   */
+  openTrackingInfoSite: function PPP_openTrackingInfoSite()
+  {
+    let thisDocEl = document.documentElement,
+        openerDocEl = window.opener && window.opener.document.documentElement,
+        url = "https://www.mozilla.org/dnt";
+    if (thisDocEl.id == "BrowserPreferences" && !thisDocEl.instantApply)
+      openUILinkIn(url, "window");
+    else
+      openUILinkIn(url, "tab");
+  },
+
+  /**
+   * Update the Tracking preferences based on controls.
+   */
+  setTrackingPrefs: function PPP_setTrackingPrefs()
+  {
+    let dntRadioGroup = document.getElementById("doNotTrackSelection"),
+        dntValuePref = document.getElementById("privacy.donottrackheader.value"),
+        dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled");
+
+    // if the selected radio button says "no preference", set on/off pref to
+    // false and don't change the value pref.
+    if (dntRadioGroup.selectedItem.value == -1) {
+      dntEnabledPref.value = false;
+      return dntValuePref.value;
+    }
+
+    dntEnabledPref.value = true;
+    return dntRadioGroup.selectedItem.value;
+  },
+
+  /**
+   * Obtain the tracking preference value and reflect it in the UI.
+   */
+  getTrackingPrefs: function PPP_getTrackingPrefs()
+  {
+    let dntValuePref = document.getElementById("privacy.donottrackheader.value"),
+        dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled");
+
+    // if DNT is enbaled, select the value from the selected radio
+    // button, otherwise choose the "no preference" radio button
+    if (dntEnabledPref.value)
+      return dntValuePref.value;
+
+    return document.getElementById("dntnopref").value;
+  },
+
+  /**
    * Update the private browsing auto-start pref and the history mode
    * micro-management prefs based on the history mode menulist
    */
   updateHistoryModePrefs: function PPP_updateHistoryModePrefs()
   {
     let pref = document.getElementById("browser.privatebrowsing.autostart");
     switch (document.getElementById("historyMode").value) {
     case "remember":
--- a/browser/components/preferences/privacy.xul
+++ b/browser/components/preferences/privacy.xul
@@ -21,16 +21,19 @@
             helpTopic="prefs-privacy">
 
     <preferences id="privacyPreferences">
   
       <!-- Tracking -->
       <preference id="privacy.donottrackheader.enabled"
                   name="privacy.donottrackheader.enabled"
                   type="bool"/>
+      <preference id="privacy.donottrackheader.value"
+                  name="privacy.donottrackheader.value"
+                  type="int"/>
 
       <!-- XXX button prefs -->
       <preference id="pref.privacy.disable_button.cookie_exceptions"
                   name="pref.privacy.disable_button.cookie_exceptions"
                   type="bool"/>
       <preference id="pref.privacy.disable_button.view_cookies"
                   name="pref.privacy.disable_button.view_cookies"
                   type="bool"/>
@@ -85,21 +88,31 @@
     
     <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
     
     <script type="application/javascript" src="chrome://browser/content/preferences/privacy.js"/>
 
     <!-- Tracking -->
     <groupbox id="trackingGroup">
       <caption label="&tracking.label;"/>
+      <radiogroup id="doNotTrackSelection" orient="vertical"
+                  preference="privacy.donottrackheader.value"
+                  onsynctopreference="return gPrivacyPane.setTrackingPrefs()"
+                  onsyncfrompreference="return gPrivacyPane.getTrackingPrefs()">
+        <radio id="dntnotrack" value="1" label="&dntTrackingNotOkay.label;"
+                accesskey="&dntTrackingNotOkay.accesskey;" />
+        <radio id="dntdotrack" value="0" label="&dntTrackingOkay.label;"
+                accesskey="&dntTrackingOkay.accesskey;" />
+        <radio id="dntnopref" value="-1" label="&dntTrackingNopref.label;"
+                accesskey="&dntTrackingNopref.accesskey;" />
+      </radiogroup>
+      <label class="text-link" id="doNotTrackInfo"
+             onclick="event.stopPropagation();gPrivacyPane.openTrackingInfoSite();"
+             value="&doNotTrackInfo.label;"/>
 
-      <checkbox id="privacyDoNotTrackPrefs"
-                label="&doNotTrack.label;"
-                accesskey="&doNotTrack.accesskey;"
-                preference="privacy.donottrackheader.enabled"/>
     </groupbox>
 
     <!-- History -->
     <groupbox id="historyGroup">
       <caption label="&history.label;"/>
 
       <hbox align="center">
         <label id="historyModeLabel"
--- a/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
@@ -1,16 +1,21 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <!ENTITY tracking.label                 "Tracking">
 
-<!ENTITY doNotTrack.label               "Tell websites I do not want to be tracked">
-<!ENTITY doNotTrack.accesskey           "d">
+<!ENTITY dntTrackingNopref.label        "Do not tell sites anything about my tracking preferences.">
+<!ENTITY dntTrackingNopref.accesskey    "o">
+<!ENTITY dntTrackingNotOkay.label       "Tell sites that I do not want to be tracked.">
+<!ENTITY dntTrackingNotOkay.accesskey   "n">
+<!ENTITY dntTrackingOkay.label          "Tell sites that I want to be tracked.">
+<!ENTITY dntTrackingOkay.accesskey      "t">
+<!ENTITY doNotTrackInfo.label           "Learn More">
 
 <!ENTITY  history.label                 "History">
 
 <!ENTITY  locationBar.label             "Location Bar">
 
 <!ENTITY  locbar.pre.label              "When using the location bar, suggest:">
 <!ENTITY  locbar.pre.accessKey          "u">
 <!ENTITY  locbar.post.label             "">
--- a/mobile/xul/app/mobile.js
+++ b/mobile/xul/app/mobile.js
@@ -540,16 +540,17 @@ pref("services.sync.prefs.sync.browser.t
 pref("services.sync.prefs.sync.browser.ui.zoom.reflow", true);
 pref("services.sync.prefs.sync.devtools.errorconsole.enabled", true);
 pref("services.sync.prefs.sync.javascript.enabled", true);
 pref("services.sync.prefs.sync.lightweightThemes.isThemeSelected", true);
 pref("services.sync.prefs.sync.lightweightThemes.usedThemes", true);
 pref("services.sync.prefs.sync.network.cookie.cookieBehavior", true);
 pref("services.sync.prefs.sync.permissions.default.image", true);
 pref("services.sync.prefs.sync.privacy.donottrackheader.enabled", true);
+pref("services.sync.prefs.sync.privacy.donottrackheader.value", true);
 pref("services.sync.prefs.sync.signon.rememberSignons", true);
 #endif
 
 // threshold where a tap becomes a drag, in 1/240" reference pixels
 // The names of the preferences are to be in sync with nsEventStateManager.cpp
 pref("ui.dragThresholdX", 25);
 pref("ui.dragThresholdY", 25);
 
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -707,16 +707,19 @@ pref("content.sink.pending_event_mode", 
 // Disable popups from plugins by default
 //   0 = openAllowed
 //   1 = openControlled
 //   2 = openAbused
 pref("privacy.popups.disable_from_plugins", 2);
 
 // "do not track" HTTP header, disabled by default
 pref("privacy.donottrackheader.enabled",    false);
+//   0 = tracking is acceptable
+//   1 = tracking is unacceptable
+pref("privacy.donottrackheader.value",      1);
 
 pref("dom.event.contextmenu.enabled",       true);
 pref("dom.event.clipboardevents.enabled",   true);
 
 pref("javascript.enabled",                  true);
 pref("javascript.options.strict",           false);
 #ifdef DEBUG
 pref("javascript.options.strict.debug",     true);
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -81,16 +81,17 @@ static NS_DEFINE_CID(kSocketProviderServ
 #define UA_SPARE_PLATFORM
 #endif
 
 #define HTTP_PREF_PREFIX        "network.http."
 #define INTL_ACCEPT_LANGUAGES   "intl.accept_languages"
 #define NETWORK_ENABLEIDN       "network.enableIDN"
 #define BROWSER_PREF_PREFIX     "browser.cache."
 #define DONOTTRACK_HEADER_ENABLED "privacy.donottrackheader.enabled"
+#define DONOTTRACK_HEADER_VALUE   "privacy.donottrackheader.value"
 #ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
 #define TELEMETRY_ENABLED        "toolkit.telemetry.enabledPreRelease"
 #else
 #define TELEMETRY_ENABLED        "toolkit.telemetry.enabled"
 #endif
 #define ALLOW_EXPERIMENTS        "network.allow-experiments"
 
 #define UA_PREF(_pref) UA_PREF_PREFIX _pref
@@ -165,16 +166,17 @@ nsHttpHandler::nsHttpHandler()
     , mLegacyAppVersion("5.0")
     , mProduct("Gecko")
     , mUserAgentIsDirty(true)
     , mUseCache(true)
     , mPromptTempRedirect(true)
     , mSendSecureXSiteReferrer(true)
     , mEnablePersistentHttpsCaching(false)
     , mDoNotTrackEnabled(false)
+    , mDoNotTrackValue(1)
     , mTelemetryEnabled(false)
     , mAllowExperiments(true)
     , mHandlerActive(false)
     , mEnableSpdy(false)
     , mSpdyV2(true)
     , mSpdyV3(true)
     , mCoalesceSpdy(true)
     , mUseAlternateProtocol(false)
@@ -244,16 +246,17 @@ nsHttpHandler::Init()
     nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (prefBranch) {
         prefBranch->AddObserver(HTTP_PREF_PREFIX, this, true);
         prefBranch->AddObserver(UA_PREF_PREFIX, this, true);
         prefBranch->AddObserver(INTL_ACCEPT_LANGUAGES, this, true);
         prefBranch->AddObserver(NETWORK_ENABLEIDN, this, true);
         prefBranch->AddObserver(BROWSER_PREF("disk_cache_ssl"), this, true);
         prefBranch->AddObserver(DONOTTRACK_HEADER_ENABLED, this, true);
+        prefBranch->AddObserver(DONOTTRACK_HEADER_VALUE, this, true);
         prefBranch->AddObserver(TELEMETRY_ENABLED, this, true);
 
         PrefsChanged(prefBranch, nullptr);
     }
 
     mMisc.AssignLiteral("rv:" MOZILLA_UAVERSION);
 
     mCompatFirefox.AssignLiteral("Firefox/" MOZILLA_UAVERSION);
@@ -376,17 +379,17 @@ nsHttpHandler::AddStandardRequestHeaders
 
     // Add the "Accept-Encoding" header
     rv = request->SetHeader(nsHttp::Accept_Encoding, mAcceptEncodings);
     if (NS_FAILED(rv)) return rv;
 
     // Add the "Do-Not-Track" header
     if (mDoNotTrackEnabled) {
       rv = request->SetHeader(nsHttp::DoNotTrack,
-                              NS_LITERAL_CSTRING("1"));
+                              nsPrintfCString("%d", mDoNotTrackValue));
       if (NS_FAILED(rv)) return rv;
     }
 
     return NS_OK;
 }
 
 nsresult
 nsHttpHandler::AddConnectionHeader(nsHttpHeaderArray *request,
@@ -1210,16 +1213,23 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
 
     if (PREF_CHANGED(DONOTTRACK_HEADER_ENABLED)) {
         cVar = false;
         rv = prefs->GetBoolPref(DONOTTRACK_HEADER_ENABLED, &cVar);
         if (NS_SUCCEEDED(rv)) {
             mDoNotTrackEnabled = cVar;
         }
     }
+    if (PREF_CHANGED(DONOTTRACK_HEADER_VALUE)) {
+        val = 1;
+        rv = prefs->GetIntPref(DONOTTRACK_HEADER_VALUE, &val);
+        if (NS_SUCCEEDED(rv)) {
+            mDoNotTrackValue = val;
+        }
+    }
 
     //
     // Telemetry
     //
 
     if (PREF_CHANGED(TELEMETRY_ENABLED)) {
         cVar = false;
         rv = prefs->GetBoolPref(TELEMETRY_ENABLED, &cVar);
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -371,19 +371,20 @@ private:
     bool           mPromptTempRedirect;
     // mSendSecureXSiteReferrer: default is false, 
     // if true allow referrer headers between secure non-matching hosts
     bool           mSendSecureXSiteReferrer;
 
     // Persistent HTTPS caching flag
     bool           mEnablePersistentHttpsCaching;
 
-    // For broadcasting the preference to not be tracked
+    // For broadcasting tracking preference
     bool           mDoNotTrackEnabled;
-    
+    PRUint8        mDoNotTrackValue;
+
     // Whether telemetry is reported or not
     bool           mTelemetryEnabled;
 
     // The value of network.allow-experiments
     bool           mAllowExperiments;
 
     // true in between init and shutdown states
     bool           mHandlerActive;