From f51cd9df3ea2771079605195d189c2c4f607a3f5 Mon Sep 17 00:00:00 2001 From: Paul Zuehlcke Date: Tue, 13 Feb 2024 11:33:05 +0000 Subject: [PATCH] Bug 1876579 - Separate BounceTrackingProtection global state objects by OriginAttributes. r=bvandersloot,anti-tracking-reviewers Differential Revision: https://phabricator.services.mozilla.com/D200818 --- .../BounceTrackingProtection.cpp | 176 ++++++++++++------ .../BounceTrackingProtection.h | 28 ++- .../BounceTrackingState.cpp | 17 +- .../BounceTrackingState.h | 7 + .../BounceTrackingStateGlobal.cpp | 13 ++ .../BounceTrackingStateGlobal.h | 43 +++++ .../bouncetrackingprotection/moz.build | 2 + 7 files changed, 215 insertions(+), 71 deletions(-) create mode 100644 toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.cpp create mode 100644 toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.h diff --git a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtection.cpp b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtection.cpp index cab9379ab5e07..23c092dabf172 100644 --- a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtection.cpp +++ b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtection.cpp @@ -8,6 +8,7 @@ #include "BounceTrackingRecord.h" #include "ErrorList.h" +#include "mozilla/AlreadyAddRefed.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/Logging.h" #include "mozilla/Services.h" @@ -101,6 +102,23 @@ BounceTrackingProtection::BounceTrackingProtection() { "Failed to schedule timer for RunPurgeBounceTrackers."); } +BounceTrackingStateGlobal* BounceTrackingProtection::GetOrCreateStateGlobal( + nsIPrincipal* aPrincipal) { + MOZ_ASSERT(aPrincipal); + return GetOrCreateStateGlobal(aPrincipal->OriginAttributesRef()); +} + +BounceTrackingStateGlobal* BounceTrackingProtection::GetOrCreateStateGlobal( + BounceTrackingState* aBounceTrackingState) { + MOZ_ASSERT(aBounceTrackingState); + return GetOrCreateStateGlobal(aBounceTrackingState->OriginAttributesRef()); +} + +BounceTrackingStateGlobal* BounceTrackingProtection::GetOrCreateStateGlobal( + const OriginAttributes& aOriginAttributes) { + return mStateGlobal.GetOrInsertNew(aOriginAttributes); +} + nsresult BounceTrackingProtection::RecordStatefulBounces( BounceTrackingState* aBounceTrackingState) { NS_ENSURE_ARG_POINTER(aBounceTrackingState); @@ -114,6 +132,11 @@ nsresult BounceTrackingProtection::RecordStatefulBounces( aBounceTrackingState->GetBounceTrackingRecord(); NS_ENSURE_TRUE(record, NS_ERROR_FAILURE); + // Get the bounce tracker map and the user activation map. + BounceTrackingStateGlobal* globalState = + GetOrCreateStateGlobal(aBounceTrackingState); + MOZ_ASSERT(globalState); + // For each host in navigable’s bounce tracking record's bounce set: for (const nsACString& host : record->GetBounceHosts()) { // If host equals navigable’s bounce tracking record's initial host, @@ -133,7 +156,7 @@ nsresult BounceTrackingProtection::RecordStatefulBounces( } // If user activation map contains host, continue. - if (mUserActivation.Contains(host)) { + if (globalState->mUserActivation.Contains(host)) { MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, ("%s: Skip host with recent user activation: %s", __FUNCTION__, PromiseFlatCString(host).get())); @@ -141,7 +164,7 @@ nsresult BounceTrackingProtection::RecordStatefulBounces( } // If stateful bounce tracking map contains host, continue. - if (mBounceTrackers.Contains(host)) { + if (globalState->mBounceTrackers.Contains(host)) { MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, ("%s: Skip already existing host: %s", __FUNCTION__, PromiseFlatCString(host).get())); @@ -162,8 +185,8 @@ nsresult BounceTrackingProtection::RecordStatefulBounces( // Set stateful bounce tracking map[host] to topDocument’s relevant settings // object's current wall time. PRTime now = PR_Now(); - MOZ_ASSERT(!mBounceTrackers.Contains(host)); - mBounceTrackers.InsertOrUpdate(host, now); + MOZ_ASSERT(!globalState->mBounceTrackers.Contains(host)); + globalState->mBounceTrackers.InsertOrUpdate(host, now); MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Info, ("%s: Added candidate to mBounceTrackers: %s, Time: %" PRIu64, @@ -212,15 +235,18 @@ nsresult BounceTrackingProtection::RecordUserActivation( MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Info, ("%s: siteHost: %s", __FUNCTION__, siteHost.get())); - bool hasRemoved = mBounceTrackers.Remove(siteHost); + BounceTrackingStateGlobal* globalState = GetOrCreateStateGlobal(aPrincipal); + MOZ_ASSERT(globalState); + + bool hasRemoved = globalState->mBounceTrackers.Remove(siteHost); if (hasRemoved) { MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, ("%s: Removed bounce tracking candidate due to user activation: %s", __FUNCTION__, siteHost.get())); } - MOZ_ASSERT(!mBounceTrackers.Contains(siteHost)); + MOZ_ASSERT(!globalState->mBounceTrackers.Contains(siteHost)); - mUserActivation.InsertOrUpdate(siteHost, PR_Now()); + globalState->mUserActivation.InsertOrUpdate(siteHost, PR_Now()); return NS_OK; } @@ -228,8 +254,10 @@ nsresult BounceTrackingProtection::RecordUserActivation( NS_IMETHODIMP BounceTrackingProtection::GetBounceTrackerCandidateHosts( nsTArray& aCandidates) { - for (const nsACString& host : mBounceTrackers.Keys()) { - aCandidates.AppendElement(host); + for (BounceTrackingStateGlobal* globalState : mStateGlobal.Values()) { + for (const nsACString& host : globalState->mBounceTrackers.Keys()) { + aCandidates.AppendElement(host); + } } return NS_OK; @@ -237,8 +265,10 @@ BounceTrackingProtection::GetBounceTrackerCandidateHosts( NS_IMETHODIMP BounceTrackingProtection::GetUserActivationHosts(nsTArray& aHosts) { - for (const nsACString& host : mUserActivation.Keys()) { - aHosts.AppendElement(host); + for (BounceTrackingStateGlobal* globalState : mStateGlobal.Values()) { + for (const nsACString& host : globalState->mUserActivation.Keys()) { + aHosts.AppendElement(host); + } } return NS_OK; @@ -247,9 +277,7 @@ BounceTrackingProtection::GetUserActivationHosts(nsTArray& aHosts) { NS_IMETHODIMP BounceTrackingProtection::Reset() { BounceTrackingState::ResetAll(); - - mBounceTrackers.Clear(); - mUserActivation.Clear(); + mStateGlobal.Clear(); return NS_OK; } @@ -288,33 +316,94 @@ BounceTrackingProtection::TestRunPurgeBounceTrackers( NS_IMETHODIMP BounceTrackingProtection::TestAddBounceTrackerCandidate( const nsACString& aHost, const PRTime aBounceTime) { + const OriginAttributes oa; + BounceTrackingStateGlobal* stateGlobal = GetOrCreateStateGlobal(oa); + MOZ_ASSERT(stateGlobal); + // Can not have a host in both maps. - mUserActivation.Remove(aHost); - mBounceTrackers.InsertOrUpdate(aHost, aBounceTime); + stateGlobal->mUserActivation.Remove(aHost); + stateGlobal->mBounceTrackers.InsertOrUpdate(aHost, aBounceTime); return NS_OK; } NS_IMETHODIMP BounceTrackingProtection::TestAddUserActivation(const nsACString& aHost, const PRTime aActivationTime) { + const OriginAttributes oa; + BounceTrackingStateGlobal* stateGlobal = GetOrCreateStateGlobal(oa); + MOZ_ASSERT(stateGlobal); + // Can not have a host in both maps. - mBounceTrackers.Remove(aHost); - mUserActivation.InsertOrUpdate(aHost, aActivationTime); + stateGlobal->mBounceTrackers.Remove(aHost); + stateGlobal->mUserActivation.InsertOrUpdate(aHost, aActivationTime); return NS_OK; } RefPtr BounceTrackingProtection::PurgeBounceTrackers() { + // Run the purging algorithm for all global state objects. + for (auto& entry : mStateGlobal) { + const OriginAttributes& originAttributes = entry.GetKey(); + BounceTrackingStateGlobal* stateGlobal = entry.GetData(); + MOZ_ASSERT(stateGlobal); + + if (MOZ_LOG_TEST(gBounceTrackingProtectionLog, LogLevel::Debug)) { + nsAutoCString oaSuffix; + originAttributes.CreateSuffix(oaSuffix); + MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, + ("%s: Running purge algorithm for OA: '%s'", __FUNCTION__, + oaSuffix.get())); + } + + PurgeBounceTrackersForStateGlobal(stateGlobal, originAttributes); + } + + // Wait for all data clearing operations to complete. mClearPromises contains + // one promise per host / clear task. + return ClearDataMozPromise::AllSettled(GetCurrentSerialEventTarget(), + mClearPromises) + ->Then( + GetCurrentSerialEventTarget(), __func__, + [&](ClearDataMozPromise::AllSettledPromiseType::ResolveOrRejectValue&& + aResults) { + MOZ_ASSERT(aResults.IsResolve(), "AllSettled never rejects"); + + MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Info, + ("%s: Done. Cleared %zu hosts.", __FUNCTION__, + aResults.ResolveValue().Length())); + + nsTArray purgedSiteHosts; + // If any clear call failed reject. + for (auto& result : aResults.ResolveValue()) { + if (result.IsReject()) { + mClearPromises.Clear(); + return PurgeBounceTrackersMozPromise::CreateAndReject( + NS_ERROR_FAILURE, __func__); + } + purgedSiteHosts.AppendElement(result.ResolveValue()); + } + + // No clearing errors, resolve. + mClearPromises.Clear(); + return PurgeBounceTrackersMozPromise::CreateAndResolve( + std::move(purgedSiteHosts), __func__); + }); +} + +nsresult BounceTrackingProtection::PurgeBounceTrackersForStateGlobal( + BounceTrackingStateGlobal* aStateGlobal, + const OriginAttributes& aOriginAttributes) { + MOZ_ASSERT(aStateGlobal); MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, ("%s: #mUserActivation: %d, #mBounceTrackers: %d", __FUNCTION__, - mUserActivation.Count(), mBounceTrackers.Count())); + aStateGlobal->mUserActivation.Count(), + aStateGlobal->mBounceTrackers.Count())); // Purge already in progress. if (!mClearPromises.IsEmpty()) { MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, ("%s: Skip: Purge already in progress.", __FUNCTION__)); - return PurgeBounceTrackersMozPromise::CreateAndReject( - NS_ERROR_NOT_AVAILABLE, __func__); + return NS_ERROR_NOT_AVAILABLE; } const PRTime now = PR_Now(); @@ -329,13 +418,13 @@ BounceTrackingProtection::PurgeBounceTrackers() { // 1. Remove hosts from the user activation map whose user activation flag has // expired. - for (auto hostIter = mUserActivation.Iter(); !hostIter.Done(); + for (auto hostIter = aStateGlobal->mUserActivation.Iter(); !hostIter.Done(); hostIter.Next()) { const nsACString& host = hostIter.Key(); // Ensure that mBounceTrackers and mUserActivation maps are disjoint. A host // can never be in both maps. - MOZ_ASSERT(!mBounceTrackers.Contains(host)); + MOZ_ASSERT(!aStateGlobal->mBounceTrackers.Contains(host)); // If activationTime + bounce tracking activation lifetime is before now, // then remove host from user activation map. @@ -352,14 +441,12 @@ BounceTrackingProtection::PurgeBounceTrackers() { nsresult rv = NS_OK; nsCOMPtr clearDataService = do_GetService("@mozilla.org/clear-data-service;1", &rv); - if (NS_FAILED(rv)) { - return PurgeBounceTrackersMozPromise::CreateAndReject(rv, __func__); - } + NS_ENSURE_SUCCESS(rv, rv); mClearPromises.Clear(); nsTArray purgedSiteHosts; - for (auto hostIter = mBounceTrackers.Iter(); !hostIter.Done(); + for (auto hostIter = aStateGlobal->mBounceTrackers.Iter(); !hostIter.Done(); hostIter.Next()) { const nsACString& host = hostIter.Key(); const PRTime& bounceTime = hostIter.Data(); @@ -405,9 +492,7 @@ BounceTrackingProtection::PurgeBounceTrackers() { ("%s: Purge state for host: %s", __FUNCTION__, PromiseFlatCString(host).get())); - // TODO: Bug 1842067: DeleteDataFromBaseDomain clears the whole cookie jar, - // including state partitioned under `host` as the top level. Consider only - // clearing unpartitioned state. + // TODO: Bug 1842067: Clear by site + OA. rv = clearDataService->DeleteDataFromBaseDomain(host, false, TRACKER_PURGE_FLAGS, cb); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -422,36 +507,7 @@ BounceTrackingProtection::PurgeBounceTrackers() { hostIter.Remove(); } - // Wait for all data clearing operations to complete. mClearPromises contains - // one promise per host / clear task. - return ClearDataMozPromise::AllSettled(GetCurrentSerialEventTarget(), - mClearPromises) - ->Then( - GetCurrentSerialEventTarget(), __func__, - [&](ClearDataMozPromise::AllSettledPromiseType::ResolveOrRejectValue&& - aResults) { - MOZ_ASSERT(aResults.IsResolve(), "AllSettled never rejects"); - - MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Info, - ("%s: Done. Cleared %zu hosts.", __FUNCTION__, - aResults.ResolveValue().Length())); - - nsTArray purgedSiteHosts; - // If any clear call failed reject. - for (auto& result : aResults.ResolveValue()) { - if (result.IsReject()) { - mClearPromises.Clear(); - return PurgeBounceTrackersMozPromise::CreateAndReject( - NS_ERROR_FAILURE, __func__); - } - purgedSiteHosts.AppendElement(result.ResolveValue()); - } - - // No clearing errors, resolve. - mClearPromises.Clear(); - return PurgeBounceTrackersMozPromise::CreateAndResolve( - std::move(purgedSiteHosts), __func__); - }); + return NS_OK; } // ClearDataCallback diff --git a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtection.h b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtection.h index 56ff36636a179..e8b263d68fdea 100644 --- a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtection.h +++ b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtection.h @@ -7,9 +7,13 @@ #include "mozilla/Logging.h" #include "mozilla/MozPromise.h" #include "nsIBounceTrackingProtection.h" +#include "BounceTrackingStateGlobal.h" #include "nsIClearDataService.h" #include "nsTHashMap.h" +#include "mozilla/OriginAttributes.h" +#include "mozilla/OriginAttributesHashKey.h" + class nsIPrincipal; class nsITimer; @@ -40,16 +44,18 @@ class BounceTrackingProtection final : public nsIBounceTrackingProtection { BounceTrackingProtection(); ~BounceTrackingProtection() = default; - // Map of site hosts to moments. The moments represent the most recent wall - // clock time at which the user activated a top-level document on the - // associated site host. - nsTHashMap mUserActivation{}; + // Map of origin attributes to global state object. This enables us to track + // bounce tracking state per OA, e.g. to separate private browsing from normal + // browsing. + nsTHashMap> + mStateGlobal{}; - // Map of site hosts to moments. The moments represent the first wall clock - // time since the last execution of the bounce tracking timer at which a page - // on the given site host performed an action that could indicate stateful - // bounce tracking took place. - nsTHashMap mBounceTrackers{}; + // Getters for mStateGlobal. + BounceTrackingStateGlobal* GetOrCreateStateGlobal( + const OriginAttributes& aOriginAttributes); + BounceTrackingStateGlobal* GetOrCreateStateGlobal(nsIPrincipal* aPrincipal); + BounceTrackingStateGlobal* GetOrCreateStateGlobal( + BounceTrackingState* aBounceTrackingState); // Timer which periodically runs PurgeBounceTrackers. nsCOMPtr mBounceTrackingPurgeTimer; @@ -59,6 +65,10 @@ class BounceTrackingProtection final : public nsIBounceTrackingProtection { MozPromise, nsresult, true>; RefPtr PurgeBounceTrackers(); + nsresult PurgeBounceTrackersForStateGlobal( + BounceTrackingStateGlobal* aStateGlobal, + const OriginAttributes& aOriginAttributes); + // Pending clear operations are stored as ClearDataMozPromise, one per host. using ClearDataMozPromise = MozPromise; nsTArray> mClearPromises; diff --git a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingState.cpp b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingState.cpp index 2fcd759f24342..9f47ad9446edb 100644 --- a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingState.cpp +++ b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingState.cpp @@ -127,6 +127,11 @@ nsresult BounceTrackingState::Init( dom::BrowsingContext* browsingContext = aWebProgress->GetBrowsingContext(); NS_ENSURE_TRUE(browsingContext, NS_ERROR_FAILURE); mBrowserId = browsingContext->BrowserId(); + // Create a copy of the BC's OriginAttributes so we can use it later without + // having to hold a reference to the BC. + mOriginAttributes = browsingContext->OriginAttributesRef(); + MOZ_ASSERT(mOriginAttributes.mPartitionKey.IsEmpty(), + "Top level BCs mus not have a partition key."); // Add a listener for window load. See BounceTrackingState::OnStateChange for // the listener code. @@ -146,9 +151,13 @@ BounceTrackingRecord* BounceTrackingState::GetBounceTrackingRecord() { } nsCString BounceTrackingState::Describe() { + nsAutoCString oaSuffix; + OriginAttributesRef().CreateSuffix(oaSuffix); + return nsPrintfCString( - "{ mBounceTrackingRecord: %s }", - mBounceTrackingRecord ? mBounceTrackingRecord->Describe().get() : "null"); + "{ mBounceTrackingRecord: %s, mOriginAttributes: %s }", + mBounceTrackingRecord ? mBounceTrackingRecord->Describe().get() : "null", + oaSuffix.get()); } // static @@ -234,6 +243,10 @@ BounceTrackingState::CurrentBrowsingContext() { return dom::BrowsingContext::GetCurrentTopByBrowserId(mBrowserId); } +const OriginAttributes& BounceTrackingState::OriginAttributesRef() { + return mOriginAttributes; +} + nsresult BounceTrackingState::OnDocumentStartRequest(nsIChannel* aChannel) { NS_ENSURE_ARG_POINTER(aChannel); MOZ_LOG(gBounceTrackingProtectionLog, LogLevel::Debug, ("%s", __FUNCTION__)); diff --git a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingState.h b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingState.h index 2a51ce54c92df..fde96d77b2e66 100644 --- a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingState.h +++ b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingState.h @@ -8,6 +8,8 @@ #define mozilla_BounceTrackingState_h #include "mozilla/WeakPtr.h" +#include "mozilla/OriginAttributes.h" +#include "nsIPrincipal.h" #include "nsIWeakReferenceUtils.h" #include "nsStringFwd.h" #include "nsIWebProgressListener.h" @@ -88,6 +90,8 @@ class BounceTrackingState : public nsIWebProgressListener, uint64_t GetBrowserId() { return mBrowserId; } + const OriginAttributes& OriginAttributesRef(); + // Create a string that describes this object. Used for logging. nsCString Describe(); @@ -97,6 +101,9 @@ class BounceTrackingState : public nsIWebProgressListener, uint64_t mBrowserId{}; + // OriginAttributes associated with the browser this state is attached to. + OriginAttributes mOriginAttributes; + // Reference to the BounceTrackingProtection singleton. RefPtr mBounceTrackingProtection; diff --git a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.cpp b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.cpp new file mode 100644 index 0000000000000..a6a1f95cfdc29 --- /dev/null +++ b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.cpp @@ -0,0 +1,13 @@ +/* -*- 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 "BounceTrackingStateGlobal.h" + +namespace mozilla { + +NS_IMPL_CYCLE_COLLECTION(BounceTrackingStateGlobal); + +} // namespace mozilla diff --git a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.h b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.h new file mode 100644 index 0000000000000..dc086e32413bd --- /dev/null +++ b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.h @@ -0,0 +1,43 @@ +/* -*- 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/. */ + +#ifndef mozilla_BounceTrackingStateGlobal_h +#define mozilla_BounceTrackingStateGlobal_h + +#include "nsCycleCollectionParticipant.h" +#include "nsTHashMap.h" +#include "nsISupports.h" + +namespace mozilla { + +/** + * This class holds the global state maps which are used to keep track of + * potential bounce trackers and user activations. + * @see BounceTrackingState for the per browser / tab state. + */ +class BounceTrackingStateGlobal final { + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(BounceTrackingStateGlobal); + NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(BounceTrackingStateGlobal); + + // Map of site hosts to moments. The moments represent the most recent wall + // clock time at which the user activated a top-level document on the + // associated site host. + nsTHashMap mUserActivation{}; + + // Map of site hosts to moments. The moments represent the first wall clock + // time since the last execution of the bounce tracking timer at which a page + // on the given site host performed an action that could indicate stateful + // bounce tracking took place. + nsTHashMap mBounceTrackers{}; + + private: + ~BounceTrackingStateGlobal() = default; +}; + +} // namespace mozilla + +#endif diff --git a/toolkit/components/antitracking/bouncetrackingprotection/moz.build b/toolkit/components/antitracking/bouncetrackingprotection/moz.build index 828efc394e2bb..45bf43c8e4d58 100644 --- a/toolkit/components/antitracking/bouncetrackingprotection/moz.build +++ b/toolkit/components/antitracking/bouncetrackingprotection/moz.build @@ -22,6 +22,7 @@ EXPORTS.mozilla += [ "BounceTrackingProtection.h", "BounceTrackingRecord.h", "BounceTrackingState.h", + "BounceTrackingStateGlobal.h", "BounceTrackingStorageObserver.h", ] @@ -29,6 +30,7 @@ UNIFIED_SOURCES += [ "BounceTrackingProtection.cpp", "BounceTrackingRecord.cpp", "BounceTrackingState.cpp", + "BounceTrackingStateGlobal.cpp", "BounceTrackingStorageObserver.cpp", ]