1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "AntiTrackingLog.h"
8 #include "ContentBlockingNotifier.h"
9 #include "AntiTrackingUtils.h"
10 
11 #include "mozilla/EventQueue.h"
12 #include "mozilla/StaticPrefs_privacy.h"
13 #include "mozilla/dom/BrowserChild.h"
14 #include "mozilla/dom/BrowsingContext.h"
15 #include "mozilla/dom/WindowGlobalParent.h"
16 #include "nsIClassifiedChannel.h"
17 #include "nsIRunnable.h"
18 #include "nsIScriptError.h"
19 #include "nsIURI.h"
20 #include "nsIOService.h"
21 #include "nsGlobalWindowInner.h"
22 #include "nsJSUtils.h"
23 #include "mozIThirdPartyUtil.h"
24 
25 using namespace mozilla;
26 using mozilla::dom::BrowsingContext;
27 using mozilla::dom::ContentChild;
28 using mozilla::dom::Document;
29 
30 static const uint32_t kMaxConsoleOutputDelayMs = 100;
31 
32 namespace {
33 
RunConsoleReportingRunnable(already_AddRefed<nsIRunnable> && aRunnable)34 void RunConsoleReportingRunnable(already_AddRefed<nsIRunnable>&& aRunnable) {
35   if (StaticPrefs::privacy_restrict3rdpartystorage_console_lazy()) {
36     nsresult rv = NS_DispatchToCurrentThreadQueue(std::move(aRunnable),
37                                                   kMaxConsoleOutputDelayMs,
38                                                   EventQueuePriority::Idle);
39     if (NS_WARN_IF(NS_FAILED(rv))) {
40       return;
41     }
42   } else {
43     nsCOMPtr<nsIRunnable> runnable(std::move(aRunnable));
44     nsresult rv = runnable->Run();
45     if (NS_WARN_IF(NS_FAILED(rv))) {
46       return;
47     }
48   }
49 }
50 
ReportUnblockingToConsole(uint64_t aWindowID,nsIPrincipal * aPrincipal,const nsAString & aTrackingOrigin,ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason)51 void ReportUnblockingToConsole(
52     uint64_t aWindowID, nsIPrincipal* aPrincipal,
53     const nsAString& aTrackingOrigin,
54     ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason) {
55   MOZ_ASSERT(aWindowID);
56   MOZ_ASSERT(aPrincipal);
57 
58   nsAutoString sourceLine;
59   uint32_t lineNumber = 0, columnNumber = 0;
60   JSContext* cx = nsContentUtils::GetCurrentJSContext();
61   if (cx) {
62     nsJSUtils::GetCallingLocation(cx, sourceLine, &lineNumber, &columnNumber);
63   }
64 
65   nsCOMPtr<nsIPrincipal> principal(aPrincipal);
66   nsAutoString trackingOrigin(aTrackingOrigin);
67 
68   RefPtr<Runnable> runnable = NS_NewRunnableFunction(
69       "ReportUnblockingToConsoleDelayed",
70       [aWindowID, sourceLine, lineNumber, columnNumber, principal,
71        trackingOrigin, aReason]() {
72         const char* messageWithSameOrigin = nullptr;
73 
74         switch (aReason) {
75           case ContentBlockingNotifier::eStorageAccessAPI:
76           case ContentBlockingNotifier::ePrivilegeStorageAccessForOriginAPI:
77             messageWithSameOrigin = "CookieAllowedForOriginByStorageAccessAPI";
78             break;
79 
80           case ContentBlockingNotifier::eOpenerAfterUserInteraction:
81             [[fallthrough]];
82           case ContentBlockingNotifier::eOpener:
83             messageWithSameOrigin = "CookieAllowedForOriginByHeuristic";
84             break;
85         }
86 
87         nsAutoString origin;
88         nsresult rv = nsContentUtils::GetUTFOrigin(principal, origin);
89         if (NS_WARN_IF(NS_FAILED(rv))) {
90           return;
91         }
92 
93         // Not adding grantedOrigin yet because we may not want it later.
94         AutoTArray<nsString, 2> params = {origin, trackingOrigin};
95 
96         nsAutoString errorText;
97         rv = nsContentUtils::FormatLocalizedString(
98             nsContentUtils::eNECKO_PROPERTIES, messageWithSameOrigin, params,
99             errorText);
100         NS_ENSURE_SUCCESS_VOID(rv);
101 
102         nsContentUtils::ReportToConsoleByWindowID(
103             errorText, nsIScriptError::warningFlag,
104             ANTITRACKING_CONSOLE_CATEGORY, aWindowID, nullptr, sourceLine,
105             lineNumber, columnNumber);
106       });
107 
108   RunConsoleReportingRunnable(runnable.forget());
109 }
110 
ReportBlockingToConsole(uint64_t aWindowID,nsIURI * aURI,uint32_t aRejectedReason)111 void ReportBlockingToConsole(uint64_t aWindowID, nsIURI* aURI,
112                              uint32_t aRejectedReason) {
113   MOZ_ASSERT(aWindowID);
114   MOZ_ASSERT(aURI);
115   MOZ_ASSERT(
116       aRejectedReason == 0 ||
117       aRejectedReason ==
118           nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
119       aRejectedReason ==
120           nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
121       aRejectedReason ==
122           nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER ||
123       aRejectedReason ==
124           nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
125       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
126       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
127 
128   if (aURI->SchemeIs("chrome") || aURI->SchemeIs("about")) {
129     return;
130   }
131 
132   nsAutoString sourceLine;
133   uint32_t lineNumber = 0, columnNumber = 0;
134   JSContext* cx = nsContentUtils::GetCurrentJSContext();
135   if (cx) {
136     nsJSUtils::GetCallingLocation(cx, sourceLine, &lineNumber, &columnNumber);
137   }
138 
139   nsCOMPtr<nsIURI> uri(aURI);
140 
141   RefPtr<Runnable> runnable = NS_NewRunnableFunction(
142       "ReportBlockingToConsoleDelayed", [aWindowID, sourceLine, lineNumber,
143                                          columnNumber, uri, aRejectedReason]() {
144         const char* message = nullptr;
145         nsAutoCString category;
146         // When changing this list, please make sure to update the corresponding
147         // code in antitracking_head.js (inside _createTask).
148         // XXX: The nsIWebProgressListener constants below are interpreted as
149         // signed integers on Windows and the compiler complains that they can't
150         // be narrowed to uint32_t. To prevent this, we cast them to uint32_t.
151         switch (aRejectedReason) {
152           case uint32_t(
153               nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION):
154             message = "CookieBlockedByPermission";
155             category = "cookieBlockedPermission"_ns;
156             break;
157 
158           case uint32_t(nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER):
159             message = "CookieBlockedTracker";
160             category = "cookieBlockedTracker"_ns;
161             break;
162 
163           case uint32_t(nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL):
164             message = "CookieBlockedAll";
165             category = "cookieBlockedAll"_ns;
166             break;
167 
168           case uint32_t(nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN):
169             message = "CookieBlockedForeign";
170             category = "cookieBlockedForeign"_ns;
171             break;
172 
173           case uint32_t(
174               nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN):
175             message = "CookiePartitionedForeign2";
176             category = "cookiePartitionedForeign"_ns;
177             break;
178 
179           default:
180             return;
181         }
182 
183         MOZ_ASSERT(message);
184 
185         // Strip the URL of any possible username/password and make it ready
186         // to be presented in the UI.
187         nsCOMPtr<nsIURI> exposableURI =
188             net::nsIOService::CreateExposableURI(uri);
189         AutoTArray<nsString, 1> params;
190         CopyUTF8toUTF16(exposableURI->GetSpecOrDefault(),
191                         *params.AppendElement());
192 
193         nsAutoString errorText;
194         nsresult rv = nsContentUtils::FormatLocalizedString(
195             nsContentUtils::eNECKO_PROPERTIES, message, params, errorText);
196         NS_ENSURE_SUCCESS_VOID(rv);
197 
198         nsContentUtils::ReportToConsoleByWindowID(
199             errorText, nsIScriptError::warningFlag, category, aWindowID,
200             nullptr, sourceLine, lineNumber, columnNumber);
201       });
202 
203   RunConsoleReportingRunnable(runnable.forget());
204 }
205 
ReportBlockingToConsole(nsIChannel * aChannel,nsIURI * aURI,uint32_t aRejectedReason)206 void ReportBlockingToConsole(nsIChannel* aChannel, nsIURI* aURI,
207                              uint32_t aRejectedReason) {
208   MOZ_ASSERT(aChannel && aURI);
209 
210   // Get the top-level window ID from the top-level BrowsingContext
211   nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
212 
213   RefPtr<dom::BrowsingContext> bc;
214   loadInfo->GetBrowsingContext(getter_AddRefs(bc));
215 
216   BrowsingContext* top = bc ? bc->Top() : nullptr;
217   if (!top) {
218     return;
219   }
220 
221   uint64_t windowID = top->GetCurrentInnerWindowId();
222 
223   ReportBlockingToConsole(windowID, aURI, aRejectedReason);
224 }
225 
NotifyBlockingDecision(nsIChannel * aTrackingChannel,ContentBlockingNotifier::BlockingDecision aDecision,uint32_t aRejectedReason,nsIURI * aURI)226 void NotifyBlockingDecision(nsIChannel* aTrackingChannel,
227                             ContentBlockingNotifier::BlockingDecision aDecision,
228                             uint32_t aRejectedReason, nsIURI* aURI) {
229   MOZ_ASSERT(aTrackingChannel);
230 
231   // This can be called in either the parent process or the child processes.
232   // When this is called in the child processes, we must have a window.
233   if (XRE_IsContentProcess()) {
234     nsCOMPtr<nsILoadContext> loadContext;
235     NS_QueryNotificationCallbacks(aTrackingChannel, loadContext);
236     if (!loadContext) {
237       return;
238     }
239 
240     nsCOMPtr<mozIDOMWindowProxy> window;
241     loadContext->GetAssociatedWindow(getter_AddRefs(window));
242     if (!window) {
243       return;
244     }
245 
246     nsCOMPtr<nsPIDOMWindowOuter> outer = nsPIDOMWindowOuter::From(window);
247     if (!outer) {
248       return;
249     }
250 
251     // When this is called in the child processes with system privileges,
252     // the decision should always be ALLOW. We can stop here because both
253     // UI and content blocking log don't care this event.
254     if (nsGlobalWindowOuter::Cast(outer)->GetPrincipal() ==
255         nsContentUtils::GetSystemPrincipal()) {
256       MOZ_DIAGNOSTIC_ASSERT(aDecision ==
257                             ContentBlockingNotifier::BlockingDecision::eAllow);
258       return;
259     }
260   }
261 
262   nsAutoCString trackingOrigin;
263   if (aURI) {
264     Unused << nsContentUtils::GetASCIIOrigin(aURI, trackingOrigin);
265   }
266 
267   if (aDecision == ContentBlockingNotifier::BlockingDecision::eBlock) {
268     ContentBlockingNotifier::OnEvent(aTrackingChannel, true, aRejectedReason,
269                                      trackingOrigin);
270 
271     ReportBlockingToConsole(aTrackingChannel, aURI, aRejectedReason);
272   }
273 
274   // Now send the generic "cookies loaded" notifications, from the most generic
275   // to the most specific.
276   ContentBlockingNotifier::OnEvent(aTrackingChannel, false,
277                                    nsIWebProgressListener::STATE_COOKIES_LOADED,
278                                    trackingOrigin);
279 
280   nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
281       do_QueryInterface(aTrackingChannel);
282   if (!classifiedChannel) {
283     return;
284   }
285 
286   uint32_t classificationFlags =
287       classifiedChannel->GetThirdPartyClassificationFlags();
288   if (classificationFlags &
289       nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_TRACKING) {
290     ContentBlockingNotifier::OnEvent(
291         aTrackingChannel, false,
292         nsIWebProgressListener::STATE_COOKIES_LOADED_TRACKER, trackingOrigin);
293   }
294 
295   if (classificationFlags &
296       nsIClassifiedChannel::ClassificationFlags::CLASSIFIED_SOCIALTRACKING) {
297     ContentBlockingNotifier::OnEvent(
298         aTrackingChannel, false,
299         nsIWebProgressListener::STATE_COOKIES_LOADED_SOCIALTRACKER,
300         trackingOrigin);
301   }
302 }
303 
304 // Send a message to notify OnContentBlockingEvent in the parent, which will
305 // update the ContentBlockingLog in the parent.
NotifyEventInChild(nsIChannel * aTrackingChannel,bool aBlocked,uint32_t aRejectedReason,const nsACString & aTrackingOrigin,const Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason> & aReason)306 void NotifyEventInChild(
307     nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
308     const nsACString& aTrackingOrigin,
309     const Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason>&
310         aReason) {
311   MOZ_ASSERT(XRE_IsContentProcess());
312 
313   // We don't need to find the top-level window here because the
314   // parent will do that for us.
315   nsCOMPtr<nsILoadContext> loadContext;
316   NS_QueryNotificationCallbacks(aTrackingChannel, loadContext);
317   if (!loadContext) {
318     return;
319   }
320 
321   nsCOMPtr<mozIDOMWindowProxy> window;
322   loadContext->GetAssociatedWindow(getter_AddRefs(window));
323   if (!window) {
324     return;
325   }
326 
327   RefPtr<dom::BrowserChild> browserChild = dom::BrowserChild::GetFrom(window);
328   NS_ENSURE_TRUE_VOID(browserChild);
329 
330   nsTArray<nsCString> trackingFullHashes;
331   nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
332       do_QueryInterface(aTrackingChannel);
333 
334   if (classifiedChannel) {
335     Unused << classifiedChannel->GetMatchedTrackingFullHashes(
336         trackingFullHashes);
337   }
338 
339   browserChild->NotifyContentBlockingEvent(aRejectedReason, aTrackingChannel,
340                                            aBlocked, aTrackingOrigin,
341                                            trackingFullHashes, aReason);
342 }
343 
344 // Update the ContentBlockingLog of the top-level WindowGlobalParent of
345 // the tracking channel.
NotifyEventInParent(nsIChannel * aTrackingChannel,bool aBlocked,uint32_t aRejectedReason,const nsACString & aTrackingOrigin,const Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason> & aReason)346 void NotifyEventInParent(
347     nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
348     const nsACString& aTrackingOrigin,
349     const Maybe<ContentBlockingNotifier::StorageAccessPermissionGrantedReason>&
350         aReason) {
351   MOZ_ASSERT(XRE_IsParentProcess());
352 
353   nsCOMPtr<nsILoadInfo> loadInfo = aTrackingChannel->LoadInfo();
354   RefPtr<dom::BrowsingContext> bc;
355   loadInfo->GetBrowsingContext(getter_AddRefs(bc));
356 
357   if (!bc || bc->IsDiscarded()) {
358     return;
359   }
360 
361   bc = bc->Top();
362   RefPtr<dom::WindowGlobalParent> wgp =
363       bc->Canonical()->GetCurrentWindowGlobal();
364   NS_ENSURE_TRUE_VOID(wgp);
365 
366   nsTArray<nsCString> trackingFullHashes;
367   nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
368       do_QueryInterface(aTrackingChannel);
369 
370   if (classifiedChannel) {
371     Unused << classifiedChannel->GetMatchedTrackingFullHashes(
372         trackingFullHashes);
373   }
374 
375   wgp->NotifyContentBlockingEvent(aRejectedReason, aTrackingChannel, aBlocked,
376                                   aTrackingOrigin, trackingFullHashes, aReason);
377 }
378 
379 }  // namespace
380 
381 /* static */
ReportUnblockingToConsole(BrowsingContext * aBrowsingContext,const nsAString & aTrackingOrigin,ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason)382 void ContentBlockingNotifier::ReportUnblockingToConsole(
383     BrowsingContext* aBrowsingContext, const nsAString& aTrackingOrigin,
384     ContentBlockingNotifier::StorageAccessPermissionGrantedReason aReason) {
385   MOZ_ASSERT(aBrowsingContext);
386   MOZ_ASSERT_IF(XRE_IsContentProcess(), aBrowsingContext->Top()->IsInProcess());
387 
388   uint64_t windowID = aBrowsingContext->GetCurrentInnerWindowId();
389 
390   // The storage permission is granted under the top-level origin.
391   nsCOMPtr<nsIPrincipal> principal =
392       AntiTrackingUtils::GetPrincipal(aBrowsingContext->Top());
393   if (NS_WARN_IF(!principal)) {
394     return;
395   }
396 
397   ::ReportUnblockingToConsole(windowID, principal, aTrackingOrigin, aReason);
398 }
399 
400 /* static */
OnDecision(nsIChannel * aChannel,BlockingDecision aDecision,uint32_t aRejectedReason)401 void ContentBlockingNotifier::OnDecision(nsIChannel* aChannel,
402                                          BlockingDecision aDecision,
403                                          uint32_t aRejectedReason) {
404   MOZ_ASSERT(
405       aRejectedReason == 0 ||
406       aRejectedReason ==
407           nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
408       aRejectedReason ==
409           nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
410       aRejectedReason ==
411           nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER ||
412       aRejectedReason ==
413           nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
414       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
415       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
416   MOZ_ASSERT(aDecision == BlockingDecision::eBlock ||
417              aDecision == BlockingDecision::eAllow);
418 
419   if (!aChannel) {
420     return;
421   }
422 
423   nsCOMPtr<nsIURI> uri;
424   aChannel->GetURI(getter_AddRefs(uri));
425 
426   // Can be called in EITHER the parent or child process.
427   NotifyBlockingDecision(aChannel, aDecision, aRejectedReason, uri);
428 }
429 
430 /* static */
OnDecision(nsPIDOMWindowInner * aWindow,BlockingDecision aDecision,uint32_t aRejectedReason)431 void ContentBlockingNotifier::OnDecision(nsPIDOMWindowInner* aWindow,
432                                          BlockingDecision aDecision,
433                                          uint32_t aRejectedReason) {
434   MOZ_ASSERT(aWindow);
435   MOZ_ASSERT(
436       aRejectedReason == 0 ||
437       aRejectedReason ==
438           nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION ||
439       aRejectedReason ==
440           nsIWebProgressListener::STATE_COOKIES_BLOCKED_TRACKER ||
441       aRejectedReason ==
442           nsIWebProgressListener::STATE_COOKIES_BLOCKED_SOCIALTRACKER ||
443       aRejectedReason ==
444           nsIWebProgressListener::STATE_COOKIES_PARTITIONED_FOREIGN ||
445       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_ALL ||
446       aRejectedReason == nsIWebProgressListener::STATE_COOKIES_BLOCKED_FOREIGN);
447   MOZ_ASSERT(aDecision == BlockingDecision::eBlock ||
448              aDecision == BlockingDecision::eAllow);
449 
450   Document* document = aWindow->GetExtantDoc();
451   if (!document) {
452     return;
453   }
454 
455   nsIChannel* channel = document->GetChannel();
456   if (!channel) {
457     return;
458   }
459 
460   nsIURI* uri = document->GetDocumentURI();
461 
462   NotifyBlockingDecision(channel, aDecision, aRejectedReason, uri);
463 }
464 
465 /* static */
OnDecision(BrowsingContext * aBrowsingContext,BlockingDecision aDecision,uint32_t aRejectedReason)466 void ContentBlockingNotifier::OnDecision(BrowsingContext* aBrowsingContext,
467                                          BlockingDecision aDecision,
468                                          uint32_t aRejectedReason) {
469   MOZ_ASSERT(aBrowsingContext);
470   MOZ_ASSERT_IF(XRE_IsContentProcess(), aBrowsingContext->IsInProcess());
471 
472   if (aBrowsingContext->IsInProcess()) {
473     nsCOMPtr<nsPIDOMWindowOuter> outer = aBrowsingContext->GetDOMWindow();
474     if (NS_WARN_IF(!outer)) {
475       return;
476     }
477 
478     nsCOMPtr<nsPIDOMWindowInner> inner = outer->GetCurrentInnerWindow();
479     if (NS_WARN_IF(!inner)) {
480       return;
481     }
482 
483     ContentBlockingNotifier::OnDecision(inner, aDecision, aRejectedReason);
484   } else {
485     // we send an IPC to the content process when we don't have an in-process
486     // browsing context. This is not smart because this should be able to be
487     // done directly in the parent. The reason we are doing this is because we
488     // need the channel, which is not accessible in the parent when you only
489     // have a browsing context.
490     MOZ_ASSERT(XRE_IsParentProcess());
491 
492     ContentParent* cp = aBrowsingContext->Canonical()->GetContentParent();
493     Unused << cp->SendOnContentBlockingDecision(aBrowsingContext, aDecision,
494                                                 aRejectedReason);
495   }
496 }
497 
498 /* static */
OnEvent(nsIChannel * aTrackingChannel,uint32_t aRejectedReason,bool aBlocked)499 void ContentBlockingNotifier::OnEvent(nsIChannel* aTrackingChannel,
500                                       uint32_t aRejectedReason, bool aBlocked) {
501   MOZ_ASSERT(XRE_IsParentProcess() && aTrackingChannel);
502 
503   nsCOMPtr<nsIURI> uri;
504   aTrackingChannel->GetURI(getter_AddRefs(uri));
505 
506   nsAutoCString trackingOrigin;
507   if (uri) {
508     Unused << nsContentUtils::GetASCIIOrigin(uri, trackingOrigin);
509   }
510 
511   return ContentBlockingNotifier::OnEvent(aTrackingChannel, aBlocked,
512                                           aRejectedReason, trackingOrigin);
513 }
514 
515 /* static */
OnEvent(nsIChannel * aTrackingChannel,bool aBlocked,uint32_t aRejectedReason,const nsACString & aTrackingOrigin,const Maybe<StorageAccessPermissionGrantedReason> & aReason)516 void ContentBlockingNotifier::OnEvent(
517     nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
518     const nsACString& aTrackingOrigin,
519     const Maybe<StorageAccessPermissionGrantedReason>& aReason) {
520   if (XRE_IsParentProcess()) {
521     NotifyEventInParent(aTrackingChannel, aBlocked, aRejectedReason,
522                         aTrackingOrigin, aReason);
523   } else {
524     NotifyEventInChild(aTrackingChannel, aBlocked, aRejectedReason,
525                        aTrackingOrigin, aReason);
526   }
527 }
528