tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 89363ce08073060b586633f4d70ab781322d5199
parent 7b43fecbee41829d6a2a5f85f950ba091b6ee6ca
Author: Tom Ritter <tom@mozilla.com>
Date:   Tue,  9 Dec 2025 16:34:57 +0000

Bug 1873716: Change the plumbing to use a CanvasFingerprintingEvent r=timhuang

SKIP_BMO_CHECK

Differential Revision: https://phabricator.services.mozilla.com/D273660

Diffstat:
Mdom/ipc/BrowserChild.cpp | 7++-----
Mdom/ipc/BrowserChild.h | 4+---
Mdom/ipc/BrowserParent.cpp | 10++++------
Mdom/ipc/BrowserParent.h | 4+---
Mdom/ipc/PBrowser.ipdl | 6+++---
Mdom/ipc/WindowGlobalParent.cpp | 6++----
Mdom/ipc/WindowGlobalParent.h | 4+---
Mtoolkit/components/antitracking/AntiTrackingIPCUtils.h | 8--------
Mtoolkit/components/antitracking/ContentBlockingLog.cpp | 26++++++++++----------------
Mtoolkit/components/antitracking/ContentBlockingLog.h | 13+++++--------
Mtoolkit/components/antitracking/ContentBlockingNotifier.cpp | 23+++++++----------------
Mtoolkit/components/antitracking/ContentBlockingNotifier.h | 5+++--
Mtoolkit/components/resistfingerprinting/moz.build | 1+
Atoolkit/components/resistfingerprinting/nsRFPIPCUtils.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Mtoolkit/components/resistfingerprinting/nsRFPService.cpp | 6++++--
Mtoolkit/components/resistfingerprinting/nsRFPService.h | 24++++++++++++++++++++++++
16 files changed, 113 insertions(+), 79 deletions(-)

diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp @@ -4199,9 +4199,7 @@ void BrowserChild::NotifyContentBlockingEvent( const Maybe< mozilla::ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason, - const Maybe<ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter, - const Maybe<bool> aCanvasFingerprinterKnownText) { + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent) { if (!IPCOpen()) { return; } @@ -4210,8 +4208,7 @@ void BrowserChild::NotifyContentBlockingEvent( if (NS_SUCCEEDED(PrepareRequestData(aChannel, requestData))) { (void)SendNotifyContentBlockingEvent( aEvent, requestData, aBlocked, PromiseFlatCString(aTrackingOrigin), - aTrackingFullHashes, aReason, aCanvasFingerprinter, - aCanvasFingerprinterKnownText); + aTrackingFullHashes, aReason, aCanvasFingerprintingEvent); } } diff --git a/dom/ipc/BrowserChild.h b/dom/ipc/BrowserChild.h @@ -702,9 +702,7 @@ class BrowserChild final : public nsMessageManagerScriptExecutor, const Maybe< ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason, - const Maybe<ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter, - const Maybe<bool> aCanvasFingerprinterKnownText); + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent); already_AddRefed<nsIDragSession> GetDragSession(); void SetDragSession(nsIDragSession* aSession); diff --git a/dom/ipc/BrowserParent.cpp b/dom/ipc/BrowserParent.cpp @@ -3083,9 +3083,7 @@ mozilla::ipc::IPCResult BrowserParent::RecvNotifyContentBlockingEvent( const Maybe< mozilla::ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason, - const Maybe<mozilla::ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter, - const Maybe<bool>& aCanvasFingerprinterKnownText) { + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent) { RefPtr<BrowsingContext> bc = GetBrowsingContext(); if (!bc || bc->IsDiscarded()) { @@ -3109,9 +3107,9 @@ mozilla::ipc::IPCResult BrowserParent::RecvNotifyContentBlockingEvent( aRequestData.matchedList()); request->SetCanceledReason(aRequestData.canceledReason()); - wgp->NotifyContentBlockingEvent( - aEvent, request, aBlocked, aTrackingOrigin, aTrackingFullHashes, aReason, - aCanvasFingerprinter, aCanvasFingerprinterKnownText); + wgp->NotifyContentBlockingEvent(aEvent, request, aBlocked, aTrackingOrigin, + aTrackingFullHashes, aReason, + aCanvasFingerprintingEvent); return IPC_OK(); } diff --git a/dom/ipc/BrowserParent.h b/dom/ipc/BrowserParent.h @@ -306,9 +306,7 @@ class BrowserParent final : public PBrowserParent, nsTArray<nsCString>&& aTrackingFullHashes, const Maybe<mozilla::ContentBlockingNotifier:: StorageAccessPermissionGrantedReason>& aReason, - const Maybe<mozilla::ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter, - const Maybe<bool>& aCanvasFingerprinterKnownText); + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent); mozilla::ipc::IPCResult RecvNavigationFinished(); diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl @@ -30,6 +30,7 @@ include PTabContext; include PBackgroundSharedTypes; include "mozilla/AntiTrackingIPCUtils.h"; +include "mozilla/nsRFPIPCUtils.h"; include "mozilla/dom/BindingIPCUtils.h"; include "mozilla/dom/CSPMessageUtils.h"; include "mozilla/dom/PolicyContainerMessageUtils.h"; @@ -103,7 +104,7 @@ using mozilla::ScrollFlags from "mozilla/PresShellForwards.h"; using struct InputFormData from "mozilla/dom/SessionStoreMessageUtils.h"; using struct CollectedInputDataValue from "mozilla/dom/SessionStoreMessageUtils.h"; using mozilla::ContentBlockingNotifier::StorageAccessPermissionGrantedReason from "mozilla/ContentBlockingNotifier.h"; -using mozilla::ContentBlockingNotifier::CanvasFingerprinter from "mozilla/ContentBlockingNotifier.h"; +using mozilla::CanvasFingerprintingEvent from "nsRFPService.h"; using mozilla::dom::CallerType from "mozilla/dom/BindingDeclarations.h"; using mozilla::dom::EmbedderElementEventType from "mozilla/dom/TabMessageTypes.h"; using mozilla::IntrinsicSize from "nsIFrame.h"; @@ -546,8 +547,7 @@ parent: bool aBlocked, nsCString aTrackingOrigin, nsCString[] aTrackingFullHashes, StorageAccessPermissionGrantedReason? aReason, - CanvasFingerprinter? aCanvasFingerprinter, - bool? aCanvasFingerprinterKnownText); + CanvasFingerprintingEvent? aCanvasFingerprintingEvent); async NavigationFinished(); diff --git a/dom/ipc/WindowGlobalParent.cpp b/dom/ipc/WindowGlobalParent.cpp @@ -579,9 +579,7 @@ void WindowGlobalParent::NotifyContentBlockingEvent( const nsTArray<nsCString>& aTrackingFullHashes, const Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason, - const Maybe<ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter, - const Maybe<bool> aCanvasFingerprinterKnownText) { + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent) { MOZ_ASSERT(NS_IsMainThread()); DebugOnly<bool> isCookiesBlocked = aEvent == nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER || @@ -600,7 +598,7 @@ void WindowGlobalParent::NotifyContentBlockingEvent( Maybe<uint32_t> event = GetContentBlockingLog()->RecordLogParent( aTrackingOrigin, aEvent, aBlocked, aReason, aTrackingFullHashes, - aCanvasFingerprinter, aCanvasFingerprinterKnownText); + aCanvasFingerprintingEvent); // Notify the OnContentBlockingEvent if necessary. if (event) { diff --git a/dom/ipc/WindowGlobalParent.h b/dom/ipc/WindowGlobalParent.h @@ -196,9 +196,7 @@ class WindowGlobalParent final : public WindowContext, const Maybe< ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason, - const Maybe<ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter, - const Maybe<bool> aCanvasFingerprinterKnownText); + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent); ContentBlockingLog* GetContentBlockingLog() { return &mContentBlockingLog; } diff --git a/toolkit/components/antitracking/AntiTrackingIPCUtils.h b/toolkit/components/antitracking/AntiTrackingIPCUtils.h @@ -54,14 +54,6 @@ struct ParamTraits<nsILoadInfo::StoragePermissionState> nsILoadInfo::StoragePermissionState, nsILoadInfo::StoragePermissionState::NoStoragePermission, nsILoadInfo::StoragePermissionState::InactiveStoragePermission> {}; - -// ContentBlockingNotifier::CanvasFingerprinter over IPC. -template <> -struct ParamTraits<mozilla::ContentBlockingNotifier::CanvasFingerprinter> - : public ContiguousEnumSerializerInclusive< - mozilla::ContentBlockingNotifier::CanvasFingerprinter, - mozilla::ContentBlockingNotifier::CanvasFingerprinter::eFingerprintJS, - mozilla::ContentBlockingNotifier::CanvasFingerprinter::eMaybe> {}; } // namespace IPC #endif // mozilla_antitrackingipcutils_h diff --git a/toolkit/components/antitracking/ContentBlockingLog.cpp b/toolkit/components/antitracking/ContentBlockingLog.cpp @@ -48,9 +48,7 @@ Maybe<uint32_t> ContentBlockingLog::RecordLogParent( const Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason, const nsTArray<nsCString>& aTrackingFullHashes, - const Maybe<ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter, - const Maybe<bool> aCanvasFingerprinterKnownText) { + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent) { MOZ_ASSERT(XRE_IsParentProcess()); uint32_t events = GetContentBlockingEventsInLog(); @@ -135,8 +133,7 @@ Maybe<uint32_t> ContentBlockingLog::RecordLogParent( "We don't expected to see blocked " "STATE_ALLOWED_CANVAS_FINGERPRINTING"); entry = RecordLogInternal(aOrigin, aType, blockedValue, Nothing(), {}, - aCanvasFingerprinter, - aCanvasFingerprinterKnownText); + aCanvasFingerprintingEvent); // Replace the flag using the suspicious fingerprinting event so that we // can report the event if we detect suspicious fingerprinting. @@ -435,9 +432,7 @@ ContentBlockingLog::OriginEntry* ContentBlockingLog::RecordLogInternal( const Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason, const nsTArray<nsCString>& aTrackingFullHashes, - const Maybe<ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter, - const Maybe<bool> aCanvasFingerprinterKnownText) { + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent) { DebugOnly<bool> isCookiesBlockedTracker = aType == nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER || aType == nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER; @@ -461,8 +456,7 @@ ContentBlockingLog::OriginEntry* ContentBlockingLog::RecordLogInternal( if (!entry.mData->mLogs.IsEmpty()) { auto& last = entry.mData->mLogs.LastElement(); if (last.mType == aType && last.mBlocked == aBlocked && - last.mCanvasFingerprinter == aCanvasFingerprinter && - last.mCanvasFingerprinterKnownText == aCanvasFingerprinterKnownText) { + last.mCanvasFingerprintingEvent == aCanvasFingerprintingEvent) { ++last.mRepeatCount; // Don't record recorded events. This helps compress our log. // We don't care about if the the reason is the same, just keep the @@ -483,9 +477,9 @@ ContentBlockingLog::OriginEntry* ContentBlockingLog::RecordLogInternal( // Cap the size at the maximum length adjustable by the pref entry.mData->mLogs.RemoveElementAt(0); } - entry.mData->mLogs.AppendElement( - LogEntry{aType, 1u, aBlocked, aReason, aTrackingFullHashes.Clone(), - aCanvasFingerprinter, aCanvasFingerprinterKnownText}); + entry.mData->mLogs.AppendElement(LogEntry{aType, 1u, aBlocked, aReason, + aTrackingFullHashes.Clone(), + aCanvasFingerprintingEvent}); // Check suspicious fingerprinting activities if the origin hasn't already // been marked. @@ -522,9 +516,9 @@ ContentBlockingLog::OriginEntry* ContentBlockingLog::RecordLogInternal( MOZ_ASSERT(entry->mData->mHasSocialTrackerCookiesLoaded.isNothing()); entry->mData->mHasSocialTrackerCookiesLoaded.emplace(aBlocked); } else { - entry->mData->mLogs.AppendElement( - LogEntry{aType, 1u, aBlocked, aReason, aTrackingFullHashes.Clone(), - aCanvasFingerprinter, aCanvasFingerprinterKnownText}); + entry->mData->mLogs.AppendElement(LogEntry{aType, 1u, aBlocked, aReason, + aTrackingFullHashes.Clone(), + aCanvasFingerprintingEvent}); // Check suspicious fingerprinting activities if the origin hasn't been // marked. diff --git a/toolkit/components/antitracking/ContentBlockingLog.h b/toolkit/components/antitracking/ContentBlockingLog.h @@ -36,8 +36,7 @@ class ContentBlockingLog final { Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason> mReason; nsTArray<nsCString> mTrackingFullHashes; - Maybe<ContentBlockingNotifier::CanvasFingerprinter> mCanvasFingerprinter; - Maybe<bool> mCanvasFingerprinterKnownText; + Maybe<CanvasFingerprintingEvent> mCanvasFingerprintingEvent; }; struct OriginDataEntry { @@ -94,9 +93,8 @@ class ContentBlockingLog final { ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason = Nothing(), const nsTArray<nsCString>& aTrackingFullHashes = nsTArray<nsCString>(), - const Maybe<ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter = Nothing(), - const Maybe<bool> aCanvasFingerprinterKnownText = Nothing()); + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent = + Nothing()); void RecordLog( const nsACString& aOrigin, uint32_t aType, bool aBlocked, @@ -267,9 +265,8 @@ class ContentBlockingLog final { ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason = Nothing(), const nsTArray<nsCString>& aTrackingFullHashes = nsTArray<nsCString>(), - const Maybe<ContentBlockingNotifier::CanvasFingerprinter>& - aCanvasFingerprinter = Nothing(), - const Maybe<bool> aCanvasFingerprinterKnownText = Nothing()); + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent = + Nothing()); bool RecordLogEntryInCustomField(uint32_t aType, OriginEntry& aEntry, bool aBlocked) { diff --git a/toolkit/components/antitracking/ContentBlockingNotifier.cpp b/toolkit/components/antitracking/ContentBlockingNotifier.cpp @@ -334,9 +334,7 @@ void NotifyEventInChild( const nsACString& aTrackingOrigin, const Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason, - const Maybe<ContentBlockingNotifier::CanvasFingerprinter> - aCanvasFingerprinter, - const Maybe<bool> aCanvasFingerprinterKnownText) { + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent) { MOZ_ASSERT(XRE_IsContentProcess()); // We don't need to find the top-level window here because the @@ -366,8 +364,7 @@ void NotifyEventInChild( browserChild->NotifyContentBlockingEvent( aRejectedReason, aTrackingChannel, aBlocked, aTrackingOrigin, - trackingFullHashes, aReason, aCanvasFingerprinter, - aCanvasFingerprinterKnownText); + trackingFullHashes, aReason, aCanvasFingerprintingEvent); } // Update the ContentBlockingLog of the top-level WindowGlobalParent of @@ -377,9 +374,7 @@ void NotifyEventInParent( const nsACString& aTrackingOrigin, const Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason>& aReason, - const Maybe<ContentBlockingNotifier::CanvasFingerprinter> - aCanvasFingerprinter, - const Maybe<bool> aCanvasFingerprinterKnownText) { + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent) { MOZ_ASSERT(XRE_IsParentProcess()); nsCOMPtr<nsILoadInfo> loadInfo = aTrackingChannel->LoadInfo(); @@ -405,8 +400,7 @@ void NotifyEventInParent( wgp->NotifyContentBlockingEvent(aRejectedReason, aTrackingChannel, aBlocked, aTrackingOrigin, trackingFullHashes, aReason, - aCanvasFingerprinter, - aCanvasFingerprinterKnownText); + aCanvasFingerprintingEvent); } } // namespace @@ -576,15 +570,12 @@ void ContentBlockingNotifier::OnEvent( nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason, const nsACString& aTrackingOrigin, const Maybe<StorageAccessPermissionGrantedReason>& aReason, - const Maybe<CanvasFingerprinter>& aCanvasFingerprinter, - const Maybe<bool> aCanvasFingerprinterKnownText) { + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent) { if (XRE_IsParentProcess()) { NotifyEventInParent(aTrackingChannel, aBlocked, aRejectedReason, - aTrackingOrigin, aReason, aCanvasFingerprinter, - aCanvasFingerprinterKnownText); + aTrackingOrigin, aReason, aCanvasFingerprintingEvent); } else { NotifyEventInChild(aTrackingChannel, aBlocked, aRejectedReason, - aTrackingOrigin, aReason, aCanvasFingerprinter, - aCanvasFingerprinterKnownText); + aTrackingOrigin, aReason, aCanvasFingerprintingEvent); } } diff --git a/toolkit/components/antitracking/ContentBlockingNotifier.h b/toolkit/components/antitracking/ContentBlockingNotifier.h @@ -9,6 +9,7 @@ #include "nsStringFwd.h" #include "mozilla/Maybe.h" +#include "nsRFPService.h" #define ANTITRACKING_CONSOLE_CATEGORY "Content Blocking"_ns @@ -85,8 +86,8 @@ class ContentBlockingNotifier final { const nsACString& aTrackingOrigin, const ::mozilla::Maybe<StorageAccessPermissionGrantedReason>& aReason = Nothing(), - const Maybe<CanvasFingerprinter>& aCanvasFingerprinter = Nothing(), - const Maybe<bool> aCanvasFingerprinterKnownText = Nothing()); + const Maybe<CanvasFingerprintingEvent>& aCanvasFingerprintingEvent = + Nothing()); static void ReportUnblockingToConsole( dom::BrowsingContext* aBrowsingContext, const nsAString& aTrackingOrigin, diff --git a/toolkit/components/resistfingerprinting/moz.build b/toolkit/components/resistfingerprinting/moz.build @@ -45,6 +45,7 @@ EXPORTS += [ "RFPTargets.inc", ] EXPORTS.mozilla += [ + "nsRFPIPCUtils.h", "RelativeTimeline.h", ] EXPORTS.mozilla.gtest += ["nsUserCharacteristics.h"] diff --git a/toolkit/components/resistfingerprinting/nsRFPIPCUtils.h b/toolkit/components/resistfingerprinting/nsRFPIPCUtils.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et 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_resistfingerprinting_nsRFPIPCUtils_h +#define mozilla_resistfingerprinting_nsRFPIPCUtils_h + +#include "ipc/IPCMessageUtils.h" +#include "ipc/EnumSerializer.h" +#include "nsRFPService.h" + +namespace IPC { + +// CanvasFingerprintingEvent +template <> +struct ParamTraits<mozilla::CanvasFingerprintingEvent> { + typedef mozilla::CanvasFingerprintingEvent paramType; + + static void Write(MessageWriter* aWriter, const paramType& aParam) { + WriteParam(aWriter, aParam.alias); + WriteParam(aWriter, aParam.knownTextBitmask); + WriteParam(aWriter, aParam.source); + } + + static bool Read(MessageReader* aReader, paramType* aResult) { + mozilla::CanvasFingerprinterAlias alias; + uint32_t knownTextBitmask; + uint8_t source; + + if (!ReadParam(aReader, &alias) || !ReadParam(aReader, &knownTextBitmask) || + !ReadParam(aReader, &source)) { + return false; + } + + *aResult = + mozilla::CanvasFingerprintingEvent(alias, knownTextBitmask, source); + return true; + } +}; + +} // namespace IPC + +#endif // mozilla_resistfingerprinting_nsRFPIPCUtils_h diff --git a/toolkit/components/resistfingerprinting/nsRFPService.cpp b/toolkit/components/resistfingerprinting/nsRFPService.cpp @@ -2040,6 +2040,9 @@ static void MaybeCurrentCaller(nsACString& aFilename, uint32_t& aLineNum, return; } + auto event = + CanvasFingerprintingEvent(fingerprinter, knownTextBitmask, aSource); + if (MOZ_LOG_TEST(gFingerprinterDetection, LogLevel::Info)) { nsAutoCString filename; uint32_t lineNum = 0; @@ -2061,8 +2064,7 @@ static void MaybeCurrentCaller(nsACString& aFilename, uint32_t& aLineNum, ContentBlockingNotifier::OnEvent( aChannel, false, nsIWebProgressListener::STATE_ALLOWED_CANVAS_FINGERPRINTING, - aOriginNoSuffix, Nothing(), fingerprinter, - Some(featureUsage & CanvasFeatureUsage::KnownFingerprintText)); + aOriginNoSuffix, Nothing(), Some(event)); } /* static */ void nsRFPService::MaybeReportFontFingerprinter( diff --git a/toolkit/components/resistfingerprinting/nsRFPService.h b/toolkit/components/resistfingerprinting/nsRFPService.h @@ -185,6 +185,30 @@ class CanvasUsage { CanvasFeatureUsage aFeatureUsage) : mSize(aSize), mType(aType), mFeatureUsage(aFeatureUsage) {} }; +struct CanvasFingerprintingEvent { + // The identity or alias of the entity doing the fingerprinting. + CanvasFingerprinterAlias alias; + // A bitmask of all of the known canvas fingerprinting texts + // non-zero indicates some known fingerprinting text was used, making the + // event highly likely to be fingerprinting. + uint32_t knownTextBitmask; + // The API source of the fingerprinting, e.g. <canvas>.toDataURL + uint8_t source; + + CanvasFingerprintingEvent() + : alias(CanvasFingerprinterAlias::eNoneIdentified), + knownTextBitmask(0), + source(0) {} + + CanvasFingerprintingEvent(CanvasFingerprinterAlias aAlias, + uint32_t aKnownTextBitmask, uint8_t aSource) + : alias(aAlias), knownTextBitmask(aKnownTextBitmask), source(aSource) {} + + bool operator==(const CanvasFingerprintingEvent& other) const { + return alias == other.alias && knownTextBitmask == other.knownTextBitmask && + source == other.source; + } +}; // ============================================================================