Bug 1501991 - Add a sub-panel for Trackers in the control center. r=Jamie,Ehsan
☠☠ backed out by 112ed7029b78 ☠ ☠
authorJohann Hofmann <jhofmann@mozilla.com>
Fri, 16 Nov 2018 10:50:31 +0000
changeset 503173 f73e25fa0d8c70b2d5451e922b20d319f2f931a3
parent 503172 b061ebcf3ba7c86654f6324fb4888a4da8053cde
child 503174 9702f65efe224bcb14f64db9eeb99ca2ad5ef8f8
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJamie, Ehsan
bugs1501991
milestone65.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 1501991 - Add a sub-panel for Trackers in the control center. r=Jamie,Ehsan Differential Revision: https://phabricator.services.mozilla.com/D11611
browser/base/content/browser-contentblocking.js
browser/base/content/browser.js
browser/base/content/test/trackingUI/browser.ini
browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
browser/base/content/test/trackingUI/browser_trackingUI_state.js
browser/base/content/test/trackingUI/browser_trackingUI_trackers_subview.js
browser/base/content/test/trackingUI/trackingAPI.js
browser/components/controlcenter/content/panel.inc.xul
browser/locales/en-US/chrome/browser/browser.dtd
browser/themes/shared/controlcenter/info.svg
browser/themes/shared/controlcenter/panel.inc.css
browser/themes/shared/jar.inc.mn
build/pgo/certs/cert9.db
build/pgo/certs/key4.db
build/pgo/certs/mochitest.client
build/pgo/server-locations.txt
--- a/browser/base/content/browser-contentblocking.js
+++ b/browser/base/content/browser-contentblocking.js
@@ -3,32 +3,46 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var TrackingProtection = {
   reportBreakageLabel: "trackingprotection",
   telemetryIdentifier: "tp",
   PREF_ENABLED_GLOBALLY: "privacy.trackingprotection.enabled",
   PREF_ENABLED_IN_PRIVATE_WINDOWS: "privacy.trackingprotection.pbmode.enabled",
   PREF_UI_ENABLED: "browser.contentblocking.trackingprotection.control-center.ui.enabled",
+  PREF_TRACKING_TABLE: "urlclassifier.trackingTable",
+  PREF_TRACKING_ANNOTATION_TABLE: "urlclassifier.trackingAnnotationTable",
   enabledGlobally: false,
   enabledInPrivateWindows: false,
 
   get categoryItem() {
     delete this.categoryItem;
     return this.categoryItem =
       document.getElementById("identity-popup-content-blocking-category-tracking-protection");
   },
 
+  get subViewList() {
+    delete this.subViewList;
+    return this.subViewList = document.getElementById("identity-popup-trackersView-list");
+  },
+
+  get strictInfo() {
+    delete this.strictInfo;
+    return this.strictInfo = document.getElementById("identity-popup-trackersView-strict-info");
+  },
+
   init() {
     this.updateEnabled();
 
     Services.prefs.addObserver(this.PREF_ENABLED_GLOBALLY, this);
     Services.prefs.addObserver(this.PREF_ENABLED_IN_PRIVATE_WINDOWS, this);
 
     XPCOMUtils.defineLazyPreferenceGetter(this, "visible", this.PREF_UI_ENABLED, false);
+    XPCOMUtils.defineLazyPreferenceGetter(this, "trackingTable", this.PREF_TRACKING_TABLE, false);
+    XPCOMUtils.defineLazyPreferenceGetter(this, "trackingAnnotationTable", this.PREF_TRACKING_ANNOTATION_TABLE, false);
   },
 
   uninit() {
     Services.prefs.removeObserver(this.PREF_ENABLED_GLOBALLY, this);
     Services.prefs.removeObserver(this.PREF_ENABLED_IN_PRIVATE_WINDOWS, this);
   },
 
   observe() {
@@ -46,16 +60,96 @@ var TrackingProtection = {
       Services.prefs.getBoolPref(this.PREF_ENABLED_GLOBALLY);
     this.enabledInPrivateWindows =
       Services.prefs.getBoolPref(this.PREF_ENABLED_IN_PRIVATE_WINDOWS);
   },
 
   isBlockerActivated(state) {
     return state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT;
   },
+
+  isAllowing(state) {
+    return state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
+  },
+
+  async updateSubView() {
+    let previousURI = gBrowser.currentURI.spec;
+    let previousWindow = gBrowser.selectedBrowser.innerWindowID;
+
+    let contentBlockingLogJSON = await gBrowser.selectedBrowser.getContentBlockingLog();
+    let contentBlockingLog = JSON.parse(contentBlockingLogJSON);
+
+    // Don't tell the user to turn on TP if they are already blocking trackers.
+    this.strictInfo.hidden = this.enabled;
+
+    let fragment = document.createDocumentFragment();
+    for (let [origin, actions] of Object.entries(contentBlockingLog)) {
+      let listItem = await this._createListItem(origin, actions);
+      if (listItem) {
+        fragment.appendChild(listItem);
+      }
+    }
+
+    // This might have taken a while. Only update the list if we're still on the same page.
+    if (previousURI == gBrowser.currentURI.spec &&
+        previousWindow == gBrowser.selectedBrowser.innerWindowID) {
+      this.subViewList.textContent = "";
+      this.subViewList.append(fragment);
+    }
+  },
+
+  // Given a URI from a source that was tracking-annotated, figure out
+  // if it's really on the tracking table or just on the annotation table.
+  _isOnTrackingTable(uri) {
+    if (this.trackingTable == this.trackingAnnotationTable) {
+      return true;
+    }
+    return new Promise(resolve => {
+      classifierService.asyncClassifyLocalWithTables(uri, this.trackingTable, [], [],
+        (code, list) => resolve(!!list));
+    });
+  },
+
+  async _createListItem(origin, actions) {
+    // Figure out if this list entry was actually detected by TP or something else.
+    let isDetected = false;
+    let isAllowed = false;
+    for (let [state] of actions) {
+      isAllowed = isAllowed || this.isAllowing(state);
+      isDetected = isDetected || isAllowed || this.isBlockerActivated(state);
+    }
+
+    if (!isDetected) {
+      return null;
+    }
+
+    let uri = Services.io.newURI(origin);
+
+    // Because we might use different lists for annotation vs. blocking, we
+    // need to make sure that this is a tracker that we would actually have blocked
+    // before showing it to the user.
+    let isTracker = await this._isOnTrackingTable(uri);
+    if (!isTracker) {
+      return null;
+    }
+
+    let listItem = document.createXULElement("hbox");
+    listItem.className = "identity-popup-trackersView-list-item";
+    listItem.classList.toggle("allowed", isAllowed);
+
+    let image = document.createXULElement("image");
+    listItem.append(image);
+
+    let label = document.createXULElement("label");
+    label.value = uri.host;
+    label.setAttribute("crop", "end");
+    listItem.append(label);
+
+    return listItem;
+  },
 };
 
 var ThirdPartyCookies = {
   telemetryIdentifier: "cr",
   PREF_ENABLED: "network.cookie.cookieBehavior",
   PREF_REPORT_BREAKAGE_ENABLED: "browser.contentblocking.rejecttrackers.reportBreakage.enabled",
   PREF_ENABLED_VALUES: [
     // These values match the ones exposed under the Content Blocking section
@@ -142,16 +236,21 @@ var ContentBlocking = {
     return this.PREF_INTRO_COUNT_CB;
   },
 
   get appMenuLabel() {
     delete this.appMenuLabel;
     return this.appMenuLabel = document.getElementById("appMenu-tp-label");
   },
 
+  get identityPopup() {
+    delete this.identityPopup;
+    return this.identityPopup = document.getElementById("identity-popup");
+  },
+
   strings: {
     get appMenuTitle() {
       delete this.appMenuTitle;
       return this.appMenuTitle =
         gNavigatorBundle.getString("contentBlocking.title");
     },
 
     get appMenuTooltip() {
@@ -233,30 +332,30 @@ var ContentBlocking = {
         blocker.uninit();
       }
     }
 
     Services.prefs.removeObserver(this.PREF_ANIMATIONS_ENABLED, this.updateAnimationsEnabled);
   },
 
   hideIdentityPopupAndReload() {
-    document.getElementById("identity-popup").hidePopup();
+    this.identityPopup.hidePopup();
     BrowserReload();
   },
 
   openPreferences(origin) {
     openPreferences("privacy-trackingprotection", { origin });
   },
 
   backToMainView() {
     this.identityPopupMultiView.goBack();
   },
 
   submitBreakageReport() {
-    document.getElementById("identity-popup").hidePopup();
+    this.identityPopup.hidePopup();
 
     let reportEndpoint = Services.prefs.getStringPref(this.PREF_REPORT_BREAKAGE_URL);
     if (!reportEndpoint) {
       return;
     }
 
     let formData = new FormData();
     formData.set("title", this.reportURI.host);
@@ -309,16 +408,21 @@ var ContentBlocking = {
     // Save this URI to make sure that the user really only submits the location
     // they see in the report breakage dialog.
     this.reportURI = gBrowser.currentURI;
     let urlWithoutQuery = this.reportURI.asciiSpec.replace("?" + this.reportURI.query, "");
     this.reportBreakageURL.textContent = urlWithoutQuery;
     this.identityPopupMultiView.showSubView("identity-popup-breakageReportView");
   },
 
+  async showTrackersSubview() {
+    await TrackingProtection.updateSubView();
+    this.identityPopupMultiView.showSubView("identity-popup-trackersView");
+  },
+
   shieldHistogramAdd(value) {
     if (PrivateBrowsingUtils.isWindowPrivate(window)) {
       return;
     }
     Services.telemetry.getHistogramById("TRACKING_PROTECTION_SHIELD").add(value);
   },
 
   onSecurityChange(oldState, state, webProgress, isSimulated,
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -138,16 +138,17 @@ XPCOMUtils.defineLazyScriptGetter(this, 
 if (AppConstants.NIGHTLY_BUILD) {
   XPCOMUtils.defineLazyScriptGetter(this, "gWebRender",
                                     "chrome://browser/content/browser-webrender.js");
 }
 
 // lazy service getters
 
 XPCOMUtils.defineLazyServiceGetters(this, {
+  classifierService: ["@mozilla.org/url-classifier/dbservice;1", "nsIURIClassifier"],
   Favicons: ["@mozilla.org/browser/favicon-service;1", "nsIFaviconService"],
   gAboutNewTabService: ["@mozilla.org/browser/aboutnewtab-service;1", "nsIAboutNewTabService"],
   gDNSService: ["@mozilla.org/network/dns-service;1", "nsIDNSService"],
   gSerializationHelper: ["@mozilla.org/network/serialization-helper;1", "nsISerializationHelper"],
   Marionette: ["@mozilla.org/remote/marionette;1", "nsIMarionette"],
   WindowsUIUtils: ["@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils"],
 });
 
--- a/browser/base/content/test/trackingUI/browser.ini
+++ b/browser/base/content/test/trackingUI/browser.ini
@@ -18,8 +18,9 @@ support-files =
   file_trackingUI_fetch.js
   file_trackingUI_fetch.js^headers^
 [browser_trackingUI_open_preferences.js]
 [browser_trackingUI_pbmode_exceptions.js]
 [browser_trackingUI_report_breakage.js]
 [browser_trackingUI_state.js]
 [browser_trackingUI_state_all_disabled.js]
 [browser_trackingUI_telemetry.js]
+[browser_trackingUI_trackers_subview.js]
--- a/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_pbmode_exceptions.js
@@ -54,19 +54,19 @@ function testTrackingPage(window) {
     ok(!hidden("#tracking-action-unblock"), "unblockButton is visible");
     ok(hidden("#tracking-action-unblock-private"), "unblockButtonPrivate is hidden");
   }
 
   ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
   ok(!hidden("#identity-popup-content-blocking-detected"), "blocking detected label is visible");
 
   ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
-  ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-add-blocking"),
-    "TP category item is not showing add blocking");
-  ok(!hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-state-label"),
+  ok(hidden("#identity-popup-content-blocking-category-tracking-protection > #identity-popup-content-blocking-tracking-protection-label-allowed"),
+    "TP category item is not showing the allowed label");
+  ok(!hidden("#identity-popup-content-blocking-category-tracking-protection > #identity-popup-content-blocking-tracking-protection-label-blocked"),
     "TP category item is set to blocked");
 }
 
 function testTrackingPageUnblocked() {
   info("Tracking content must be white-listed and not blocked");
   ok(ContentBlocking.content.hasAttribute("detected"), "trackers are detected");
   ok(ContentBlocking.content.hasAttribute("hasException"), "content shows exception");
 
@@ -79,19 +79,19 @@ function testTrackingPageUnblocked() {
   ok(!hidden("#tracking-action-block"), "blockButton is visible");
   ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
   ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
 
   ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
   ok(!hidden("#identity-popup-content-blocking-detected"), "blocking detected label is visible");
 
   ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
-  ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-add-blocking"),
-    "TP category item is not showing add blocking");
-  ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-state-label"),
+  ok(!hidden("#identity-popup-content-blocking-category-tracking-protection > #identity-popup-content-blocking-tracking-protection-label-allowed"),
+    "TP category item is showing the allowed label");
+  ok(hidden("#identity-popup-content-blocking-category-tracking-protection > #identity-popup-content-blocking-tracking-protection-label-blocked"),
     "TP category item is not set to blocked");
 }
 
 add_task(async function testExceptionAddition() {
   await UrlClassifierTestUtils.addTestTrackers();
   let privateWin = await BrowserTestUtils.openNewBrowserWindow({private: true});
   browser = privateWin.gBrowser;
   let tab = await BrowserTestUtils.openNewForegroundTab({ gBrowser: browser, waitForLoad: true, waitForStateStop: true });
--- a/browser/base/content/test/trackingUI/browser_trackingUI_state.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_state.js
@@ -129,30 +129,36 @@ function testTrackingPage(window) {
     is(!hidden("#tracking-action-unblock"), blockedByTP,
        "unblockButton is" + (blockedByTP ? "" : " not") + " visible");
   }
 
   ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
   ok(!hidden("#identity-popup-content-blocking-detected"), "blocking detected label is visible");
 
   ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
-  let category = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ?
-               "#identity-popup-content-blocking-category-3rdpartycookies" :
-               "#identity-popup-content-blocking-category-tracking-protection";
-  is(hidden(category + " > .identity-popup-content-blocking-category-add-blocking"), blockedByTP,
-    "Category item is" + (blockedByTP ? " not" : "") + " showing add blocking");
-  is(hidden(category + " > .identity-popup-content-blocking-category-state-label"), !blockedByTP,
-    "Category item is" + (blockedByTP ? "" : " not") + " set to blocked");
 
-  if (Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER) {
+  let cookiesBlocked = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
+  if (cookiesBlocked) {
+    let category = "#identity-popup-content-blocking-category-3rdpartycookies";
+    is(hidden(category + " > .identity-popup-content-blocking-category-add-blocking"), blockedByTP,
+      "Category item is" + (blockedByTP ? " not" : "") + " showing add blocking");
+    is(hidden(category + " > .identity-popup-content-blocking-category-state-label"), !blockedByTP,
+      "Category item is" + (blockedByTP ? "" : " not") + " set to blocked");
+
     ok(hidden("#identity-popup-content-blocking-category-label-default"),
       "Not showing default cookie restrictions label.");
     ok(!hidden("#identity-popup-content-blocking-category-label-trackers"),
       "Showing trackers cookie restrictions label.");
   } else {
+    let category = "#identity-popup-content-blocking-category-tracking-protection";
+    is(hidden(category + " > #identity-popup-content-blocking-tracking-protection-label-allowed"), blockedByTP,
+      "Category item is" + (blockedByTP ? " not" : "") + " showing the allowed label");
+    is(!hidden(category + " > #identity-popup-content-blocking-tracking-protection-label-blocked"), blockedByTP,
+      "Category item is" + (blockedByTP ? "" : " not") + " set to blocked");
+
     ok(hidden("#identity-popup-content-blocking-category-label-trackers"),
       "Not showing trackers cookie restrictions label.");
     ok(!hidden("#identity-popup-content-blocking-category-label-default"),
       "Showing default cookie restrictions label.");
   }
 }
 
 function testTrackingPageUnblocked(blockedByTP, window) {
@@ -170,24 +176,32 @@ function testTrackingPageUnblocked(block
   ok(!hidden("#tracking-action-block"), "blockButton is visible");
   ok(hidden("#tracking-action-unblock"), "unblockButton is hidden");
   ok(!hidden("#identity-popup-content-blocking-disabled-label"), "disabled label is visible");
 
   ok(hidden("#identity-popup-content-blocking-not-detected"), "blocking not detected label is hidden");
   ok(!hidden("#identity-popup-content-blocking-detected"), "blocking detected label is visible");
 
   ok(!hidden("#identity-popup-content-blocking-category-list"), "category list is visible");
-  let category = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER ?
-               "#identity-popup-content-blocking-category-3rdpartycookies" :
-               "#identity-popup-content-blocking-category-tracking-protection";
-  is(hidden(category + " > .identity-popup-content-blocking-category-add-blocking"), blockedByTP,
-    "Category item is" + (blockedByTP ? " not" : "") + " showing add blocking");
-  // Always hidden no matter if blockedByTP or not, since we have an exception.
-  ok(hidden("#identity-popup-content-blocking-category-tracking-protection > .identity-popup-content-blocking-category-state-label"),
-    "TP category item is not set to blocked");
+
+  let cookiesBlocked = Services.prefs.getIntPref(TPC_PREF) == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
+  if (cookiesBlocked) {
+    let category = "#identity-popup-content-blocking-category-3rdpartycookies";
+    is(hidden(category + " > .identity-popup-content-blocking-category-add-blocking"), blockedByTP,
+      "Category item is" + (blockedByTP ? " not" : "") + " showing add blocking");
+    ok(!hidden("#identity-popup-content-blocking-category-tracking-protection > #identity-popup-content-blocking-tracking-protection-label-allowed"),
+      "TP category item is showing the allowed label");
+  } else {
+    let category = "#identity-popup-content-blocking-category-tracking-protection";
+    // If there's an exception we always show the "Allowed" label.
+    ok(!hidden(category + " > #identity-popup-content-blocking-tracking-protection-label-allowed"),
+      "Category item is showing the allowed label");
+    ok(hidden(category + " > #identity-popup-content-blocking-tracking-protection-label-blocked"),
+      "Category item is not set to blocked");
+  }
 }
 
 async function testContentBlocking(tab) {
   info("Testing with Tracking Protection ENABLED.");
 
   info("Load a test page not containing tracking elements");
   await promiseTabLoadEvent(tab, BENIGN_PAGE);
   testBenignPage();
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_trackers_subview.js
@@ -0,0 +1,118 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
+
+const TP_PREF = "privacy.trackingprotection.enabled";
+
+add_task(async function setup() {
+  await UrlClassifierTestUtils.addTestTrackers();
+});
+
+function openIdentityPopup() {
+  let mainView = document.getElementById("identity-popup-mainView");
+  let viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
+  gIdentityHandler._identityBox.click();
+  return viewShown;
+}
+
+function waitForSecurityChange(blocked) {
+  return new Promise(resolve => {
+    let webProgressListener = {
+      onStateChange: () => {},
+      onStatusChange: () => {},
+      onLocationChange: () => {},
+      onSecurityChange: (webProgress, request, oldState, state) => {
+        if ((!blocked && state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT) ||
+            (blocked && state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT)) {
+          gBrowser.removeProgressListener(webProgressListener);
+          resolve();
+        }
+      },
+      onProgressChange: () => {},
+      QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener]),
+    };
+
+    gBrowser.addProgressListener(webProgressListener);
+  });
+}
+
+async function assertSitesListed(blocked) {
+  await BrowserTestUtils.withNewTab(TRACKING_PAGE, async function(browser) {
+    await openIdentityPopup();
+
+    let categoryItem =
+      document.getElementById("identity-popup-content-blocking-category-tracking-protection");
+    ok(BrowserTestUtils.is_visible(categoryItem), "TP category item is visible");
+    let trackersView = document.getElementById("identity-popup-trackersView");
+    let viewShown = BrowserTestUtils.waitForEvent(trackersView, "ViewShown");
+    categoryItem.click();
+    await viewShown;
+
+    ok(true, "Trackers view was shown");
+
+    let listItems = document.querySelectorAll(".identity-popup-trackersView-list-item");
+    is(listItems.length, 1, "We have 1 tracker in the list");
+
+    let strictInfo = document.getElementById("identity-popup-trackersView-strict-info");
+    is(BrowserTestUtils.is_hidden(strictInfo), Services.prefs.getBoolPref(TP_PREF),
+      "Strict info is hidden if TP is enabled.");
+
+    let mainView = document.getElementById("identity-popup-mainView");
+    viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
+    let backButton = trackersView.querySelector(".subviewbutton-back");
+    backButton.click();
+    await viewShown;
+
+    ok(true, "Main view was shown");
+
+    let change = waitForSecurityChange(blocked);
+
+    await ContentTask.spawn(browser, {}, function() {
+      content.postMessage("more-tracking", "*");
+    });
+
+    await change;
+
+    viewShown = BrowserTestUtils.waitForEvent(trackersView, "ViewShown");
+    categoryItem.click();
+    await viewShown;
+
+    ok(true, "Trackers view was shown");
+
+    listItems = Array.from(document.querySelectorAll(".identity-popup-trackersView-list-item"));
+    is(listItems.length, 2, "We have 2 trackers in the list");
+
+    let listItem = listItems.find(item => item.querySelector("label").value == "trackertest.org");
+    ok(listItem, "Has an item for trackertest.org");
+    ok(BrowserTestUtils.is_visible(listItem), "List item is visible");
+    is(listItem.classList.contains("allowed"), !blocked,
+      "Indicates whether the tracker was blocked or allowed");
+
+    listItem = listItems.find(item => item.querySelector("label").value == "itisatracker.org");
+    ok(listItem, "Has an item for itisatracker.org");
+    ok(BrowserTestUtils.is_visible(listItem), "List item is visible");
+    is(listItem.classList.contains("allowed"), !blocked,
+      "Indicates whether the tracker was blocked or allowed");
+  });
+}
+
+add_task(async function testTrackersSubView() {
+  Services.prefs.setBoolPref(TP_PREF, false);
+  await assertSitesListed(false);
+  Services.prefs.setBoolPref(TP_PREF, true);
+  await assertSitesListed(true);
+  let uri = Services.io.newURI("https://tracking.example.org");
+  Services.perms.add(uri, "trackingprotection", Services.perms.ALLOW_ACTION);
+  await assertSitesListed(false);
+  Services.perms.remove(uri, "trackingprotection");
+  await assertSitesListed(true);
+  Services.prefs.clearUserPref(TP_PREF);
+});
+
+add_task(function cleanup() {
+  Services.prefs.clearUserPref(TP_PREF);
+  UrlClassifierTestUtils.cleanupTestTrackers();
+});
--- a/browser/base/content/test/trackingUI/trackingAPI.js
+++ b/browser/base/content/test/trackingUI/trackingAPI.js
@@ -1,16 +1,22 @@
 onmessage = event => {
   switch (event.data) {
   case "tracking": {
       let ifr = document.createElement("iframe");
       ifr.src = "https://trackertest.org/";
       document.body.appendChild(ifr);
     }
     break;
+  case "more-tracking": {
+      let ifr = document.createElement("iframe");
+      ifr.src = "https://itisatracker.org/";
+      document.body.appendChild(ifr);
+    }
+    break;
   case "cookie": {
       let ifr = document.createElement("iframe");
       ifr.src = "https://trackertest.org/browser/browser/base/content/test/trackingUI/cookieServer.sjs";
       document.body.appendChild(ifr);
     }
     break;
   }
 };
--- a/browser/components/controlcenter/content/panel.inc.xul
+++ b/browser/components/controlcenter/content/panel.inc.xul
@@ -77,25 +77,26 @@
           </hbox>
 
           <description id="identity-popup-content-blocking-detected"
                        crop="end">&contentBlocking.detected;</description>
           <description id="identity-popup-content-blocking-not-detected"
                        crop="end">&contentBlocking.notDetected;</description>
 
           <vbox id="identity-popup-content-blocking-category-list">
-            <hbox id="identity-popup-content-blocking-category-tracking-protection"
-                  class="identity-popup-content-blocking-category" align="center" role="group">
+            <toolbarbutton id="identity-popup-content-blocking-category-tracking-protection"
+                  onclick="ContentBlocking.showTrackersSubview()"
+                  class="identity-popup-content-blocking-category" align="center">
               <image class="identity-popup-content-blocking-category-icon tracking-protection-icon"/>
               <label flex="1" class="identity-popup-content-blocking-category-label">&contentBlocking.trackingProtection3.label;</label>
-              <label flex="1" class="identity-popup-content-blocking-category-state-label">&contentBlocking.trackingProtection.blocking.label;</label>
-              <label flex="1" class="identity-popup-content-blocking-category-add-blocking text-link"
-                     id="identity-popup-tracking-protection-add-blocking"
-                     onclick="ContentBlocking.openPreferences('identityPopup-CB-tracking-protection'); gIdentityHandler.recordClick('tp_add_blocking');">&contentBlocking.trackingProtection.add.label;</label>
-            </hbox>
+              <label flex="1" id="identity-popup-content-blocking-tracking-protection-label-allowed"
+                     class="identity-popup-content-blocking-category-state-label">&contentBlocking.trackingProtection.allowed.label;</label>
+              <label flex="1" id="identity-popup-content-blocking-tracking-protection-label-blocked"
+                     class="identity-popup-content-blocking-category-state-label">&contentBlocking.trackingProtection.blocked.label;</label>
+            </toolbarbutton>
             <hbox id="identity-popup-content-blocking-category-3rdpartycookies"
                   class="identity-popup-content-blocking-category" align="center" role="group">
               <image class="identity-popup-content-blocking-category-icon thirdpartycookies-icon"/>
               <label flex="1" id="identity-popup-content-blocking-category-label-default"
                      class="identity-popup-content-blocking-category-label">&contentBlocking.3rdPartyCookies.label;</label>
               <label flex="1" id="identity-popup-content-blocking-category-label-trackers"
                      hidden="true" class="identity-popup-content-blocking-category-label">&contentBlocking.3rdPartyCookies.trackers.label;</label>
               <label flex="1" class="identity-popup-content-blocking-category-state-label">&contentBlocking.3rdPartyCookies.blocking.label;</label>
@@ -244,16 +245,35 @@
         <!-- More Security Information -->
         <button id="identity-popup-more-info"
                 label="&identity.moreInfoLinkText2;"
                 oncommand="gIdentityHandler.handleMoreInfoClick(event);"/>
       </vbox>
 
     </panelview>
 
+    <!-- Trackers SubView -->
+    <panelview id="identity-popup-trackersView"
+               role="document"
+               title="&contentBlocking.trackersView.label;"
+               descriptionheightworkaround="true">
+        <vbox id="identity-popup-trackersView-list">
+        </vbox>
+        <hbox id="identity-popup-trackersView-strict-info">
+          <image/>
+          <label>&contentBlocking.trackersView.strictInfo.label;</label>
+        </hbox>
+        <vbox class="identity-popup-footer">
+          <button id="identity-popup-trackersView-settings-button"
+                  label="&contentBlocking.manageSettings.label;"
+                  accesskey="&contentBlocking.manageSettings.accesskey;"
+                  oncommand="ContentBlocking.openPreferences();"/>
+        </vbox>
+    </panelview>
+
     <!-- Report Breakage SubView -->
     <panelview id="identity-popup-breakageReportView"
                title="&contentBlocking.breakageReportView.label;"
                descriptionheightworkaround="true">
         <vbox id="identity-popup-breakageReportView-heading">
           <description>&contentBlocking.breakageReportView2.description;</description>
           <label id="identity-popup-breakageReportView-learn-more"
                  class="text-link">&contentBlocking.breakageReportView.learnMore;</label>
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -965,34 +965,29 @@ you can use these alternative items. Oth
 
 <!ENTITY contentBlocking.title "Content Blocking">
 <!ENTITY contentBlocking.detected "Blockable content detected on this site.">
 <!ENTITY contentBlocking.notDetected "No blockable content detected on this page.">
 <!ENTITY contentBlocking.disabled.label "Disabled">
 <!ENTITY contentBlocking.disabled.tooltip "You have disabled Content Blocking.">
 <!ENTITY contentBlocking.exception.tooltip "You have disabled Content Blocking for this site.">
 
-<!ENTITY contentBlocking.trackingProtection2.label "All Detected Trackers">
 <!ENTITY contentBlocking.trackingProtection3.label "Trackers">
+<!-- LOCALIZATION NOTE (contentBlocking.trackingProtection.allowed.label):
+     This label signals that this type of content blocking is turned
+     OFF and is not blocking tracker content, so this is not
+     a positive thing. It forms the end of the (imaginary) sentence
+     "Trackers [are] Allowed"-->
+<!ENTITY contentBlocking.trackingProtection.allowed.label "Allowed">
 <!-- LOCALIZATION NOTE (contentBlocking.trackingProtection.blocked.label):
      This label signals that this type of content blocking is turned
      ON and is successfully blocking tracker content, so this is
      a positive thing. It forms the end of the (imaginary) sentence
      "Trackers [are] Blocked"-->
 <!ENTITY contentBlocking.trackingProtection.blocked.label "Blocked">
-<!-- LOCALIZATION NOTE (contentBlocking.tranckingProtection.blocking.label):
-     This label signals that this type of content blocking is turned
-     ON, so this is a positive thing. It forms the verb in the (imaginary) sentence
-     "Firefox is blocking Trackers"-->
-<!ENTITY contentBlocking.trackingProtection.blocking.label "Blocking">
-<!-- LOCALIZATION NOTE (contentBlocking.trackingProtection.add.label):
-     This is displayed as a link to preferences, where the user can add
-     this specific type of content blocking. When this text is shown
-     the type of content blocking is currently not enabled. -->
-<!ENTITY contentBlocking.trackingProtection.add.label "Add Blocking…">
 
 <!ENTITY contentBlocking.3rdPartyCookies.label "Third-Party Cookies">
 <!ENTITY contentBlocking.3rdPartyCookies.trackers.label "Tracking Cookies">
 <!-- LOCALIZATION NOTE (contentBlocking.3rdPartyCookies.blocked.label):
      This label signals that this type of content blocking is turned
      ON and is successfully blocking third-party cookies, so this is
      a positive thing. It forms the end of the (imaginary) sentence
      "Third-Party Cookies [are] Blocked"-->
@@ -1003,16 +998,22 @@ you can use these alternative items. Oth
      "Firefox is blocking Third-Party Cookies"-->
 <!ENTITY contentBlocking.3rdPartyCookies.blocking.label "Blocking">
 <!-- LOCALIZATION NOTE (contentBlocking.3rdPartyCookies.add.label):
      This is displayed as a link to preferences, where the user can add
      this specific type of content blocking. When this text is shown
      the type of content blocking is currently not enabled. -->
 <!ENTITY contentBlocking.3rdPartyCookies.add.label "Add Blocking…">
 
+<!ENTITY contentBlocking.manageSettings.label "Manage Content Blocking">
+<!ENTITY contentBlocking.manageSettings.accesskey "M">
+
+<!ENTITY contentBlocking.trackersView.label "Trackers">
+<!ENTITY contentBlocking.trackersView.strictInfo.label "To block all trackers, set content blocking to “Strict”.">
+
 <!ENTITY contentBlocking.openBreakageReportView2.label "Report a problem">
 <!ENTITY contentBlocking.breakageReportView.label "Report Problems">
 <!ENTITY contentBlocking.breakageReportView2.description "Content blocking can cause problems with some websites. When you report problems, you’ll help make &brandShortName; better for everyone. (This will send a URL as well as information about your browser settings to Mozilla.)">
 <!ENTITY contentBlocking.breakageReportView.learnMore "Learn More">
 <!ENTITY contentBlocking.breakageReportView.collection.url.label "URL">
 <!ENTITY contentBlocking.breakageReportView.collection.comments.label "What problems did you have? (Optional)">
 <!ENTITY contentBlocking.breakageReportView.sendReport.label "Send Report">
 <!ENTITY contentBlocking.breakageReportView.cancel.label "Cancel">
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/controlcenter/info.svg
@@ -0,0 +1,4 @@
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="context-fill" fill-rule="evenodd" d="M8 1a7 7 0 1 1-7 7 7 7 0 0 1 7-7zm0 3a1 1 0 1 1-1 1 1 1 0 0 1 1-1zm0 3a1 1 0 0 1 1 1v3a1 1 0 0 1-2 0V8a1 1 0 0 1 1-1z"></path></svg>
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -4,16 +4,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 %endif
 
 /* Hide all conditional elements by default. */
 :-moz-any([when-connection],[when-mixedcontent],[when-ciphers],[when-loginforms]) {
   display: none;
 }
 
+#identity-popup {
+  --identity-popup-width: 33rem;
+}
+
 /* This is used by screenshots tests to hide intermittently different
  * identity popup shadows (see bug 1425253). */
 #identity-popup.no-shadow {
   -moz-window-shadow: none;
 }
 
 /* Show the right elements for the right connection states. */
 #identity-popup[connection=not-secure] [when-connection~=not-secure],
@@ -63,18 +67,18 @@
   padding: 0;
   /* Set default fill for icons in the identity popup.
      Individual icons can override this. */
   fill: currentColor;
   fill-opacity: .6;
 }
 
 #identity-popup-mainView {
-  min-width: 33em;
-  max-width: 33em;
+  min-width: var(--identity-popup-width);
+  max-width: var(--identity-popup-width);
 }
 
 .identity-popup-section {
   border-top: 1px solid var(--panel-separator-color);
 }
 
 .identity-popup-security-content,
 #identity-popup-permissions-content,
@@ -140,17 +144,22 @@
 }
 
 .identity-popup-preferences-button > .toolbarbutton-text {
   display: none;
 }
 
 /* CONTENT */
 
+.identity-popup-footer,
+.tracking-protection-button,
+#identity-popup-trackersView-strict-info > label,
+.identity-popup-trackersView-list-item > label,
 #identity-popup-mainView-panel-header > label,
+#identity-popup-trackersView > .panel-header,
 #identity-popup-securityView > .panel-header,
 #identity-popup-breakageReportView > .panel-header,
 #identity-popup-content-blocking-report-breakage,
 #identity-popup-content-blocking-disabled-label,
 .identity-popup-content-blocking-category-label,
 .identity-popup-content-blocking-category-state-label,
 .identity-popup-content-blocking-category-add-blocking,
 .identity-popup-permission-label,
@@ -173,17 +182,17 @@
 
 #identity-popup-mainView-panel-header-span {
   display: inline-block;
   font-weight: 600;
   text-align: center;
   overflow-wrap: break-word;
   /* This is needed for the overflow-wrap to work correctly.
    * 33em is the panel width, panel-header has 1em padding on each side. */
-  max-width: calc(33rem - 2em);
+  max-width: calc(var(--identity-popup-width) - 2em);
 }
 
 #identity-popup-permissions-content > description,
 #identity-popup-content-blocking-content > description {
   color: var(--panel-disabled-color);
 }
 
 /* This element needs the pre-wrap because we add newlines to it in the code. */
@@ -196,17 +205,17 @@
   font-size: 150%;
 }
 
 #identity-popup-host {
   overflow-wrap: break-word;
   /* This is needed for the overflow-wrap to work correctly.
    * 1em + 2em + 24px is .identity-popup-security-content padding
    * 33em is the panel width */
-  max-width: calc(33rem - 3rem - 24px);
+  max-width: calc(var(--identity-popup-width) - 3rem - 24px);
 }
 
 .identity-popup-warning-gray {
   padding-inline-start: 24px;
   background: url(chrome://browser/skin/controlcenter/warning.svg) no-repeat 0 50%;
   fill: #808080;
   stroke: #fff;
   -moz-context-properties: fill, stroke;
@@ -377,16 +386,103 @@ description#identity-popup-content-verif
 #identity-popup-breakageReportView-collection-comments {
   height: 120px;
 }
 
 #identity-popup-content-blocking-content {
   background-image: url("chrome://browser/skin/controlcenter/tracking-protection.svg");
 }
 
+#identity-popup-content-blocking-category-tracking-protection {
+  /* Overwrite toolbarbutton styles */
+  margin: 0;
+  padding-inline-start: 0;
+}
+
+#identity-popup-content-blocking-category-tracking-protection:-moz-focusring,
+#identity-popup-content-blocking-category-tracking-protection:hover {
+  border-radius: 2px;
+  background-color: var(--arrowpanel-dimmed-further);
+}
+
+#identity-popup-content-blocking-category-tracking-protection:hover:active {
+  background-color: var(--arrowpanel-dimmed-even-further);
+}
+
+#identity-popup-content-blocking-category-tracking-protection::after {
+  content: url(chrome://browser/skin/back-12.svg);
+  -moz-context-properties: fill, fill-opacity;
+  transform: scaleX(-1) translateY(1px);
+  float: right;
+}
+
+#identity-popup-content-blocking-category-tracking-protection:-moz-locale-dir(rtl)::after {
+  transform: scaleX(1) translateY(1px);
+}
+
+/* This subview could get filled with a lot of trackers, set a maximum size
+ * and allow it to scroll vertically.*/
+#identity-popup-trackersView {
+  max-height: 600px;
+}
+
+#identity-popup-trackersView-list {
+  padding: 5px 20px;
+  -moz-box-flex: 1;
+  overflow: scroll;
+}
+
+.identity-popup-trackersView-list-item {
+  margin: 5px 0;
+  overflow: hidden;
+}
+
+.identity-popup-trackersView-list-item > label {
+  /* Limit to full width - container padding - icon width - icon margin */
+  max-width: calc(var(--identity-popup-width) - 40px - 16px - 10px);
+}
+
+.identity-popup-trackersView-list-item > image {
+  list-style-image: url(chrome://browser/skin/controlcenter/trackers-disabled.svg);
+  margin-inline-end: 10px;
+  -moz-context-properties: fill, fill-opacity;
+}
+
+.identity-popup-trackersView-list-item.allowed > image {
+  list-style-image: url(chrome://browser/skin/controlcenter/trackers.svg);
+}
+
+#identity-popup-trackersView-strict-info {
+  min-height: 40px;
+  /* Limit to full width - margin */
+  max-width: calc(var(--identity-popup-width) - 12px);
+  min-width: calc(var(--identity-popup-width) - 12px);
+  background-color: #45a1ff80;
+  margin: 6px;
+  text-align: center;
+  -moz-box-align: center;
+  -moz-box-pack: center;
+  padding: 5px 15px;
+  border-radius: 3px;
+  color: #002275;
+}
+
+#identity-popup-trackersView-strict-info > image {
+  list-style-image: url(chrome://browser/skin/controlcenter/info.svg);
+  -moz-context-properties: fill;
+  fill: currentColor;
+  margin-inline-end: 10px;
+}
+
+#identity-popup-trackersView-strict-info > label {
+  overflow-wrap: break-word;
+  /* Limit to full width - container margin - container padding - icon width - icon margin */
+  max-width: calc(var(--identity-popup-width) - 12px - 20px - 16px - 10px);
+}
+
 /* Disabled label */
 
 #identity-popup-content-blocking-disabled-label {
   padding: 2px 5px;
   border-radius: 3px;
   margin: 5px;
   display: none;
   color: #fff;
@@ -428,21 +524,30 @@ description#identity-popup-content-verif
 }
 
 /* Show the "detected"/"not detected" message depending on the content state. */
 #identity-popup-content-blocking-content:not([detected]) > #identity-popup-content-blocking-detected,
 #identity-popup-content-blocking-content[detected] > #identity-popup-content-blocking-not-detected {
   display: none;
 }
 
-#identity-popup-content-blocking-content[hasException] .identity-popup-content-blocking-category-state-label,
-.identity-popup-content-blocking-category:not(.blocked) .identity-popup-content-blocking-category-state-label {
+.identity-popup-content-blocking-category-state-label {
   display: none;
 }
 
+/* TODO: This will be cleaned up by bug 1501992 */
+/* Hide the state label unless we blocked something only for third party cookies */
+#identity-popup-content-blocking-content:not([hasException]) #identity-popup-content-blocking-category-3rdpartycookies.blocked .identity-popup-content-blocking-category-state-label,
+/* For trackers, either show a "blocked" or "allowed" label depending on the state. */
+#identity-popup-content-blocking-content:not([hasException]) #identity-popup-content-blocking-category-tracking-protection.blocked > #identity-popup-content-blocking-tracking-protection-label-blocked,
+#identity-popup-content-blocking-category-tracking-protection:not(.blocked) > #identity-popup-content-blocking-tracking-protection-label-allowed,
+#identity-popup-content-blocking-content[hasException] #identity-popup-content-blocking-tracking-protection-label-allowed {
+  display: -moz-box;
+}
+
 .identity-popup-content-blocking-category.blocked .identity-popup-content-blocking-category-add-blocking {
   display: none;
 }
 
 .tracking-protection-icon {
   list-style-image: url(chrome://browser/skin/controlcenter/trackers.svg);
 }
 
@@ -463,16 +568,17 @@ description#identity-popup-content-verif
 .tracking-protection-button {
   list-style-image: url(chrome://browser/skin/tracking-protection.svg);
   -moz-appearance: none;
   margin: 1em 0 0;
   display: none;
   height: 32px;
   background-color: var(--arrowpanel-dimmed);
   color: inherit;
+  margin-inline-end: 8px;
 }
 
 .tracking-protection-button:hover {
   background-color: var(--arrowpanel-dimmed-further);
 }
 
 .tracking-protection-button:hover:active {
   background-color: var(--arrowpanel-dimmed-even-further);
@@ -546,32 +652,41 @@ description#identity-popup-content-verif
   min-height: 24px;
 }
 
 #identity-popup-content-blocking-category-list,
 #identity-popup-permission-list {
   /* Offset the padding set on #identity-popup-permissions-content so that it
      shows up just below the section. The permission icons are 16px wide and
      should be right aligned with the section icon. */
-  margin-inline-start: calc(-1em - 16px);
+  margin-inline-start: calc(-1em - 24px);
 }
 
 .identity-popup-content-blocking-category,
 .identity-popup-permission-item {
   min-height: 24px;
 }
 
+.identity-popup-content-blocking-category {
+  padding-inline-end: 12px;
+}
+
+.identity-popup-permission-item {
+  padding-inline-end: 8px;
+}
+
 #identity-popup-permission-list:not(:empty) {
   margin-top: 5px;
 }
 
 .identity-popup-content-blocking-category-icon,
 .identity-popup-permission-icon {
   width: 16px;
   height: 16px;
+  margin-inline-start: 12px;
 }
 
 .identity-popup-permission-icon.in-use {
   -moz-context-properties: fill;
   fill: rgb(224, 41, 29);
   animation: 1.5s ease in-use-blink infinite;
 }
 
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -23,16 +23,17 @@
   skin/classic/browser/addons/addon-install-installed.svg      (../shared/addons/addon-install-installed.svg)
   skin/classic/browser/addons/addon-install-warning.svg        (../shared/addons/addon-install-warning.svg)
   skin/classic/browser/controlcenter/3rdpartycookies.svg       (../shared/controlcenter/3rdpartycookies.svg)
   skin/classic/browser/controlcenter/3rdpartycookies-disabled.svg (../shared/controlcenter/3rdpartycookies-disabled.svg)
   skin/classic/browser/controlcenter/conn-not-secure.svg       (../shared/controlcenter/conn-not-secure.svg)
   skin/classic/browser/controlcenter/connection.svg            (../shared/controlcenter/connection.svg)
   skin/classic/browser/controlcenter/mcb-disabled.svg          (../shared/controlcenter/mcb-disabled.svg)
   skin/classic/browser/controlcenter/extension.svg             (../shared/controlcenter/extension.svg)
+  skin/classic/browser/controlcenter/info.svg                  (../shared/controlcenter/info.svg)
   skin/classic/browser/controlcenter/permissions.svg           (../shared/controlcenter/permissions.svg)
   skin/classic/browser/controlcenter/trackers.svg              (../shared/controlcenter/trackers.svg)
   skin/classic/browser/controlcenter/trackers-disabled.svg     (../shared/controlcenter/trackers-disabled.svg)
   skin/classic/browser/controlcenter/tracking-protection.svg   (../shared/controlcenter/tracking-protection.svg)
   skin/classic/browser/controlcenter/warning.svg               (../shared/controlcenter/warning.svg)
   skin/classic/browser/customizableui/empty-overflow-panel.png     (../shared/customizableui/empty-overflow-panel.png)
   skin/classic/browser/customizableui/empty-overflow-panel@2x.png  (../shared/customizableui/empty-overflow-panel@2x.png)
   skin/classic/browser/customizableui/density-compact.svg      (../shared/customizableui/density-compact.svg)
index 4c453a7a9c928a97ab4ee4350298d709927494ce..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
index 06c967ea7e9f3a56b1e5e8736f55a4402a41534a..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
index b79fb90c8518548dfb6fdf9d1c3a4a8ab8343058..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/build/pgo/server-locations.txt
+++ b/build/pgo/server-locations.txt
@@ -170,16 +170,17 @@ https://sub.sectest1.example.org:443
 #
 http://malware.example.com:80
 http://unwanted.example.com:80
 http://tracking.example.com:80
 http://not-tracking.example.com:80
 http://tracking.example.org:80
 http://another-tracking.example.net:80
 http://itisatracker.org:80
+https://itisatracker.org:443
 http://trackertest.org:80
 
 https://malware.example.com:443
 https://unwanted.example.com:443
 https://tracking.example.com:443
 https://not-tracking.example.com:443
 https://tracking.example.org:443
 https://another-tracking.example.net:443