Bug 1554361 - Move the high-level storage access check APIs to mozilla/StorageAccess.h; r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 27 May 2019 14:06:49 +0000
changeset 475727 fffc348e55232b77c9bf026d5b3bd00012961113
parent 475726 284a94a4c77209d354f81cacd64d278a77c2e621
child 475728 7ba9be16835ff29b9c0b7b55310d9233da236a95
push id36072
push userdluca@mozilla.com
push dateTue, 28 May 2019 09:38:00 +0000
treeherdermozilla-central@c6a17846e2d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1554361
milestone69.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 1554361 - Move the high-level storage access check APIs to mozilla/StorageAccess.h; r=baku Differential Revision: https://phabricator.services.mozilla.com/D32556
docshell/base/nsDocShell.cpp
dom/base/Document.cpp
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsGlobalWindowInner.cpp
dom/broadcastchannel/BroadcastChannel.cpp
dom/cache/CacheStorage.cpp
dom/clients/api/Client.cpp
dom/clients/api/Client.h
dom/clients/api/Clients.cpp
dom/clients/manager/ClientIPCTypes.ipdlh
dom/clients/manager/ClientIPCUtils.h
dom/clients/manager/ClientSource.cpp
dom/clients/manager/ClientState.cpp
dom/clients/manager/ClientState.h
dom/indexedDB/IDBFactory.cpp
dom/localstorage/LSObject.cpp
dom/serviceworkers/ServiceWorker.cpp
dom/serviceworkers/ServiceWorkerContainer.cpp
dom/serviceworkers/ServiceWorkerInterceptController.cpp
dom/serviceworkers/ServiceWorkerPrivate.cpp
dom/storage/Storage.cpp
dom/workers/WorkerLoadInfo.cpp
dom/workers/WorkerLoadInfo.h
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/WorkerScope.cpp
dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh
dom/workers/sharedworkers/SharedWorker.cpp
image/ImageCacheKey.cpp
toolkit/components/antitracking/StorageAccess.cpp
toolkit/components/antitracking/StorageAccess.h
toolkit/components/perfmonitoring/PerformanceMetricsCollector.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -29,16 +29,17 @@
 #include "mozilla/MediaFeatureChange.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/ScrollTypes.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/StartupTimeline.h"
+#include "mozilla/StorageAccess.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "mozilla/WidgetUtils.h"
 
 #include "mozilla/dom/ClientChannelHelper.h"
 #include "mozilla/dom/ClientHandle.h"
 #include "mozilla/dom/ClientInfo.h"
 #include "mozilla/dom/ClientManager.h"
@@ -13096,20 +13097,20 @@ bool nsDocShell::ServiceWorkerAllowedToC
   }
 
   nsCOMPtr<nsIDocShellTreeItem> parent;
   GetSameTypeParent(getter_AddRefs(parent));
   nsPIDOMWindowOuter* parentOuter = parent ? parent->GetWindow() : nullptr;
   nsPIDOMWindowInner* parentInner =
       parentOuter ? parentOuter->GetCurrentInnerWindow() : nullptr;
 
-  nsContentUtils::StorageAccess storage =
-      nsContentUtils::StorageAllowedForNewWindow(aPrincipal, aURI, parentInner);
-
-  return storage == nsContentUtils::StorageAccess::eAllow;
+  StorageAccess storage =
+      StorageAllowedForNewWindow(aPrincipal, aURI, parentInner);
+
+  return storage == StorageAccess::eAllow;
 }
 
 nsresult nsDocShell::SetOriginAttributes(const OriginAttributes& aAttrs) {
   MOZ_ASSERT(!mIsBeingDestroyed);
 
   if (!CanSetOriginAttributes()) {
     return NS_ERROR_FAILURE;
   }
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -3513,19 +3513,18 @@ void Document::GetCookie(nsAString& aCoo
 
   // If the document's sandboxed origin flag is set, access to read cookies
   // is prohibited.
   if (mSandboxFlags & SANDBOXED_ORIGIN) {
     rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
-  nsContentUtils::StorageAccess storageAccess =
-      nsContentUtils::StorageAllowedForDocument(this);
-  if (storageAccess == nsContentUtils::StorageAccess::eDeny) {
+  StorageAccess storageAccess = StorageAllowedForDocument(this);
+  if (storageAccess == StorageAccess::eDeny) {
     return;
   }
 
   if (ShouldPartitionStorage(storageAccess) &&
       !StoragePartitioningEnabled(storageAccess, CookieSettings())) {
     return;
   }
 
@@ -3573,19 +3572,18 @@ void Document::SetCookie(const nsAString
 
   // If the document's sandboxed origin flag is set, access to write cookies
   // is prohibited.
   if (mSandboxFlags & SANDBOXED_ORIGIN) {
     rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
-  nsContentUtils::StorageAccess storageAccess =
-      nsContentUtils::StorageAllowedForDocument(this);
-  if (storageAccess == nsContentUtils::StorageAccess::eDeny) {
+  StorageAccess storageAccess = StorageAllowedForDocument(this);
+  if (storageAccess == StorageAccess::eDeny) {
     return;
   }
 
   if (ShouldPartitionStorage(storageAccess) &&
       !StoragePartitioningEnabled(storageAccess, CookieSettings())) {
     return;
   }
 
@@ -13017,17 +13015,17 @@ already_AddRefed<mozilla::dom::Promise> 
     // If the document is in PB mode, it doesn't have access to its persistent
     // cookie jar, so reject the promise here.
     promise->MaybeRejectWithUndefined();
     return promise.forget();
   }
 
   if (CookieSettings()->GetRejectThirdPartyTrackers() && inner) {
     // Only do something special for third-party tracking content.
-    if (nsContentUtils::StorageDisabledByAntiTracking(this, nullptr)) {
+    if (StorageDisabledByAntiTracking(this, nullptr)) {
       // Note: If this has returned true, the top-level document is guaranteed
       // to not be on the Content Blocking allow list.
       DebugOnly<bool> isOnAllowList = false;
       // If we have a parent document, it has to be non-private since we
       // verified earlier that our own document is non-private and a private
       // document can never have a non-private document as its child.
       MOZ_ASSERT_IF(parent, !nsContentUtils::IsInPrivateBrowsing(parent));
       MOZ_ASSERT_IF(
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -8108,139 +8108,16 @@ bool nsContentUtils::IsNonSubresourceInt
     nsContentPolicyType aType) {
   return aType == nsIContentPolicy::TYPE_DOCUMENT ||
          aType == nsIContentPolicy::TYPE_INTERNAL_IFRAME ||
          aType == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
          aType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
          aType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER;
 }
 
-// static, public
-nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForWindow(
-    nsPIDOMWindowInner* aWindow, uint32_t* aRejectedReason) {
-  uint32_t rejectedReason;
-  if (!aRejectedReason) {
-    aRejectedReason = &rejectedReason;
-  }
-
-  *aRejectedReason = 0;
-
-  if (Document* document = aWindow->GetExtantDoc()) {
-    nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
-    // Note that GetChannel() below may return null, but that's OK, since the
-    // callee is able to deal with a null channel argument, and if passed null,
-    // will only fail to notify the UI in case storage gets blocked.
-    nsIChannel* channel = document->GetChannel();
-    return InternalStorageAllowedCheck(principal, aWindow, nullptr, channel,
-                                       document->CookieSettings(),
-                                       *aRejectedReason);
-  }
-
-  // No document? Let's return a generic rejected reason.
-  return StorageAccess::eDeny;
-}
-
-// static, public
-nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForDocument(
-    const Document* aDoc) {
-  MOZ_ASSERT(aDoc);
-
-  if (nsPIDOMWindowInner* inner = aDoc->GetInnerWindow()) {
-    nsCOMPtr<nsIPrincipal> principal = aDoc->NodePrincipal();
-    // Note that GetChannel() below may return null, but that's OK, since the
-    // callee is able to deal with a null channel argument, and if passed null,
-    // will only fail to notify the UI in case storage gets blocked.
-    nsIChannel* channel = aDoc->GetChannel();
-
-    uint32_t rejectedReason = 0;
-    return InternalStorageAllowedCheck(
-        principal, inner, nullptr, channel,
-        const_cast<Document*>(aDoc)->CookieSettings(), rejectedReason);
-  }
-
-  return StorageAccess::eDeny;
-}
-
-// static, public
-nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForNewWindow(
-    nsIPrincipal* aPrincipal, nsIURI* aURI, nsPIDOMWindowInner* aParent) {
-  MOZ_ASSERT(aPrincipal);
-  MOZ_ASSERT(aURI);
-  // parent may be nullptr
-
-  uint32_t rejectedReason = 0;
-  nsCOMPtr<nsICookieSettings> cs;
-  if (aParent && aParent->GetExtantDoc()) {
-    cs = aParent->GetExtantDoc()->CookieSettings();
-  } else {
-    cs = net::CookieSettings::Create();
-  }
-  return InternalStorageAllowedCheck(aPrincipal, aParent, aURI, nullptr, cs,
-                                     rejectedReason);
-}
-
-// static, public
-nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForChannel(
-    nsIChannel* aChannel) {
-  MOZ_DIAGNOSTIC_ASSERT(sSecurityManager);
-  MOZ_DIAGNOSTIC_ASSERT(aChannel);
-
-  nsCOMPtr<nsIPrincipal> principal;
-  Unused << sSecurityManager->GetChannelResultPrincipal(
-      aChannel, getter_AddRefs(principal));
-  NS_ENSURE_TRUE(principal, nsContentUtils::StorageAccess::eDeny);
-
-  nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
-  nsCOMPtr<nsICookieSettings> cookieSettings;
-  nsresult rv = loadInfo->GetCookieSettings(getter_AddRefs(cookieSettings));
-  NS_ENSURE_SUCCESS(rv, nsContentUtils::StorageAccess::eDeny);
-
-  uint32_t rejectedReason = 0;
-  nsContentUtils::StorageAccess result = InternalStorageAllowedCheck(
-      principal, nullptr, nullptr, aChannel, cookieSettings, rejectedReason);
-
-  return result;
-}
-
-// static, public
-nsContentUtils::StorageAccess nsContentUtils::StorageAllowedForServiceWorker(
-    nsIPrincipal* aPrincipal, nsICookieSettings* aCookieSettings) {
-  uint32_t rejectedReason = 0;
-  return InternalStorageAllowedCheck(aPrincipal, nullptr, nullptr, nullptr,
-                                     aCookieSettings, rejectedReason);
-}
-
-// static, private
-void nsContentUtils::GetCookieLifetimePolicyFromCookieSettings(
-    nsICookieSettings* aCookieSettings, nsIPrincipal* aPrincipal,
-    uint32_t* aLifetimePolicy) {
-  *aLifetimePolicy = StaticPrefs::network_cookie_lifetimePolicy();
-
-  if (aCookieSettings) {
-    uint32_t cookiePermission = 0;
-    nsresult rv =
-        aCookieSettings->CookiePermission(aPrincipal, &cookiePermission);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-
-    switch (cookiePermission) {
-      case nsICookiePermission::ACCESS_ALLOW:
-        *aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
-        break;
-      case nsICookiePermission::ACCESS_DENY:
-        *aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
-        break;
-      case nsICookiePermission::ACCESS_SESSION:
-        *aLifetimePolicy = nsICookieService::ACCEPT_SESSION;
-        break;
-    }
-  }
-}
-
 // static public
 bool nsContentUtils::IsThirdPartyWindowOrChannel(nsPIDOMWindowInner* aWindow,
                                                  nsIChannel* aChannel,
                                                  nsIURI* aURI) {
   MOZ_ASSERT(!aWindow || !aChannel,
              "A window and channel should not both be provided.");
 
   ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
@@ -8329,197 +8206,16 @@ bool nsContentUtils::IsThirdPartyTrackin
       do_QueryInterface(document->GetChannel());
   if (!httpChannel) {
     return false;
   }
 
   return httpChannel->IsThirdPartyTrackingResource();
 }
 
-static bool StorageDisabledByAntiTrackingInternal(
-    nsPIDOMWindowInner* aWindow, nsIChannel* aChannel, nsIPrincipal* aPrincipal,
-    nsIURI* aURI, nsICookieSettings* aCookieSettings,
-    uint32_t& aRejectedReason) {
-  MOZ_ASSERT(aWindow || aChannel || aPrincipal);
-
-  if (aWindow) {
-    nsIURI* documentURI = aURI ? aURI : aWindow->GetDocumentURI();
-    return !documentURI ||
-           !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
-               aWindow, documentURI, &aRejectedReason);
-  }
-
-  if (aChannel) {
-    nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
-    if (!httpChannel) {
-      return false;
-    }
-
-    nsCOMPtr<nsIURI> uri;
-    nsresult rv = httpChannel->GetURI(getter_AddRefs(uri));
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return false;
-    }
-
-    return !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
-        httpChannel, uri, &aRejectedReason);
-  }
-
-  MOZ_ASSERT(aPrincipal);
-  return !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
-      aPrincipal, aCookieSettings);
-}
-
-// static public
-bool nsContentUtils::StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
-                                                   nsIChannel* aChannel,
-                                                   nsIPrincipal* aPrincipal,
-                                                   nsIURI* aURI,
-                                                   uint32_t& aRejectedReason) {
-  nsCOMPtr<nsICookieSettings> cookieSettings;
-  if (aWindow) {
-    if (aWindow->GetExtantDoc()) {
-      cookieSettings = aWindow->GetExtantDoc()->CookieSettings();
-    }
-  } else if (aChannel) {
-    nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
-    Unused << loadInfo->GetCookieSettings(getter_AddRefs(cookieSettings));
-  }
-  if (!cookieSettings) {
-    cookieSettings = net::CookieSettings::Create();
-  }
-  bool disabled = StorageDisabledByAntiTrackingInternal(
-      aWindow, aChannel, aPrincipal, aURI, cookieSettings, aRejectedReason);
-  if (StaticPrefs::
-          browser_contentblocking_rejecttrackers_control_center_ui_enabled()) {
-    if (aWindow) {
-      AntiTrackingCommon::NotifyBlockingDecision(
-          aWindow,
-          disabled ? AntiTrackingCommon::BlockingDecision::eBlock
-                   : AntiTrackingCommon::BlockingDecision::eAllow,
-          aRejectedReason);
-    } else if (aChannel) {
-      AntiTrackingCommon::NotifyBlockingDecision(
-          aChannel,
-          disabled ? AntiTrackingCommon::BlockingDecision::eBlock
-                   : AntiTrackingCommon::BlockingDecision::eAllow,
-          aRejectedReason);
-    }
-  }
-  return disabled;
-}
-
-// static, private
-nsContentUtils::StorageAccess nsContentUtils::InternalStorageAllowedCheck(
-    nsIPrincipal* aPrincipal, nsPIDOMWindowInner* aWindow, nsIURI* aURI,
-    nsIChannel* aChannel, nsICookieSettings* aCookieSettings,
-    uint32_t& aRejectedReason) {
-  MOZ_ASSERT(aPrincipal);
-
-  aRejectedReason = 0;
-
-  StorageAccess access = StorageAccess::eAllow;
-
-  // We don't allow storage on the null principal, in general. Even if the
-  // calling context is chrome.
-  if (aPrincipal->GetIsNullPrincipal()) {
-    return StorageAccess::eDeny;
-  }
-
-  if (aWindow) {
-    // If the document is sandboxed, then it is not permitted to use storage
-    Document* document = aWindow->GetExtantDoc();
-    if (document && document->GetSandboxFlags() & SANDBOXED_ORIGIN) {
-      return StorageAccess::eDeny;
-    }
-
-    // Check if we are in private browsing, and record that fact
-    if (IsInPrivateBrowsing(document)) {
-      access = StorageAccess::ePrivateBrowsing;
-    }
-  }
-
-  uint32_t lifetimePolicy;
-
-  // WebExtensions principals always get BEHAVIOR_ACCEPT as cookieBehavior
-  // and ACCEPT_NORMALLY as lifetimePolicy (See Bug 1406675 for rationale).
-  auto policy = BasePrincipal::Cast(aPrincipal)->AddonPolicy();
-
-  if (policy) {
-    lifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
-  } else {
-    GetCookieLifetimePolicyFromCookieSettings(aCookieSettings, aPrincipal,
-                                              &lifetimePolicy);
-  }
-
-  // Check if we should only allow storage for the session, and record that fact
-  if (lifetimePolicy == nsICookieService::ACCEPT_SESSION) {
-    // Storage could be StorageAccess::ePrivateBrowsing or StorageAccess::eAllow
-    // so perform a std::min comparison to make sure we preserve
-    // ePrivateBrowsing if it has been set.
-    access = std::min(StorageAccess::eSessionScoped, access);
-  }
-
-  // About URIs are allowed to access storage, even if they don't have chrome
-  // privileges. If this is not desired, than the consumer will have to
-  // implement their own restriction functionality.
-  //
-  // This is due to backwards-compatibility and the state of storage access
-  // before the introducton of
-  // nsContentUtils::InternalStorageAllowedCheck:
-  //
-  // BEFORE:
-  // localStorage, caches: allowed in 3rd-party iframes always
-  // IndexedDB: allowed in 3rd-party iframes only if 3rd party URI is an about:
-  //   URI within a specific whitelist
-  //
-  // AFTER:
-  // localStorage, caches: allowed in 3rd-party iframes by default. Preference
-  //   can be set to disable in 3rd-party, which will not disallow in about:
-  //   URIs.
-  // IndexedDB: allowed in 3rd-party iframes by default. Preference can be set
-  //   to disable in 3rd-party, which will disallow in about: URIs, unless they
-  //   are within a specific whitelist.
-  //
-  // This means that behavior for storage with internal about: URIs should not
-  // be affected, which is desireable due to the lack of automated testing for
-  // about: URIs with these preferences set, and the importance of the correct
-  // functioning of these URIs even with custom preferences.
-  nsCOMPtr<nsIURI> uri = aURI;
-  if (!uri) {
-    Unused << aPrincipal->GetURI(getter_AddRefs(uri));
-  }
-  if (uri) {
-    bool isAbout = false;
-    MOZ_ALWAYS_SUCCEEDS(uri->SchemeIs("about", &isAbout));
-    if (isAbout) {
-      return access;
-    }
-  }
-
-  if (!StorageDisabledByAntiTracking(aWindow, aChannel, aPrincipal, aURI,
-                                     aRejectedReason)) {
-    return access;
-  }
-
-  // We want to have a partitioned storage only for trackers.
-  if (aRejectedReason ==
-      nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER) {
-    return StorageAccess::ePartitionTrackersOrDeny;
-  }
-
-  // We want to have a partitioned storage for all third parties.
-  if (aRejectedReason ==
-      nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN) {
-    return StorageAccess::ePartitionForeignOrDeny;
-  }
-
-  return StorageAccess::eDeny;
-}
-
 namespace {
 
 // We put StringBuilder in the anonymous namespace to prevent anything outside
 // this file from accidentally being linked against it.
 class BulkAppender {
   typedef typename nsAString::size_type size_type;
 
  public:
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -124,16 +124,18 @@ class nsReadingIterator;
 namespace mozilla {
 class Dispatcher;
 class ErrorResult;
 class EventListenerManager;
 class HTMLEditor;
 class PresShell;
 class TextEditor;
 
+enum class StorageAccess;
+
 namespace dom {
 class ContentFrameMessageManager;
 struct CustomElementDefinition;
 class DataTransfer;
 class DocumentFragment;
 class Element;
 class Event;
 class EventTarget;
@@ -2883,111 +2885,16 @@ class nsContentUtils {
    */
   static mozilla::net::ReferrerPolicy GetReferrerPolicyFromHeader(
       const nsAString& aHeader);
 
   static bool IsNonSubresourceRequest(nsIChannel* aChannel);
 
   static bool IsNonSubresourceInternalPolicyType(nsContentPolicyType aType);
 
-  // The order of these entries matters, as we use std::min for total ordering
-  // of permissions. Private Browsing is considered to be more limiting
-  // then session scoping
-  enum class StorageAccess {
-    // The storage should be partitioned for third-party resources. if the
-    // caller is unable to do it, deny the storage access.
-    ePartitionForeignOrDeny = -2,
-    // The storage should be partitioned for third-party trackers. if the caller
-    // is unable to do it, deny the storage access.
-    ePartitionTrackersOrDeny = -1,
-    // Don't allow access to the storage
-    eDeny = 0,
-    // Allow access to the storage, but only if it is secure to do so in a
-    // private browsing context.
-    ePrivateBrowsing = 1,
-    // Allow access to the storage, but only persist it for the current session
-    eSessionScoped = 2,
-    // Allow access to the storage
-    eAllow = 3,
-    // Keep this at the end.  Used for serialization, but not a valid value.
-    eNumValues = 4,
-  };
-
-  /*
-   * Checks if storage for the given window is permitted by a combination of
-   * the user's preferences, and whether the window is a third-party iframe.
-   *
-   * This logic is intended to be shared between the different forms of
-   * persistent storage which are available to web pages. Cookies don't use
-   * this logic, and security logic related to them must be updated separately.
-   */
-  static StorageAccess StorageAllowedForWindow(
-      nsPIDOMWindowInner* aWindow, uint32_t* aRejectedReason = nullptr);
-
-  /*
-   * Checks if storage for the given document is permitted by a combination of
-   * the user's preferences, and whether the document's window is a third-party
-   * iframe.
-   *
-   * Note, this may be used on documents during the loading process where
-   * the window's extant document has not been set yet.  The code in
-   * StorageAllowedForWindow(), however, will not work in these cases.
-   */
-  static StorageAccess StorageAllowedForDocument(const Document* aDoc);
-
-  /*
-   * Checks if storage should be allowed for a new window with the given
-   * principal, load URI, and parent.
-   */
-  static StorageAccess StorageAllowedForNewWindow(nsIPrincipal* aPrincipal,
-                                                  nsIURI* aURI,
-                                                  nsPIDOMWindowInner* aParent);
-
-  /*
-   * Checks if storage should be allowed for the given channel.  The check will
-   * be based on the channel result principal and, depending on preferences and
-   * permissions, mozIThirdPartyUtil.isThirdPartyChannel().
-   */
-  static StorageAccess StorageAllowedForChannel(nsIChannel* aChannel);
-
-  /*
-   * Checks if storage for the given principal is permitted by the user's
-   * preferences. This method should be used only by ServiceWorker loading.
-   */
-  static StorageAccess StorageAllowedForServiceWorker(
-      nsIPrincipal* aPrincipal, nsICookieSettings* aCookieSettings);
-
-  /*
-   * Returns true if this document should disable storages because of the
-   * anti-tracking feature.
-   */
-  static bool StorageDisabledByAntiTracking(Document* aDocument, nsIURI* aURI) {
-    uint32_t rejectedReason = 0;
-    // Note that GetChannel() below may return null, but that's OK, since the
-    // callee is able to deal with a null channel argument, and if passed null,
-    // will only fail to notify the UI in case storage gets blocked.
-    return StorageDisabledByAntiTracking(
-        aDocument->GetInnerWindow(), aDocument->GetChannel(),
-        aDocument->NodePrincipal(), aURI, rejectedReason);
-  }
-
- private:
-  /*
-   * Returns true if this window/channel/aPrincipal should disable storages
-   * because of the anti-tracking feature.
-   * Note that either aWindow or aChannel may be null when calling this
-   * function. If the caller wants the UI to be notified when the storage gets
-   * disabled, it must pass a non-null channel object.
-   */
-  static bool StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
-                                            nsIChannel* aChannel,
-                                            nsIPrincipal* aPrincipal,
-                                            nsIURI* aURI,
-                                            uint32_t& aRejectedReason);
-
  public:
   /*
    * Returns true if this window/channel is a 3rd party context.
    */
   static bool IsThirdPartyWindowOrChannel(nsPIDOMWindowInner* aWindow,
                                           nsIChannel* aChannel, nsIURI* aURI);
 
   /*
@@ -3310,43 +3217,16 @@ class nsContentUtils {
   static AutocompleteAttrState InternalSerializeAutocompleteAttribute(
       const nsAttrValue* aAttrVal, mozilla::dom::AutocompleteInfo& aInfo,
       bool aGrantAllValidValue = false);
 
   static bool CallOnAllRemoteChildren(
       mozilla::dom::MessageBroadcaster* aManager,
       CallOnRemoteChildFunction aCallback, void* aArg);
 
-  /**
-   * Gets the cookie lifetime policy for a given cookieSettings and a given
-   * principal by checking the permission value.
-   *
-   * Used in the implementation of InternalStorageAllowedCheck.
-   */
-  static void GetCookieLifetimePolicyFromCookieSettings(
-      nsICookieSettings* aCookieSettings, nsIPrincipal* aPrincipal,
-      uint32_t* aLifetimePolicy);
-
-  /*
-   * Checks if storage for a given principal is permitted by the user's
-   * preferences. If aWindow is non-null, its principal must be passed as
-   * aPrincipal, and the third-party iframe and sandboxing status of the window
-   * are also checked.  If aURI is non-null, then it is used as the comparison
-   * against aWindow to determine if this is a third-party load.  We also
-   * allow a channel instead of the window reference when determining 3rd party
-   * status.
-   *
-   * Used in the implementation of StorageAllowedForWindow,
-   * StorageAllowedForChannel and StorageAllowedForServiceWorker.
-   */
-  static StorageAccess InternalStorageAllowedCheck(
-      nsIPrincipal* aPrincipal, nsPIDOMWindowInner* aWindow, nsIURI* aURI,
-      nsIChannel* aChannel, nsICookieSettings* aCookieSettings,
-      uint32_t& aRejectedReason);
-
   static nsINode* GetCommonAncestorHelper(nsINode* aNode1, nsINode* aNode2);
   static nsIContent* GetCommonFlattenedTreeAncestorHelper(
       nsIContent* aContent1, nsIContent* aContent2);
 
   static nsIXPConnect* sXPConnect;
 
   static nsIScriptSecurityManager* sSecurityManager;
   static nsIPrincipal* sSystemPrincipal;
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -4342,18 +4342,17 @@ Storage* nsGlobalWindowInner::GetSession
     }
 
     if (mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) {
       aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
       return nullptr;
     }
 
     uint32_t rejectedReason = 0;
-    nsContentUtils::StorageAccess access =
-        nsContentUtils::StorageAllowedForWindow(this, &rejectedReason);
+    StorageAccess access = StorageAllowedForWindow(this, &rejectedReason);
 
     // SessionStorage is an ephemeral per-tab per-origin storage that only lives
     // as long as the tab is open, although it may survive browser restarts
     // thanks to the session store. So we interpret storage access differently
     // than we would for persistent per-origin storage like LocalStorage and so
     // it may be okay to provide SessionStorage even when we receive a value of
     // eDeny.
     //
@@ -4376,17 +4375,17 @@ Storage* nsGlobalWindowInner::GetSession
     // a reason of STATE_COOKIES_BLOCKED_TRACKER.
     //
     // In the 1st case, the user has explicitly indicated that they don't want
     // to allow any storage to the origin or all origins and so we throw an
     // error and deny access to SessionStorage. In the 2nd case, a legacy
     // decision reasoned that there's no harm in providing SessionStorage
     // because the information is not durable and cannot escape the current tab.
     // The rationale is similar for the 3rd case.
-    if (access == nsContentUtils::StorageAccess::eDeny &&
+    if (access == StorageAccess::eDeny &&
         rejectedReason !=
             nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN) {
       aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
       return nullptr;
     }
 
     nsresult rv;
 
@@ -4439,35 +4438,34 @@ Storage* nsGlobalWindowInner::GetLocalSt
   // environment.
   // For Partitioned Trackers, we expose a partitioned LocalStorage, which
   // doesn't share data with other contexts, and it's just in memory.
   // Partitioned localStorage is available only for trackers listed in the
   // privacy.restrict3rdpartystorage.partitionedHosts pref. See
   // nsContentUtils::IsURIInPrefList to know the syntax for the pref value.
   // This is a temporary web-compatibility hack.
 
-  nsContentUtils::StorageAccess access =
-      nsContentUtils::StorageAllowedForWindow(this);
+  StorageAccess access = StorageAllowedForWindow(this);
 
   // We allow partitioned localStorage only to some hosts.
   if (ShouldPartitionStorage(access)) {
     if (!mDoc) {
-      access = nsContentUtils::StorageAccess::eDeny;
+      access = StorageAccess::eDeny;
     } else if (!StaticPrefs::privacy_storagePrincipal_enabledForTrackers()) {
       nsCOMPtr<nsIURI> uri;
       Unused << mDoc->NodePrincipal()->GetURI(getter_AddRefs(uri));
       static const char* kPrefName =
           "privacy.restrict3rdpartystorage.partitionedHosts";
       if (!uri || !nsContentUtils::IsURIInPrefList(uri, kPrefName)) {
-        access = nsContentUtils::StorageAccess::eDeny;
+        access = StorageAccess::eDeny;
       }
     }
   }
 
-  if (access == nsContentUtils::StorageAccess::eDeny) {
+  if (access == StorageAccess::eDeny) {
     if (mDoc && (mDoc->GetSandboxFlags() & SANDBOXED_ORIGIN) != 0) {
       // Only raise the exception if we are denying storage access due to
       // sandbox restrictions.  If we're denying storage access due to other
       // reasons (e.g. cookie policy enforcement), withhold raising the
       // exception in an effort to achieve more web compatibility.
       aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
     }
     return nullptr;
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -227,17 +227,17 @@ already_AddRefed<BroadcastChannel> Broad
     return nullptr;
   }
 
   RefPtr<BroadcastChannel> bc = new BroadcastChannel(global, aChannel);
 
   nsAutoCString origin;
   PrincipalInfo storagePrincipalInfo;
 
-  nsContentUtils::StorageAccess storageAccess;
+  StorageAccess storageAccess;
 
   nsCOMPtr<nsICookieSettings> cs;
   if (NS_IsMainThread()) {
     nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(global);
     if (NS_WARN_IF(!window)) {
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
@@ -266,17 +266,17 @@ already_AddRefed<BroadcastChannel> Broad
       return nullptr;
     }
 
     aRv = PrincipalToPrincipalInfo(storagePrincipal, &storagePrincipalInfo);
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
 
-    storageAccess = nsContentUtils::StorageAllowedForWindow(window);
+    storageAccess = StorageAllowedForWindow(window);
 
     Document* doc = window->GetExtantDoc();
     if (doc) {
       cs = doc->CookieSettings();
     }
   } else {
     JSContext* cx = aGlobal.Context();
 
@@ -304,17 +304,17 @@ already_AddRefed<BroadcastChannel> Broad
     storageAccess = workerPrivate->StorageAccess();
     bc->mWorkerRef = workerRef;
 
     cs = workerPrivate->CookieSettings();
   }
 
   // We want to allow opaque origins.
   if (storagePrincipalInfo.type() != PrincipalInfo::TNullPrincipalInfo &&
-      (storageAccess == nsContentUtils::StorageAccess::eDeny ||
+      (storageAccess == StorageAccess::eDeny ||
        (ShouldPartitionStorage(storageAccess) &&
         !StoragePartitioningEnabled(storageAccess, cs)))) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
 
   // Register this component to PBackground.
   PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread();
--- a/dom/cache/CacheStorage.cpp
+++ b/dom/cache/CacheStorage.cpp
@@ -562,30 +562,30 @@ void CacheStorage::RunRequest(nsAutoPtr<
 
 OpenMode CacheStorage::GetOpenMode() const {
   return mNamespace == CHROME_ONLY_NAMESPACE ? OpenMode::Eager : OpenMode::Lazy;
 }
 
 bool CacheStorage::HasStorageAccess() const {
   NS_ASSERT_OWNINGTHREAD(CacheStorage);
 
-  nsContentUtils::StorageAccess access;
+  StorageAccess access;
 
   if (NS_IsMainThread()) {
     nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mGlobal);
     if (NS_WARN_IF(!window)) {
       return true;
     }
 
-    access = nsContentUtils::StorageAllowedForWindow(window);
+    access = StorageAllowedForWindow(window);
   } else {
     WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     MOZ_ASSERT(workerPrivate);
 
     access = workerPrivate->StorageAccess();
   }
 
-  return access > nsContentUtils::StorageAccess::ePrivateBrowsing;
+  return access > StorageAccess::ePrivateBrowsing;
 }
 
 }  // namespace cache
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/clients/api/Client.cpp
+++ b/dom/clients/api/Client.cpp
@@ -50,17 +50,17 @@ TimeStamp Client::CreationTime() const {
 
 TimeStamp Client::LastFocusTime() const {
   if (mData->info().type() != ClientType::Window) {
     return TimeStamp();
   }
   return mData->state().get_IPCClientWindowState().lastFocusTime();
 }
 
-nsContentUtils::StorageAccess Client::GetStorageAccess() const {
+StorageAccess Client::GetStorageAccess() const {
   ClientState state(ClientState::FromIPC(mData->state()));
   return state.GetStorageAccess();
 }
 
 JSObject* Client::WrapObject(JSContext* aCx,
                              JS::Handle<JSObject*> aGivenProto) {
   if (mData->info().type() == ClientType::Window) {
     return WindowClient_Binding::Wrap(aCx, this, aGivenProto);
--- a/dom/clients/api/Client.h
+++ b/dom/clients/api/Client.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 #ifndef _mozilla_dom_Client_h
 #define _mozilla_dom_Client_h
 
 #include "mozilla/dom/ClientBinding.h"
+#include "mozilla/StorageAccess.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsISupports.h"
 #include "nsWrapperCache.h"
 
 class nsIGlobalObject;
 
 namespace mozilla {
@@ -39,17 +40,17 @@ class Client final : public nsISupports,
 
  public:
   Client(nsIGlobalObject* aGlobal, const ClientInfoAndState& aData);
 
   TimeStamp CreationTime() const;
 
   TimeStamp LastFocusTime() const;
 
-  nsContentUtils::StorageAccess GetStorageAccess() const;
+  StorageAccess GetStorageAccess() const;
 
   // nsWrapperCache interface methods
   JSObject* WrapObject(JSContext* aCx,
                        JS::Handle<JSObject*> aGivenProto) override;
 
   // DOM bindings methods
   nsIGlobalObject* GetParentObject() const;
 
--- a/dom/clients/api/Clients.cpp
+++ b/dom/clients/api/Clients.cpp
@@ -10,16 +10,17 @@
 #include "mozilla/dom/ClientIPCTypes.h"
 #include "mozilla/dom/ClientManager.h"
 #include "mozilla/dom/ClientsBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ServiceWorkerDescriptor.h"
 #include "mozilla/dom/ServiceWorkerManager.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/ipc/BackgroundUtils.h"
+#include "mozilla/StorageAccess.h"
 #include "mozilla/SystemGroup.h"
 #include "nsIGlobalObject.h"
 #include "nsString.h"
 
 namespace mozilla {
 namespace dom {
 
 using mozilla::ipc::CSPInfo;
@@ -84,18 +85,17 @@ already_AddRefed<Promise> Clients::Get(c
   innerPromise
       ->Then(
           target, __func__,
           [outerPromise, holder, scope](const ClientOpResult& aResult) {
             holder->Complete();
             NS_ENSURE_TRUE_VOID(holder->GetParentObject());
             RefPtr<Client> client = new Client(
                 holder->GetParentObject(), aResult.get_ClientInfoAndState());
-            if (client->GetStorageAccess() ==
-                nsContentUtils::StorageAccess::eAllow) {
+            if (client->GetStorageAccess() == StorageAccess::eAllow) {
               outerPromise->MaybeResolve(std::move(client));
               return;
             }
             nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
                 "Clients::Get() storage denied", [scope] {
                   ServiceWorkerManager::LocalizeAndReportToAllClients(
                       scope, "ServiceWorkerGetClientStorageError",
                       nsTArray<nsString>());
@@ -165,18 +165,17 @@ already_AddRefed<Promise> Clients::Match
   StartClientManagerOp(
       &ClientManager::MatchAll, args, mGlobal,
       [outerPromise, global, scope](const ClientOpResult& aResult) {
         nsTArray<RefPtr<Client>> clientList;
         bool storageDenied = false;
         for (const ClientInfoAndState& value :
              aResult.get_ClientList().values()) {
           RefPtr<Client> client = new Client(global, value);
-          if (client->GetStorageAccess() !=
-              nsContentUtils::StorageAccess::eAllow) {
+          if (client->GetStorageAccess() != StorageAccess::eAllow) {
             storageDenied = true;
             continue;
           }
           clientList.AppendElement(std::move(client));
         }
         if (storageDenied) {
           nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
               "Clients::MatchAll() storage denied", [scope] {
--- a/dom/clients/manager/ClientIPCTypes.ipdlh
+++ b/dom/clients/manager/ClientIPCTypes.ipdlh
@@ -5,17 +5,17 @@
 include protocol PClientSource;
 include DOMTypes;
 include PBackgroundSharedTypes;
 include IPCServiceWorkerDescriptor;
 include ProtocolTypes;
 using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
 using ClientType from "mozilla/dom/ClientIPCUtils.h";
 using FrameType from "mozilla/dom/ClientIPCUtils.h";
-using nsContentUtils::StorageAccess from "mozilla/dom/ClientIPCUtils.h";
+using mozilla::StorageAccess from "mozilla/dom/ClientIPCUtils.h";
 using VisibilityState from "mozilla/dom/ClientIPCUtils.h";
 
 namespace mozilla {
 namespace dom {
 
 struct ClientSourceConstructorArgs
 {
   nsID id;
--- a/dom/clients/manager/ClientIPCUtils.h
+++ b/dom/clients/manager/ClientIPCUtils.h
@@ -6,17 +6,17 @@
 #ifndef _mozilla_dom_ClientIPCUtils_h
 #define _mozilla_dom_ClientIPCUtils_h
 
 #include "ipc/IPCMessageUtils.h"
 
 #include "mozilla/dom/ClientBinding.h"
 #include "mozilla/dom/ClientsBinding.h"
 #include "mozilla/dom/DocumentBinding.h"
-#include "nsContentUtils.h"
+#include "mozilla/StorageAccess.h"
 
 namespace IPC {
 template <>
 struct ParamTraits<mozilla::dom::ClientType>
     : public ContiguousEnumSerializer<mozilla::dom::ClientType,
                                       mozilla::dom::ClientType::Window,
                                       mozilla::dom::ClientType::EndGuard_> {};
 
@@ -28,16 +28,16 @@ struct ParamTraits<mozilla::dom::FrameTy
 
 template <>
 struct ParamTraits<mozilla::dom::VisibilityState>
     : public ContiguousEnumSerializer<
           mozilla::dom::VisibilityState, mozilla::dom::VisibilityState::Hidden,
           mozilla::dom::VisibilityState::EndGuard_> {};
 
 template <>
-struct ParamTraits<nsContentUtils::StorageAccess>
+struct ParamTraits<mozilla::StorageAccess>
     : public ContiguousEnumSerializer<
-          nsContentUtils::StorageAccess,
-          nsContentUtils::StorageAccess::ePartitionForeignOrDeny,
-          nsContentUtils::StorageAccess::eNumValues> {};
+          mozilla::StorageAccess,
+          mozilla::StorageAccess::ePartitionForeignOrDeny,
+          mozilla::StorageAccess::eNumValues> {};
 }  // namespace IPC
 
 #endif  // _mozilla_dom_ClientIPCUtils_h
--- a/dom/clients/manager/ClientSource.cpp
+++ b/dom/clients/manager/ClientSource.cpp
@@ -18,16 +18,17 @@
 #include "mozilla/dom/MessageEvent.h"
 #include "mozilla/dom/MessageEventBinding.h"
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerScope.h"
 #include "mozilla/dom/ServiceWorker.h"
 #include "mozilla/dom/ServiceWorkerContainer.h"
 #include "mozilla/dom/ServiceWorkerManager.h"
+#include "mozilla/StorageAccess.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsContentUtils.h"
 #include "nsIDocShell.h"
 #include "nsPIDOMWindow.h"
 
 #include "mozilla/ipc/BackgroundUtils.h"
 
 namespace mozilla {
@@ -69,36 +70,34 @@ void ClientSource::ExecutionReady(const 
 }
 
 nsresult ClientSource::SnapshotWindowState(ClientState* aStateOut) {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsPIDOMWindowInner* window = GetInnerWindow();
   if (!window || !window->IsCurrentInnerWindow() ||
       !window->HasActiveDocument()) {
-    *aStateOut = ClientState(
-        ClientWindowState(VisibilityState::Hidden, TimeStamp(),
-                          nsContentUtils::StorageAccess::eDeny, false));
+    *aStateOut = ClientState(ClientWindowState(
+        VisibilityState::Hidden, TimeStamp(), StorageAccess::eDeny, false));
     return NS_OK;
   }
 
   Document* doc = window->GetExtantDoc();
   if (NS_WARN_IF(!doc)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   ErrorResult rv;
   bool focused = doc->HasFocus(rv);
   if (NS_WARN_IF(rv.Failed())) {
     rv.SuppressException();
     return rv.StealNSResult();
   }
 
-  nsContentUtils::StorageAccess storage =
-      nsContentUtils::StorageAllowedForDocument(doc);
+  StorageAccess storage = StorageAllowedForDocument(doc);
 
   *aStateOut = ClientState(ClientWindowState(
       doc->VisibilityState(), doc->LastFocusTime(), storage, focused));
 
   return NS_OK;
 }
 
 WorkerPrivate* ClientSource::GetWorkerPrivate() const {
@@ -207,17 +206,17 @@ void ClientSource::WorkerExecutionReady(
   }
 
   // A client without access to storage should never be controlled by
   // a service worker.  Check this here in case we were controlled before
   // execution ready.  We can't reliably determine what our storage policy
   // is before execution ready, unfortunately.
   if (mController.isSome()) {
     MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate->StorageAccess() >
-                              nsContentUtils::StorageAccess::ePrivateBrowsing ||
+                              StorageAccess::ePrivateBrowsing ||
                           StringBeginsWith(aWorkerPrivate->ScriptURL(),
                                            NS_LITERAL_STRING("blob:")));
   }
 
   // Its safe to store the WorkerPrivate* here because the ClientSource
   // is explicitly destroyed by WorkerPrivate before exiting its run loop.
   MOZ_DIAGNOSTIC_ASSERT(mOwner.is<Nothing>());
   mOwner = AsVariant(aWorkerPrivate);
@@ -256,21 +255,20 @@ nsresult ClientSource::WindowExecutionRe
   //
   // Note, explicitly avoid checking storage policy for windows that inherit
   // service workers from their parent.  If a user opens a controlled window
   // and then blocks storage, that window will continue to be controlled by
   // the SW until the window is closed.  Any about:blank or blob URL should
   // continue to inherit the SW as well.  We need to avoid triggering the
   // assertion in this corner case.
   if (mController.isSome()) {
-    MOZ_DIAGNOSTIC_ASSERT(
-        spec.LowerCaseEqualsLiteral("about:blank") ||
-        StringBeginsWith(spec, NS_LITERAL_CSTRING("blob:")) ||
-        nsContentUtils::StorageAllowedForWindow(aInnerWindow) ==
-            nsContentUtils::StorageAccess::eAllow);
+    MOZ_DIAGNOSTIC_ASSERT(spec.LowerCaseEqualsLiteral("about:blank") ||
+                          StringBeginsWith(spec, NS_LITERAL_CSTRING("blob:")) ||
+                          StorageAllowedForWindow(aInnerWindow) ==
+                              StorageAccess::eAllow);
   }
 
   nsPIDOMWindowOuter* outer = aInnerWindow->GetOuterWindow();
   NS_ENSURE_TRUE(outer, NS_ERROR_UNEXPECTED);
 
   FrameType frameType = FrameType::Top_level;
   if (!outer->IsTopLevelWindow()) {
     frameType = FrameType::Nested;
@@ -378,21 +376,20 @@ void ClientSource::SetController(
   //
   // Note, explicitly avoid checking storage policy for clients that inherit
   // service workers from their parent.  This basically means blob: URLs
   // and about:blank windows.
   if (GetInnerWindow()) {
     MOZ_DIAGNOSTIC_ASSERT(
         Info().URL().LowerCaseEqualsLiteral("about:blank") ||
         StringBeginsWith(Info().URL(), NS_LITERAL_CSTRING("blob:")) ||
-        nsContentUtils::StorageAllowedForWindow(GetInnerWindow()) ==
-            nsContentUtils::StorageAccess::eAllow);
+        StorageAllowedForWindow(GetInnerWindow()) == StorageAccess::eAllow);
   } else if (GetWorkerPrivate()) {
     MOZ_DIAGNOSTIC_ASSERT(GetWorkerPrivate()->StorageAccess() >
-                              nsContentUtils::StorageAccess::ePrivateBrowsing ||
+                              StorageAccess::ePrivateBrowsing ||
                           StringBeginsWith(GetWorkerPrivate()->ScriptURL(),
                                            NS_LITERAL_STRING("blob:")));
   }
 
   if (mController.isSome() && mController.ref() == aServiceWorker) {
     return;
   }
 
@@ -433,24 +430,23 @@ RefPtr<ClientOpPromise> ClientSource::Co
   // that do not have an inner window created yet.  We explicitly allow initial
   // about:blank.
   bool controlAllowed = true;
   if (GetInnerWindow()) {
     // Local URL windows and windows with access to storage can be controlled.
     controlAllowed =
         Info().URL().LowerCaseEqualsLiteral("about:blank") ||
         StringBeginsWith(Info().URL(), NS_LITERAL_CSTRING("blob:")) ||
-        nsContentUtils::StorageAllowedForWindow(GetInnerWindow()) ==
-            nsContentUtils::StorageAccess::eAllow;
+        StorageAllowedForWindow(GetInnerWindow()) == StorageAccess::eAllow;
   } else if (GetWorkerPrivate()) {
     // Local URL workers and workers with access to storage cna be controlled.
-    controlAllowed = GetWorkerPrivate()->StorageAccess() >
-                         nsContentUtils::StorageAccess::ePrivateBrowsing ||
-                     StringBeginsWith(GetWorkerPrivate()->ScriptURL(),
-                                      NS_LITERAL_STRING("blob:"));
+    controlAllowed =
+        GetWorkerPrivate()->StorageAccess() > StorageAccess::ePrivateBrowsing ||
+        StringBeginsWith(GetWorkerPrivate()->ScriptURL(),
+                         NS_LITERAL_STRING("blob:"));
   }
 
   if (NS_WARN_IF(!controlAllowed)) {
     return ClientOpPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR,
                                             __func__);
   }
 
   SetController(ServiceWorkerDescriptor(aArgs.serviceWorker()));
--- a/dom/clients/manager/ClientState.cpp
+++ b/dom/clients/manager/ClientState.cpp
@@ -8,18 +8,18 @@
 
 #include "mozilla/dom/ClientIPCTypes.h"
 
 namespace mozilla {
 namespace dom {
 
 ClientWindowState::ClientWindowState(
     mozilla::dom::VisibilityState aVisibilityState,
-    const TimeStamp& aLastFocusTime,
-    nsContentUtils::StorageAccess aStorageAccess, bool aFocused)
+    const TimeStamp& aLastFocusTime, StorageAccess aStorageAccess,
+    bool aFocused)
     : mData(MakeUnique<IPCClientWindowState>(aVisibilityState, aLastFocusTime,
                                              aStorageAccess, aFocused)) {}
 
 ClientWindowState::ClientWindowState(const IPCClientWindowState& aData)
     : mData(MakeUnique<IPCClientWindowState>(aData)) {}
 
 ClientWindowState::ClientWindowState(const ClientWindowState& aRight) {
   operator=(aRight);
@@ -48,24 +48,23 @@ mozilla::dom::VisibilityState ClientWind
 }
 
 const TimeStamp& ClientWindowState::LastFocusTime() const {
   return mData->lastFocusTime();
 }
 
 bool ClientWindowState::Focused() const { return mData->focused(); }
 
-nsContentUtils::StorageAccess ClientWindowState::GetStorageAccess() const {
+StorageAccess ClientWindowState::GetStorageAccess() const {
   return mData->storageAccess();
 }
 
 const IPCClientWindowState& ClientWindowState::ToIPC() const { return *mData; }
 
-ClientWorkerState::ClientWorkerState(
-    nsContentUtils::StorageAccess aStorageAccess)
+ClientWorkerState::ClientWorkerState(StorageAccess aStorageAccess)
     : mData(MakeUnique<IPCClientWorkerState>(aStorageAccess)) {}
 
 ClientWorkerState::ClientWorkerState(const IPCClientWorkerState& aData)
     : mData(MakeUnique<IPCClientWorkerState>(aData)) {}
 
 ClientWorkerState::ClientWorkerState(ClientWorkerState&& aRight)
     : mData(std::move(aRight.mData)) {}
 
@@ -83,17 +82,17 @@ ClientWorkerState& ClientWorkerState::op
 ClientWorkerState& ClientWorkerState::operator=(ClientWorkerState&& aRight) {
   mData.reset();
   mData = std::move(aRight.mData);
   return *this;
 }
 
 ClientWorkerState::~ClientWorkerState() {}
 
-nsContentUtils::StorageAccess ClientWorkerState::GetStorageAccess() const {
+StorageAccess ClientWorkerState::GetStorageAccess() const {
   return mData->storageAccess();
 }
 
 const IPCClientWorkerState& ClientWorkerState::ToIPC() const { return *mData; }
 
 ClientState::ClientState() {}
 
 ClientState::ClientState(const ClientWindowState& aWindowState) {
@@ -145,17 +144,17 @@ const ClientWindowState& ClientState::As
 bool ClientState::IsWorkerState() const {
   return mData.isSome() && mData.ref().is<ClientWorkerState>();
 }
 
 const ClientWorkerState& ClientState::AsWorkerState() const {
   return mData.ref().as<ClientWorkerState>();
 }
 
-nsContentUtils::StorageAccess ClientState::GetStorageAccess() const {
+StorageAccess ClientState::GetStorageAccess() const {
   if (IsWindowState()) {
     return AsWindowState().GetStorageAccess();
   }
 
   return AsWorkerState().GetStorageAccess();
 }
 
 const IPCClientState ClientState::ToIPC() const {
--- a/dom/clients/manager/ClientState.h
+++ b/dom/clients/manager/ClientState.h
@@ -4,16 +4,17 @@
  * 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/. */
 
 #ifndef _mozilla_dom_ClientState_h
 #define _mozilla_dom_ClientState_h
 
 #include "mozilla/dom/DocumentBinding.h"
 #include "mozilla/Maybe.h"
+#include "mozilla/StorageAccess.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 class IPCClientState;
@@ -24,18 +25,17 @@ class IPCClientWorkerState;
 // through the ClientManagerService.  It is a snapshot of the state and
 // is not live updated.
 class ClientWindowState final {
   UniquePtr<IPCClientWindowState> mData;
 
  public:
   ClientWindowState(mozilla::dom::VisibilityState aVisibilityState,
                     const TimeStamp& aLastFocusTime,
-                    nsContentUtils::StorageAccess aStorageAccess,
-                    bool aFocused);
+                    StorageAccess aStorageAccess, bool aFocused);
 
   explicit ClientWindowState(const IPCClientWindowState& aData);
 
   ClientWindowState(const ClientWindowState& aRight);
   ClientWindowState(ClientWindowState&& aRight);
 
   ClientWindowState& operator=(const ClientWindowState& aRight);
 
@@ -44,45 +44,45 @@ class ClientWindowState final {
   ~ClientWindowState();
 
   mozilla::dom::VisibilityState VisibilityState() const;
 
   const TimeStamp& LastFocusTime() const;
 
   bool Focused() const;
 
-  nsContentUtils::StorageAccess GetStorageAccess() const;
+  StorageAccess GetStorageAccess() const;
 
   const IPCClientWindowState& ToIPC() const;
 };
 
 // This class defines the mutable worker state we support querying
 // through the ClientManagerService.  It is a snapshot of the state and
 // is not live updated.  Right now, we don't actually providate any
 // worker specific state values, but we may in the future.  This
 // class also services as a placeholder that the state is referring
 // to a worker in ClientState.
 class ClientWorkerState final {
   UniquePtr<IPCClientWorkerState> mData;
 
  public:
-  explicit ClientWorkerState(nsContentUtils::StorageAccess aStorageAccess);
+  explicit ClientWorkerState(StorageAccess aStorageAccess);
 
   explicit ClientWorkerState(const IPCClientWorkerState& aData);
 
   ClientWorkerState(const ClientWorkerState& aRight);
   ClientWorkerState(ClientWorkerState&& aRight);
 
   ClientWorkerState& operator=(const ClientWorkerState& aRight);
 
   ClientWorkerState& operator=(ClientWorkerState&& aRight);
 
   ~ClientWorkerState();
 
-  nsContentUtils::StorageAccess GetStorageAccess() const;
+  StorageAccess GetStorageAccess() const;
 
   const IPCClientWorkerState& ToIPC() const;
 };
 
 // This is a union of the various types of mutable state we support
 // querying in ClientManagerService.  Right now it can contain either
 // window or worker states.
 class ClientState final {
@@ -110,17 +110,17 @@ class ClientState final {
   bool IsWindowState() const;
 
   const ClientWindowState& AsWindowState() const;
 
   bool IsWorkerState() const;
 
   const ClientWorkerState& AsWorkerState() const;
 
-  nsContentUtils::StorageAccess GetStorageAccess() const;
+  StorageAccess GetStorageAccess() const;
 
   const IPCClientState ToIPC() const;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // _mozilla_dom_ClientState_h
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -291,23 +291,22 @@ nsresult IDBFactory::AllowedForWindowInt
                                               nsIPrincipal** aPrincipal) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aWindow);
 
   if (NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate())) {
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
-  nsContentUtils::StorageAccess access =
-      nsContentUtils::StorageAllowedForWindow(aWindow);
+  StorageAccess access = StorageAllowedForWindow(aWindow);
 
   // the factory callsite records whether the browser is in private browsing.
   // and thus we don't have to respect that setting here. IndexedDB has no
   // concept of session-local storage, and thus ignores it.
-  if (access == nsContentUtils::StorageAccess::eDeny) {
+  if (access == StorageAccess::eDeny) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   if (ShouldPartitionStorage(access) &&
       !StoragePartitioningEnabled(access,
                                   aWindow->GetExtantDoc()->CookieSettings())) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
--- a/dom/localstorage/LSObject.cpp
+++ b/dom/localstorage/LSObject.cpp
@@ -240,18 +240,17 @@ void LSObject::Initialize() {
 
 // static
 nsresult LSObject::CreateForWindow(nsPIDOMWindowInner* aWindow,
                                    Storage** aStorage) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aWindow);
   MOZ_ASSERT(aStorage);
   MOZ_ASSERT(NextGenLocalStorageEnabled());
-  MOZ_ASSERT(nsContentUtils::StorageAllowedForWindow(aWindow) !=
-             nsContentUtils::StorageAccess::eDeny);
+  MOZ_ASSERT(StorageAllowedForWindow(aWindow) != StorageAccess::eDeny);
 
   nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
   MOZ_ASSERT(sop);
 
   nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
   if (NS_WARN_IF(!principal)) {
     return NS_ERROR_FAILURE;
   }
--- a/dom/serviceworkers/ServiceWorker.cpp
+++ b/dom/serviceworkers/ServiceWorker.cpp
@@ -18,16 +18,17 @@
 
 #include "mozilla/dom/ClientIPCTypes.h"
 #include "mozilla/dom/ClientState.h"
 #include "mozilla/dom/MessagePortBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/StaticPrefs.h"
+#include "mozilla/StorageAccess.h"
 
 #ifdef XP_WIN
 #  undef PostMessage
 #endif
 
 using mozilla::ErrorResult;
 using namespace mozilla::dom;
 
@@ -175,18 +176,18 @@ void ServiceWorker::PostMessage(JSContex
   }
 
   nsPIDOMWindowInner* window = GetOwner();
   if (NS_WARN_IF(!window || !window->GetExtantDoc())) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
-  auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
-  if (storageAllowed != nsContentUtils::StorageAccess::eAllow) {
+  auto storageAllowed = StorageAllowedForWindow(window);
+  if (storageAllowed != StorageAccess::eAllow) {
     ServiceWorkerManager::LocalizeAndReportToAllClients(
         mDescriptor.Scope(), "ServiceWorkerPostMessageStorageError",
         nsTArray<nsString>{NS_ConvertUTF8toUTF16(mDescriptor.Scope())});
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return;
   }
 
   Maybe<ClientInfo> clientInfo = window->GetClientInfo();
--- a/dom/serviceworkers/ServiceWorkerContainer.cpp
+++ b/dom/serviceworkers/ServiceWorkerContainer.cpp
@@ -18,16 +18,17 @@
 #include "nsPIDOMWindow.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPrefs.h"
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsServiceManagerUtils.h"
 
 #include "mozilla/LoadInfo.h"
+#include "mozilla/StorageAccess.h"
 #include "mozilla/dom/ClientIPCTypes.h"
 #include "mozilla/dom/DOMMozPromiseRequestHolder.h"
 #include "mozilla/dom/MessageEvent.h"
 #include "mozilla/dom/MessageEventBinding.h"
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ServiceWorker.h"
 #include "mozilla/dom/ServiceWorkerContainerBinding.h"
@@ -624,18 +625,18 @@ nsIGlobalObject* ServiceWorkerContainer:
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
 
   // Don't allow a service worker to access service worker registrations
   // from a window with storage disabled.  If these windows can access
   // the registration it increases the chance they can bypass the storage
   // block via postMessage(), etc.
-  auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
-  if (NS_WARN_IF(storageAllowed != nsContentUtils::StorageAccess::eAllow)) {
+  auto storageAllowed = StorageAllowedForWindow(window);
+  if (NS_WARN_IF(storageAllowed != StorageAccess::eAllow)) {
     if (aStorageFailureCB) {
       aStorageFailureCB(doc);
     }
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
 
   // Don't allow service workers when the document is chrome.
--- a/dom/serviceworkers/ServiceWorkerInterceptController.cpp
+++ b/dom/serviceworkers/ServiceWorkerInterceptController.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "ServiceWorkerInterceptController.h"
 
 #include "mozilla/BasePrincipal.h"
+#include "mozilla/StorageAccess.h"
 #include "nsContentUtils.h"
 #include "nsIChannel.h"
 #include "ServiceWorkerManager.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_ISUPPORTS(ServiceWorkerInterceptController,
@@ -43,18 +44,17 @@ ServiceWorkerInterceptController::Should
   if (!swm || !swm->IsAvailable(principal, aURI)) {
     return NS_OK;
   }
 
   // Then check to see if we are allowed to control the window.
   // It is important to check for the availability of the service worker first
   // to avoid showing warnings about the use of third-party cookies in the UI
   // unnecessarily when no service worker is being accessed.
-  if (nsContentUtils::StorageAllowedForChannel(aChannel) !=
-      nsContentUtils::StorageAccess::eAllow) {
+  if (StorageAllowedForChannel(aChannel) != StorageAccess::eAllow) {
     return NS_OK;
   }
 
   *aShouldIntercept = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
@@ -1725,18 +1725,18 @@ nsresult ServiceWorkerPrivate::SpawnWork
 
   // StoragePrincipal for ServiceWorkers is equal to mPrincipal because, at the
   // moment, ServiceWorkers are not exposed in partitioned contexts.
   info.mStoragePrincipal = info.mPrincipal;
 
   info.mCookieSettings = mozilla::net::CookieSettings::Create();
   MOZ_ASSERT(info.mCookieSettings);
 
-  info.mStorageAccess = nsContentUtils::StorageAllowedForServiceWorker(
-      info.mPrincipal, info.mCookieSettings);
+  info.mStorageAccess =
+      StorageAllowedForServiceWorker(info.mPrincipal, info.mCookieSettings);
 
   info.mOriginAttributes = mInfo->GetOriginAttributes();
 
   // Verify that we don't have any CSP on pristine client.
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   nsCOMPtr<nsIContentSecurityPolicy> csp;
   if (info.mChannel) {
     nsCOMPtr<nsILoadInfo> loadinfo = info.mChannel->LoadInfo();
--- a/dom/storage/Storage.cpp
+++ b/dom/storage/Storage.cpp
@@ -3,16 +3,17 @@
 /* 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/. */
 
 #include "Storage.h"
 #include "StorageNotifierService.h"
 
 #include "mozilla/dom/StorageBinding.h"
+#include "mozilla/StorageAccess.h"
 #include "nsIPrincipal.h"
 #include "nsPIDOMWindow.h"
 
 namespace mozilla {
 namespace dom {
 
 static const char kStorageEnabled[] = "dom.storage.enabled";
 
@@ -34,24 +35,23 @@ Storage::Storage(nsPIDOMWindowInner* aWi
       mStoragePrincipal(aStoragePrincipal),
       mIsSessionOnly(false) {
   MOZ_ASSERT(aPrincipal);
 
   if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
     mIsSessionOnly = false;
   } else if (mWindow) {
     uint32_t rejectedReason = 0;
-    nsContentUtils::StorageAccess access =
-        nsContentUtils::StorageAllowedForWindow(mWindow, &rejectedReason);
+    StorageAccess access = StorageAllowedForWindow(mWindow, &rejectedReason);
 
-    MOZ_ASSERT(access != nsContentUtils::StorageAccess::eDeny ||
+    MOZ_ASSERT(access != StorageAccess::eDeny ||
                rejectedReason ==
                    nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
 
-    mIsSessionOnly = access <= nsContentUtils::StorageAccess::eSessionScoped;
+    mIsSessionOnly = access <= StorageAccess::eSessionScoped;
   }
 }
 
 Storage::~Storage() = default;
 
 /* static */
 bool Storage::StoragePrefIsEnabled() {
   return mozilla::Preferences::GetBool(kStorageEnabled);
--- a/dom/workers/WorkerLoadInfo.cpp
+++ b/dom/workers/WorkerLoadInfo.cpp
@@ -8,16 +8,17 @@
 #include "WorkerPrivate.h"
 
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/dom/nsCSPUtils.h"
 #include "mozilla/dom/BrowserChild.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/LoadContext.h"
+#include "mozilla/StorageAccess.h"
 #include "nsContentUtils.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsINetworkInterceptController.h"
 #include "nsIProtocolHandler.h"
 #include "nsIBrowserChild.h"
 #include "nsScriptSecurityManager.h"
 #include "nsNetUtil.h"
 
@@ -84,17 +85,17 @@ WorkerLoadInfoData::WorkerLoadInfoData()
       mWindowID(UINT64_MAX),
       mReferrerPolicy(net::RP_Unset),
       mFromWindow(false),
       mEvalAllowed(false),
       mReportCSPViolations(false),
       mXHRParamsAllowed(false),
       mPrincipalIsSystem(false),
       mWatchedByDevtools(false),
-      mStorageAccess(nsContentUtils::StorageAccess::eDeny),
+      mStorageAccess(StorageAccess::eDeny),
       mFirstPartyStorageAccessGranted(false),
       mServiceWorkersTestingInWindow(false),
       mSecureContext(eNotSet) {}
 
 nsresult WorkerLoadInfo::SetPrincipalsAndCSPOnMainThread(
     nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal,
     nsILoadGroup* aLoadGroup, nsIContentSecurityPolicy* aCsp) {
   AssertIsOnMainThread();
--- a/dom/workers/WorkerLoadInfo.h
+++ b/dom/workers/WorkerLoadInfo.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef mozilla_dom_workers_WorkerLoadInfo_h
 #define mozilla_dom_workers_WorkerLoadInfo_h
 
+#include "mozilla/StorageAccess.h"
 #include "mozilla/dom/ChannelInfo.h"
 #include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/net/ReferrerPolicy.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsILoadContext.h"
 #include "nsIRequest.h"
 #include "nsISupportsImpl.h"
@@ -119,17 +120,17 @@ struct WorkerLoadInfoData {
 
   net::ReferrerPolicy mReferrerPolicy;
   bool mFromWindow;
   bool mEvalAllowed;
   bool mReportCSPViolations;
   bool mXHRParamsAllowed;
   bool mPrincipalIsSystem;
   bool mWatchedByDevtools;
-  nsContentUtils::StorageAccess mStorageAccess;
+  StorageAccess mStorageAccess;
   bool mFirstPartyStorageAccessGranted;
   bool mServiceWorkersTestingInWindow;
   OriginAttributes mOriginAttributes;
 
   enum {
     eNotSet,
     eInsecureContext,
     eSecureContext,
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -31,16 +31,17 @@
 #include "mozilla/dom/MessagePortBinding.h"
 #include "mozilla/dom/nsCSPContext.h"
 #include "mozilla/dom/nsCSPUtils.h"
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/PerformanceStorageWorker.h"
 #include "mozilla/dom/PromiseDebugging.h"
 #include "mozilla/dom/RemoteWorkerChild.h"
 #include "mozilla/dom/WorkerBinding.h"
+#include "mozilla/StorageAccess.h"
 #include "mozilla/ThreadEventQueue.h"
 #include "mozilla/ThrottledEventQueue.h"
 #include "mozilla/TimelineConsumers.h"
 #include "mozilla/WorkerTimelineMarker.h"
 #include "nsCycleCollector.h"
 #include "nsGlobalWindowInner.h"
 #include "nsNetUtil.h"
 #include "nsIMemoryReporter.h"
@@ -2520,18 +2521,17 @@ nsresult WorkerPrivate::GetLoadInfo(JSCo
 
       nsIDocShell* docShell = globalWindow->GetDocShell();
       if (docShell) {
         loadInfo.mWatchedByDevtools = docShell->GetWatchedByDevtools();
       }
 
       loadInfo.mFromWindow = true;
       loadInfo.mWindowID = globalWindow->WindowID();
-      loadInfo.mStorageAccess =
-          nsContentUtils::StorageAllowedForWindow(globalWindow);
+      loadInfo.mStorageAccess = StorageAllowedForWindow(globalWindow);
       loadInfo.mCookieSettings = document->CookieSettings();
       loadInfo.mOriginAttributes =
           nsContentUtils::GetOriginAttributes(document);
       loadInfo.mParentController = globalWindow->GetController();
       loadInfo.mSecureContext = loadInfo.mWindow->IsSecureContext()
                                     ? WorkerLoadInfo::eSecureContext
                                     : WorkerLoadInfo::eInsecureContext;
     } else {
@@ -2567,17 +2567,17 @@ nsresult WorkerPrivate::GetLoadInfo(JSCo
         }
         if (NS_FAILED(rv)) {
           return rv;
         }
       }
       loadInfo.mXHRParamsAllowed = true;
       loadInfo.mFromWindow = false;
       loadInfo.mWindowID = UINT64_MAX;
-      loadInfo.mStorageAccess = nsContentUtils::StorageAccess::eAllow;
+      loadInfo.mStorageAccess = StorageAccess::eAllow;
       loadInfo.mCookieSettings = mozilla::net::CookieSettings::Create();
       MOZ_ASSERT(loadInfo.mCookieSettings);
 
       loadInfo.mOriginAttributes = OriginAttributes();
     }
 
     MOZ_ASSERT(loadInfo.mLoadingPrincipal);
     MOZ_ASSERT(isChrome || !loadInfo.mDomain.IsEmpty());
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_dom_workers_workerprivate_h__
 #define mozilla_dom_workers_workerprivate_h__
 
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/CondVar.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/RelativeTimeline.h"
+#include "mozilla/StorageAccess.h"
 #include "nsContentUtils.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIEventTarget.h"
 #include "nsTObserverArray.h"
 
 #include "js/ContextOptions.h"
 #include "mozilla/dom/Worker.h"
 #include "mozilla/dom/WorkerHolder.h"
@@ -737,20 +738,20 @@ class WorkerPrivate : public RelativeTim
   }
 
   bool XHRParamsAllowed() const { return mLoadInfo.mXHRParamsAllowed; }
 
   void SetXHRParamsAllowed(bool aAllowed) {
     mLoadInfo.mXHRParamsAllowed = aAllowed;
   }
 
-  nsContentUtils::StorageAccess StorageAccess() const {
+  mozilla::StorageAccess StorageAccess() const {
     AssertIsOnWorkerThread();
     if (mLoadInfo.mFirstPartyStorageAccessGranted) {
-      return nsContentUtils::StorageAccess::eAllow;
+      return mozilla::StorageAccess::eAllow;
     }
 
     return mLoadInfo.mStorageAccess;
   }
 
   nsICookieSettings* CookieSettings() const {
     // Any thread.
     MOZ_ASSERT(mLoadInfo.mCookieSettings);
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -397,19 +397,19 @@ already_AddRefed<Promise> WorkerGlobalSc
 
 already_AddRefed<IDBFactory> WorkerGlobalScope::GetIndexedDB(
     ErrorResult& aErrorResult) {
   mWorkerPrivate->AssertIsOnWorkerThread();
 
   RefPtr<IDBFactory> indexedDB = mIndexedDB;
 
   if (!indexedDB) {
-    nsContentUtils::StorageAccess access = mWorkerPrivate->StorageAccess();
+    StorageAccess access = mWorkerPrivate->StorageAccess();
 
-    if (access == nsContentUtils::StorageAccess::eDeny) {
+    if (access == StorageAccess::eDeny) {
       NS_WARNING("IndexedDB is not allowed in this worker!");
       aErrorResult = NS_ERROR_DOM_SECURITY_ERR;
       return nullptr;
     }
 
     if (ShouldPartitionStorage(access) &&
         !StoragePartitioningEnabled(access, mWorkerPrivate->CookieSettings())) {
       NS_WARNING("IndexedDB is not allowed in this worker!");
--- a/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh
+++ b/dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh
@@ -2,17 +2,17 @@
  * 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/. */
 
 include ClientIPCTypes;
 include PBackgroundSharedTypes;
 include URIParams;
 
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
-using nsContentUtils::StorageAccess from "mozilla/dom/ClientIPCUtils.h";
+using mozilla::StorageAccess from "mozilla/dom/ClientIPCUtils.h";
 
 namespace mozilla {
 namespace dom {
 
 struct RemoteWorkerData
 {
   // This should only be used for devtools.
   nsString originalScriptURL;
--- a/dom/workers/sharedworkers/SharedWorker.cpp
+++ b/dom/workers/sharedworkers/SharedWorker.cpp
@@ -58,33 +58,33 @@ already_AddRefed<SharedWorker> SharedWor
     const GlobalObject& aGlobal, const nsAString& aScriptURL,
     const StringOrWorkerOptions& aOptions, ErrorResult& aRv) {
   AssertIsOnMainThread();
 
   nsCOMPtr<nsPIDOMWindowInner> window =
       do_QueryInterface(aGlobal.GetAsSupports());
   MOZ_ASSERT(window);
 
-  auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
-  if (storageAllowed == nsContentUtils::StorageAccess::eDeny) {
+  auto storageAllowed = StorageAllowedForWindow(window);
+  if (storageAllowed == StorageAccess::eDeny) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
 
   if (ShouldPartitionStorage(storageAllowed) &&
       !StoragePartitioningEnabled(storageAllowed,
                                   window->GetExtantDoc()->CookieSettings())) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     return nullptr;
   }
 
   // Assert that the principal private browsing state matches the
   // StorageAccess value.
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
-  if (storageAllowed == nsContentUtils::StorageAccess::ePrivateBrowsing) {
+  if (storageAllowed == StorageAccess::ePrivateBrowsing) {
     nsCOMPtr<Document> doc = window->GetExtantDoc();
     nsCOMPtr<nsIPrincipal> principal = doc ? doc->NodePrincipal() : nullptr;
     uint32_t privateBrowsingId = 0;
     if (principal) {
       MOZ_ALWAYS_SUCCEEDS(principal->GetPrivateBrowsingId(&privateBrowsingId));
     }
     MOZ_DIAGNOSTIC_ASSERT(privateBrowsingId != 0);
   }
--- a/image/ImageCacheKey.cpp
+++ b/image/ImageCacheKey.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/Move.h"
 #include "mozilla/Unused.h"
 #include "nsContentUtils.h"
 #include "nsICookieService.h"
 #include "nsLayoutUtils.h"
 #include "nsString.h"
 #include "mozilla/AntiTrackingCommon.h"
 #include "mozilla/HashFunctions.h"
+#include "mozilla/StorageAccess.h"
 #include "mozilla/dom/BlobURLProtocolHandler.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/ServiceWorkerManager.h"
 #include "mozilla/dom/Document.h"
 #include "nsHashKeys.h"
 #include "nsPrintfCString.h"
 
 namespace mozilla {
@@ -174,17 +175,17 @@ nsCString ImageCacheKey::GetTopLevelBase
   if (!aDocument || !aDocument->GetInnerWindow()) {
     return EmptyCString();
   }
 
   // If the window is 3rd party resource, let's see if first-party storage
   // access is granted for this image.
   if (nsContentUtils::IsThirdPartyTrackingResourceWindow(
           aDocument->GetInnerWindow())) {
-    return nsContentUtils::StorageDisabledByAntiTracking(aDocument, aURI)
+    return StorageDisabledByAntiTracking(aDocument, aURI)
                ? aDocument->GetBaseDomain()
                : EmptyCString();
   }
 
   // Another scenario is if this image is a 3rd party resource loaded by a
   // first party context. In this case, we should check if the nsIChannel has
   // been marked as tracking resource, but we don't have the channel yet at
   // this point.  The best approach here is to be conservative: if we are sure
--- a/toolkit/components/antitracking/StorageAccess.cpp
+++ b/toolkit/components/antitracking/StorageAccess.cpp
@@ -1,41 +1,354 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
+#include "mozilla/dom/Document.h"
+#include "mozilla/net/CookieSettings.h"
+#include "mozilla/AntiTrackingCommon.h"
 #include "mozilla/StorageAccess.h"
 #include "nsICookieService.h"
 #include "nsICookieSettings.h"
 #include "nsIWebProgressListener.h"
 
+/**
+ * Gets the cookie lifetime policy for a given cookieSettings and a given
+ * principal by checking the permission value.
+ *
+ * Used in the implementation of InternalStorageAllowedCheck.
+ */
+static void GetCookieLifetimePolicyFromCookieSettings(
+    nsICookieSettings* aCookieSettings, nsIPrincipal* aPrincipal,
+    uint32_t* aLifetimePolicy) {
+  *aLifetimePolicy = StaticPrefs::network_cookie_lifetimePolicy();
+
+  if (aCookieSettings) {
+    uint32_t cookiePermission = 0;
+    nsresult rv =
+        aCookieSettings->CookiePermission(aPrincipal, &cookiePermission);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return;
+    }
+
+    switch (cookiePermission) {
+      case nsICookiePermission::ACCESS_ALLOW:
+        *aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
+        break;
+      case nsICookiePermission::ACCESS_DENY:
+        *aLifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
+        break;
+      case nsICookiePermission::ACCESS_SESSION:
+        *aLifetimePolicy = nsICookieService::ACCEPT_SESSION;
+        break;
+    }
+  }
+}
+
+/*
+ * Checks if storage for a given principal is permitted by the user's
+ * preferences. If aWindow is non-null, its principal must be passed as
+ * aPrincipal, and the third-party iframe and sandboxing status of the window
+ * are also checked.  If aURI is non-null, then it is used as the comparison
+ * against aWindow to determine if this is a third-party load.  We also
+ * allow a channel instead of the window reference when determining 3rd party
+ * status.
+ *
+ * Used in the implementation of StorageAllowedForWindow,
+ * StorageAllowedForChannel and StorageAllowedForServiceWorker.
+ */
+static StorageAccess InternalStorageAllowedCheck(
+    nsIPrincipal* aPrincipal, nsPIDOMWindowInner* aWindow, nsIURI* aURI,
+    nsIChannel* aChannel, nsICookieSettings* aCookieSettings,
+    uint32_t& aRejectedReason) {
+  MOZ_ASSERT(aPrincipal);
+
+  aRejectedReason = 0;
+
+  StorageAccess access = StorageAccess::eAllow;
+
+  // We don't allow storage on the null principal, in general. Even if the
+  // calling context is chrome.
+  if (aPrincipal->GetIsNullPrincipal()) {
+    return StorageAccess::eDeny;
+  }
+
+  if (aWindow) {
+    // If the document is sandboxed, then it is not permitted to use storage
+    Document* document = aWindow->GetExtantDoc();
+    if (document && document->GetSandboxFlags() & SANDBOXED_ORIGIN) {
+      return StorageAccess::eDeny;
+    }
+
+    // Check if we are in private browsing, and record that fact
+    if (nsContentUtils::IsInPrivateBrowsing(document)) {
+      access = StorageAccess::ePrivateBrowsing;
+    }
+  }
+
+  uint32_t lifetimePolicy;
+
+  // WebExtensions principals always get BEHAVIOR_ACCEPT as cookieBehavior
+  // and ACCEPT_NORMALLY as lifetimePolicy (See Bug 1406675 for rationale).
+  auto policy = BasePrincipal::Cast(aPrincipal)->AddonPolicy();
+
+  if (policy) {
+    lifetimePolicy = nsICookieService::ACCEPT_NORMALLY;
+  } else {
+    GetCookieLifetimePolicyFromCookieSettings(aCookieSettings, aPrincipal,
+                                              &lifetimePolicy);
+  }
+
+  // Check if we should only allow storage for the session, and record that fact
+  if (lifetimePolicy == nsICookieService::ACCEPT_SESSION) {
+    // Storage could be StorageAccess::ePrivateBrowsing or StorageAccess::eAllow
+    // so perform a std::min comparison to make sure we preserve
+    // ePrivateBrowsing if it has been set.
+    access = std::min(StorageAccess::eSessionScoped, access);
+  }
+
+  // About URIs are allowed to access storage, even if they don't have chrome
+  // privileges. If this is not desired, than the consumer will have to
+  // implement their own restriction functionality.
+  //
+  // This is due to backwards-compatibility and the state of storage access
+  // before the introducton of InternalStorageAllowedCheck:
+  //
+  // BEFORE:
+  // localStorage, caches: allowed in 3rd-party iframes always
+  // IndexedDB: allowed in 3rd-party iframes only if 3rd party URI is an about:
+  //   URI within a specific whitelist
+  //
+  // AFTER:
+  // localStorage, caches: allowed in 3rd-party iframes by default. Preference
+  //   can be set to disable in 3rd-party, which will not disallow in about:
+  //   URIs.
+  // IndexedDB: allowed in 3rd-party iframes by default. Preference can be set
+  //   to disable in 3rd-party, which will disallow in about: URIs, unless they
+  //   are within a specific whitelist.
+  //
+  // This means that behavior for storage with internal about: URIs should not
+  // be affected, which is desireable due to the lack of automated testing for
+  // about: URIs with these preferences set, and the importance of the correct
+  // functioning of these URIs even with custom preferences.
+  nsCOMPtr<nsIURI> uri = aURI;
+  if (!uri) {
+    Unused << aPrincipal->GetURI(getter_AddRefs(uri));
+  }
+  if (uri) {
+    bool isAbout = false;
+    MOZ_ALWAYS_SUCCEEDS(uri->SchemeIs("about", &isAbout));
+    if (isAbout) {
+      return access;
+    }
+  }
+
+  if (!StorageDisabledByAntiTracking(aWindow, aChannel, aPrincipal, aURI,
+                                     aRejectedReason)) {
+    return access;
+  }
+
+  // We want to have a partitioned storage only for trackers.
+  if (aRejectedReason ==
+      nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER) {
+    return StorageAccess::ePartitionTrackersOrDeny;
+  }
+
+  // We want to have a partitioned storage for all third parties.
+  if (aRejectedReason ==
+      nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN) {
+    return StorageAccess::ePartitionForeignOrDeny;
+  }
+
+  return StorageAccess::eDeny;
+}
+
+static bool StorageDisabledByAntiTrackingInternal(
+    nsPIDOMWindowInner* aWindow, nsIChannel* aChannel, nsIPrincipal* aPrincipal,
+    nsIURI* aURI, nsICookieSettings* aCookieSettings,
+    uint32_t& aRejectedReason) {
+  MOZ_ASSERT(aWindow || aChannel || aPrincipal);
+
+  if (aWindow) {
+    nsIURI* documentURI = aURI ? aURI : aWindow->GetDocumentURI();
+    return !documentURI ||
+           !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
+               aWindow, documentURI, &aRejectedReason);
+  }
+
+  if (aChannel) {
+    nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
+    if (!httpChannel) {
+      return false;
+    }
+
+    nsCOMPtr<nsIURI> uri;
+    nsresult rv = httpChannel->GetURI(getter_AddRefs(uri));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return false;
+    }
+
+    return !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
+        httpChannel, uri, &aRejectedReason);
+  }
+
+  MOZ_ASSERT(aPrincipal);
+  return !AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
+      aPrincipal, aCookieSettings);
+}
+
 namespace mozilla {
 
-bool ShouldPartitionStorage(nsContentUtils::StorageAccess aAccess) {
-  return aAccess == nsContentUtils::StorageAccess::ePartitionTrackersOrDeny ||
-         aAccess == nsContentUtils::StorageAccess::ePartitionForeignOrDeny;
+StorageAccess StorageAllowedForWindow(nsPIDOMWindowInner* aWindow,
+                                      uint32_t* aRejectedReason) {
+  uint32_t rejectedReason;
+  if (!aRejectedReason) {
+    aRejectedReason = &rejectedReason;
+  }
+
+  *aRejectedReason = 0;
+
+  if (Document* document = aWindow->GetExtantDoc()) {
+    nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
+    // Note that GetChannel() below may return null, but that's OK, since the
+    // callee is able to deal with a null channel argument, and if passed null,
+    // will only fail to notify the UI in case storage gets blocked.
+    nsIChannel* channel = document->GetChannel();
+    return InternalStorageAllowedCheck(principal, aWindow, nullptr, channel,
+                                       document->CookieSettings(),
+                                       *aRejectedReason);
+  }
+
+  // No document? Let's return a generic rejected reason.
+  return StorageAccess::eDeny;
+}
+
+StorageAccess StorageAllowedForDocument(const Document* aDoc) {
+  MOZ_ASSERT(aDoc);
+
+  if (nsPIDOMWindowInner* inner = aDoc->GetInnerWindow()) {
+    nsCOMPtr<nsIPrincipal> principal = aDoc->NodePrincipal();
+    // Note that GetChannel() below may return null, but that's OK, since the
+    // callee is able to deal with a null channel argument, and if passed null,
+    // will only fail to notify the UI in case storage gets blocked.
+    nsIChannel* channel = aDoc->GetChannel();
+
+    uint32_t rejectedReason = 0;
+    return InternalStorageAllowedCheck(
+        principal, inner, nullptr, channel,
+        const_cast<Document*>(aDoc)->CookieSettings(), rejectedReason);
+  }
+
+  return StorageAccess::eDeny;
+}
+
+StorageAccess StorageAllowedForNewWindow(nsIPrincipal* aPrincipal, nsIURI* aURI,
+                                         nsPIDOMWindowInner* aParent) {
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(aURI);
+  // parent may be nullptr
+
+  uint32_t rejectedReason = 0;
+  nsCOMPtr<nsICookieSettings> cs;
+  if (aParent && aParent->GetExtantDoc()) {
+    cs = aParent->GetExtantDoc()->CookieSettings();
+  } else {
+    cs = net::CookieSettings::Create();
+  }
+  return InternalStorageAllowedCheck(aPrincipal, aParent, aURI, nullptr, cs,
+                                     rejectedReason);
+}
+
+StorageAccess StorageAllowedForChannel(nsIChannel* aChannel) {
+  MOZ_DIAGNOSTIC_ASSERT(nsContentUtils::GetSecurityManager());
+  MOZ_DIAGNOSTIC_ASSERT(aChannel);
+
+  nsCOMPtr<nsIPrincipal> principal;
+  Unused << nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
+      aChannel, getter_AddRefs(principal));
+  NS_ENSURE_TRUE(principal, StorageAccess::eDeny);
+
+  nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
+  nsCOMPtr<nsICookieSettings> cookieSettings;
+  nsresult rv = loadInfo->GetCookieSettings(getter_AddRefs(cookieSettings));
+  NS_ENSURE_SUCCESS(rv, StorageAccess::eDeny);
+
+  uint32_t rejectedReason = 0;
+  StorageAccess result = InternalStorageAllowedCheck(
+      principal, nullptr, nullptr, aChannel, cookieSettings, rejectedReason);
+
+  return result;
+}
+
+StorageAccess StorageAllowedForServiceWorker(
+    nsIPrincipal* aPrincipal, nsICookieSettings* aCookieSettings) {
+  uint32_t rejectedReason = 0;
+  return InternalStorageAllowedCheck(aPrincipal, nullptr, nullptr, nullptr,
+                                     aCookieSettings, rejectedReason);
+}
+
+bool StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
+                                   nsIChannel* aChannel,
+                                   nsIPrincipal* aPrincipal, nsIURI* aURI,
+                                   uint32_t& aRejectedReason) {
+  nsCOMPtr<nsICookieSettings> cookieSettings;
+  if (aWindow) {
+    if (aWindow->GetExtantDoc()) {
+      cookieSettings = aWindow->GetExtantDoc()->CookieSettings();
+    }
+  } else if (aChannel) {
+    nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
+    Unused << loadInfo->GetCookieSettings(getter_AddRefs(cookieSettings));
+  }
+  if (!cookieSettings) {
+    cookieSettings = net::CookieSettings::Create();
+  }
+  bool disabled = StorageDisabledByAntiTrackingInternal(
+      aWindow, aChannel, aPrincipal, aURI, cookieSettings, aRejectedReason);
+  if (StaticPrefs::
+          browser_contentblocking_rejecttrackers_control_center_ui_enabled()) {
+    if (aWindow) {
+      AntiTrackingCommon::NotifyBlockingDecision(
+          aWindow,
+          disabled ? AntiTrackingCommon::BlockingDecision::eBlock
+                   : AntiTrackingCommon::BlockingDecision::eAllow,
+          aRejectedReason);
+    } else if (aChannel) {
+      AntiTrackingCommon::NotifyBlockingDecision(
+          aChannel,
+          disabled ? AntiTrackingCommon::BlockingDecision::eBlock
+                   : AntiTrackingCommon::BlockingDecision::eAllow,
+          aRejectedReason);
+    }
+  }
+  return disabled;
+}
+
+bool ShouldPartitionStorage(StorageAccess aAccess) {
+  return aAccess == StorageAccess::ePartitionTrackersOrDeny ||
+         aAccess == StorageAccess::ePartitionForeignOrDeny;
 }
 
 bool ShouldPartitionStorage(uint32_t aRejectedReason) {
   return aRejectedReason ==
              nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
          aRejectedReason ==
              nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN;
 }
 
-bool StoragePartitioningEnabled(nsContentUtils::StorageAccess aAccess,
+bool StoragePartitioningEnabled(StorageAccess aAccess,
                                 nsICookieSettings* aCookieSettings) {
-  if (aAccess == nsContentUtils::StorageAccess::ePartitionTrackersOrDeny) {
+  if (aAccess == StorageAccess::ePartitionTrackersOrDeny) {
     return aCookieSettings->GetCookieBehavior() ==
                nsICookieService::BEHAVIOR_REJECT_TRACKER &&
            StaticPrefs::privacy_storagePrincipal_enabledForTrackers();
   }
-  if (aAccess == nsContentUtils::StorageAccess::ePartitionForeignOrDeny) {
+  if (aAccess == StorageAccess::ePartitionForeignOrDeny) {
     return aCookieSettings->GetCookieBehavior() ==
            nsICookieService::BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN;
   }
   return false;
 }
 
 bool StoragePartitioningEnabled(uint32_t aRejectedReason,
                                 nsICookieSettings* aCookieSettings) {
--- a/toolkit/components/antitracking/StorageAccess.h
+++ b/toolkit/components/antitracking/StorageAccess.h
@@ -2,27 +2,124 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef mozilla_StorageAccess_h
 #define mozilla_StorageAccess_h
 
-#include "nsContentUtils.h"
+#include "mozilla/dom/Document.h"
 
+class nsIChannel;
 class nsICookieSettings;
+class nsIPrincipal;
+class nsIURI;
+class nsPIDOMWindowInner;
 
 namespace mozilla {
 
-bool ShouldPartitionStorage(nsContentUtils::StorageAccess aAccess);
+// The order of these entries matters, as we use std::min for total ordering
+// of permissions. Private Browsing is considered to be more limiting
+// then session scoping
+enum class StorageAccess {
+  // The storage should be partitioned for third-party resources. if the
+  // caller is unable to do it, deny the storage access.
+  ePartitionForeignOrDeny = -2,
+  // The storage should be partitioned for third-party trackers. if the caller
+  // is unable to do it, deny the storage access.
+  ePartitionTrackersOrDeny = -1,
+  // Don't allow access to the storage
+  eDeny = 0,
+  // Allow access to the storage, but only if it is secure to do so in a
+  // private browsing context.
+  ePrivateBrowsing = 1,
+  // Allow access to the storage, but only persist it for the current session
+  eSessionScoped = 2,
+  // Allow access to the storage
+  eAllow = 3,
+  // Keep this at the end.  Used for serialization, but not a valid value.
+  eNumValues = 4,
+};
+
+/*
+ * Checks if storage for the given window is permitted by a combination of
+ * the user's preferences, and whether the window is a third-party iframe.
+ *
+ * This logic is intended to be shared between the different forms of
+ * persistent storage which are available to web pages. Cookies don't use
+ * this logic, and security logic related to them must be updated separately.
+ */
+StorageAccess StorageAllowedForWindow(nsPIDOMWindowInner* aWindow,
+                                      uint32_t* aRejectedReason = nullptr);
+
+/*
+ * Checks if storage for the given document is permitted by a combination of
+ * the user's preferences, and whether the document's window is a third-party
+ * iframe.
+ *
+ * Note, this may be used on documents during the loading process where
+ * the window's extant document has not been set yet.  The code in
+ * StorageAllowedForWindow(), however, will not work in these cases.
+ */
+StorageAccess StorageAllowedForDocument(const dom::Document* aDoc);
+
+/*
+ * Checks if storage should be allowed for a new window with the given
+ * principal, load URI, and parent.
+ */
+StorageAccess StorageAllowedForNewWindow(nsIPrincipal* aPrincipal, nsIURI* aURI,
+                                         nsPIDOMWindowInner* aParent);
+
+/*
+ * Checks if storage should be allowed for the given channel.  The check will
+ * be based on the channel result principal and, depending on preferences and
+ * permissions, mozIThirdPartyUtil.isThirdPartyChannel().
+ */
+StorageAccess StorageAllowedForChannel(nsIChannel* aChannel);
+
+/*
+ * Checks if storage for the given principal is permitted by the user's
+ * preferences. This method should be used only by ServiceWorker loading.
+ */
+StorageAccess StorageAllowedForServiceWorker(
+    nsIPrincipal* aPrincipal, nsICookieSettings* aCookieSettings);
+
+/*
+ * Returns true if this window/channel/aPrincipal should disable storages
+ * because of the anti-tracking feature.
+ * Note that either aWindow or aChannel may be null when calling this
+ * function. If the caller wants the UI to be notified when the storage gets
+ * disabled, it must pass a non-null channel object.
+ */
+bool StorageDisabledByAntiTracking(nsPIDOMWindowInner* aWindow,
+                                   nsIChannel* aChannel,
+                                   nsIPrincipal* aPrincipal, nsIURI* aURI,
+                                   uint32_t& aRejectedReason);
+
+/*
+ * Returns true if this document should disable storages because of the
+ * anti-tracking feature.
+ */
+inline bool StorageDisabledByAntiTracking(dom::Document* aDocument,
+                                          nsIURI* aURI) {
+  uint32_t rejectedReason = 0;
+  // Note that GetChannel() below may return null, but that's OK, since the
+  // callee is able to deal with a null channel argument, and if passed null,
+  // will only fail to notify the UI in case storage gets blocked.
+  return StorageDisabledByAntiTracking(
+      aDocument->GetInnerWindow(), aDocument->GetChannel(),
+      aDocument->NodePrincipal(), aURI, rejectedReason);
+}
+
+bool ShouldPartitionStorage(StorageAccess aAccess);
 
 bool ShouldPartitionStorage(uint32_t aRejectedReason);
 
-bool StoragePartitioningEnabled(nsContentUtils::StorageAccess aAccess,
+bool StoragePartitioningEnabled(StorageAccess aAccess,
                                 nsICookieSettings* aCookieSettings);
 
 bool StoragePartitioningEnabled(uint32_t aRejectedReason,
                                 nsICookieSettings* aCookieSettings);
 
 }  // namespace mozilla
 
 #endif  // mozilla_StorageAccess_h
--- a/toolkit/components/perfmonitoring/PerformanceMetricsCollector.cpp
+++ b/toolkit/components/perfmonitoring/PerformanceMetricsCollector.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
+#include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "mozilla/AbstractThread.h"
 #include "mozilla/Logging.h"
 #include "mozilla/PerformanceUtils.h"
 #include "mozilla/PerformanceMetricsCollector.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/TaskQueue.h"
 #include "mozilla/dom/ContentParent.h"