Bug 1501992 - Add a sub-panel for Cookies in the control center. r=Ehsan
☠☠ backed out by e2b33de5f4c7 ☠ ☠
authorJohann Hofmann <jhofmann@mozilla.com>
Fri, 30 Nov 2018 21:57:23 +0000
changeset 449047 3ab27af474f99084e7d9a969c46937722264a90d
parent 449046 d9dd441d53fd99128a87395409a95399d7f75845
child 449048 ae07b833833146811d507abd3166794be91b1fa4
push id74127
push userjhofmann@mozilla.com
push dateSat, 01 Dec 2018 02:05:00 +0000
treeherderautoland@ae07b8338331 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersEhsan
bugs1501992
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 1501992 - Add a sub-panel for Cookies in the control center. r=Ehsan Differential Revision: https://phabricator.services.mozilla.com/D12596
browser/base/content/browser-contentblocking.js
browser/base/content/test/trackingUI/browser_trackingUI_open_preferences.js
browser/base/content/test/trackingUI/browser_trackingUI_report_breakage.js
browser/components/controlcenter/content/panel.inc.xul
browser/locales/en-US/chrome/browser/browser.dtd
browser/locales/en-US/chrome/browser/browser.properties
browser/themes/shared/controlcenter/panel.inc.css
toolkit/components/telemetry/Events.yaml
--- a/browser/base/content/browser-contentblocking.js
+++ b/browser/base/content/browser-contentblocking.js
@@ -2,45 +2,57 @@
  * 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/. */
 
 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 categoryLabel() {
+    delete this.categoryLabel;
+    return this.categoryLabel =
+      document.getElementById("identity-popup-content-blocking-tracking-protection-state-label");
+  },
+
   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");
   },
 
+  strings: {
+    get subViewBlocked() {
+      delete this.subViewBlocked;
+      return this.subViewBlocked =
+        gNavigatorBundle.getString("contentBlocking.trackersView.blocked.label");
+    },
+  },
+
   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);
   },
@@ -55,24 +67,39 @@ var TrackingProtection = {
             PrivateBrowsingUtils.isWindowPrivate(window));
   },
 
   updateEnabled() {
     this.enabledGlobally =
       Services.prefs.getBoolPref(this.PREF_ENABLED_GLOBALLY);
     this.enabledInPrivateWindows =
       Services.prefs.getBoolPref(this.PREF_ENABLED_IN_PRIVATE_WINDOWS);
+    this.updateCategoryLabel();
   },
 
-  isBlockerActivated(state) {
-    return state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT;
+  updateCategoryLabel() {
+    let label;
+    if (this.enabled) {
+      label = "contentBlocking.trackers.blocked.label";
+    } else {
+      label = "contentBlocking.trackers.allowed.label";
+    }
+    this.categoryLabel.textContent = gNavigatorBundle.getString(label);
+  },
+
+  isBlocking(state) {
+    return (state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT) != 0;
   },
 
   isAllowing(state) {
-    return state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
+    return (state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT) != 0;
+  },
+
+  isDetected(state) {
+    return this.isBlocking(state) || this.isAllowing(state);
   },
 
   async updateSubView() {
     let previousURI = gBrowser.currentURI.spec;
     let previousWindow = gBrowser.selectedBrowser.innerWindowID;
 
     let contentBlockingLogJSON = await gBrowser.selectedBrowser.getContentBlockingLog();
     let contentBlockingLog = JSON.parse(contentBlockingLogJSON);
@@ -109,17 +136,17 @@ var TrackingProtection = {
   },
 
   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);
+      isDetected = isDetected || isAllowed || this.isBlocking(state);
     }
 
     if (!isDetected) {
       return null;
     }
 
     let uri = Services.io.newURI(origin);
 
@@ -127,47 +154,84 @@ var TrackingProtection = {
     // 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.className = "identity-popup-content-blocking-list-item";
     listItem.classList.toggle("allowed", isAllowed);
+    // Repeat the host in the tooltip in case it's too long
+    // and overflows in our panel.
+    listItem.tooltipText = uri.host;
 
     let image = document.createXULElement("image");
+    image.className = "identity-popup-trackersView-icon";
+    image.classList.toggle("allowed", isAllowed);
     listItem.append(image);
 
     let label = document.createXULElement("label");
     label.value = uri.host;
+    label.className = "identity-popup-content-blocking-list-host-label";
     label.setAttribute("crop", "end");
     listItem.append(label);
 
+    if (!isAllowed) {
+      let stateLabel = document.createXULElement("label");
+      stateLabel.value = this.strings.subViewBlocked;
+      stateLabel.className = "identity-popup-content-blocking-list-state-label";
+      listItem.append(stateLabel);
+    }
+
     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
     // of the Preferences UI.
     Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN,  // Block all third-party cookies
     Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,  // Block third-party cookies from trackers
   ],
-  PREF_UI_ENABLED: "browser.contentblocking.rejecttrackers.control-center.ui.enabled",
 
   get categoryItem() {
     delete this.categoryItem;
     return this.categoryItem =
-      document.getElementById("identity-popup-content-blocking-category-3rdpartycookies");
+      document.getElementById("identity-popup-content-blocking-category-cookies");
+  },
+
+  get categoryLabel() {
+    delete this.categoryLabel;
+    return this.categoryLabel =
+      document.getElementById("identity-popup-content-blocking-cookies-state-label");
+  },
+
+  get subViewList() {
+    delete this.subViewList;
+    return this.subViewList = document.getElementById("identity-popup-cookiesView-list");
+  },
+
+  strings: {
+    get subViewAllowed() {
+      delete this.subViewAllowed;
+      return this.subViewAllowed =
+        gNavigatorBundle.getString("contentBlocking.cookiesView.allowed.label");
+    },
+
+    get subViewBlocked() {
+      delete this.subViewBlocked;
+      return this.subViewBlocked =
+        gNavigatorBundle.getString("contentBlocking.cookiesView.blocked.label");
+    },
   },
 
   get reportBreakageLabel() {
     switch (this.behaviorPref) {
     case Ci.nsICookieService.BEHAVIOR_ACCEPT:
       return "nocookiesblocked";
     case Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN:
       return "allthirdpartycookiesblocked";
@@ -178,50 +242,246 @@ var ThirdPartyCookies = {
     default:
       Cu.reportError(`Error: Unknown cookieBehavior pref observed: ${this.behaviorPref}`);
       // fall through
     case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER:
       return "cookierestrictions";
     }
   },
 
-  get categoryLabelDefault() {
-    delete this.categoryLabelDefault;
-    return this.categoryLabelDefault =
-      document.getElementById("identity-popup-content-blocking-category-label-default");
-  },
-
-  get categoryLabelTrackers() {
-    delete this.categoryLabelTrackers;
-    return this.categoryLabelTrackers =
-      document.getElementById("identity-popup-content-blocking-category-label-trackers");
-  },
-
   updateCategoryLabel() {
-    let rejectTrackers = this.behaviorPref == Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
-    this.categoryLabelDefault.hidden = rejectTrackers;
-    this.categoryLabelTrackers.hidden = !rejectTrackers;
+    let label;
+    switch (this.behaviorPref) {
+    case Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN:
+      label = "contentBlocking.cookies.3rdPartyBlocked.label";
+      break;
+    case Ci.nsICookieService.BEHAVIOR_REJECT:
+      label = "contentBlocking.cookies.allBlocked.label";
+      break;
+    case Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN:
+      label = "contentBlocking.cookies.unvisitedBlocked.label";
+      break;
+    case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER:
+      label = "contentBlocking.cookies.trackersBlocked.label";
+      break;
+    default:
+      Cu.reportError(`Error: Unknown cookieBehavior pref observed: ${this.behaviorPref}`);
+      // fall through
+    case Ci.nsICookieService.BEHAVIOR_ACCEPT:
+      label = "contentBlocking.cookies.allowed.label";
+      break;
+    }
+    this.categoryLabel.textContent = gNavigatorBundle.getString(label);
   },
 
   init() {
     XPCOMUtils.defineLazyPreferenceGetter(this, "behaviorPref", this.PREF_ENABLED,
       Ci.nsICookieService.BEHAVIOR_ACCEPT, this.updateCategoryLabel.bind(this));
-    XPCOMUtils.defineLazyPreferenceGetter(this, "visible", this.PREF_UI_ENABLED, false);
     XPCOMUtils.defineLazyPreferenceGetter(this, "reportBreakageEnabled",
       this.PREF_REPORT_BREAKAGE_ENABLED, false);
     this.updateCategoryLabel();
   },
+
   get enabled() {
     return this.PREF_ENABLED_VALUES.includes(this.behaviorPref);
   },
 
-  isBlockerActivated(state) {
+  isBlocking(state) {
     return (state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_TRACKER) != 0 ||
+           (state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_ALL) != 0 ||
+           (state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_BY_PERMISSION) != 0 ||
            (state & Ci.nsIWebProgressListener.STATE_COOKIES_BLOCKED_FOREIGN) != 0;
   },
+
+  isDetected(state) {
+    return (state & Ci.nsIWebProgressListener.STATE_COOKIES_LOADED) != 0;
+  },
+
+  async updateSubView() {
+    let contentBlockingLogJSON = await gBrowser.selectedBrowser.getContentBlockingLog();
+    let contentBlockingLog = JSON.parse(contentBlockingLogJSON);
+
+    let categories = this._processContentBlockingLog(contentBlockingLog);
+
+    this.subViewList.textContent = "";
+
+    for (let category of ["firstParty", "trackers", "thirdParty"]) {
+      if (categories[category].length) {
+        let box = document.createXULElement("vbox");
+        let label = document.createXULElement("label");
+        label.className = "identity-popup-cookiesView-list-header";
+        label.textContent = gNavigatorBundle.getString(`contentBlocking.cookiesView.${category}.label`);
+        box.appendChild(label);
+        for (let info of categories[category]) {
+          box.appendChild(this._createListItem(info));
+        }
+        this.subViewList.appendChild(box);
+      }
+    }
+  },
+
+  _hasException(origin) {
+    for (let perm of Services.perms.getAllForPrincipal(gBrowser.contentPrincipal)) {
+      if (perm.type == "3rdPartyStorage^" + origin || perm.type.startsWith("3rdPartyStorage^" + origin + "^")) {
+        return true;
+      }
+    }
+
+    let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);
+    // Cookie exceptions get "inherited" from parent- to sub-domain, so we need to
+    // make sure to include parent domains in the permission check for "cookies".
+    return Services.perms.testPermissionFromPrincipal(principal, "cookie") != Services.perms.UNKNOWN_ACTION;
+  },
+
+  _clearException(origin) {
+    for (let perm of Services.perms.getAllForPrincipal(gBrowser.contentPrincipal)) {
+      if (perm.type == "3rdPartyStorage^" + origin || perm.type.startsWith("3rdPartyStorage^" + origin + "^")) {
+        Services.perms.removePermission(perm);
+      }
+    }
+
+    // OAs don't matter here, so we can just use the hostname.
+    let host = Services.io.newURI(origin).host;
+
+    // Cookie exceptions get "inherited" from parent- to sub-domain, so we need to
+    // clear any cookie permissions from parent domains as well.
+    for (let perm of Services.perms.enumerator) {
+      if (perm.type == "cookie" &&
+          Services.eTLD.hasRootDomain(host, perm.principal.URI.host)) {
+        Services.perms.removePermission(perm);
+      }
+    }
+  },
+
+  // Transforms and filters cookie entries in the content blocking log
+  // so that we can categorize and display them in the UI.
+  _processContentBlockingLog(log) {
+    let newLog = {
+      firstParty: [],
+      trackers: [],
+      thirdParty: [],
+    };
+
+    let firstPartyDomain = null;
+    try {
+      firstPartyDomain = Services.eTLD.getBaseDomain(gBrowser.currentURI);
+    } catch (e) {
+      // There are nasty edge cases here where someone is trying to set a cookie
+      // on a public suffix or an IP address. Just categorize those as third party...
+      if (e.result != Cr.NS_ERROR_HOST_IS_IP_ADDRESS &&
+          e.result != Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
+        throw e;
+      }
+    }
+
+    for (let [origin, actions] of Object.entries(log)) {
+      if (!origin.startsWith("http")) {
+        continue;
+      }
+
+      let info = {origin, isAllowed: true, hasException: this._hasException(origin)};
+      let hasCookie = false;
+      let isTracker = false;
+
+      // Extract information from the states entries in the content blocking log.
+      // Each state will contain a single state flag from nsIWebProgressListener.
+      // Note that we are using the same helper functions that are applied to the
+      // bit map passed to onSecurityChange (which contains multiple states), thus
+      // not checking exact equality, just presence of bits.
+      for (let [state, blocked] of actions) {
+        if (this.isDetected(state)) {
+          hasCookie = true;
+        }
+        if (TrackingProtection.isAllowing(state)) {
+          isTracker = true;
+        }
+        // blocked tells us whether the resource was actually blocked
+        // (which it may not be in case of an exception).
+        if (this.isBlocking(state) && blocked) {
+          info.isAllowed = false;
+        }
+      }
+
+      if (!hasCookie) {
+        continue;
+      }
+
+      let isFirstParty = false;
+      try {
+        let uri = Services.io.newURI(origin);
+        isFirstParty = Services.eTLD.getBaseDomain(uri) == firstPartyDomain;
+      } catch (e) {
+        if (e.result != Cr.NS_ERROR_HOST_IS_IP_ADDRESS &&
+            e.result != Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
+          throw e;
+        }
+      }
+
+      if (isFirstParty) {
+        newLog.firstParty.push(info);
+      } else if (isTracker) {
+        newLog.trackers.push(info);
+      } else {
+        newLog.thirdParty.push(info);
+      }
+    }
+
+    return newLog;
+  },
+
+  _createListItem({origin, isAllowed, hasException}) {
+    let listItem = document.createXULElement("hbox");
+    listItem.className = "identity-popup-content-blocking-list-item";
+    listItem.classList.toggle("allowed", isAllowed);
+    // Repeat the origin in the tooltip in case it's too long
+    // and overflows in our panel.
+    listItem.tooltipText = origin;
+
+    let image = document.createXULElement("image");
+    image.className = "identity-popup-cookiesView-icon";
+    image.classList.toggle("allowed", isAllowed);
+    listItem.append(image);
+
+    let label = document.createXULElement("label");
+    label.value = origin;
+    label.className = "identity-popup-content-blocking-list-host-label";
+    label.setAttribute("crop", "end");
+    listItem.append(label);
+
+    let stateLabel;
+    if (isAllowed && hasException) {
+      stateLabel = document.createXULElement("label");
+      stateLabel.value = this.strings.subViewAllowed;
+      stateLabel.className = "identity-popup-content-blocking-list-state-label";
+      listItem.append(stateLabel);
+    } else if (!isAllowed) {
+      stateLabel = document.createXULElement("label");
+      stateLabel.value = this.strings.subViewBlocked;
+      stateLabel.className = "identity-popup-content-blocking-list-state-label";
+      listItem.append(stateLabel);
+    }
+
+    if (hasException) {
+      let removeException = document.createXULElement("button");
+      removeException.className = "identity-popup-permission-remove-button";
+      removeException.tooltipText = gNavigatorBundle.getFormattedString(
+        "contentBlocking.cookiesView.removeButton.tooltip", [origin]);
+      removeException.addEventListener("click", () => {
+        this._clearException(origin);
+        // Just flip the display based on what state we had previously.
+        stateLabel.value = isAllowed ? this.strings.subViewBlocked : this.strings.subViewAllowed;
+        listItem.classList.toggle("allowed", !isAllowed);
+        image.classList.toggle("allowed", !isAllowed);
+        removeException.hidden = true;
+      });
+      listItem.append(removeException);
+    }
+
+    return listItem;
+  },
 };
 
 
 var ContentBlocking = {
   // If the user ignores the doorhanger, we stop showing it after some time.
   MAX_INTROS: 20,
   PREF_ANIMATIONS_ENABLED: "toolkit.cosmeticAnimations.enabled",
   PREF_REPORT_BREAKAGE_ENABLED: "browser.contentblocking.reportBreakage.enabled",
@@ -392,21 +652,19 @@ var ContentBlocking = {
     // Leave the ? at the end of the URL to signify that this URL had its query stripped.
     let urlWithoutQuery = this.reportURI.asciiSpec.replace(this.reportURI.query, "");
     let body = `Full URL: ${urlWithoutQuery}\n`;
     body += `userAgent: ${navigator.userAgent}\n`;
 
     body += "\n**Preferences**\n";
     body += `${TrackingProtection.PREF_ENABLED_GLOBALLY}: ${Services.prefs.getBoolPref(TrackingProtection.PREF_ENABLED_GLOBALLY)}\n`;
     body += `${TrackingProtection.PREF_ENABLED_IN_PRIVATE_WINDOWS}: ${Services.prefs.getBoolPref(TrackingProtection.PREF_ENABLED_IN_PRIVATE_WINDOWS)}\n`;
-    body += `${TrackingProtection.PREF_UI_ENABLED}: ${Services.prefs.getBoolPref(TrackingProtection.PREF_UI_ENABLED)}\n`;
     body += `urlclassifier.trackingTable: ${Services.prefs.getStringPref("urlclassifier.trackingTable")}\n`;
     body += `network.http.referer.defaultPolicy: ${Services.prefs.getIntPref("network.http.referer.defaultPolicy")}\n`;
     body += `network.http.referer.defaultPolicy.pbmode: ${Services.prefs.getIntPref("network.http.referer.defaultPolicy.pbmode")}\n`;
-    body += `${ThirdPartyCookies.PREF_UI_ENABLED}: ${Services.prefs.getBoolPref(ThirdPartyCookies.PREF_UI_ENABLED)}\n`;
     body += `${ThirdPartyCookies.PREF_ENABLED}: ${Services.prefs.getIntPref(ThirdPartyCookies.PREF_ENABLED)}\n`;
     body += `network.cookie.lifetimePolicy: ${Services.prefs.getIntPref("network.cookie.lifetimePolicy")}\n`;
     body += `privacy.restrict3rdpartystorage.expiration: ${Services.prefs.getIntPref("privacy.restrict3rdpartystorage.expiration")}\n`;
 
     let comments = document.getElementById("identity-popup-breakageReportView-collection-comments");
     body += "\n**Comments**\n" + comments.value;
 
     formData.set("body", body);
@@ -442,16 +700,21 @@ var ContentBlocking = {
     this.identityPopupMultiView.showSubView("identity-popup-breakageReportView");
   },
 
   async showTrackersSubview() {
     await TrackingProtection.updateSubView();
     this.identityPopupMultiView.showSubView("identity-popup-trackersView");
   },
 
+  async showCookiesSubview() {
+    await ThirdPartyCookies.updateSubView();
+    this.identityPopupMultiView.showSubView("identity-popup-cookiesView");
+  },
+
   shieldHistogramAdd(value) {
     if (PrivateBrowsingUtils.isWindowPrivate(window)) {
       return;
     }
     Services.telemetry.getHistogramById("TRACKING_PROTECTION_SHIELD").add(value);
   },
 
   onSecurityChange(oldState, state, webProgress, isSimulated,
@@ -468,81 +731,80 @@ var ContentBlocking = {
 
     // The user might have navigated before the shield animation
     // finished. In this case, reset the animation to be able to
     // play it in full again and avoid choppiness.
     if (webProgress.isTopLevel) {
       this.iconBox.removeAttribute("animate");
     }
 
-    let anyBlockerActivated = false;
+    let anyDetected = false;
+    let anyBlocking = false;
 
     for (let blocker of this.blockers) {
       // Store data on whether the blocker is activated in the current document for
       // reporting it using the "report breakage" dialog. Under normal circumstances this
       // dialog should only be able to open in the currently selected tab and onSecurityChange
       // runs on tab switch, so we can avoid associating the data with the document directly.
-      blocker.activated = blocker.isBlockerActivated(state);
+      blocker.activated = blocker.isBlocking(state);
       blocker.categoryItem.classList.toggle("blocked", blocker.enabled);
-      blocker.categoryItem.hidden = !blocker.visible;
-      anyBlockerActivated = anyBlockerActivated || blocker.activated;
+      let detected = blocker.isDetected(state);
+      blocker.categoryItem.hidden = !detected;
+      anyDetected = anyDetected || detected;
+      anyBlocking = anyBlocking || blocker.activated;
     }
 
-    // We consider the shield state "active" when some kind of blocking activity
-    // occurs on the page.  Note that merely allowing the loading of content that
-    // we could have blocked does not trigger the appearance of the shield.
-    // This state will be overriden later if there's an exception set for this site.
-    let active = anyBlockerActivated;
-    let isAllowing = state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT;
-    let detected = anyBlockerActivated || isAllowing;
-
     let isBrowserPrivate = PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser);
 
     // Check whether the user has added an exception for this site.
     let type =  isBrowserPrivate ? "trackingprotection-pb" : "trackingprotection";
     let hasException = Services.perms.testExactPermission(baseURI, type) ==
       Services.perms.ALLOW_ACTION;
 
-    this.content.toggleAttribute("detected", detected);
+    // We consider the shield state "active" when some kind of blocking activity
+    // occurs on the page.  Note that merely allowing the loading of content that
+    // we could have blocked does not trigger the appearance of the shield.
+    // This state will be overriden later if there's an exception set for this site.
+    this.content.toggleAttribute("detected", anyDetected);
+    this.content.toggleAttribute("blocking", anyBlocking);
     this.content.toggleAttribute("hasException", hasException);
-    this.content.toggleAttribute("active", active);
 
-    this.iconBox.toggleAttribute("active", active);
+    this.iconBox.toggleAttribute("active", anyBlocking);
     this.iconBox.toggleAttribute("hasException", hasException);
 
     // For release (due to the large volume) we only want to receive reports
     // for breakage that is directly related to third party cookie blocking.
     if (this.reportBreakageEnabled ||
         (ThirdPartyCookies.reportBreakageEnabled &&
          ThirdPartyCookies.activated &&
          !TrackingProtection.activated)) {
       this.reportBreakageButton.removeAttribute("hidden");
     } else {
       this.reportBreakageButton.setAttribute("hidden", "true");
     }
 
     if (isSimulated) {
       this.iconBox.removeAttribute("animate");
-    } else if (active && webProgress.isTopLevel) {
+    } else if (anyBlocking && webProgress.isTopLevel) {
       this.iconBox.setAttribute("animate", "true");
 
       if (!isBrowserPrivate) {
         let introCount = Services.prefs.getIntPref(this.prefIntroCount);
         if (introCount < this.MAX_INTROS) {
           Services.prefs.setIntPref(this.prefIntroCount, ++introCount);
           Services.prefs.savePrefFile(null);
           this.showIntroPanel();
         }
       }
     }
 
     if (hasException) {
       this.iconBox.setAttribute("tooltiptext", this.disabledTooltipText);
       this.shieldHistogramAdd(1);
-    } else if (active) {
+    } else if (anyBlocking) {
       this.iconBox.setAttribute("tooltiptext", this.activeTooltipText);
       this.shieldHistogramAdd(2);
     } else {
       this.iconBox.removeAttribute("tooltiptext");
       this.shieldHistogramAdd(0);
     }
   },
 
--- a/browser/base/content/test/trackingUI/browser_trackingUI_open_preferences.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_open_preferences.js
@@ -1,17 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const TP_PREF = "privacy.trackingprotection.enabled";
 const TPC_PREF = "network.cookie.cookieBehavior";
-const TP_UI_PREF = "browser.contentblocking.trackingprotection.control-center.ui.enabled";
-const RT_UI_PREF = "browser.contentblocking.rejecttrackers.control-center.ui.enabled";
 const TRACKING_PAGE = "http://tracking.example.org/browser/browser/base/content/test/trackingUI/trackingPage.html";
 
 async function waitAndAssertPreferencesShown() {
   await BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popuphidden");
   await TestUtils.waitForCondition(() => gBrowser.currentURI.spec == "about:preferences#privacy",
     "Should open about:preferences.");
 
   await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
--- a/browser/base/content/test/trackingUI/browser_trackingUI_report_breakage.js
+++ b/browser/base/content/test/trackingUI/browser_trackingUI_report_breakage.js
@@ -181,21 +181,19 @@ add_task(async function testReportBreaka
         let body = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
         let boundary = request.getHeader("Content-Type").match(/boundary=-+([^-]*)/i)[1];
         let regex = new RegExp("-+" + boundary + "-*\\s+");
         let sections = body.split(regex);
 
         let prefs = [
           "privacy.trackingprotection.enabled",
           "privacy.trackingprotection.pbmode.enabled",
-          "browser.contentblocking.trackingprotection.control-center.ui.enabled",
           "urlclassifier.trackingTable",
           "network.http.referer.defaultPolicy",
           "network.http.referer.defaultPolicy.pbmode",
-          "browser.contentblocking.rejecttrackers.control-center.ui.enabled",
           "network.cookie.cookieBehavior",
           "network.cookie.lifetimePolicy",
           "privacy.restrict3rdpartystorage.expiration",
         ];
         let prefsBody = "";
 
         for (let pref of prefs) {
           prefsBody += `${pref}: ${Preferences.get(pref)}\r\n`;
--- a/browser/components/controlcenter/content/panel.inc.xul
+++ b/browser/components/controlcenter/content/panel.inc.xul
@@ -69,37 +69,30 @@
 
           <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">
             <toolbarbutton id="identity-popup-content-blocking-category-tracking-protection"
-                  onclick="ContentBlocking.showTrackersSubview()"
-                  class="identity-popup-content-blocking-category" align="center">
+                           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" 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>
+              <label flex="1" id="identity-popup-content-blocking-tracking-protection-state-label" class="identity-popup-content-blocking-category-state-label"/>
             </toolbarbutton>
-            <hbox id="identity-popup-content-blocking-category-3rdpartycookies"
-                  class="identity-popup-content-blocking-category" align="center" role="group">
+            <toolbarbutton id="identity-popup-content-blocking-category-cookies"
+                           onclick="ContentBlocking.showCookiesSubview()"
+                           class="identity-popup-content-blocking-category" align="center">
               <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>
-              <label flex="1" class="identity-popup-content-blocking-category-add-blocking text-link"
-                     id="identity-popup-3rdpartycookies-add-blocking"
-                     onclick="ContentBlocking.openPreferences('identityPopup-CB-3rdpartycookies'); gIdentityHandler.recordClick('cookies_add_blocking');">&contentBlocking.3rdPartyCookies.add.label;</label>
-            </hbox>
+                     class="identity-popup-content-blocking-category-label">&contentBlocking.cookies.label;</label>
+              <label flex="1" id="identity-popup-content-blocking-cookies-state-label" class="identity-popup-content-blocking-category-state-label"/>
+            </toolbarbutton>
           </vbox>
 
           <button id="tracking-action-unblock"
                   class="panel-button tracking-protection-button"
                   label="&trackingProtection.unblock5.label;"
                   accesskey="&trackingProtection.unblock5.accesskey;"
                   oncommand="ContentBlocking.disableForCurrentPage(); gIdentityHandler.recordClick('unblock');" />
           <button id="tracking-action-unblock-private"
@@ -241,30 +234,45 @@
 
     </panelview>
 
     <!-- Trackers SubView -->
     <panelview id="identity-popup-trackersView"
                role="document"
                title="&contentBlocking.trackersView.label;"
                descriptionheightworkaround="true">
-        <vbox id="identity-popup-trackersView-list">
+        <vbox id="identity-popup-trackersView-list" class="identity-popup-content-blocking-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>
 
+    <!-- Cookies SubView -->
+    <panelview id="identity-popup-cookiesView"
+               role="document"
+               title="&contentBlocking.cookiesView.label;"
+               descriptionheightworkaround="true">
+        <vbox id="identity-popup-cookiesView-list" class="identity-popup-content-blocking-list">
+        </vbox>
+        <vbox class="identity-popup-footer">
+          <button id="identity-popup-cookiesView-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
@@ -964,54 +964,26 @@ you can use these alternative items. Oth
 <!ENTITY getUserMedia.audioCapture.label "Audio from the tab will be shared.">
 <!ENTITY getUserMedia.allWindowsShared.message "All visible windows on your screen will be shared.">
 
 <!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.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">
-
-<!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"-->
-<!ENTITY contentBlocking.3rdPartyCookies.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 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.cookies.label "Cookies">
+<!ENTITY contentBlocking.cookiesView.label "Cookies and Site Data">
+
 <!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">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -500,16 +500,59 @@ contentBlocking.tooltip=Open Content Blo
 # The terminology used to refer to levels of Content Blocking is also used
 # in preferences and should be translated consistently.
 # LOCALIZATION NOTE (contentBlocking.category.standard):
 # "Standard" in this case is an adjective, meaning "default" or "normal"
 contentBlocking.category.standard=Standard
 contentBlocking.category.strict=Strict
 contentBlocking.category.custom=Custom
 
+# LOCALIZATION NOTE (contentBlocking.trackers.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"
+contentBlocking.trackers.allowed.label=Allowed
+# LOCALIZATION NOTE (contentBlocking.trackers.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"
+contentBlocking.trackers.blocked.label=Blocked
+
+# LOCALIZATION NOTE (contentBlocking.trackersView.blocked.label):
+#   This label is shown next to a tracker in the trackers subview.
+#   It forms the end of the (imaginary) sentence "www.example.com [was] Blocked"
+contentBlocking.trackersView.blocked.label=Blocked
+
+# LOCALIZATION NOTE (contentBlocking.cookies.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
+#   "Cookies [are] Allowed"
+contentBlocking.cookies.allowed.label=Allowed
+contentBlocking.cookies.trackersBlocked.label=Tracking Cookies Blocked
+contentBlocking.cookies.3rdPartyBlocked.label=Third-Party Cookies Blocked
+contentBlocking.cookies.unvisitedBlocked.label=Unvisited Site Cookies Blocked
+contentBlocking.cookies.allBlocked.label=All Cookies Blocked
+
+contentBlocking.cookiesView.firstParty.label=From This Site
+contentBlocking.cookiesView.trackers.label=Tracking Cookies
+contentBlocking.cookiesView.thirdParty.label=Third-Party Cookies
+# LOCALIZATION NOTE (contentBlocking.cookiesView.allowed.label):
+#   This label is shown next to a cookie origin in the cookies subview.
+#   It forms the end of the (imaginary) sentence "www.example.com [was] Allowed"
+contentBlocking.cookiesView.allowed.label=Allowed
+# LOCALIZATION NOTE (contentBlocking.cookiesView.blocked.label):
+#   This label is shown next to a cookie origin in the cookies subview.
+#   It forms the end of the (imaginary) sentence "www.example.com [was] Blocked"
+contentBlocking.cookiesView.blocked.label=Blocked
+# LOCALIZATION NOTE (contentBlocking.cookiesView.removeButton.tooltip): %S is the domain of the site.
+contentBlocking.cookiesView.removeButton.tooltip=Clear cookie exception for %S
+
 # LOCALIZATION NOTE (contentBlocking.intro.title): %S is brandShortName.
 contentBlocking.intro.title=New in %S: Content Blocking
 # LOCALIZATION NOTE (contentBlocking.v1.intro.description): %S is brandShortName.
 contentBlocking.intro.v1.description=When you see the shield, %S is blocking parts of the page that can slow your browsing or track you online.
 contentBlocking.intro.v2.description=The privacy benefits of Tracking Protection are now just one part of content blocking. When you see the shield, content blocking is on.
 # LOCALIZATION NOTE (trackingProtection.intro.step1of3): Indicates that the intro panel is step one of three in a tour.
 trackingProtection.intro.step1of3=1 of 3
 trackingProtection.intro.nextButton.label=Next
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -160,17 +160,18 @@
 }
 
 /* CONTENT */
 
 #tracking-protection-preferences-button > .toolbarbutton-text,
 .identity-popup-footer,
 .tracking-protection-button,
 #identity-popup-trackersView-strict-info > label,
-.identity-popup-trackersView-list-item > label,
+.identity-popup-cookiesView-list-header,
+.identity-popup-content-blocking-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-category-label,
 .identity-popup-content-blocking-category-state-label,
 .identity-popup-content-blocking-category-add-blocking,
@@ -398,76 +399,105 @@ 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 {
+.identity-popup-content-blocking-category {
   /* Overwrite toolbarbutton styles */
   -moz-appearance: none;
   margin: 0;
   padding-inline-start: 0;
 }
 
-#identity-popup-content-blocking-category-tracking-protection:-moz-focusring,
-#identity-popup-content-blocking-category-tracking-protection:hover {
+.identity-popup-content-blocking-category:-moz-focusring,
+.identity-popup-content-blocking-category:hover {
   border-radius: 2px;
   background-color: var(--arrowpanel-dimmed-further);
 }
 
-#identity-popup-content-blocking-category-tracking-protection:hover:active {
+.identity-popup-content-blocking-category:hover:active {
   background-color: var(--arrowpanel-dimmed-even-further);
 }
 
-#identity-popup-content-blocking-category-tracking-protection::after {
+.identity-popup-content-blocking-category::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 {
+.identity-popup-content-blocking-category:-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-cookiesView,
 #identity-popup-trackersView {
   max-height: 600px;
 }
 
-#identity-popup-trackersView-list {
+.identity-popup-cookiesView-list-header {
+  color: var(--panel-disabled-color);
+  margin: 5px 0;
+}
+
+.identity-popup-content-blocking-list {
   padding: 5px 20px;
   -moz-box-flex: 1;
   overflow: auto;
 }
 
-.identity-popup-trackersView-list-item {
+.identity-popup-content-blocking-list-item {
   margin: 5px 0;
   overflow: hidden;
+  -moz-box-align: center;
+}
+
+.identity-popup-content-blocking-list-item:not(.allowed) {
+  color: var(--panel-disabled-color);
 }
 
-.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-content-blocking-list-host-label {
+  -moz-box-flex: 1;
 }
 
-.identity-popup-trackersView-list-item > image {
-  list-style-image: url(chrome://browser/skin/controlcenter/trackers-disabled.svg);
+.identity-popup-content-blocking-list-state-label {
+  -moz-box-flex: 1;
+  text-align: end;
+  margin-inline-start: 5px;
+  margin-inline-end: 2px;
+}
+
+.identity-popup-trackersView-icon,
+.identity-popup-cookiesView-icon {
   margin-inline-end: 10px;
   -moz-context-properties: fill, fill-opacity;
 }
 
-.identity-popup-trackersView-list-item.allowed > image {
+.identity-popup-trackersView-icon {
+  list-style-image: url(chrome://browser/skin/controlcenter/trackers-disabled.svg);
+}
+
+.identity-popup-trackersView-icon.allowed {
   list-style-image: url(chrome://browser/skin/controlcenter/trackers.svg);
 }
 
+.identity-popup-cookiesView-icon {
+  list-style-image: url(chrome://browser/skin/controlcenter/3rdpartycookies-disabled.svg);
+}
+
+.identity-popup-cookiesView-icon.allowed {
+  list-style-image: url(chrome://browser/skin/controlcenter/3rdpartycookies.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;
@@ -492,61 +522,30 @@ description#identity-popup-content-verif
 }
 
 /* Content Blocking categories */
 
 #identity-popup-content-blocking-category-list {
   margin-top: 10px;
 }
 
-/* Don't show the categories when no trackers were detected. */
-#identity-popup-content-blocking-content:not([detected]) > #identity-popup-content-blocking-category-list {
-  display: none;
-}
-
 /* 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-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);
 }
 
-#identity-popup-content-blocking-category-tracking-protection.blocked > .tracking-protection-icon {
-  list-style-image: url(chrome://browser/skin/controlcenter/trackers-disabled.svg);
-}
-
 .thirdpartycookies-icon {
   list-style-image: url(chrome://browser/skin/controlcenter/3rdpartycookies.svg);
 }
 
-#identity-popup-content-blocking-category-3rdpartycookies.blocked > .thirdpartycookies-icon {
-  list-style-image: url(chrome://browser/skin/controlcenter/3rdpartycookies-disabled.svg);
-}
-
 /* Content Blocking action button */
 
 .tracking-protection-button {
   list-style-image: url(chrome://browser/skin/tracking-protection.svg);
   -moz-appearance: none;
   margin: 1em 0 0;
   display: none;
   height: 32px;
@@ -593,25 +592,25 @@ description#identity-popup-content-verif
 
 #identity-popup-content-blocking-report-breakage {
   margin-top: 6px;
 }
 
 /* Hide the "report breakage" button if we have not detected any trackers
  * (except if the user added an exception, in which case they might still
  * (especially!) want to report the breakage). */
-#identity-popup-content-blocking-content:not([active]):not([hasException]) #identity-popup-content-blocking-report-breakage {
+#identity-popup-content-blocking-content:not([blocking]):not([hasException]) #identity-popup-content-blocking-report-breakage {
   display: none;
 }
 
 /* Show the right action buttons depending on content state */
 /* Offer to temporarily add an exception in private mode. */
-#main-window:not([privatebrowsingmode]) #identity-popup-content-blocking-content[active]:not([hasException]) > #tracking-action-unblock,
+#main-window:not([privatebrowsingmode]) #identity-popup-content-blocking-content[blocking]:not([hasException]) > #tracking-action-unblock,
 /* Offer to permanently add an exception in normal mode. */
-#main-window[privatebrowsingmode] #identity-popup-content-blocking-content[active]:not([hasException]) > #tracking-action-unblock-private,
+#main-window[privatebrowsingmode] #identity-popup-content-blocking-content[blocking]:not([hasException]) > #tracking-action-unblock-private,
 /* If there's an exception just offer to remove the exception again. */
 #identity-popup-content-blocking-content[hasException] > #tracking-action-block {
   display: -moz-box;
 }
 
 /* PERMISSIONS */
 
 #identity-popup-permissions-content {
@@ -713,16 +712,17 @@ description#identity-popup-content-verif
   margin: 0;
   border-width: 0;
   border-radius: 50%;
   min-width: 0;
   padding: 2px;
   background-color: transparent;
   color: inherit;
   opacity: 0.6;
+  margin-inline-start: 2px;
 }
 
 .identity-popup-permission-remove-button > .button-box {
   padding: 0;
 }
 
 .identity-popup-permission-remove-button > .button-box > .button-icon {
   margin: 0;
--- a/toolkit/components/telemetry/Events.yaml
+++ b/toolkit/components/telemetry/Events.yaml
@@ -623,18 +623,16 @@ security.ui.identitypopup:
       - main
     extra_keys:
       tp: Whether Tracking Protection was active while the user opened the popup
       cr: Whether Cookie Restrictions was active while the user opened the popup
     products:
       - firefox
   click:
     objects: [
-      "tp_add_blocking",
-      "cookies_add_blocking",
       "cb_prefs_button",
       "clear_sitedata",
       "unblock",
       "unblock_private",
       "block",
       "report_breakage"
     ]
     bug_numbers: